EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Universal/Network/SnpDxe/Receive_filters.c

Go to the documentation of this file.
00001 
00018 #include "Snp.h"
00019 
00035 EFI_STATUS
00036 PxeRecvFilterEnable (
00037   SNP_DRIVER      *Snp,
00038   UINT32          EnableFlags,
00039   UINTN           MCastAddressCount,
00040   EFI_MAC_ADDRESS *MCastAddressList
00041   )
00042 {
00043   Snp->Cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;
00044   Snp->Cdb.OpFlags    = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
00045   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;
00046   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;
00047   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;
00048   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;
00049   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
00050   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
00051   Snp->Cdb.IFnum      = Snp->IfNum;
00052   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
00053 
00054   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
00055     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
00056   }
00057 
00058   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
00059     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
00060   }
00061 
00062   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
00063     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
00064   }
00065 
00066   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
00067     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
00068   }
00069 
00070   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
00071     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
00072   }
00073 
00074   if (MCastAddressCount != 0) {
00075     Snp->Cdb.CPBsize  = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
00076     Snp->Cdb.CPBaddr  = (UINT64)(UINTN)Snp->Cpb;
00077     CopyMem (Snp->Cpb, MCastAddressList, Snp->Cdb.CPBsize);
00078   }
00079   //
00080   // Issue UNDI command and check result.
00081   //
00082   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));
00083 
00084   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
00085 
00086   if (Snp->Cdb.StatCode != EFI_SUCCESS) {
00087     //
00088     // UNDI command failed.  Return UNDI status to caller.
00089     //
00090     DEBUG (
00091       (EFI_D_ERROR,
00092       "\nsnp->undi.receive_filters()  %xh:%xh\n",
00093       Snp->Cdb.StatFlags,
00094       Snp->Cdb.StatCode)
00095       );
00096 
00097     switch (Snp->Cdb.StatCode) {
00098     case PXE_STATCODE_INVALID_CDB:
00099     case PXE_STATCODE_INVALID_CPB:
00100     case PXE_STATCODE_INVALID_PARAMETER:
00101       return EFI_INVALID_PARAMETER;
00102 
00103     case PXE_STATCODE_UNSUPPORTED:
00104       return EFI_UNSUPPORTED;
00105     }
00106 
00107     return EFI_DEVICE_ERROR;
00108   }
00109 
00110   return EFI_SUCCESS;
00111 }
00112 
00125 EFI_STATUS
00126 PxeRecvFilterDisable (
00127   SNP_DRIVER *Snp,
00128   UINT32     DisableFlags,
00129   BOOLEAN    ResetMCastList
00130   )
00131 {
00132   Snp->Cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;
00133   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;
00134   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;
00135   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;
00136   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;
00137   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
00138   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
00139   Snp->Cdb.IFnum      = Snp->IfNum;
00140   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
00141 
00142   Snp->Cdb.OpFlags    = (UINT16) ((DisableFlags != 0) ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
00143 
00144   if (ResetMCastList) {
00145     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;
00146   }
00147 
00148   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
00149     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
00150   }
00151 
00152   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
00153     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
00154   }
00155 
00156   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
00157     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
00158   }
00159 
00160   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
00161     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
00162   }
00163 
00164   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
00165     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
00166   }
00167   //
00168   // Issue UNDI command and check result.
00169   //
00170   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));
00171 
00172   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
00173 
00174   if (Snp->Cdb.StatCode != EFI_SUCCESS) {
00175     //
00176     // UNDI command failed.  Return UNDI status to caller.
00177     //
00178     DEBUG (
00179       (EFI_D_ERROR,
00180       "\nsnp->undi.receive_filters()  %xh:%xh\n",
00181       Snp->Cdb.StatFlags,
00182       Snp->Cdb.StatCode)
00183       );
00184 
00185     return EFI_DEVICE_ERROR;
00186   }
00187 
00188   return EFI_SUCCESS;
00189 }
00190 
00200 EFI_STATUS
00201 PxeRecvFilterRead (
00202   SNP_DRIVER *Snp
00203   )
00204 {
00205   Snp->Cdb.OpCode   = PXE_OPCODE_RECEIVE_FILTERS;
00206   Snp->Cdb.OpFlags  = PXE_OPFLAGS_RECEIVE_FILTER_READ;
00207   Snp->Cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;
00208   Snp->Cdb.DBsize   = (UINT16) (Snp->Mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
00209   Snp->Cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;
00210   if (Snp->Cdb.DBsize == 0) {
00211     Snp->Cdb.DBaddr = (UINT64)(UINTN) NULL;
00212   } else {
00213     Snp->Cdb.DBaddr = (UINT64)(UINTN) Snp->Db;
00214     ZeroMem (Snp->Db, Snp->Cdb.DBsize);
00215   }
00216 
00217   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
00218   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
00219   Snp->Cdb.IFnum      = Snp->IfNum;
00220   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
00221 
00222   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));
00223 
00224   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
00225 
00226   if (Snp->Cdb.StatCode != EFI_SUCCESS) {
00227     //
00228     // UNDI command failed.  Return UNDI status to caller.
00229     //
00230     DEBUG (
00231       (EFI_D_ERROR,
00232       "\nsnp->undi.receive_filters()  %xh:%xh\n",
00233       Snp->Cdb.StatFlags,
00234       Snp->Cdb.StatCode)
00235       );
00236 
00237     return EFI_DEVICE_ERROR;
00238   }
00239   //
00240   // Convert UNDI32 StatFlags to EFI SNP filter flags.
00241   //
00242   Snp->Mode.ReceiveFilterSetting = 0;
00243 
00244   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
00245     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
00246   }
00247 
00248   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
00249     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
00250   }
00251 
00252   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
00253     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
00254   }
00255 
00256   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
00257     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
00258   }
00259 
00260   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
00261     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
00262   }
00263 
00264   CopyMem (Snp->Mode.MCastFilter, Snp->Db, Snp->Cdb.DBsize);
00265 
00266   //
00267   // Count number of active entries in multicast filter list.
00268   //
00269   {
00270     EFI_MAC_ADDRESS ZeroMacAddr;
00271 
00272     SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
00273 
00274     for (Snp->Mode.MCastFilterCount = 0;
00275          Snp->Mode.MCastFilterCount < Snp->Mode.MaxMCastFilterCount;
00276          Snp->Mode.MCastFilterCount++
00277         ) {
00278       if (CompareMem (
00279             &Snp->Mode.MCastFilter[Snp->Mode.MCastFilterCount],
00280             &ZeroMacAddr,
00281             sizeof ZeroMacAddr
00282             ) == 0) {
00283         break;
00284       }
00285     }
00286   }
00287 
00288   return EFI_SUCCESS;
00289 }
00290 
00291 
00386 EFI_STATUS
00387 EFIAPI
00388 SnpUndi32ReceiveFilters (
00389   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
00390   IN UINT32                      Enable,
00391   IN UINT32                      Disable,
00392   IN BOOLEAN                     ResetMCastFilter,
00393   IN UINTN                       MCastFilterCnt,  OPTIONAL
00394   IN EFI_MAC_ADDRESS             *MCastFilter     OPTIONAL
00395   )
00396 {
00397   SNP_DRIVER  *Snp;
00398   EFI_STATUS  Status;
00399   EFI_TPL     OldTpl;
00400 
00401   if (This == NULL) {
00402     return EFI_INVALID_PARAMETER;
00403   }
00404 
00405   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
00406 
00407   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
00408 
00409   switch (Snp->Mode.State) {
00410   case EfiSimpleNetworkInitialized:
00411     break;
00412 
00413   case EfiSimpleNetworkStopped:
00414     Status = EFI_NOT_STARTED;
00415     goto ON_EXIT;
00416 
00417   default:
00418     Status = EFI_DEVICE_ERROR;
00419     goto ON_EXIT;
00420   }
00421   //
00422   // check if we are asked to enable or disable something that the UNDI
00423   // does not even support!
00424   //
00425   if (((Enable &~Snp->Mode.ReceiveFilterMask) != 0) ||
00426     ((Disable &~Snp->Mode.ReceiveFilterMask) != 0)) {
00427     Status = EFI_INVALID_PARAMETER;
00428     goto ON_EXIT;
00429   }
00430 
00431   if (ResetMCastFilter) {
00432 
00433     Disable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Snp->Mode.ReceiveFilterMask;
00434     MCastFilterCnt = 0;
00435     MCastFilter    = NULL;
00436   } else {
00437     if (MCastFilterCnt != 0) {
00438       if ((MCastFilterCnt > Snp->Mode.MaxMCastFilterCount) ||
00439           (MCastFilter == NULL)) {
00440 
00441         Status = EFI_INVALID_PARAMETER;
00442         goto ON_EXIT;
00443       }
00444     }
00445   }
00446 
00447   if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {
00448     Status = EFI_SUCCESS;
00449     goto ON_EXIT;
00450   }
00451 
00452   if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
00453     Status = EFI_INVALID_PARAMETER;
00454     goto ON_EXIT;
00455   }
00456 
00457   if ((Enable != 0) || (MCastFilterCnt != 0)) {
00458     Status = PxeRecvFilterEnable (
00459                Snp,
00460                Enable,
00461                MCastFilterCnt,
00462                MCastFilter
00463                );
00464 
00465     if (EFI_ERROR (Status)) {
00466       goto ON_EXIT;
00467     }
00468   }
00469 
00470   if ((Disable != 0) || ResetMCastFilter) {
00471     Status = PxeRecvFilterDisable (Snp, Disable, ResetMCastFilter);
00472 
00473     if (EFI_ERROR (Status)) {
00474       goto ON_EXIT;
00475     }
00476   }
00477 
00478   Status = PxeRecvFilterRead (Snp);
00479 
00480 ON_EXIT:
00481   gBS->RestoreTPL (OldTpl);
00482 
00483   return Status;
00484 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines