/** @file
  Connect to and disconnect from the various network layers

  Copyright (c) 2011, Intel Corporation
  All rights reserved. This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Socket.h"


/**
  Connect to the network service bindings

  Walk the network service protocols on the controller handle and
  locate any that are not in use.  Create ::ESL_SERVICE structures to
  manage the network layer interfaces for the socket driver.  Tag
  each of the network interfaces that are being used.  Finally, this
  routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
  interface for use by the socket layer.

  @param [in] BindingHandle    Handle for protocol binding.
  @param [in] Controller       Handle of device to work with.

  @retval EFI_SUCCESS          This driver is added to Controller.
  @retval EFI_OUT_OF_RESOURCES No more memory available.
  @retval EFI_UNSUPPORTED      This driver does not support this device.

**/
EFI_STATUS
EFIAPI
EslServiceConnect (
  IN EFI_HANDLE BindingHandle,
  IN EFI_HANDLE Controller
  )
{
  BOOLEAN bInUse;
  EFI_STATUS ExitStatus;
  UINTN LengthInBytes;
  UINT8 * pBuffer;
  CONST ESL_SOCKET_BINDING * pEnd;
  VOID * pJunk;
  ESL_SERVICE ** ppServiceListHead;
  ESL_SERVICE * pService;
  CONST ESL_SOCKET_BINDING * pSocketBinding;
  EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
  EFI_STATUS Status;
  EFI_TPL TplPrevious;

  DBG_ENTER ( );

  //
  //  Assume the list is empty
  //
  ExitStatus = EFI_UNSUPPORTED;
  bInUse = FALSE;

  //
  //  Walk the list of network connection points
  //
  pSocketBinding = &cEslSocketBinding[0];
  pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
  while ( pEnd > pSocketBinding ) {
    //
    //  Determine if the controller supports the network protocol
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    pSocketBinding->pNetworkBinding,
                    (VOID**)&pServiceBinding,
                    BindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if ( !EFI_ERROR ( Status )) {
      //
      //  Determine if the socket layer is already connected
      //
      Status = gBS->OpenProtocol (
                      Controller,
                      (EFI_GUID *)pSocketBinding->pTagGuid,
                      &pJunk,
                      BindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if ( EFI_UNSUPPORTED == Status ) {
        //
        //  Allocate a service structure since the tag is not present
        //
        LengthInBytes = sizeof ( *pService );
        Status = gBS->AllocatePool (
                        EfiRuntimeServicesData,
                        LengthInBytes,
                        (VOID **) &pService
                        );
        if ( !EFI_ERROR ( Status )) {
          DEBUG (( DEBUG_POOL | DEBUG_INIT,
                    "0x%08x: Allocate pService, %d bytes\r\n",
                    pService,
                    LengthInBytes ));

          //
          //  Set the structure signature and service binding
          //
          ZeroMem ( pService, LengthInBytes );
          pService->Signature = SERVICE_SIGNATURE;
          pService->pSocketBinding = pSocketBinding;
          pService->Controller = Controller;
          pService->pServiceBinding = pServiceBinding;

          //
          //  Mark the controller in use
          //
          if ( !bInUse ) {
            Status = gBS->InstallMultipleProtocolInterfaces (
                            &Controller,
                            &gEfiCallerIdGuid,
                            NULL,
                            NULL
                            );
            if ( !EFI_ERROR ( Status )) {
              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                        "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
                        Controller ));
              bInUse = TRUE;
            }
            else {
              if ( EFI_INVALID_PARAMETER == Status ) {
                Status = EFI_SUCCESS;
              }
            }
          }
          if ( !EFI_ERROR ( Status )) {
            //
            //  Mark the network service protocol in use
            //
            Status = gBS->InstallMultipleProtocolInterfaces (
                            &Controller,
                            pSocketBinding->pTagGuid,
                            pService,
                            NULL
                            );
            if ( !EFI_ERROR ( Status )) {
              DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                        "Installed: %s TagGuid on   0x%08x\r\n",
                        pSocketBinding->pName,
                        Controller ));

              //
              //  Synchronize with the socket layer
              //
              RAISE_TPL ( TplPrevious, TPL_SOCKETS );

              //
              //  Connect the service to the list
              //
              pBuffer = (UINT8 *)&mEslLayer;
              pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];
              ppServiceListHead = (ESL_SERVICE **)pBuffer;
              pService->pNext = *ppServiceListHead;
              *ppServiceListHead = pService;

              //
              //  Release the socket layer synchronization
              //
              RESTORE_TPL ( TplPrevious );

              //
              //  At least one service was made available
              //
              ExitStatus = EFI_SUCCESS;
            }
            else {
              DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                        "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",
                        pSocketBinding->pName,
                        Controller,
                        Status ));
            }

            if ( EFI_ERROR ( Status )) {
              //
              //  The controller is no longer in use
              //
              if ( bInUse ) {
                gBS->UninstallMultipleProtocolInterfaces (
                          Controller,
                          &gEfiCallerIdGuid,
                          NULL,
                          NULL );
                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                            "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
                            Controller ));
              }
            }
          }
          else {
            DEBUG (( DEBUG_ERROR | DEBUG_INIT,
                      "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",
                      Controller,
                      Status ));
          }

          //
          //  Release the service if necessary
          //
          if ( EFI_ERROR ( Status )) {
            gBS->FreePool ( pService );
            DEBUG (( DEBUG_POOL | DEBUG_INIT,
                      "0x%08x: Free pService, %d bytes\r\n",
                      pService,
                      sizeof ( *pService )));
            pService = NULL;
          }
        }
        else {
          DEBUG (( DEBUG_ERROR | DEBUG_INIT,
                    "ERROR - Failed service allocation, Status: %r\r\n",
                    Status ));
          ExitStatus = EFI_OUT_OF_RESOURCES;
          break;
        }
      }
    }
  
    //
    //  Set the next network protocol
    //
    pSocketBinding += 1;
  }
  
  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( ExitStatus );
  return ExitStatus;
}


/**
  Shutdown the connections to the network layer by locating the
  tags on the network interfaces established by ::EslServiceConnect.
  This routine shutdowns any activity on the network interface and
  then frees the ::ESL_SERVICE structures.

  @param [in] BindingHandle    Handle for protocol binding.
  @param [in] Controller       Handle of device to stop driver on.

  @retval EFI_SUCCESS          This driver is removed Controller.
  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
  @retval other                This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
EslServiceDisconnect (
  IN  EFI_HANDLE BindingHandle,
  IN  EFI_HANDLE Controller
  )
{
  UINT8 * pBuffer;
  CONST ESL_SOCKET_BINDING * pEnd;
  ESL_PORT * pPort;
  ESL_SERVICE * pPreviousService;
  ESL_SERVICE * pService;
  ESL_SERVICE ** ppServiceListHead;
  CONST ESL_SOCKET_BINDING * pSocketBinding;
  EFI_STATUS Status;
  EFI_TPL TplPrevious;
  
  DBG_ENTER ( );

  //
  //  Walk the list of network connection points in reverse order
  //
  pEnd = &cEslSocketBinding[0];
  pSocketBinding = &pEnd[ cEslSocketBindingEntries ];
  while ( pEnd < pSocketBinding ) {
    //
    //  Set the next network protocol
    //
    pSocketBinding -= 1;

    //
    //  Determine if the driver connected
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    (EFI_GUID *)pSocketBinding->pTagGuid,
                    (VOID **)&pService,
                    BindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if ( !EFI_ERROR ( Status )) {

      //
      //  Synchronize with the socket layer
      //
      RAISE_TPL ( TplPrevious, TPL_SOCKETS );

      //
      //  Walk the list of ports
      //
      pPort = pService->pPortList;
      while ( NULL != pPort ) {
        //
        //  Remove the port from the port list
        //
        pPort->pService = NULL;
        pService->pPortList = pPort->pLinkService;
  
        //
        //  Close the port
        //
        EslSocketPortCloseStart ( pPort,
                                  TRUE,
                                  DEBUG_POOL | DEBUG_INIT );

        //
        //  Set the next port
        //
        pPort = pService->pPortList;
      }
    
      //
      //  Remove the service from the service list
      //
      pBuffer = (UINT8 *)&mEslLayer;
      pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];
      ppServiceListHead = (ESL_SERVICE **)pBuffer;
      pPreviousService = *ppServiceListHead;
      if ( pService == pPreviousService ) {
        //
        //  Remove the service from the beginning of the list
        //
        *ppServiceListHead = pService->pNext;
      }
      else {
        //
        //  Remove the service from the middle of the list
        //
        while ( NULL != pPreviousService ) {
          if ( pService == pPreviousService->pNext ) {
            pPreviousService->pNext = pService->pNext;
            break;
          }
          pPreviousService = pPreviousService->pNext;
        }
      }

      //
      //  Release the socket layer synchronization
      //
      RESTORE_TPL ( TplPrevious );

      //
      //  Break the driver connection
      //
      Status = gBS->UninstallMultipleProtocolInterfaces (
                Controller,
                pSocketBinding->pTagGuid,
                pService,
                NULL );
      if ( !EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                    "Removed:   %s TagGuid from 0x%08x\r\n",
                    pSocketBinding->pName,
                    Controller ));
      }
      else {
        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                    "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",
                    pSocketBinding->pName,
                    Controller,
                    Status ));
      }

      //
      //  Free the service structure
      //
      Status = gBS->FreePool ( pService );
      if ( !EFI_ERROR ( Status )) {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                  "0x%08x: Free pService, %d bytes\r\n",
                  pService,
                  sizeof ( *pService )));
      }
      else {
        DEBUG (( DEBUG_POOL | DEBUG_INIT,
                  "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",
                  pService,
                  Status ));
      }
      pService = NULL;
    }
  }

  //
  //  The controller is no longer in use
  //
  gBS->UninstallMultipleProtocolInterfaces (
            Controller,
            &gEfiCallerIdGuid,
            NULL,
            NULL );
  DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
              Controller ));

  //
  //  The driver is disconnected from the network controller
  //
  Status = EFI_SUCCESS;

  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}



/**
Initialize the service layer

@param [in] ImageHandle       Handle for the image.

**/
VOID
EFIAPI
EslServiceLoad (
  IN EFI_HANDLE ImageHandle
  )
{
  ESL_LAYER * pLayer;

  //
  //  Save the image handle
  //
  pLayer = &mEslLayer;
  ZeroMem ( pLayer, sizeof ( *pLayer ));
  pLayer->Signature = LAYER_SIGNATURE;
  pLayer->ImageHandle = ImageHandle;

  //
  //  Connect the service binding protocol to the image handle
  //
  pLayer->pServiceBinding = &mEfiServiceBinding;
}


/**
  Shutdown the service layer

**/
VOID
EFIAPI
EslServiceUnload (
  VOID
  )
{
  ESL_LAYER * pLayer;

  //
  //  Undo the work by ServiceLoad
  //
  pLayer = &mEslLayer;
  pLayer->ImageHandle = NULL;
  pLayer->pServiceBinding = NULL;
}
