Home | History | Annotate | Download | only in SnpDxe
      1 /** @file
      2     Implementation of starting a network adapter.
      3 
      4 Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials are licensed
      6 and made available under the terms and conditions of the BSD License which
      7 accompanies this distribution. The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "Snp.h"
     16 
     17 
     18 /**
     19   Call UNDI to start the interface and changes the snp state.
     20 
     21   @param  Snp                    pointer to snp driver structure.
     22 
     23   @retval EFI_SUCCESS            UNDI is started successfully.
     24   @retval EFI_DEVICE_ERROR       UNDI could not be started.
     25 
     26 **/
     27 EFI_STATUS
     28 PxeStart (
     29   IN SNP_DRIVER *Snp
     30   )
     31 {
     32   PXE_CPB_START_31  *Cpb31;
     33 
     34   Cpb31  = Snp->Cpb;
     35   //
     36   // Initialize UNDI Start CDB for H/W UNDI
     37   //
     38   Snp->Cdb.OpCode     = PXE_OPCODE_START;
     39   Snp->Cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;
     40   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;
     41   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;
     42   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;
     43   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;
     44   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
     45   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
     46   Snp->Cdb.IFnum      = Snp->IfNum;
     47   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
     48 
     49   //
     50   // Make changes to H/W UNDI Start CDB if this is
     51   // a S/W UNDI.
     52   //
     53   if (Snp->IsSwUndi) {
     54     Snp->Cdb.CPBsize  = (UINT16) sizeof (PXE_CPB_START_31);
     55     Snp->Cdb.CPBaddr  = (UINT64)(UINTN) Cpb31;
     56 
     57     Cpb31->Delay     = (UINT64)(UINTN) &SnpUndi32CallbackDelay;
     58     Cpb31->Block     = (UINT64)(UINTN) &SnpUndi32CallbackBlock;
     59 
     60     //
     61     // Virtual == Physical.  This can be set to zero.
     62     //
     63     Cpb31->Virt2Phys = (UINT64)(UINTN) 0;
     64     Cpb31->Mem_IO    = (UINT64)(UINTN) &SnpUndi32CallbackMemio;
     65 
     66     Cpb31->Map_Mem   = (UINT64)(UINTN) &SnpUndi32CallbackMap;
     67     Cpb31->UnMap_Mem = (UINT64)(UINTN) &SnpUndi32CallbackUnmap;
     68     Cpb31->Sync_Mem  = (UINT64)(UINTN) &SnpUndi32CallbackSync;
     69 
     70     Cpb31->Unique_ID = (UINT64)(UINTN) Snp;
     71   }
     72   //
     73   // Issue UNDI command and check result.
     74   //
     75   DEBUG ((EFI_D_NET, "\nsnp->undi.start()  "));
     76 
     77   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
     78 
     79   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
     80     //
     81     // UNDI could not be started. Return UNDI error.
     82     //
     83     DEBUG (
     84       (EFI_D_ERROR,
     85       "\nsnp->undi.start()  %xh:%xh\n",
     86       Snp->Cdb.StatCode,
     87       Snp->Cdb.StatFlags)
     88       );
     89 
     90     return EFI_DEVICE_ERROR;
     91   }
     92   //
     93   // Set simple network state to Started and return success.
     94   //
     95   Snp->Mode.State = EfiSimpleNetworkStarted;
     96 
     97   return EFI_SUCCESS;
     98 }
     99 
    100 
    101 /**
    102   Change the state of a network interface from "stopped" to "started."
    103 
    104   This function starts a network interface. If the network interface successfully
    105   starts, then EFI_SUCCESS will be returned.
    106 
    107   @param  This                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
    108 
    109   @retval EFI_SUCCESS            The network interface was started.
    110   @retval EFI_ALREADY_STARTED    The network interface is already in the started state.
    111   @retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid
    112                                  EFI_SIMPLE_NETWORK_PROTOCOL structure.
    113   @retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
    114   @retval EFI_UNSUPPORTED        This function is not supported by the network interface.
    115 
    116 **/
    117 EFI_STATUS
    118 EFIAPI
    119 SnpUndi32Start (
    120   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
    121   )
    122 {
    123   SNP_DRIVER  *Snp;
    124   EFI_STATUS  Status;
    125   UINTN       Index;
    126   EFI_TPL     OldTpl;
    127 
    128   if (This == NULL) {
    129     return EFI_INVALID_PARAMETER;
    130   }
    131 
    132   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
    133 
    134   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
    135 
    136   switch (Snp->Mode.State) {
    137   case EfiSimpleNetworkStopped:
    138     break;
    139 
    140   case EfiSimpleNetworkStarted:
    141   case EfiSimpleNetworkInitialized:
    142     Status = EFI_ALREADY_STARTED;
    143     goto ON_EXIT;
    144 
    145   default:
    146     Status = EFI_DEVICE_ERROR;
    147     goto ON_EXIT;
    148   }
    149 
    150   Status = PxeStart (Snp);
    151   if (EFI_ERROR (Status)) {
    152     goto ON_EXIT;
    153   }
    154   //
    155   // clear the map_list in SNP structure
    156   //
    157   for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
    158     Snp->MapList[Index].VirtualAddress = 0;
    159     Snp->MapList[Index].MapCookie      = 0;
    160   }
    161 
    162   Snp->Mode.MCastFilterCount = 0;
    163 
    164 ON_EXIT:
    165   gBS->RestoreTPL (OldTpl);
    166 
    167   return Status;
    168 }
    169