/** @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 other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
EslServiceConnect (
  IN EFI_HANDLE BindingHandle,
  IN EFI_HANDLE Controller
  )
{
  BOOLEAN bInUse;
  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
  //
  Status = 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 );

              //
              //  Determine if the initialization was successful
              //
              if ( EFI_ERROR ( Status )) {
                DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                          "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",
                          pSocketBinding->pName,
                          Controller,
                          Status ));

                //
                //  Free the network service binding if necessary
                //
                gBS->UninstallMultipleProtocolInterfaces (
                          Controller,
                          pSocketBinding->pTagGuid,
                          pService,
                          NULL );
                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
                            "Removed:   %s TagGuid from 0x%08x\r\n",
                            pSocketBinding->pName,
                            Controller ));
              }
            }
            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 ));
        }
      }
    }
  
    //
    //  Set the next network protocol
    //
    pSocketBinding += 1;
  }
  
  //
  //  Display the driver start status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}


/**
  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;
}
