+/** @file\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ SnpNt32.c\r
+\r
+Abstract:\r
+\r
+-**/\r
+\r
+#include "SnpNt32.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gSnpNt32DriverBinding = {\r
+ SnpNt32DriverBindingSupported,\r
+ SnpNt32DriverBindingStart,\r
+ SnpNt32DriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+SNPNT32_GLOBAL_DATA gSnpNt32GlobalData = {\r
+ SNP_NT32_DRIVER_SIGNATURE, // Signature\r
+ {\r
+ NULL,\r
+ NULL\r
+ }, // InstanceList\r
+ NULL, // WinNtThunk\r
+ NULL, // NetworkLibraryHandle\r
+ {\r
+ 0\r
+ }, // NtNetUtilityTable\r
+ {\r
+ 0,\r
+ 0,\r
+ 0\r
+ }, // Lock\r
+ //\r
+ // Private functions\r
+ //\r
+ SnpNt32InitializeGlobalData, // InitializeGlobalData\r
+ SnpNt32InitializeInstanceData, // InitializeInstanceData\r
+ SnpNt32CloseInstance // CloseInstance\r
+};\r
+\r
+\r
+/**\r
+ Test to see if this driver supports ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver supports this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SnpNt32DriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+\r
+ SNPNT32_GLOBAL_DATA *GlobalData;\r
+ NET_LIST_ENTRY *Entry;\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+\r
+ GlobalData = &gSnpNt32GlobalData;\r
+\r
+ NET_LIST_FOR_EACH (Entry, &GlobalData->InstanceList) {\r
+\r
+ Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
+\r
+ if (Instance->DeviceHandle == ControllerHandle) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Start this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver is added to ControllerHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SnpNt32DriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Stop this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on.\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
+ of children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCES This driver is removed ControllerHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SnpNt32DriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Start the SnpNt32 interface.\r
+\r
+ @param This Context pointer.\r
+\r
+ @retval EFI_SUCCESS The interface is started.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Start (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Stop the SnpNt32 interface.\r
+\r
+ @param This Context pointer.\r
+\r
+ @retval EFI_SUCCESS The interface is stopped.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Stop (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Initialize the SnpNt32 interface.\r
+\r
+ @param This Context pointer.\r
+ @param ExtraRxBufferSize Number of extra receive buffer.\r
+ @param ExtraTxBufferSize Number of extra transmit buffer.\r
+\r
+ @retval EFI_SUCCESS The interface is initialized.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Initialize (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN UINTN ExtraRxBufferSize OPTIONAL,\r
+ IN UINTN ExtraTxBufferSize OPTIONAL\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Reset the snpnt32 interface.\r
+\r
+ @param This Context pointer.\r
+ @param ExtendedVerification Not implemented.\r
+\r
+ @retval EFI_SUCCESS The interface is reseted.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Reset (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Shut down the snpnt32 interface.\r
+\r
+ @param This Context pointer.\r
+\r
+ @retval EFI_SUCCESS The interface is shut down.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Shutdown (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Change the interface's receive filter setting.\r
+\r
+ @param This Context pointer.\r
+ @param EnableBits The receive filters to enable.\r
+ @param DisableBits The receive filters to disable\r
+ @param ResetMcastFilter Reset the multicast filters or not.\r
+ @param McastFilterCount The count of multicast filter to set.\r
+ @param McastFilter Pointer to the arrya of multicast addresses to set.\r
+\r
+ @retval EFI_SUCCESS The receive filter is updated.\r
+ @retval EFI_ACCESS_DENIED The snpnt32 lock is already owned by another\r
+ routine.\r
+ @retval EFI_DEVICE_ERROR Failed to update the receive filter.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32ReceiveFilters (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN UINT32 EnableBits,\r
+ IN UINT32 DisableBits,\r
+ IN BOOLEAN ResetMcastFilter,\r
+ IN UINTN McastFilterCount OPTIONAL,\r
+ IN EFI_MAC_ADDRESS *McastFilter OPTIONAL\r
+ )\r
+{\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+ SNPNT32_GLOBAL_DATA *GlobalData;\r
+ INT32 ReturnValue;\r
+\r
+ Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
+\r
+ GlobalData = Instance->GlobalData;\r
+\r
+ if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (\r
+ Instance->InterfaceInfo.InterfaceIndex,\r
+ EnableBits,\r
+ McastFilterCount,\r
+ McastFilter\r
+ );\r
+\r
+ NET_UNLOCK (&GlobalData->Lock);\r
+\r
+ if (ReturnValue <= 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Change or reset the mac address of the interface.\r
+\r
+ @param This Context pointer.\r
+ @param reset Reset the mac address to the original one or not.\r
+ @param NewMacAddr Pointer to the new mac address to set.\r
+\r
+ @retval EFI_UNSUPPORTED Not supported yet.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32StationAddress (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN BOOLEAN Reset,\r
+ IN EFI_MAC_ADDRESS *NewMacAddr OPTIONAL\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Get or reset the statistics data.\r
+\r
+ @param This Context pointer.\r
+ @param Reset Reset the statistics or not.\r
+ @param StatisticsSize The size of the buffer used to receive the\r
+ statistics data.\r
+ @param StatisticsTable Pointer to the table used to receive the statistics\r
+ data.\r
+\r
+ @retval EFI_UNSUPPORTED Not supported yet.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Statistics (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
+ IN BOOLEAN Reset,\r
+ IN OUT UINTN *StatisticsSize OPTIONAL,\r
+ IN OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Convert a multicast ip address to the multicast mac address.\r
+\r
+ @param This Context pointer.\r
+ @param Ipv6 The Ip is an Ipv6 address or not.\r
+ @param Ip Pointer to the Ip address to convert.\r
+ @param Mac Pointer to the buffer used to hold the converted\r
+ mac address.\r
+\r
+ @retval EFI_UNSUPPORTED Not supported yet.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32McastIptoMac (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN BOOLEAN Ipv6,\r
+ IN EFI_IP_ADDRESS *Ip,\r
+ OUT EFI_MAC_ADDRESS *Mac\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Read or write the nv data.\r
+\r
+ @param This Context pinter.\r
+ @param ReadOrWrite Read or write the nv data.\r
+ @param Offset The offset to the start of the nv data.\r
+ @param BufferSize Size of the buffer.\r
+ @param Buffer Pointer to the buffer containing the data to write\r
+ or used to receive the data read.\r
+\r
+ @retval EFI_UNSUPPORTED Not supported yet.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Nvdata (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN BOOLEAN ReadOrWrite,\r
+ IN UINTN Offset,\r
+ IN UINTN BufferSize,\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Get the status information of the interface.\r
+\r
+ @param This Context pointer.\r
+ @param InterruptStatus The storage to hold the interrupt status.\r
+ @param TxBuffer Pointer to get the list of pointers of previously\r
+ transmitted buffers whose transmission was\r
+ completed asynchrnously.\r
+\r
+ @retval EFI_SUCCESS The status is got.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32GetStatus (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ OUT UINT32 *InterruptStatus,\r
+ OUT VOID **TxBuffer\r
+ )\r
+{\r
+\r
+ if (TxBuffer != NULL) {\r
+ *((UINT8 **) TxBuffer) = (UINT8 *) 1;\r
+ }\r
+\r
+ if (InterruptStatus != NULL) {\r
+ *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Transmit a packet.\r
+\r
+ @param This Context pointer.\r
+ @param HeaderSize The media header size contained in the packet\r
+ buffer.\r
+ @param BufferSize The size of the packet buffer.\r
+ @param Buffer Pointer to the buffer containing the packet data.\r
+ @param SrcAddr If non null, points to the source address of this\r
+ packet.\r
+ @param DestAddr If non null, points to the destination address of\r
+ this packet.\r
+ @param Protocol The protocol type of this packet.\r
+\r
+ @retval EFI_SUCCESS The packet is transmitted or put into the transmit\r
+ queue.\r
+ @retval other Some error occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Transmit (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN UINTN HeaderSize,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer,\r
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
+ IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
+ IN UINT16 *Protocol OPTIONAL\r
+ )\r
+{\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+ SNPNT32_GLOBAL_DATA *GlobalData;\r
+ INT32 ReturnValue;\r
+\r
+ Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
+\r
+ GlobalData = Instance->GlobalData;\r
+\r
+ if ((HeaderSize != 0) && (SrcAddr == NULL)) {\r
+ SrcAddr = &Instance->Mode.CurrentAddress;\r
+ }\r
+\r
+ if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ ReturnValue = GlobalData->NtNetUtilityTable.Transmit (\r
+ Instance->InterfaceInfo.InterfaceIndex,\r
+ HeaderSize,\r
+ BufferSize,\r
+ Buffer,\r
+ SrcAddr,\r
+ DestAddr,\r
+ Protocol\r
+ );\r
+\r
+ NET_UNLOCK (&GlobalData->Lock);\r
+\r
+ if (ReturnValue < 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Receive network data.\r
+\r
+ @param This Context pointer.\r
+ @param HeaderSize Optional parameter and is a pointer to the header\r
+ portion of the data received.\r
+ @param BuffSize Pointer to the length of the Buffer on entry and\r
+ contains the length of the received data on return\r
+ @param Buffer Pointer to the memory for the received data\r
+ @param SourceAddr Optional parameter, is a pointer to contain the\r
+ source ethernet address on return\r
+ @param DestinationAddr Optional parameter, is a pointer to contain the\r
+ destination ethernet address on return.\r
+ @param Protocol Optional parameter, is a pointer to contain the\r
+ Protocol type from the ethernet header on return.\r
+\r
+ @retval EFI_SUCCESS A packet is received and put into the buffer.\r
+ @retval EFI_BUFFER_TOO_SMALL The provided buffer is too small to receive the\r
+ packet.\r
+ @retval EFI_NOT_READY There is no packet received.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32Receive (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ OUT UINTN *HeaderSize,\r
+ IN OUT UINTN *BuffSize,\r
+ OUT VOID *Buffer,\r
+ OUT EFI_MAC_ADDRESS *SourceAddr,\r
+ OUT EFI_MAC_ADDRESS *DestinationAddr,\r
+ OUT UINT16 *Protocol\r
+ )\r
+{\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+ SNPNT32_GLOBAL_DATA *GlobalData;\r
+ INT32 ReturnValue;\r
+\r
+ Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
+\r
+ GlobalData = Instance->GlobalData;\r
+\r
+ ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);\r
+\r
+ if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ ReturnValue = GlobalData->NtNetUtilityTable.Receive (\r
+ Instance->InterfaceInfo.InterfaceIndex,\r
+ BuffSize,\r
+ Buffer\r
+ );\r
+\r
+ NET_UNLOCK (&GlobalData->Lock);\r
+\r
+ if (ReturnValue < 0) {\r
+ if (ReturnValue == -100) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ return EFI_DEVICE_ERROR;\r
+ } else if (ReturnValue == 0) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ if (HeaderSize != NULL) {\r
+ *HeaderSize = 14;\r
+ }\r
+\r
+ if (SourceAddr != NULL) {\r
+ NetZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));\r
+ NetCopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);\r
+ }\r
+\r
+ if (DestinationAddr != NULL) {\r
+ NetZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));\r
+ NetCopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);\r
+ }\r
+\r
+ if (Protocol != NULL) {\r
+ *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12)));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {\r
+ SNP_NT32_INSTANCE_SIGNATURE, // Signature\r
+ {\r
+ NULL,\r
+ NULL\r
+ }, // Entry\r
+ NULL, // GlobalData\r
+ NULL, // DeviceHandle\r
+ NULL, // DevicePath\r
+ { // Snp\r
+ EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision\r
+ SnpNt32Start, // Start\r
+ SnpNt32Stop, // Stop\r
+ SnpNt32Initialize, // Initialize\r
+ SnpNt32Reset, // Reset\r
+ SnpNt32Shutdown, // Shutdown\r
+ SnpNt32ReceiveFilters, // ReceiveFilters\r
+ SnpNt32StationAddress, // StationAddress\r
+ SnpNt32Statistics, // Statistics\r
+ SnpNt32McastIptoMac, // MCastIpToMac\r
+ SnpNt32Nvdata, // NvData\r
+ SnpNt32GetStatus, // GetStatus\r
+ SnpNt32Transmit, // Transmit\r
+ SnpNt32Receive, // Receive\r
+ NULL, // WaitForPacket\r
+ NULL // Mode\r
+ },\r
+ { // Mode\r
+ EfiSimpleNetworkInitialized, // State\r
+ NET_ETHER_ADDR_LEN, // HwAddressSize\r
+ NET_ETHER_HEADER_SIZE, // MediaHeaderSize\r
+ 1500, // MaxPacketSize\r
+ 0, // NvRamSize\r
+ 0, // NvRamAccessSize\r
+ 0, // ReceiveFilterMask\r
+ 0, // ReceiveFilterSetting\r
+ MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount\r
+ 0, // MCastFilterCount\r
+ {\r
+ 0\r
+ }, // MCastFilter\r
+ {\r
+ 0\r
+ }, // CurrentAddress\r
+ {\r
+ 0\r
+ }, // BroadcastAddress\r
+ {\r
+ 0\r
+ }, // PermanentAddress\r
+ NET_IFTYPE_ETHERNET, // IfType\r
+ FALSE, // MacAddressChangeable\r
+ FALSE, // MultipleTxSupported\r
+ FALSE, // MediaPresentSupported\r
+ TRUE // MediaPresent\r
+ },\r
+ {\r
+ 0\r
+ } // InterfaceInfo\r
+};\r
+\r
+\r
+/**\r
+ Initialize the driver's global data.\r
+\r
+ @param This Pointer to the global context data.\r
+\r
+ @retval EFI_SUCCESS The global data is initialized.\r
+ @retval EFI_NOT_FOUND The required DLL is not found.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32InitializeGlobalData (\r
+ IN SNPNT32_GLOBAL_DATA *This\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *DllFileNameU;\r
+ UINT32 Index;\r
+ INT32 ReturnValue;\r
+ BOOLEAN NetUtilityLibInitDone;\r
+ NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+ NET_LIST_ENTRY *Entry;\r
+ UINT32 InterfaceCount;\r
+\r
+ ASSERT (This != NULL);\r
+\r
+ NetUtilityLibInitDone = FALSE;\r
+ InterfaceCount = MAX_INTERFACE_INFO_NUMBER;\r
+\r
+ NetListInit (&This->InstanceList);\r
+ NET_LOCK_INIT (&This->Lock);\r
+\r
+ //\r
+ // Get the WinNT thunk\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, &This->WinNtThunk);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (This->WinNtThunk != NULL);\r
+\r
+ DllFileNameU = NETWORK_LIBRARY_NAME_U;\r
+\r
+ //\r
+ // Load network utility library\r
+ //\r
+ This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);\r
+\r
+ if (NULL == This->NetworkLibraryHandle) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (\r
+ This->NetworkLibraryHandle,\r
+ NETWORK_LIBRARY_INITIALIZE\r
+ );\r
+\r
+ if (NULL == This->NtNetUtilityTable.Initialize) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (\r
+ This->NetworkLibraryHandle,\r
+ NETWORK_LIBRARY_FINALIZE\r
+ );\r
+\r
+ if (NULL == This->NtNetUtilityTable.Finalize) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (\r
+ This->NetworkLibraryHandle,\r
+ NETWORK_LIBRARY_SET_RCV_FILTER\r
+ );\r
+\r
+ if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (\r
+ This->NetworkLibraryHandle,\r
+ NETWORK_LIBRARY_RECEIVE\r
+ );\r
+\r
+ if (NULL == This->NtNetUtilityTable.Receive) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (\r
+ This->NetworkLibraryHandle,\r
+ NETWORK_LIBRARY_TRANSMIT\r
+ );\r
+\r
+ if (NULL == This->NtNetUtilityTable.Transmit) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+ //\r
+ // Initialize the network utility library\r
+ // And enumerate the interfaces in NT32 host\r
+ //\r
+ ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);\r
+ if (ReturnValue <= 0) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ NetUtilityLibInitDone = TRUE;\r
+\r
+ if (InterfaceCount == 0) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto ErrorReturn;\r
+ }\r
+ //\r
+ // Create fake SNP instances\r
+ //\r
+ for (Index = 0; Index < InterfaceCount; Index++) {\r
+\r
+ Instance = NetAllocatePool (sizeof (SNPNT32_INSTANCE_DATA));\r
+\r
+ if (NULL == Instance) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorReturn;\r
+ }\r
+ //\r
+ // Copy the content from a template\r
+ //\r
+ NetCopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));\r
+\r
+ //\r
+ // Set the interface information.\r
+ //\r
+ Instance->InterfaceInfo = NetInterfaceInfoBuffer[Index];\r
+ //\r
+ // Initialize this instance\r
+ //\r
+ Status = This->InitializeInstanceData (This, Instance);\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ NetFreePool (Instance);\r
+ goto ErrorReturn;\r
+ }\r
+ //\r
+ // Insert this instance into the instance list\r
+ //\r
+ NetListInsertTail (&This->InstanceList, &Instance->Entry);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorReturn:\r
+\r
+ while (!NetListIsEmpty (&This->InstanceList)) {\r
+\r
+ Entry = This->InstanceList.ForwardLink;\r
+\r
+ Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
+\r
+ NetListRemoveEntry (Entry);\r
+\r
+ This->CloseInstance (This, Instance);\r
+ NetFreePool (Instance);\r
+ }\r
+\r
+ if (NetUtilityLibInitDone) {\r
+\r
+ ASSERT (This->WinNtThunk != NULL);\r
+\r
+ if (This->NtNetUtilityTable.Finalize != NULL) {\r
+ This->NtNetUtilityTable.Finalize ();\r
+ This->NtNetUtilityTable.Finalize = NULL;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Initialize the snpnt32 driver instance.\r
+\r
+ @param This Pointer to the SnpNt32 global data.\r
+ @param Instance Pointer to the instance context data.\r
+\r
+ @retval EFI_SUCCESS The driver instance is initialized.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32InitializeInstanceData (\r
+ IN SNPNT32_GLOBAL_DATA *This,\r
+ IN SNPNT32_INSTANCE_DATA *Instance\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEV_PATH EndNode;\r
+ EFI_DEV_PATH Node;\r
+\r
+ Instance->GlobalData = This;\r
+ Instance->Snp.Mode = &Instance->Mode;\r
+ //\r
+ // Set broadcast address\r
+ //\r
+ SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);\r
+\r
+ //\r
+ // Copy Current/PermanentAddress MAC address\r
+ //\r
+ Instance->Mode.CurrentAddress = Instance->InterfaceInfo.MacAddr;\r
+ Instance->Mode.PermanentAddress = Instance->InterfaceInfo.MacAddr;\r
+\r
+ //\r
+ // Since the fake SNP is based on a real NIC, to avoid conflict with the host\r
+ // NIC network stack, we use a different MAC address.\r
+ // So just change the last byte of the MAC address for the real NIC.\r
+ //\r
+ Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;\r
+\r
+ //\r
+ // Create a fake device path for the instance\r
+ //\r
+ NetZeroMem (&Node, sizeof (Node));\r
+\r
+ Node.DevPath.Type = MESSAGING_DEVICE_PATH;\r
+ Node.DevPath.SubType = MSG_MAC_ADDR_DP;\r
+ SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));\r
+\r
+ NetCopyMem (\r
+ &Node.MacAddr.MacAddress,\r
+ &Instance->Mode.CurrentAddress,\r
+ sizeof (EFI_MAC_ADDRESS)\r
+ );\r
+\r
+ Node.MacAddr.IfType = Instance->Mode.IfType;\r
+\r
+ SetDevicePathEndNode (&EndNode.DevPath);\r
+\r
+ Instance->DevicePath = AppendDevicePathNode (\r
+ &EndNode.DevPath,\r
+ &Node.DevPath\r
+ );\r
+\r
+ //\r
+ // Create a fake device handle for the fake SNP\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Instance->DeviceHandle,\r
+ &gEfiSimpleNetworkProtocolGuid,\r
+ &Instance->Snp,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Instance->DevicePath,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorReturn;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorReturn:\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Close the SnpNt32 driver instance.\r
+\r
+ @param This Pointer to the SnpNt32 global data.\r
+ @param Instance Pointer to the instance context data.\r
+\r
+ @retval EFI_SUCCESS The instance is closed.\r
+\r
+**/\r
+EFI_STATUS\r
+SnpNt32CloseInstance (\r
+ IN SNPNT32_GLOBAL_DATA *This,\r
+ IN SNPNT32_INSTANCE_DATA *Instance\r
+ )\r
+{\r
+ ASSERT (This != NULL);\r
+ ASSERT (Instance != NULL);\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Instance->DeviceHandle,\r
+ &gEfiSimpleNetworkProtocolGuid,\r
+ &Instance->Snp,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Instance->DevicePath,\r
+ NULL\r
+ );\r
+\r
+ if (Instance->DevicePath != NULL) {\r
+ gBS->FreePool (Instance->DevicePath);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Unload the SnpNt32 driver.\r
+\r
+ @param ImageHandle The handle of the driver image.\r
+\r
+ @retval EFI_SUCCESS The driver is unloaded.\r
+ @retval other Some error occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SnpNt32Unload (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SNPNT32_GLOBAL_DATA *This;\r
+ NET_LIST_ENTRY *Entry;\r
+ SNPNT32_INSTANCE_DATA *Instance;\r
+\r
+ This = &gSnpNt32GlobalData;\r
+\r
+ Status = NetLibDefaultUnload (ImageHandle);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (!NetListIsEmpty (&This->InstanceList)) {\r
+ //\r
+ // Walkthrough the interfaces and remove all the SNP instance\r
+ //\r
+ Entry = This->InstanceList.ForwardLink;\r
+\r
+ Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
+\r
+ NetListRemoveEntry (Entry);\r
+\r
+ This->CloseInstance (This, Instance);\r
+ NetFreePool (Instance);\r
+ }\r
+\r
+ if (This->NtNetUtilityTable.Finalize != NULL) {\r
+ This->NtNetUtilityTable.Finalize ();\r
+ }\r
+\r
+ This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+InitializeSnpNt32river (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Install DriverBinding Protocol for the Win NT Bus driver on the drivers\r
+ image handle.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - The handle of this image.\r
+ SystemTable - Pointer to the EFI system table.\r
+\r
+Returns:\r
+\r
+ EFI_SUCEESS - The protocols are installed and the SnpNt32 is initialized.\r
+ other - Some error occurs.\r
+\r
+--*/\r
+{\r
+\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install the Driver Protocols\r
+ //\r
+\r
+ Status = NetLibInstallAllDriverProtocolsWithUnload (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gSnpNt32DriverBinding,\r
+ ImageHandle,\r
+ &gSnpNt32DriverComponentName,\r
+ NULL,\r
+ NULL,\r
+ SnpNt32Unload\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Initialize the global data\r
+ //\r
+ Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);\r
+ if (EFI_ERROR (Status)) {\r
+ SnpNt32Unload (ImageHandle);\r
+ }\r
+\r
+ return Status;\r
+}\r