]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/SnpNt32Dxe/SnpNt32.c
1. Import SnpNt32Dxe. That is a thunk driver could produce SNP protocol on NT32 platf...
[mirror_edk2.git] / Nt32Pkg / SnpNt32Dxe / SnpNt32.c
CommitLineData
593a8308 1/** @file\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 SnpNt32.c\r
15\r
16Abstract:\r
17\r
18-**/\r
19\r
20#include "SnpNt32.h"\r
21\r
22EFI_DRIVER_BINDING_PROTOCOL gSnpNt32DriverBinding = {\r
23 SnpNt32DriverBindingSupported,\r
24 SnpNt32DriverBindingStart,\r
25 SnpNt32DriverBindingStop,\r
26 0xa,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31SNPNT32_GLOBAL_DATA gSnpNt32GlobalData = {\r
32 SNP_NT32_DRIVER_SIGNATURE, // Signature\r
33 {\r
34 NULL,\r
35 NULL\r
36 }, // InstanceList\r
37 NULL, // WinNtThunk\r
38 NULL, // NetworkLibraryHandle\r
39 {\r
40 0\r
41 }, // NtNetUtilityTable\r
42 {\r
43 0,\r
44 0,\r
45 0\r
46 }, // Lock\r
47 //\r
48 // Private functions\r
49 //\r
50 SnpNt32InitializeGlobalData, // InitializeGlobalData\r
51 SnpNt32InitializeInstanceData, // InitializeInstanceData\r
52 SnpNt32CloseInstance // CloseInstance\r
53};\r
54\r
55\r
56/**\r
57 Test to see if this driver supports ControllerHandle.\r
58\r
59 @param This Protocol instance pointer.\r
60 @param ControllerHandle Handle of device to test.\r
61 @param RemainingDevicePath Optional parameter use to pick a specific child\r
62 device to start.\r
63\r
64 @retval EFI_SUCCES This driver supports this device.\r
65 @retval other This driver does not support this device.\r
66\r
67**/\r
68EFI_STATUS\r
69EFIAPI\r
70SnpNt32DriverBindingSupported (\r
71 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
72 IN EFI_HANDLE ControllerHandle,\r
73 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
74 )\r
75{\r
76\r
77 SNPNT32_GLOBAL_DATA *GlobalData;\r
78 NET_LIST_ENTRY *Entry;\r
79 SNPNT32_INSTANCE_DATA *Instance;\r
80\r
81 GlobalData = &gSnpNt32GlobalData;\r
82\r
83 NET_LIST_FOR_EACH (Entry, &GlobalData->InstanceList) {\r
84\r
85 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
86\r
87 if (Instance->DeviceHandle == ControllerHandle) {\r
88 return EFI_SUCCESS;\r
89 }\r
90\r
91 }\r
92\r
93 return EFI_UNSUPPORTED;\r
94}\r
95\r
96\r
97/**\r
98 Start this driver on ControllerHandle.\r
99\r
100 @param This Protocol instance pointer.\r
101 @param ControllerHandle Handle of device to bind driver to.\r
102 @param RemainingDevicePath Optional parameter use to pick a specific child\r
103 device to start.\r
104\r
105 @retval EFI_SUCCES This driver is added to ControllerHandle.\r
106\r
107**/\r
108EFI_STATUS\r
109EFIAPI\r
110SnpNt32DriverBindingStart (\r
111 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
112 IN EFI_HANDLE ControllerHandle,\r
113 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
114 )\r
115{\r
116 return EFI_SUCCESS;\r
117}\r
118\r
119\r
120/**\r
121 Stop this driver on ControllerHandle.\r
122\r
123 @param This Protocol instance pointer.\r
124 @param ControllerHandle Handle of device to stop driver on.\r
125 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
126 of children is zero stop the entire bus driver.\r
127 @param ChildHandleBuffer List of Child Handles to Stop.\r
128\r
129 @retval EFI_SUCCES This driver is removed ControllerHandle.\r
130\r
131**/\r
132EFI_STATUS\r
133EFIAPI\r
134SnpNt32DriverBindingStop (\r
135 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
136 IN EFI_HANDLE ControllerHandle,\r
137 IN UINTN NumberOfChildren,\r
138 IN EFI_HANDLE *ChildHandleBuffer\r
139 )\r
140{\r
141\r
142 return EFI_SUCCESS;\r
143}\r
144\r
145\r
146/**\r
147 Start the SnpNt32 interface.\r
148\r
149 @param This Context pointer.\r
150\r
151 @retval EFI_SUCCESS The interface is started.\r
152\r
153**/\r
154EFI_STATUS\r
155SnpNt32Start (\r
156 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
157 )\r
158{\r
159 return EFI_SUCCESS;\r
160}\r
161\r
162\r
163/**\r
164 Stop the SnpNt32 interface.\r
165\r
166 @param This Context pointer.\r
167\r
168 @retval EFI_SUCCESS The interface is stopped.\r
169\r
170**/\r
171EFI_STATUS\r
172SnpNt32Stop (\r
173 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
174 )\r
175{\r
176 return EFI_SUCCESS;\r
177}\r
178\r
179\r
180/**\r
181 Initialize the SnpNt32 interface.\r
182\r
183 @param This Context pointer.\r
184 @param ExtraRxBufferSize Number of extra receive buffer.\r
185 @param ExtraTxBufferSize Number of extra transmit buffer.\r
186\r
187 @retval EFI_SUCCESS The interface is initialized.\r
188\r
189**/\r
190EFI_STATUS\r
191SnpNt32Initialize (\r
192 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
193 IN UINTN ExtraRxBufferSize OPTIONAL,\r
194 IN UINTN ExtraTxBufferSize OPTIONAL\r
195 )\r
196{\r
197 return EFI_SUCCESS;\r
198}\r
199\r
200\r
201/**\r
202 Reset the snpnt32 interface.\r
203\r
204 @param This Context pointer.\r
205 @param ExtendedVerification Not implemented.\r
206\r
207 @retval EFI_SUCCESS The interface is reseted.\r
208\r
209**/\r
210EFI_STATUS\r
211SnpNt32Reset (\r
212 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
213 IN BOOLEAN ExtendedVerification\r
214 )\r
215{\r
216 return EFI_SUCCESS;\r
217}\r
218\r
219\r
220/**\r
221 Shut down the snpnt32 interface.\r
222\r
223 @param This Context pointer.\r
224\r
225 @retval EFI_SUCCESS The interface is shut down.\r
226\r
227**/\r
228EFI_STATUS\r
229SnpNt32Shutdown (\r
230 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
231 )\r
232{\r
233 return EFI_SUCCESS;\r
234}\r
235\r
236\r
237/**\r
238 Change the interface's receive filter setting.\r
239\r
240 @param This Context pointer.\r
241 @param EnableBits The receive filters to enable.\r
242 @param DisableBits The receive filters to disable\r
243 @param ResetMcastFilter Reset the multicast filters or not.\r
244 @param McastFilterCount The count of multicast filter to set.\r
245 @param McastFilter Pointer to the arrya of multicast addresses to set.\r
246\r
247 @retval EFI_SUCCESS The receive filter is updated.\r
248 @retval EFI_ACCESS_DENIED The snpnt32 lock is already owned by another\r
249 routine.\r
250 @retval EFI_DEVICE_ERROR Failed to update the receive filter.\r
251\r
252**/\r
253EFI_STATUS\r
254SnpNt32ReceiveFilters (\r
255 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
256 IN UINT32 EnableBits,\r
257 IN UINT32 DisableBits,\r
258 IN BOOLEAN ResetMcastFilter,\r
259 IN UINTN McastFilterCount OPTIONAL,\r
260 IN EFI_MAC_ADDRESS *McastFilter OPTIONAL\r
261 )\r
262{\r
263 SNPNT32_INSTANCE_DATA *Instance;\r
264 SNPNT32_GLOBAL_DATA *GlobalData;\r
265 INT32 ReturnValue;\r
266\r
267 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
268\r
269 GlobalData = Instance->GlobalData;\r
270\r
271 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
272 return EFI_ACCESS_DENIED;\r
273 }\r
274\r
275 ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (\r
276 Instance->InterfaceInfo.InterfaceIndex,\r
277 EnableBits,\r
278 McastFilterCount,\r
279 McastFilter\r
280 );\r
281\r
282 NET_UNLOCK (&GlobalData->Lock);\r
283\r
284 if (ReturnValue <= 0) {\r
285 return EFI_DEVICE_ERROR;\r
286 }\r
287\r
288 return EFI_SUCCESS;\r
289}\r
290\r
291\r
292/**\r
293 Change or reset the mac address of the interface.\r
294\r
295 @param This Context pointer.\r
296 @param reset Reset the mac address to the original one or not.\r
297 @param NewMacAddr Pointer to the new mac address to set.\r
298\r
299 @retval EFI_UNSUPPORTED Not supported yet.\r
300\r
301**/\r
302EFI_STATUS\r
303SnpNt32StationAddress (\r
304 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
305 IN BOOLEAN Reset,\r
306 IN EFI_MAC_ADDRESS *NewMacAddr OPTIONAL\r
307 )\r
308{\r
309 return EFI_UNSUPPORTED;\r
310}\r
311\r
312\r
313/**\r
314 Get or reset the statistics data.\r
315\r
316 @param This Context pointer.\r
317 @param Reset Reset the statistics or not.\r
318 @param StatisticsSize The size of the buffer used to receive the\r
319 statistics data.\r
320 @param StatisticsTable Pointer to the table used to receive the statistics\r
321 data.\r
322\r
323 @retval EFI_UNSUPPORTED Not supported yet.\r
324\r
325**/\r
326EFI_STATUS\r
327SnpNt32Statistics (\r
328 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
329 IN BOOLEAN Reset,\r
330 IN OUT UINTN *StatisticsSize OPTIONAL,\r
331 IN OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL\r
332 )\r
333{\r
334 return EFI_UNSUPPORTED;\r
335}\r
336\r
337\r
338/**\r
339 Convert a multicast ip address to the multicast mac address.\r
340\r
341 @param This Context pointer.\r
342 @param Ipv6 The Ip is an Ipv6 address or not.\r
343 @param Ip Pointer to the Ip address to convert.\r
344 @param Mac Pointer to the buffer used to hold the converted\r
345 mac address.\r
346\r
347 @retval EFI_UNSUPPORTED Not supported yet.\r
348\r
349**/\r
350EFI_STATUS\r
351SnpNt32McastIptoMac (\r
352 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
353 IN BOOLEAN Ipv6,\r
354 IN EFI_IP_ADDRESS *Ip,\r
355 OUT EFI_MAC_ADDRESS *Mac\r
356 )\r
357{\r
358 return EFI_UNSUPPORTED;\r
359}\r
360\r
361\r
362/**\r
363 Read or write the nv data.\r
364\r
365 @param This Context pinter.\r
366 @param ReadOrWrite Read or write the nv data.\r
367 @param Offset The offset to the start of the nv data.\r
368 @param BufferSize Size of the buffer.\r
369 @param Buffer Pointer to the buffer containing the data to write\r
370 or used to receive the data read.\r
371\r
372 @retval EFI_UNSUPPORTED Not supported yet.\r
373\r
374**/\r
375EFI_STATUS\r
376SnpNt32Nvdata (\r
377 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
378 IN BOOLEAN ReadOrWrite,\r
379 IN UINTN Offset,\r
380 IN UINTN BufferSize,\r
381 IN OUT VOID *Buffer\r
382 )\r
383{\r
384 return EFI_UNSUPPORTED;\r
385}\r
386\r
387\r
388/**\r
389 Get the status information of the interface.\r
390\r
391 @param This Context pointer.\r
392 @param InterruptStatus The storage to hold the interrupt status.\r
393 @param TxBuffer Pointer to get the list of pointers of previously\r
394 transmitted buffers whose transmission was\r
395 completed asynchrnously.\r
396\r
397 @retval EFI_SUCCESS The status is got.\r
398\r
399**/\r
400EFI_STATUS\r
401SnpNt32GetStatus (\r
402 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
403 OUT UINT32 *InterruptStatus,\r
404 OUT VOID **TxBuffer\r
405 )\r
406{\r
407\r
408 if (TxBuffer != NULL) {\r
409 *((UINT8 **) TxBuffer) = (UINT8 *) 1;\r
410 }\r
411\r
412 if (InterruptStatus != NULL) {\r
413 *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
414 }\r
415\r
416 return EFI_SUCCESS;\r
417}\r
418\r
419\r
420/**\r
421 Transmit a packet.\r
422\r
423 @param This Context pointer.\r
424 @param HeaderSize The media header size contained in the packet\r
425 buffer.\r
426 @param BufferSize The size of the packet buffer.\r
427 @param Buffer Pointer to the buffer containing the packet data.\r
428 @param SrcAddr If non null, points to the source address of this\r
429 packet.\r
430 @param DestAddr If non null, points to the destination address of\r
431 this packet.\r
432 @param Protocol The protocol type of this packet.\r
433\r
434 @retval EFI_SUCCESS The packet is transmitted or put into the transmit\r
435 queue.\r
436 @retval other Some error occurs.\r
437\r
438**/\r
439EFI_STATUS\r
440SnpNt32Transmit (\r
441 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
442 IN UINTN HeaderSize,\r
443 IN UINTN BufferSize,\r
444 IN VOID *Buffer,\r
445 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
446 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
447 IN UINT16 *Protocol OPTIONAL\r
448 )\r
449{\r
450 SNPNT32_INSTANCE_DATA *Instance;\r
451 SNPNT32_GLOBAL_DATA *GlobalData;\r
452 INT32 ReturnValue;\r
453\r
454 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
455\r
456 GlobalData = Instance->GlobalData;\r
457\r
458 if ((HeaderSize != 0) && (SrcAddr == NULL)) {\r
459 SrcAddr = &Instance->Mode.CurrentAddress;\r
460 }\r
461\r
462 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
463 return EFI_ACCESS_DENIED;\r
464 }\r
465\r
466 ReturnValue = GlobalData->NtNetUtilityTable.Transmit (\r
467 Instance->InterfaceInfo.InterfaceIndex,\r
468 HeaderSize,\r
469 BufferSize,\r
470 Buffer,\r
471 SrcAddr,\r
472 DestAddr,\r
473 Protocol\r
474 );\r
475\r
476 NET_UNLOCK (&GlobalData->Lock);\r
477\r
478 if (ReturnValue < 0) {\r
479 return EFI_DEVICE_ERROR;\r
480 }\r
481\r
482 return EFI_SUCCESS;\r
483}\r
484\r
485\r
486/**\r
487 Receive network data.\r
488\r
489 @param This Context pointer.\r
490 @param HeaderSize Optional parameter and is a pointer to the header\r
491 portion of the data received.\r
492 @param BuffSize Pointer to the length of the Buffer on entry and\r
493 contains the length of the received data on return\r
494 @param Buffer Pointer to the memory for the received data\r
495 @param SourceAddr Optional parameter, is a pointer to contain the\r
496 source ethernet address on return\r
497 @param DestinationAddr Optional parameter, is a pointer to contain the\r
498 destination ethernet address on return.\r
499 @param Protocol Optional parameter, is a pointer to contain the\r
500 Protocol type from the ethernet header on return.\r
501\r
502 @retval EFI_SUCCESS A packet is received and put into the buffer.\r
503 @retval EFI_BUFFER_TOO_SMALL The provided buffer is too small to receive the\r
504 packet.\r
505 @retval EFI_NOT_READY There is no packet received.\r
506\r
507**/\r
508EFI_STATUS\r
509SnpNt32Receive (\r
510 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
511 OUT UINTN *HeaderSize,\r
512 IN OUT UINTN *BuffSize,\r
513 OUT VOID *Buffer,\r
514 OUT EFI_MAC_ADDRESS *SourceAddr,\r
515 OUT EFI_MAC_ADDRESS *DestinationAddr,\r
516 OUT UINT16 *Protocol\r
517 )\r
518{\r
519 SNPNT32_INSTANCE_DATA *Instance;\r
520 SNPNT32_GLOBAL_DATA *GlobalData;\r
521 INT32 ReturnValue;\r
522\r
523 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);\r
524\r
525 GlobalData = Instance->GlobalData;\r
526\r
527 ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);\r
528\r
529 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {\r
530 return EFI_ACCESS_DENIED;\r
531 }\r
532\r
533 ReturnValue = GlobalData->NtNetUtilityTable.Receive (\r
534 Instance->InterfaceInfo.InterfaceIndex,\r
535 BuffSize,\r
536 Buffer\r
537 );\r
538\r
539 NET_UNLOCK (&GlobalData->Lock);\r
540\r
541 if (ReturnValue < 0) {\r
542 if (ReturnValue == -100) {\r
543 return EFI_BUFFER_TOO_SMALL;\r
544 }\r
545\r
546 return EFI_DEVICE_ERROR;\r
547 } else if (ReturnValue == 0) {\r
548 return EFI_NOT_READY;\r
549 }\r
550\r
551 if (HeaderSize != NULL) {\r
552 *HeaderSize = 14;\r
553 }\r
554\r
555 if (SourceAddr != NULL) {\r
556 NetZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));\r
557 NetCopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);\r
558 }\r
559\r
560 if (DestinationAddr != NULL) {\r
561 NetZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));\r
562 NetCopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);\r
563 }\r
564\r
565 if (Protocol != NULL) {\r
566 *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12)));\r
567 }\r
568\r
569 return EFI_SUCCESS;\r
570}\r
571\r
572SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {\r
573 SNP_NT32_INSTANCE_SIGNATURE, // Signature\r
574 {\r
575 NULL,\r
576 NULL\r
577 }, // Entry\r
578 NULL, // GlobalData\r
579 NULL, // DeviceHandle\r
580 NULL, // DevicePath\r
581 { // Snp\r
582 EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision\r
583 SnpNt32Start, // Start\r
584 SnpNt32Stop, // Stop\r
585 SnpNt32Initialize, // Initialize\r
586 SnpNt32Reset, // Reset\r
587 SnpNt32Shutdown, // Shutdown\r
588 SnpNt32ReceiveFilters, // ReceiveFilters\r
589 SnpNt32StationAddress, // StationAddress\r
590 SnpNt32Statistics, // Statistics\r
591 SnpNt32McastIptoMac, // MCastIpToMac\r
592 SnpNt32Nvdata, // NvData\r
593 SnpNt32GetStatus, // GetStatus\r
594 SnpNt32Transmit, // Transmit\r
595 SnpNt32Receive, // Receive\r
596 NULL, // WaitForPacket\r
597 NULL // Mode\r
598 },\r
599 { // Mode\r
600 EfiSimpleNetworkInitialized, // State\r
601 NET_ETHER_ADDR_LEN, // HwAddressSize\r
602 NET_ETHER_HEADER_SIZE, // MediaHeaderSize\r
603 1500, // MaxPacketSize\r
604 0, // NvRamSize\r
605 0, // NvRamAccessSize\r
606 0, // ReceiveFilterMask\r
607 0, // ReceiveFilterSetting\r
608 MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount\r
609 0, // MCastFilterCount\r
610 {\r
611 0\r
612 }, // MCastFilter\r
613 {\r
614 0\r
615 }, // CurrentAddress\r
616 {\r
617 0\r
618 }, // BroadcastAddress\r
619 {\r
620 0\r
621 }, // PermanentAddress\r
622 NET_IFTYPE_ETHERNET, // IfType\r
623 FALSE, // MacAddressChangeable\r
624 FALSE, // MultipleTxSupported\r
625 FALSE, // MediaPresentSupported\r
626 TRUE // MediaPresent\r
627 },\r
628 {\r
629 0\r
630 } // InterfaceInfo\r
631};\r
632\r
633\r
634/**\r
635 Initialize the driver's global data.\r
636\r
637 @param This Pointer to the global context data.\r
638\r
639 @retval EFI_SUCCESS The global data is initialized.\r
640 @retval EFI_NOT_FOUND The required DLL is not found.\r
641\r
642**/\r
643EFI_STATUS\r
644SnpNt32InitializeGlobalData (\r
645 IN SNPNT32_GLOBAL_DATA *This\r
646 )\r
647{\r
648 EFI_STATUS Status;\r
649 CHAR16 *DllFileNameU;\r
650 UINT32 Index;\r
651 INT32 ReturnValue;\r
652 BOOLEAN NetUtilityLibInitDone;\r
653 NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];\r
654 SNPNT32_INSTANCE_DATA *Instance;\r
655 NET_LIST_ENTRY *Entry;\r
656 UINT32 InterfaceCount;\r
657\r
658 ASSERT (This != NULL);\r
659\r
660 NetUtilityLibInitDone = FALSE;\r
661 InterfaceCount = MAX_INTERFACE_INFO_NUMBER;\r
662\r
663 NetListInit (&This->InstanceList);\r
664 NET_LOCK_INIT (&This->Lock);\r
665\r
666 //\r
667 // Get the WinNT thunk\r
668 //\r
669 Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, &This->WinNtThunk);\r
670\r
671 if (EFI_ERROR (Status)) {\r
672 return Status;\r
673 }\r
674\r
675 ASSERT (This->WinNtThunk != NULL);\r
676\r
677 DllFileNameU = NETWORK_LIBRARY_NAME_U;\r
678\r
679 //\r
680 // Load network utility library\r
681 //\r
682 This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);\r
683\r
684 if (NULL == This->NetworkLibraryHandle) {\r
685 return EFI_NOT_FOUND;\r
686 }\r
687\r
688 This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (\r
689 This->NetworkLibraryHandle,\r
690 NETWORK_LIBRARY_INITIALIZE\r
691 );\r
692\r
693 if (NULL == This->NtNetUtilityTable.Initialize) {\r
694 Status = EFI_NOT_FOUND;\r
695 goto ErrorReturn;\r
696 }\r
697\r
698 This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (\r
699 This->NetworkLibraryHandle,\r
700 NETWORK_LIBRARY_FINALIZE\r
701 );\r
702\r
703 if (NULL == This->NtNetUtilityTable.Finalize) {\r
704 Status = EFI_NOT_FOUND;\r
705 goto ErrorReturn;\r
706 }\r
707\r
708 This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (\r
709 This->NetworkLibraryHandle,\r
710 NETWORK_LIBRARY_SET_RCV_FILTER\r
711 );\r
712\r
713 if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {\r
714 Status = EFI_NOT_FOUND;\r
715 goto ErrorReturn;\r
716 }\r
717\r
718 This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (\r
719 This->NetworkLibraryHandle,\r
720 NETWORK_LIBRARY_RECEIVE\r
721 );\r
722\r
723 if (NULL == This->NtNetUtilityTable.Receive) {\r
724 Status = EFI_NOT_FOUND;\r
725 goto ErrorReturn;\r
726 }\r
727\r
728 This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (\r
729 This->NetworkLibraryHandle,\r
730 NETWORK_LIBRARY_TRANSMIT\r
731 );\r
732\r
733 if (NULL == This->NtNetUtilityTable.Transmit) {\r
734 Status = EFI_NOT_FOUND;\r
735 goto ErrorReturn;\r
736 }\r
737 //\r
738 // Initialize the network utility library\r
739 // And enumerate the interfaces in NT32 host\r
740 //\r
741 ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);\r
742 if (ReturnValue <= 0) {\r
743 Status = EFI_DEVICE_ERROR;\r
744 goto ErrorReturn;\r
745 }\r
746\r
747 NetUtilityLibInitDone = TRUE;\r
748\r
749 if (InterfaceCount == 0) {\r
750 Status = EFI_NOT_FOUND;\r
751 goto ErrorReturn;\r
752 }\r
753 //\r
754 // Create fake SNP instances\r
755 //\r
756 for (Index = 0; Index < InterfaceCount; Index++) {\r
757\r
758 Instance = NetAllocatePool (sizeof (SNPNT32_INSTANCE_DATA));\r
759\r
760 if (NULL == Instance) {\r
761 Status = EFI_OUT_OF_RESOURCES;\r
762 goto ErrorReturn;\r
763 }\r
764 //\r
765 // Copy the content from a template\r
766 //\r
767 NetCopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));\r
768\r
769 //\r
770 // Set the interface information.\r
771 //\r
772 Instance->InterfaceInfo = NetInterfaceInfoBuffer[Index];\r
773 //\r
774 // Initialize this instance\r
775 //\r
776 Status = This->InitializeInstanceData (This, Instance);\r
777 if (EFI_ERROR (Status)) {\r
778\r
779 NetFreePool (Instance);\r
780 goto ErrorReturn;\r
781 }\r
782 //\r
783 // Insert this instance into the instance list\r
784 //\r
785 NetListInsertTail (&This->InstanceList, &Instance->Entry);\r
786 }\r
787\r
788 return EFI_SUCCESS;\r
789\r
790ErrorReturn:\r
791\r
792 while (!NetListIsEmpty (&This->InstanceList)) {\r
793\r
794 Entry = This->InstanceList.ForwardLink;\r
795\r
796 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
797\r
798 NetListRemoveEntry (Entry);\r
799\r
800 This->CloseInstance (This, Instance);\r
801 NetFreePool (Instance);\r
802 }\r
803\r
804 if (NetUtilityLibInitDone) {\r
805\r
806 ASSERT (This->WinNtThunk != NULL);\r
807\r
808 if (This->NtNetUtilityTable.Finalize != NULL) {\r
809 This->NtNetUtilityTable.Finalize ();\r
810 This->NtNetUtilityTable.Finalize = NULL;\r
811 }\r
812 }\r
813\r
814 return Status;\r
815}\r
816\r
817\r
818/**\r
819 Initialize the snpnt32 driver instance.\r
820\r
821 @param This Pointer to the SnpNt32 global data.\r
822 @param Instance Pointer to the instance context data.\r
823\r
824 @retval EFI_SUCCESS The driver instance is initialized.\r
825\r
826**/\r
827EFI_STATUS\r
828SnpNt32InitializeInstanceData (\r
829 IN SNPNT32_GLOBAL_DATA *This,\r
830 IN SNPNT32_INSTANCE_DATA *Instance\r
831 )\r
832{\r
833 EFI_STATUS Status;\r
834 EFI_DEV_PATH EndNode;\r
835 EFI_DEV_PATH Node;\r
836\r
837 Instance->GlobalData = This;\r
838 Instance->Snp.Mode = &Instance->Mode;\r
839 //\r
840 // Set broadcast address\r
841 //\r
842 SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);\r
843\r
844 //\r
845 // Copy Current/PermanentAddress MAC address\r
846 //\r
847 Instance->Mode.CurrentAddress = Instance->InterfaceInfo.MacAddr;\r
848 Instance->Mode.PermanentAddress = Instance->InterfaceInfo.MacAddr;\r
849\r
850 //\r
851 // Since the fake SNP is based on a real NIC, to avoid conflict with the host\r
852 // NIC network stack, we use a different MAC address.\r
853 // So just change the last byte of the MAC address for the real NIC.\r
854 //\r
855 Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;\r
856\r
857 //\r
858 // Create a fake device path for the instance\r
859 //\r
860 NetZeroMem (&Node, sizeof (Node));\r
861\r
862 Node.DevPath.Type = MESSAGING_DEVICE_PATH;\r
863 Node.DevPath.SubType = MSG_MAC_ADDR_DP;\r
864 SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));\r
865\r
866 NetCopyMem (\r
867 &Node.MacAddr.MacAddress,\r
868 &Instance->Mode.CurrentAddress,\r
869 sizeof (EFI_MAC_ADDRESS)\r
870 );\r
871\r
872 Node.MacAddr.IfType = Instance->Mode.IfType;\r
873\r
874 SetDevicePathEndNode (&EndNode.DevPath);\r
875\r
876 Instance->DevicePath = AppendDevicePathNode (\r
877 &EndNode.DevPath,\r
878 &Node.DevPath\r
879 );\r
880\r
881 //\r
882 // Create a fake device handle for the fake SNP\r
883 //\r
884 Status = gBS->InstallMultipleProtocolInterfaces (\r
885 &Instance->DeviceHandle,\r
886 &gEfiSimpleNetworkProtocolGuid,\r
887 &Instance->Snp,\r
888 &gEfiDevicePathProtocolGuid,\r
889 Instance->DevicePath,\r
890 NULL\r
891 );\r
892 if (EFI_ERROR (Status)) {\r
893 goto ErrorReturn;\r
894 }\r
895\r
896 return EFI_SUCCESS;\r
897\r
898ErrorReturn:\r
899 return Status;\r
900}\r
901\r
902\r
903/**\r
904 Close the SnpNt32 driver instance.\r
905\r
906 @param This Pointer to the SnpNt32 global data.\r
907 @param Instance Pointer to the instance context data.\r
908\r
909 @retval EFI_SUCCESS The instance is closed.\r
910\r
911**/\r
912EFI_STATUS\r
913SnpNt32CloseInstance (\r
914 IN SNPNT32_GLOBAL_DATA *This,\r
915 IN SNPNT32_INSTANCE_DATA *Instance\r
916 )\r
917{\r
918 ASSERT (This != NULL);\r
919 ASSERT (Instance != NULL);\r
920\r
921 gBS->UninstallMultipleProtocolInterfaces (\r
922 Instance->DeviceHandle,\r
923 &gEfiSimpleNetworkProtocolGuid,\r
924 &Instance->Snp,\r
925 &gEfiDevicePathProtocolGuid,\r
926 Instance->DevicePath,\r
927 NULL\r
928 );\r
929\r
930 if (Instance->DevicePath != NULL) {\r
931 gBS->FreePool (Instance->DevicePath);\r
932 }\r
933\r
934 return EFI_SUCCESS;\r
935}\r
936\r
937\r
938/**\r
939 Unload the SnpNt32 driver.\r
940\r
941 @param ImageHandle The handle of the driver image.\r
942\r
943 @retval EFI_SUCCESS The driver is unloaded.\r
944 @retval other Some error occurs.\r
945\r
946**/\r
947EFI_STATUS\r
948EFIAPI\r
949SnpNt32Unload (\r
950 IN EFI_HANDLE ImageHandle\r
951 )\r
952{\r
953 EFI_STATUS Status;\r
954 SNPNT32_GLOBAL_DATA *This;\r
955 NET_LIST_ENTRY *Entry;\r
956 SNPNT32_INSTANCE_DATA *Instance;\r
957\r
958 This = &gSnpNt32GlobalData;\r
959\r
960 Status = NetLibDefaultUnload (ImageHandle);\r
961\r
962 if (EFI_ERROR (Status)) {\r
963 return Status;\r
964 }\r
965\r
966 while (!NetListIsEmpty (&This->InstanceList)) {\r
967 //\r
968 // Walkthrough the interfaces and remove all the SNP instance\r
969 //\r
970 Entry = This->InstanceList.ForwardLink;\r
971\r
972 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);\r
973\r
974 NetListRemoveEntry (Entry);\r
975\r
976 This->CloseInstance (This, Instance);\r
977 NetFreePool (Instance);\r
978 }\r
979\r
980 if (This->NtNetUtilityTable.Finalize != NULL) {\r
981 This->NtNetUtilityTable.Finalize ();\r
982 }\r
983\r
984 This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);\r
985\r
986 return EFI_SUCCESS;\r
987}\r
988\r
989\r
990EFI_STATUS\r
991InitializeSnpNt32river (\r
992 IN EFI_HANDLE ImageHandle,\r
993 IN EFI_SYSTEM_TABLE *SystemTable\r
994 )\r
995/*++\r
996\r
997Routine Description:\r
998\r
999 Install DriverBinding Protocol for the Win NT Bus driver on the drivers\r
1000 image handle.\r
1001\r
1002Arguments:\r
1003\r
1004 ImageHandle - The handle of this image.\r
1005 SystemTable - Pointer to the EFI system table.\r
1006\r
1007Returns:\r
1008\r
1009 EFI_SUCEESS - The protocols are installed and the SnpNt32 is initialized.\r
1010 other - Some error occurs.\r
1011\r
1012--*/\r
1013{\r
1014\r
1015 EFI_STATUS Status;\r
1016\r
1017 //\r
1018 // Install the Driver Protocols\r
1019 //\r
1020\r
1021 Status = NetLibInstallAllDriverProtocolsWithUnload (\r
1022 ImageHandle,\r
1023 SystemTable,\r
1024 &gSnpNt32DriverBinding,\r
1025 ImageHandle,\r
1026 &gSnpNt32DriverComponentName,\r
1027 NULL,\r
1028 NULL,\r
1029 SnpNt32Unload\r
1030 );\r
1031 if (EFI_ERROR (Status)) {\r
1032 return Status;\r
1033 }\r
1034\r
1035 //\r
1036 // Initialize the global data\r
1037 //\r
1038 Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);\r
1039 if (EFI_ERROR (Status)) {\r
1040 SnpNt32Unload (ImageHandle);\r
1041 }\r
1042\r
1043 return Status;\r
1044}\r