• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13 
14   SnpNt32.c
15 
16 Abstract:
17 
18 -**/
19 
20 #include "SnpNt32.h"
21 
22 EFI_DRIVER_BINDING_PROTOCOL gSnpNt32DriverBinding = {
23   SnpNt32DriverBindingSupported,
24   SnpNt32DriverBindingStart,
25   SnpNt32DriverBindingStop,
26   0xa,
27   NULL,
28   NULL
29 };
30 
31 SNPNT32_GLOBAL_DATA         gSnpNt32GlobalData = {
32   SNP_NT32_DRIVER_SIGNATURE,  //  Signature
33   {
34     NULL,
35     NULL
36   },                          //  InstanceList
37   NULL,                       //  WinNtThunk
38   NULL,                       //  NetworkLibraryHandle
39   {
40     0
41   },                          //  NtNetUtilityTable
42   {
43     0,
44     0,
45     EfiLockUninitialized
46   },                          //  Lock
47   //
48   //  Private functions
49   //
50   SnpNt32InitializeGlobalData,            //  InitializeGlobalData
51   SnpNt32InitializeInstanceData,          //  InitializeInstanceData
52   SnpNt32CloseInstance                    //  CloseInstance
53 };
54 
55 /**
56   Changes the state of a network interface from "stopped" to "started".
57 
58   @param  This Protocol instance pointer.
59 
60   @retval EFI_SUCCESS           Always succeeds.
61 
62 **/
63 EFI_STATUS
64 EFIAPI
65 SnpNt32Start (
66   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
67   );
68 
69 /**
70   Changes the state of a network interface from "started" to "stopped".
71 
72   @param  This Protocol instance pointer.
73 
74   @retval EFI_SUCCESS           Always succeeds.
75 
76 **/
77 EFI_STATUS
78 EFIAPI
79 SnpNt32Stop (
80   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
81   );
82 
83 /**
84   Resets a network adapter and allocates the transmit and receive buffers
85   required by the network interface; optionally, also requests allocation
86   of additional transmit and receive buffers.
87 
88   @param  This              Protocol instance pointer.
89   @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
90                             that the driver should allocate for the network interface.
91                             Some network interfaces will not be able to use the extra
92                             buffer, and the caller will not know if it is actually
93                             being used.
94   @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
95                             that the driver should allocate for the network interface.
96                             Some network interfaces will not be able to use the extra
97                             buffer, and the caller will not know if it is actually
98                             being used.
99 
100   @retval EFI_SUCCESS           Always succeeds.
101 
102 **/
103 EFI_STATUS
104 EFIAPI
105 SnpNt32Initialize (
106   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
107   IN UINTN                       ExtraRxBufferSize OPTIONAL,
108   IN UINTN                       ExtraTxBufferSize OPTIONAL
109   );
110 
111 /**
112   Resets a network adapter and re-initializes it with the parameters that were
113   provided in the previous call to Initialize().
114 
115   @param  This                 Protocol instance pointer.
116   @param  ExtendedVerification Indicates that the driver may perform a more
117                                exhaustive verification operation of the device
118                                during reset.
119 
120   @retval EFI_SUCCESS           Always succeeds.
121 
122 **/
123 EFI_STATUS
124 EFIAPI
125 SnpNt32Reset (
126   IN EFI_SIMPLE_NETWORK_PROTOCOL  *This,
127   IN BOOLEAN                      ExtendedVerification
128   );
129 
130 /**
131   Resets a network adapter and leaves it in a state that is safe for
132   another driver to initialize.
133 
134   @param  This Protocol instance pointer.
135 
136   @retval EFI_SUCCESS           Always succeeds.
137 
138 **/
139 EFI_STATUS
140 EFIAPI
141 SnpNt32Shutdown (
142   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
143   );
144 
145 /**
146   Manages the multicast receive filters of a network interface.
147 
148   @param  This               Protocol instance pointer.
149   @param  EnableBits         A bit mask of receive filters to enable on the network interface.
150   @param  DisableBits        A bit mask of receive filters to disable on the network interface.
151   @param  ResetMcastFilter   Set to TRUE to reset the contents of the multicast receive
152                              filters on the network interface to their default values.
153   @param  McastFilterCount   Number of multicast HW MAC addresses in the new
154                              MCastFilter list. This value must be less than or equal to
155                              the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
156                              field is optional if ResetMCastFilter is TRUE.
157   @param  McastFilter        A pointer to a list of new multicast receive filter HW MAC
158                              addresses. This list will replace any existing multicast
159                              HW MAC address list. This field is optional if
160                              ResetMCastFilter is TRUE.
161 
162   @retval EFI_SUCCESS           The multicast receive filter list was updated.
163   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
164 
165 **/
166 EFI_STATUS
167 EFIAPI
168 SnpNt32ReceiveFilters (
169   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
170   IN UINT32                      EnableBits,
171   IN UINT32                      DisableBits,
172   IN BOOLEAN                     ResetMcastFilter,
173   IN UINTN                       McastFilterCount OPTIONAL,
174   IN EFI_MAC_ADDRESS             *McastFilter     OPTIONAL
175   );
176 
177 /**
178   Modifies or resets the current station address, if supported.
179 
180   @param  This         Protocol instance pointer.
181   @param  Reset        Flag used to reset the station address to the network interfaces
182                        permanent address.
183   @param  NewMacAddr   New station address to be used for the network interface.
184 
185   @retval EFI_UNSUPPORTED       Not supported yet.
186 
187 **/
188 EFI_STATUS
189 EFIAPI
190 SnpNt32StationAddress (
191   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
192   IN BOOLEAN                     Reset,
193   IN EFI_MAC_ADDRESS             *NewMacAddr OPTIONAL
194   );
195 
196 /**
197   Resets or collects the statistics on a network interface.
198 
199   @param  This            Protocol instance pointer.
200   @param  Reset           Set to TRUE to reset the statistics for the network interface.
201   @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On
202                           output the size, in bytes, of the resulting table of
203                           statistics.
204   @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
205                           contains the statistics.
206 
207   @retval EFI_SUCCESS           The statistics were collected from the network interface.
208   @retval EFI_NOT_STARTED       The network interface has not been started.
209   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
210                                 size needed to hold the statistics is returned in
211                                 StatisticsSize.
212   @retval EFI_UNSUPPORTED       Not supported yet.
213 
214 **/
215 EFI_STATUS
216 EFIAPI
217 SnpNt32Statistics (
218   IN EFI_SIMPLE_NETWORK_PROTOCOL  * This,
219   IN BOOLEAN                      Reset,
220   IN OUT UINTN                    *StatisticsSize OPTIONAL,
221   OUT EFI_NETWORK_STATISTICS      *StatisticsTable OPTIONAL
222   );
223 
224 /**
225   Converts a multicast IP address to a multicast HW MAC address.
226 
227   @param  This  Protocol instance pointer.
228   @param  Ipv6  Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
229                 to FALSE if the multicast IP address is IPv4 [RFC 791].
230   @param  Ip    The multicast IP address that is to be converted to a multicast
231                 HW MAC address.
232   @param  Mac   The multicast HW MAC address that is to be generated from IP.
233 
234   @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast
235                                 HW MAC address.
236   @retval EFI_NOT_STARTED       The network interface has not been started.
237   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
238                                 size needed to hold the statistics is returned in
239                                 StatisticsSize.
240   @retval EFI_UNSUPPORTED       Not supported yet.
241 
242 **/
243 EFI_STATUS
244 EFIAPI
245 SnpNt32McastIptoMac (
246   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
247   IN BOOLEAN                     Ipv6,
248   IN EFI_IP_ADDRESS              *Ip,
249   OUT EFI_MAC_ADDRESS            *Mac
250   );
251 
252 /**
253   Performs read and write operations on the NVRAM device attached to a
254   network interface.
255 
256   @param  This         Protocol instance pointer.
257   @param  ReadOrWrite  TRUE for read operations, FALSE for write operations.
258   @param  Offset       Byte offset in the NVRAM device at which to start the read or
259                        write operation. This must be a multiple of NvRamAccessSize and
260                        less than NvRamSize.
261   @param  BufferSize   The number of bytes to read or write from the NVRAM device.
262                        This must also be a multiple of NvramAccessSize.
263   @param  Buffer       A pointer to the data buffer.
264 
265   @retval EFI_UNSUPPORTED       Not supported yet.
266 
267 **/
268 EFI_STATUS
269 EFIAPI
270 SnpNt32Nvdata (
271   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
272   IN BOOLEAN                     ReadOrWrite,
273   IN UINTN                       Offset,
274   IN UINTN                       BufferSize,
275   IN OUT VOID                    *Buffer
276   );
277 
278 /**
279   Reads the current interrupt status and recycled transmit buffer status from
280   a network interface.
281 
282   @param  This            Protocol instance pointer.
283   @param  InterruptStatus A pointer to the bit mask of the currently active interrupts
284                           If this is NULL, the interrupt status will not be read from
285                           the device. If this is not NULL, the interrupt status will
286                           be read from the device. When the  interrupt status is read,
287                           it will also be cleared. Clearing the transmit  interrupt
288                           does not empty the recycled transmit buffer array.
289   @param  TxBuffer        Recycled transmit buffer address. The network interface will
290                           not transmit if its internal recycled transmit buffer array
291                           is full. Reading the transmit buffer does not clear the
292                           transmit interrupt. If this is NULL, then the transmit buffer
293                           status will not be read. If there are no transmit buffers to
294                           recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
295 
296   @retval EFI_SUCCESS           Always succeeds.
297 
298 **/
299 EFI_STATUS
300 EFIAPI
301 SnpNt32GetStatus (
302   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
303   OUT UINT32                     *InterruptStatus,
304   OUT VOID                       **TxBuffer
305   );
306 
307 /**
308   Places a packet in the transmit queue of a network interface.
309 
310   @param  This       Protocol instance pointer.
311   @param  HeaderSize The size, in bytes, of the media header to be filled in by
312                      the Transmit() function. If HeaderSize is non-zero, then it
313                      must be equal to This->Mode->MediaHeaderSize and the DestAddr
314                      and Protocol parameters must not be NULL.
315   @param  BufferSize The size, in bytes, of the entire packet (media header and
316                      data) to be transmitted through the network interface.
317   @param  Buffer     A pointer to the packet (media header followed by data) to be
318                      transmitted. This parameter cannot be NULL. If HeaderSize is zero,
319                      then the media header in Buffer must already be filled in by the
320                      caller. If HeaderSize is non-zero, then the media header will be
321                      filled in by the Transmit() function.
322   @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter
323                      is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
324                      This->Mode->CurrentAddress is used for the source HW MAC address.
325   @param  DestAddr   The destination HW MAC address. If HeaderSize is zero, then this
326                      parameter is ignored.
327   @param  Protocol   The type of header to build. If HeaderSize is zero, then this
328                      parameter is ignored. See RFC 1700, section "Ether Types", for
329                      examples.
330 
331   @retval EFI_SUCCESS           The packet was placed on the transmit queue.
332   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
333   @retval EFI_ACCESS_DENIED     Error acquire global lock for operation.
334 
335 **/
336 EFI_STATUS
337 EFIAPI
338 SnpNt32Transmit (
339   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
340   IN UINTN                       HeaderSize,
341   IN UINTN                       BufferSize,
342   IN VOID                        *Buffer,
343   IN EFI_MAC_ADDRESS             *SrcAddr OPTIONAL,
344   IN EFI_MAC_ADDRESS             *DestAddr OPTIONAL,
345   IN UINT16                      *Protocol OPTIONAL
346   );
347 
348 /**
349   Receives a packet from a network interface.
350 
351   @param  This             Protocol instance pointer.
352   @param  HeaderSize       The size, in bytes, of the media header received on the network
353                            interface. If this parameter is NULL, then the media header size
354                            will not be returned.
355   @param  BuffSize         On entry, the size, in bytes, of Buffer. On exit, the size, in
356                            bytes, of the packet that was received on the network interface.
357   @param  Buffer           A pointer to the data buffer to receive both the media header and
358                            the data.
359   @param  SourceAddr       The source HW MAC address. If this parameter is NULL, the
360                            HW MAC source address will not be extracted from the media
361                            header.
362   @param  DestinationAddr  The destination HW MAC address. If this parameter is NULL,
363                            the HW MAC destination address will not be extracted from the
364                            media header.
365   @param  Protocol         The media header type. If this parameter is NULL, then the
366                            protocol will not be extracted from the media header. See
367                            RFC 1700 section "Ether Types" for examples.
368 
369   @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has
370                                  been updated to the number of bytes received.
371   @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit
372                                  request.
373   @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
374   @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.
375   @retval  EFI_ACCESS_DENIED     Error acquire global lock for operation.
376 
377 **/
378 EFI_STATUS
379 EFIAPI
380 SnpNt32Receive (
381   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
382   OUT UINTN                      *HeaderSize,
383   IN OUT UINTN                   *BuffSize,
384   OUT VOID                       *Buffer,
385   OUT EFI_MAC_ADDRESS            *SourceAddr,
386   OUT EFI_MAC_ADDRESS            *DestinationAddr,
387   OUT UINT16                     *Protocol
388   );
389 
390 SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {
391   SNP_NT32_INSTANCE_SIGNATURE,            //  Signature
392   {
393     NULL,
394     NULL
395   },                                      //  Entry
396   NULL,                                   //  GlobalData
397   NULL,                                   //  DeviceHandle
398   NULL,                                   //  DevicePath
399   {                                       //  Snp
400     EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, //  Revision
401     SnpNt32Start,                         //  Start
402     SnpNt32Stop,                          //  Stop
403     SnpNt32Initialize,                    //  Initialize
404     SnpNt32Reset,                         //  Reset
405     SnpNt32Shutdown,                      //  Shutdown
406     SnpNt32ReceiveFilters,                //  ReceiveFilters
407     SnpNt32StationAddress,                //  StationAddress
408     SnpNt32Statistics,                    //  Statistics
409     SnpNt32McastIptoMac,                  //  MCastIpToMac
410     SnpNt32Nvdata,                        //  NvData
411     SnpNt32GetStatus,                     //  GetStatus
412     SnpNt32Transmit,                      //  Transmit
413     SnpNt32Receive,                       //  Receive
414     NULL,                                 //  WaitForPacket
415     NULL                                  //  Mode
416   },
417   {                                       //  Mode
418     EfiSimpleNetworkInitialized,          //  State
419     NET_ETHER_ADDR_LEN,                   //  HwAddressSize
420     NET_ETHER_HEADER_SIZE,                //  MediaHeaderSize
421     1500,                                 //  MaxPacketSize
422     0,                                    //  NvRamSize
423     0,                                    //  NvRamAccessSize
424     0,                                    //  ReceiveFilterMask
425     0,                                    //  ReceiveFilterSetting
426     MAX_MCAST_FILTER_CNT,                 //  MaxMCastFilterCount
427     0,                                    //  MCastFilterCount
428     {
429       0
430     },                                    //  MCastFilter
431     {
432       0
433     },                                    //  CurrentAddress
434     {
435       0
436     },                                    //  BroadcastAddress
437     {
438       0
439     },                                    //  PermanentAddress
440     NET_IFTYPE_ETHERNET,                  //  IfType
441     FALSE,                                //  MacAddressChangeable
442     FALSE,                                //  MultipleTxSupported
443     TRUE,                                 //  MediaPresentSupported
444     TRUE                                  //  MediaPresent
445   },
446   {
447     0
448   }                                       //  InterfaceInfo
449 };
450 
451 /**
452   Test to see if this driver supports ControllerHandle. This service
453   is called by the EFI boot service ConnectController(). In
454   order to make drivers as small as possible, there are a few calling
455   restrictions for this service. ConnectController() must
456   follow these calling restrictions. If any other agent wishes to call
457   Supported() it must also follow these calling restrictions.
458 
459   @param  This                Protocol instance pointer.
460   @param  ControllerHandle    Handle of device to test
461   @param  RemainingDevicePath Optional parameter use to pick a specific child
462                               device to start.
463 
464   @retval EFI_SUCCESS         This driver supports this device
465   @retval EFI_UNSUPPORTED     This driver does not support this device
466 
467 **/
468 EFI_STATUS
469 EFIAPI
SnpNt32DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)470 SnpNt32DriverBindingSupported (
471   IN EFI_DRIVER_BINDING_PROTOCOL  * This,
472   IN EFI_HANDLE                   ControllerHandle,
473   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
474   )
475 {
476 
477   SNPNT32_GLOBAL_DATA   *GlobalData;
478   LIST_ENTRY            *Entry;
479   SNPNT32_INSTANCE_DATA *Instance;
480 
481   GlobalData = &gSnpNt32GlobalData;
482 
483   NET_LIST_FOR_EACH (Entry, &GlobalData->InstanceList) {
484 
485     Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
486 
487     if (Instance->DeviceHandle == ControllerHandle) {
488       return EFI_SUCCESS;
489     }
490 
491   }
492 
493   return EFI_UNSUPPORTED;
494 }
495 
496 
497 /**
498   Start this driver on ControllerHandle. This service is called by the
499   EFI boot service ConnectController(). In order to make
500   drivers as small as possible, there are a few calling restrictions for
501   this service. ConnectController() must follow these
502   calling restrictions. If any other agent wishes to call Start() it
503   must also follow these calling restrictions.
504 
505   @param  This                 Protocol instance pointer.
506   @param  ControllerHandle     Handle of device to bind driver to
507   @param  RemainingDevicePath  Optional parameter use to pick a specific child
508                                device to start.
509 
510   @retval EFI_SUCCESS          Always succeeds.
511 
512 **/
513 EFI_STATUS
514 EFIAPI
SnpNt32DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)515 SnpNt32DriverBindingStart (
516   IN EFI_DRIVER_BINDING_PROTOCOL  * This,
517   IN EFI_HANDLE                   ControllerHandle,
518   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
519   )
520 {
521   return EFI_SUCCESS;
522 }
523 
524 /**
525   Stop this driver on ControllerHandle. This service is called by the
526   EFI boot service DisconnectController(). In order to
527   make drivers as small as possible, there are a few calling
528   restrictions for this service. DisconnectController()
529   must follow these calling restrictions. If any other agent wishes
530   to call Stop() it must also follow these calling restrictions.
531 
532   @param  This              Protocol instance pointer.
533   @param  ControllerHandle  Handle of device to stop driver on
534   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
535                             children is zero stop the entire bus driver.
536   @param  ChildHandleBuffer List of Child Handles to Stop.
537 
538   @retval EFI_SUCCESS       Always succeeds.
539 
540 **/
541 EFI_STATUS
542 EFIAPI
SnpNt32DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)543 SnpNt32DriverBindingStop (
544   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
545   IN  EFI_HANDLE                   ControllerHandle,
546   IN  UINTN                        NumberOfChildren,
547   IN  EFI_HANDLE                   *ChildHandleBuffer
548   )
549 {
550   return EFI_SUCCESS;
551 }
552 
553 
554 /**
555   Changes the state of a network interface from "stopped" to "started".
556 
557   @param  This Protocol instance pointer.
558 
559   @retval EFI_SUCCESS           Always succeeds.
560 
561 **/
562 EFI_STATUS
563 EFIAPI
SnpNt32Start(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)564 SnpNt32Start (
565   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
566   )
567 {
568   return EFI_SUCCESS;
569 }
570 
571 
572 /**
573   Changes the state of a network interface from "started" to "stopped".
574 
575   @param  This Protocol instance pointer.
576 
577   @retval EFI_SUCCESS           Always succeeds.
578 
579 **/
580 EFI_STATUS
581 EFIAPI
SnpNt32Stop(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)582 SnpNt32Stop (
583   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
584   )
585 {
586   return EFI_SUCCESS;
587 }
588 
589 /**
590   Resets a network adapter and allocates the transmit and receive buffers
591   required by the network interface; optionally, also requests allocation
592   of additional transmit and receive buffers.
593 
594   @param  This              Protocol instance pointer.
595   @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
596                             that the driver should allocate for the network interface.
597                             Some network interfaces will not be able to use the extra
598                             buffer, and the caller will not know if it is actually
599                             being used.
600   @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
601                             that the driver should allocate for the network interface.
602                             Some network interfaces will not be able to use the extra
603                             buffer, and the caller will not know if it is actually
604                             being used.
605 
606   @retval EFI_SUCCESS           Always succeeds.
607 
608 **/
609 EFI_STATUS
610 EFIAPI
SnpNt32Initialize(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN UINTN ExtraRxBufferSize OPTIONAL,IN UINTN ExtraTxBufferSize OPTIONAL)611 SnpNt32Initialize (
612   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
613   IN UINTN                       ExtraRxBufferSize OPTIONAL,
614   IN UINTN                       ExtraTxBufferSize OPTIONAL
615   )
616 {
617   return EFI_SUCCESS;
618 }
619 
620 /**
621   Resets a network adapter and re-initializes it with the parameters that were
622   provided in the previous call to Initialize().
623 
624   @param  This                 Protocol instance pointer.
625   @param  ExtendedVerification Indicates that the driver may perform a more
626                                exhaustive verification operation of the device
627                                during reset.
628 
629   @retval EFI_SUCCESS           Always succeeds.
630 
631 **/
632 EFI_STATUS
633 EFIAPI
SnpNt32Reset(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN ExtendedVerification)634 SnpNt32Reset (
635   IN EFI_SIMPLE_NETWORK_PROTOCOL  *This,
636   IN BOOLEAN                      ExtendedVerification
637   )
638 {
639   return EFI_SUCCESS;
640 }
641 
642 /**
643   Resets a network adapter and leaves it in a state that is safe for
644   another driver to initialize.
645 
646   @param  This Protocol instance pointer.
647 
648   @retval EFI_SUCCESS           Always succeeds.
649 
650 **/
651 EFI_STATUS
652 EFIAPI
SnpNt32Shutdown(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)653 SnpNt32Shutdown (
654   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
655   )
656 {
657   return EFI_SUCCESS;
658 }
659 
660 /**
661   Manages the multicast receive filters of a network interface.
662 
663   @param  This               Protocol instance pointer.
664   @param  EnableBits         A bit mask of receive filters to enable on the network interface.
665   @param  DisableBits        A bit mask of receive filters to disable on the network interface.
666   @param  ResetMcastFilter   Set to TRUE to reset the contents of the multicast receive
667                              filters on the network interface to their default values.
668   @param  McastFilterCount   Number of multicast HW MAC addresses in the new
669                              MCastFilter list. This value must be less than or equal to
670                              the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
671                              field is optional if ResetMCastFilter is TRUE.
672   @param  McastFilter        A pointer to a list of new multicast receive filter HW MAC
673                              addresses. This list will replace any existing multicast
674                              HW MAC address list. This field is optional if
675                              ResetMCastFilter is TRUE.
676 
677   @retval EFI_SUCCESS           The multicast receive filter list was updated.
678   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
679 
680 **/
681 EFI_STATUS
682 EFIAPI
SnpNt32ReceiveFilters(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN UINT32 EnableBits,IN UINT32 DisableBits,IN BOOLEAN ResetMcastFilter,IN UINTN McastFilterCount OPTIONAL,IN EFI_MAC_ADDRESS * McastFilter OPTIONAL)683 SnpNt32ReceiveFilters (
684   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
685   IN UINT32                      EnableBits,
686   IN UINT32                      DisableBits,
687   IN BOOLEAN                     ResetMcastFilter,
688   IN UINTN                       McastFilterCount OPTIONAL,
689   IN EFI_MAC_ADDRESS             *McastFilter     OPTIONAL
690   )
691 {
692   SNPNT32_INSTANCE_DATA *Instance;
693   SNPNT32_GLOBAL_DATA   *GlobalData;
694   INT32                 ReturnValue;
695 
696   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
697 
698   GlobalData  = Instance->GlobalData;
699 
700   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
701     return EFI_ACCESS_DENIED;
702   }
703 
704   ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (
705                                                 Instance->InterfaceInfo.InterfaceIndex,
706                                                 EnableBits,
707                                                 (UINT32)McastFilterCount,
708                                                 McastFilter
709                                                 );
710 
711   EfiReleaseLock (&GlobalData->Lock);
712 
713   if (ReturnValue <= 0) {
714     return EFI_DEVICE_ERROR;
715   }
716 
717   return EFI_SUCCESS;
718 }
719 
720 /**
721   Modifies or resets the current station address, if supported.
722 
723   @param  This         Protocol instance pointer.
724   @param  Reset        Flag used to reset the station address to the network interfaces
725                        permanent address.
726   @param  NewMacAddr   New station address to be used for the network interface.
727 
728   @retval EFI_UNSUPPORTED       Not supported yet.
729 
730 **/
731 EFI_STATUS
732 EFIAPI
SnpNt32StationAddress(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN Reset,IN EFI_MAC_ADDRESS * NewMacAddr OPTIONAL)733 SnpNt32StationAddress (
734   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
735   IN BOOLEAN                     Reset,
736   IN EFI_MAC_ADDRESS             *NewMacAddr OPTIONAL
737   )
738 {
739   return EFI_UNSUPPORTED;
740 }
741 
742 /**
743   Resets or collects the statistics on a network interface.
744 
745   @param  This            Protocol instance pointer.
746   @param  Reset           Set to TRUE to reset the statistics for the network interface.
747   @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On
748                           output the size, in bytes, of the resulting table of
749                           statistics.
750   @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
751                           contains the statistics.
752 
753   @retval EFI_SUCCESS           The statistics were collected from the network interface.
754   @retval EFI_NOT_STARTED       The network interface has not been started.
755   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
756                                 size needed to hold the statistics is returned in
757                                 StatisticsSize.
758   @retval EFI_UNSUPPORTED       Not supported yet.
759 
760 **/
761 EFI_STATUS
762 EFIAPI
SnpNt32Statistics(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN Reset,IN OUT UINTN * StatisticsSize OPTIONAL,OUT EFI_NETWORK_STATISTICS * StatisticsTable OPTIONAL)763 SnpNt32Statistics (
764   IN EFI_SIMPLE_NETWORK_PROTOCOL  * This,
765   IN BOOLEAN                      Reset,
766   IN OUT UINTN                    *StatisticsSize OPTIONAL,
767   OUT EFI_NETWORK_STATISTICS      *StatisticsTable OPTIONAL
768   )
769 {
770   return EFI_UNSUPPORTED;
771 }
772 
773 /**
774   Converts a multicast IP address to a multicast HW MAC address.
775 
776   @param  This Protocol instance pointer.
777   @param  Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
778                to FALSE if the multicast IP address is IPv4 [RFC 791].
779   @param  Ip   The multicast IP address that is to be converted to a multicast
780                HW MAC address.
781   @param  Mac  The multicast HW MAC address that is to be generated from IP.
782 
783   @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast
784                                 HW MAC address.
785   @retval EFI_NOT_STARTED       The network interface has not been started.
786   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
787                                 size needed to hold the statistics is returned in
788                                 StatisticsSize.
789   @retval EFI_UNSUPPORTED       Not supported yet.
790 
791 **/
792 EFI_STATUS
793 EFIAPI
SnpNt32McastIptoMac(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN Ipv6,IN EFI_IP_ADDRESS * Ip,OUT EFI_MAC_ADDRESS * Mac)794 SnpNt32McastIptoMac (
795   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
796   IN BOOLEAN                     Ipv6,
797   IN EFI_IP_ADDRESS              *Ip,
798   OUT EFI_MAC_ADDRESS            *Mac
799   )
800 {
801   return EFI_UNSUPPORTED;
802 }
803 
804 
805 /**
806   Performs read and write operations on the NVRAM device attached to a
807   network interface.
808 
809   @param  This         Protocol instance pointer.
810   @param  ReadOrWrite  TRUE for read operations, FALSE for write operations.
811   @param  Offset       Byte offset in the NVRAM device at which to start the read or
812                        write operation. This must be a multiple of NvRamAccessSize and
813                        less than NvRamSize.
814   @param  BufferSize   The number of bytes to read or write from the NVRAM device.
815                        This must also be a multiple of NvramAccessSize.
816   @param  Buffer       A pointer to the data buffer.
817 
818   @retval EFI_UNSUPPORTED       Not supported yet.
819 
820 **/
821 EFI_STATUS
822 EFIAPI
SnpNt32Nvdata(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN ReadOrWrite,IN UINTN Offset,IN UINTN BufferSize,IN OUT VOID * Buffer)823 SnpNt32Nvdata (
824   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
825   IN BOOLEAN                     ReadOrWrite,
826   IN UINTN                       Offset,
827   IN UINTN                       BufferSize,
828   IN OUT VOID                    *Buffer
829   )
830 {
831   return EFI_UNSUPPORTED;
832 }
833 
834 
835 /**
836   Reads the current interrupt status and recycled transmit buffer status from
837   a network interface.
838 
839   @param  This            Protocol instance pointer.
840   @param  InterruptStatus A pointer to the bit mask of the currently active interrupts
841                           If this is NULL, the interrupt status will not be read from
842                           the device. If this is not NULL, the interrupt status will
843                           be read from the device. When the  interrupt status is read,
844                           it will also be cleared. Clearing the transmit  interrupt
845                           does not empty the recycled transmit buffer array.
846   @param  TxBuffer        Recycled transmit buffer address. The network interface will
847                           not transmit if its internal recycled transmit buffer array
848                           is full. Reading the transmit buffer does not clear the
849                           transmit interrupt. If this is NULL, then the transmit buffer
850                           status will not be read. If there are no transmit buffers to
851                           recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
852 
853   @retval EFI_SUCCESS           Always succeeds.
854 
855 **/
856 EFI_STATUS
857 EFIAPI
SnpNt32GetStatus(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,OUT UINT32 * InterruptStatus,OUT VOID ** TxBuffer)858 SnpNt32GetStatus (
859   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
860   OUT UINT32                     *InterruptStatus,
861   OUT VOID                       **TxBuffer
862   )
863 {
864 
865   if (TxBuffer != NULL) {
866     *((UINT8 **) TxBuffer) = (UINT8 *)(UINTN) 1;
867   }
868 
869   if (InterruptStatus != NULL) {
870     *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
871   }
872 
873   return EFI_SUCCESS;
874 }
875 
876 
877 /**
878   Places a packet in the transmit queue of a network interface.
879 
880   @param  This       Protocol instance pointer.
881   @param  HeaderSize The size, in bytes, of the media header to be filled in by
882                      the Transmit() function. If HeaderSize is non-zero, then it
883                      must be equal to This->Mode->MediaHeaderSize and the DestAddr
884                      and Protocol parameters must not be NULL.
885   @param  BufferSize The size, in bytes, of the entire packet (media header and
886                      data) to be transmitted through the network interface.
887   @param  Buffer     A pointer to the packet (media header followed by data) to be
888                      transmitted. This parameter cannot be NULL. If HeaderSize is zero,
889                      then the media header in Buffer must already be filled in by the
890                      caller. If HeaderSize is non-zero, then the media header will be
891                      filled in by the Transmit() function.
892   @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter
893                      is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
894                      This->Mode->CurrentAddress is used for the source HW MAC address.
895   @param  DestAddr   The destination HW MAC address. If HeaderSize is zero, then this
896                      parameter is ignored.
897   @param  Protocol   The type of header to build. If HeaderSize is zero, then this
898                      parameter is ignored. See RFC 1700, section "Ether Types", for
899                      examples.
900 
901   @retval EFI_SUCCESS           The packet was placed on the transmit queue.
902   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
903   @retval EFI_ACCESS_DENIED     Error acquire global lock for operation.
904 
905 **/
906 EFI_STATUS
907 EFIAPI
SnpNt32Transmit(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN UINTN HeaderSize,IN UINTN BufferSize,IN VOID * Buffer,IN EFI_MAC_ADDRESS * SrcAddr OPTIONAL,IN EFI_MAC_ADDRESS * DestAddr OPTIONAL,IN UINT16 * Protocol OPTIONAL)908 SnpNt32Transmit (
909   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
910   IN UINTN                       HeaderSize,
911   IN UINTN                       BufferSize,
912   IN VOID                        *Buffer,
913   IN EFI_MAC_ADDRESS             *SrcAddr OPTIONAL,
914   IN EFI_MAC_ADDRESS             *DestAddr OPTIONAL,
915   IN UINT16                      *Protocol OPTIONAL
916   )
917 {
918   SNPNT32_INSTANCE_DATA *Instance;
919   SNPNT32_GLOBAL_DATA   *GlobalData;
920   INT32                 ReturnValue;
921 
922   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
923 
924   GlobalData  = Instance->GlobalData;
925 
926   if ((HeaderSize != 0) && (SrcAddr == NULL)) {
927     SrcAddr = &Instance->Mode.CurrentAddress;
928   }
929 
930   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
931     return EFI_ACCESS_DENIED;
932   }
933 
934   ReturnValue = GlobalData->NtNetUtilityTable.Transmit (
935                                                 Instance->InterfaceInfo.InterfaceIndex,
936                                                 (UINT32)HeaderSize,
937                                                 (UINT32)BufferSize,
938                                                 Buffer,
939                                                 SrcAddr,
940                                                 DestAddr,
941                                                 Protocol
942                                                 );
943 
944   EfiReleaseLock (&GlobalData->Lock);
945 
946   if (ReturnValue < 0) {
947     return EFI_DEVICE_ERROR;
948   }
949 
950   return EFI_SUCCESS;
951 }
952 
953 /**
954   Receives a packet from a network interface.
955 
956   @param  This             Protocol instance pointer.
957   @param  HeaderSize       The size, in bytes, of the media header received on the network
958                            interface. If this parameter is NULL, then the media header size
959                            will not be returned.
960   @param  BuffSize         On entry, the size, in bytes, of Buffer. On exit, the size, in
961                            bytes, of the packet that was received on the network interface.
962   @param  Buffer           A pointer to the data buffer to receive both the media header and
963                            the data.
964   @param  SourceAddr       The source HW MAC address. If this parameter is NULL, the
965                            HW MAC source address will not be extracted from the media
966                            header.
967   @param  DestinationAddr  The destination HW MAC address. If this parameter is NULL,
968                            the HW MAC destination address will not be extracted from the
969                            media header.
970   @param  Protocol         The media header type. If this parameter is NULL, then the
971                            protocol will not be extracted from the media header. See
972                            RFC 1700 section "Ether Types" for examples.
973 
974   @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has
975                                  been updated to the number of bytes received.
976   @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit
977                                  request.
978   @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
979   @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.
980   @retval  EFI_ACCESS_DENIED     Error acquire global lock for operation.
981 
982 **/
983 EFI_STATUS
984 EFIAPI
SnpNt32Receive(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,OUT UINTN * HeaderSize,IN OUT UINTN * BuffSize,OUT VOID * Buffer,OUT EFI_MAC_ADDRESS * SourceAddr,OUT EFI_MAC_ADDRESS * DestinationAddr,OUT UINT16 * Protocol)985 SnpNt32Receive (
986   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
987   OUT UINTN                      *HeaderSize,
988   IN OUT UINTN                   *BuffSize,
989   OUT VOID                       *Buffer,
990   OUT EFI_MAC_ADDRESS            *SourceAddr,
991   OUT EFI_MAC_ADDRESS            *DestinationAddr,
992   OUT UINT16                     *Protocol
993   )
994 {
995   SNPNT32_INSTANCE_DATA *Instance;
996   SNPNT32_GLOBAL_DATA   *GlobalData;
997   INT32                 ReturnValue;
998   UINTN                 BufSize;
999 
1000   BufSize     = *BuffSize;
1001 
1002   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
1003 
1004   GlobalData  = Instance->GlobalData;
1005 
1006   ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);
1007 
1008   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
1009     return EFI_ACCESS_DENIED;
1010   }
1011 
1012   ReturnValue = GlobalData->NtNetUtilityTable.Receive (
1013                                                 Instance->InterfaceInfo.InterfaceIndex,
1014                                                 BuffSize,
1015                                                 Buffer
1016                                                 );
1017 
1018   EfiReleaseLock (&GlobalData->Lock);
1019 
1020   if (ReturnValue < 0) {
1021     if (ReturnValue == -100) {
1022       return EFI_BUFFER_TOO_SMALL;
1023     }
1024 
1025     return EFI_DEVICE_ERROR;
1026   } else if (ReturnValue == 0) {
1027     return EFI_NOT_READY;
1028   }
1029 
1030   if (HeaderSize != NULL) {
1031     *HeaderSize = 14;
1032   }
1033 
1034   if (SourceAddr != NULL) {
1035     ZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));
1036     CopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);
1037   }
1038 
1039   if (DestinationAddr != NULL) {
1040     ZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));
1041     CopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);
1042   }
1043 
1044   if (Protocol != NULL) {
1045     *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12)));
1046   }
1047 
1048   return (*BuffSize <= BufSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
1049 }
1050 
1051 /**
1052   Initialize the driver's global data.
1053 
1054   @param  This                  Pointer to the global context data.
1055 
1056   @retval EFI_SUCCESS           The global data is initialized.
1057   @retval EFI_NOT_FOUND         The required DLL is not found.
1058   @retval EFI_DEVICE_ERROR      Error initialize network utility library.
1059   @retval EFI_OUT_OF_RESOURCES  Out of resource.
1060   @retval other                 Other errors.
1061 
1062 **/
1063 EFI_STATUS
SnpNt32InitializeGlobalData(IN OUT SNPNT32_GLOBAL_DATA * This)1064 SnpNt32InitializeGlobalData (
1065   IN OUT SNPNT32_GLOBAL_DATA *This
1066   )
1067 {
1068   EFI_STATUS            Status;
1069   CHAR16                *DllFileNameU;
1070   UINT32                Index;
1071   INT32                 ReturnValue;
1072   BOOLEAN               NetUtilityLibInitDone;
1073   NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];
1074   SNPNT32_INSTANCE_DATA *Instance;
1075   LIST_ENTRY            *Entry;
1076   UINT32                InterfaceCount;
1077 
1078   ASSERT (This != NULL);
1079 
1080   NetUtilityLibInitDone = FALSE;
1081   InterfaceCount        = MAX_INTERFACE_INFO_NUMBER;
1082 
1083   InitializeListHead (&This->InstanceList);
1084   EfiInitializeLock (&This->Lock, TPL_CALLBACK);
1085 
1086   //
1087   //  Get the WinNT thunk
1088   //
1089   Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, (VOID **)&This->WinNtThunk);
1090 
1091   if (EFI_ERROR (Status)) {
1092     return Status;
1093   }
1094 
1095   ASSERT (This->WinNtThunk != NULL);
1096 
1097   DllFileNameU = NETWORK_LIBRARY_NAME_U;
1098 
1099   //
1100   //  Load network utility library
1101   //
1102   This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);
1103 
1104   if (NULL == This->NetworkLibraryHandle) {
1105     return EFI_NOT_FOUND;
1106   }
1107 
1108   This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (
1109                                                                                This->NetworkLibraryHandle,
1110                                                                                NETWORK_LIBRARY_INITIALIZE
1111                                                                                );
1112 
1113   if (NULL == This->NtNetUtilityTable.Initialize) {
1114     Status = EFI_NOT_FOUND;
1115     goto ErrorReturn;
1116   }
1117 
1118   This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (
1119                                                                            This->NetworkLibraryHandle,
1120                                                                            NETWORK_LIBRARY_FINALIZE
1121                                                                            );
1122 
1123   if (NULL == This->NtNetUtilityTable.Finalize) {
1124     Status = EFI_NOT_FOUND;
1125     goto ErrorReturn;
1126   }
1127 
1128   This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (
1129                                                                                              This->NetworkLibraryHandle,
1130                                                                                              NETWORK_LIBRARY_SET_RCV_FILTER
1131                                                                                              );
1132 
1133   if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {
1134     Status = EFI_NOT_FOUND;
1135     goto ErrorReturn;
1136   }
1137 
1138   This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (
1139                                                                          This->NetworkLibraryHandle,
1140                                                                          NETWORK_LIBRARY_RECEIVE
1141                                                                          );
1142 
1143   if (NULL == This->NtNetUtilityTable.Receive) {
1144     Status = EFI_NOT_FOUND;
1145     goto ErrorReturn;
1146   }
1147 
1148   This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (
1149                                                                            This->NetworkLibraryHandle,
1150                                                                            NETWORK_LIBRARY_TRANSMIT
1151                                                                            );
1152 
1153   if (NULL == This->NtNetUtilityTable.Transmit) {
1154     Status = EFI_NOT_FOUND;
1155     goto ErrorReturn;
1156   }
1157   //
1158   //  Initialize the network utility library
1159   //  And enumerate the interfaces in NT32 host
1160   //
1161   ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);
1162   if (ReturnValue <= 0) {
1163     Status = EFI_DEVICE_ERROR;
1164     goto ErrorReturn;
1165   }
1166 
1167   NetUtilityLibInitDone = TRUE;
1168 
1169   if (InterfaceCount == 0) {
1170     Status = EFI_NOT_FOUND;
1171     goto ErrorReturn;
1172   }
1173   //
1174   //  Create fake SNP instances
1175   //
1176   for (Index = 0; Index < InterfaceCount; Index++) {
1177 
1178     Instance = AllocatePool (sizeof (SNPNT32_INSTANCE_DATA));
1179 
1180     if (NULL == Instance) {
1181       Status = EFI_OUT_OF_RESOURCES;
1182       goto ErrorReturn;
1183     }
1184     //
1185     //  Copy the content from a template
1186     //
1187     CopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));
1188 
1189     //
1190     //  Set the interface information.
1191     //
1192     CopyMem (&Instance->InterfaceInfo, &NetInterfaceInfoBuffer[Index], sizeof(Instance->InterfaceInfo));
1193     //
1194     //  Initialize this instance
1195     //
1196     Status = This->InitializeInstanceData (This, Instance);
1197     if (EFI_ERROR (Status)) {
1198 
1199       gBS->FreePool (Instance);
1200       goto ErrorReturn;
1201     }
1202     //
1203     //  Insert this instance into the instance list
1204     //
1205     InsertTailList (&This->InstanceList, &Instance->Entry);
1206   }
1207 
1208   return EFI_SUCCESS;
1209 
1210 ErrorReturn:
1211 
1212   while (!IsListEmpty (&This->InstanceList)) {
1213 
1214     Entry     = This->InstanceList.ForwardLink;
1215 
1216     Instance  = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
1217 
1218     RemoveEntryList (Entry);
1219 
1220     This->CloseInstance (This, Instance);
1221     gBS->FreePool (Instance);
1222   }
1223 
1224   if (NetUtilityLibInitDone) {
1225 
1226     ASSERT (This->WinNtThunk != NULL);
1227 
1228     if (This->NtNetUtilityTable.Finalize != NULL) {
1229       This->NtNetUtilityTable.Finalize ();
1230       This->NtNetUtilityTable.Finalize = NULL;
1231     }
1232   }
1233 
1234   return Status;
1235 }
1236 
1237 
1238 /**
1239   Initialize the snpnt32 driver instance.
1240 
1241   @param  This                  Pointer to the SnpNt32 global data.
1242   @param  Instance              Pointer to the instance context data.
1243 
1244   @retval EFI_SUCCESS           The driver instance is initialized.
1245   @retval other                 Initialization errors.
1246 
1247 **/
1248 EFI_STATUS
SnpNt32InitializeInstanceData(IN SNPNT32_GLOBAL_DATA * This,IN OUT SNPNT32_INSTANCE_DATA * Instance)1249 SnpNt32InitializeInstanceData (
1250   IN SNPNT32_GLOBAL_DATA        *This,
1251   IN OUT SNPNT32_INSTANCE_DATA  *Instance
1252   )
1253 {
1254   EFI_STATUS    Status;
1255   EFI_DEV_PATH  EndNode;
1256   EFI_DEV_PATH  Node;
1257 
1258   Instance->GlobalData  = This;
1259   Instance->Snp.Mode    = &Instance->Mode;
1260   //
1261   //  Set broadcast address
1262   //
1263   SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
1264 
1265   //
1266   //  Copy Current/PermanentAddress MAC address
1267   //
1268   CopyMem (&Instance->Mode.CurrentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.CurrentAddress));
1269   CopyMem (&Instance->Mode.PermanentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.PermanentAddress));
1270 
1271   //
1272   //  Since the fake SNP is based on a real NIC, to avoid conflict with the host
1273   //  NIC network stack, we use a different MAC address.
1274   //  So just change the last byte of the MAC address for the real NIC.
1275   //
1276   Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;
1277 
1278   //
1279   //  Create a fake device path for the instance
1280   //
1281   ZeroMem (&Node, sizeof (Node));
1282 
1283   Node.DevPath.Type     = MESSAGING_DEVICE_PATH;
1284   Node.DevPath.SubType  = MSG_MAC_ADDR_DP;
1285   SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));
1286 
1287   CopyMem (
1288     &Node.MacAddr.MacAddress,
1289     &Instance->Mode.CurrentAddress,
1290     NET_ETHER_ADDR_LEN
1291     );
1292 
1293   Node.MacAddr.IfType = Instance->Mode.IfType;
1294 
1295   SetDevicePathEndNode (&EndNode.DevPath);
1296 
1297   Instance->DevicePath = AppendDevicePathNode (
1298                            &EndNode.DevPath,
1299                            &Node.DevPath
1300                            );
1301 
1302   //
1303   //  Create a fake device handle for the fake SNP
1304   //
1305   Status = gBS->InstallMultipleProtocolInterfaces (
1306                   &Instance->DeviceHandle,
1307                   &gEfiSimpleNetworkProtocolGuid,
1308                   &Instance->Snp,
1309                   &gEfiDevicePathProtocolGuid,
1310                   Instance->DevicePath,
1311                   NULL
1312                   );
1313   return Status;
1314 }
1315 
1316 
1317 /**
1318   Close the SnpNt32 driver instance.
1319 
1320   @param  This                  Pointer to the SnpNt32 global data.
1321   @param  Instance              Pointer to the instance context data.
1322 
1323   @retval EFI_SUCCESS           The instance is closed.
1324 
1325 **/
1326 EFI_STATUS
SnpNt32CloseInstance(IN SNPNT32_GLOBAL_DATA * This,IN OUT SNPNT32_INSTANCE_DATA * Instance)1327 SnpNt32CloseInstance (
1328   IN SNPNT32_GLOBAL_DATA        *This,
1329   IN OUT SNPNT32_INSTANCE_DATA  *Instance
1330   )
1331 {
1332   ASSERT (This != NULL);
1333   ASSERT (Instance != NULL);
1334 
1335   gBS->UninstallMultipleProtocolInterfaces (
1336          Instance->DeviceHandle,
1337          &gEfiSimpleNetworkProtocolGuid,
1338          &Instance->Snp,
1339          &gEfiDevicePathProtocolGuid,
1340          Instance->DevicePath,
1341          NULL
1342          );
1343 
1344   if (Instance->DevicePath != NULL) {
1345     gBS->FreePool (Instance->DevicePath);
1346   }
1347 
1348   return EFI_SUCCESS;
1349 }
1350 
1351 /**
1352   Unloads an image.
1353 
1354   @param  ImageHandle           Handle that identifies the image to be unloaded.
1355 
1356   @retval EFI_SUCCESS           The image has been unloaded.
1357   @return Exit code from the image's unload handler
1358 
1359 **/
1360 EFI_STATUS
1361 EFIAPI
SnpNt32Unload(IN EFI_HANDLE ImageHandle)1362 SnpNt32Unload (
1363   IN EFI_HANDLE  ImageHandle
1364   )
1365 {
1366   EFI_STATUS            Status;
1367   SNPNT32_GLOBAL_DATA   *This;
1368   LIST_ENTRY            *Entry;
1369   SNPNT32_INSTANCE_DATA *Instance;
1370 
1371   This    = &gSnpNt32GlobalData;
1372 
1373   Status  = NetLibDefaultUnload (ImageHandle);
1374 
1375   if (EFI_ERROR (Status)) {
1376     return Status;
1377   }
1378 
1379   while (!IsListEmpty (&This->InstanceList)) {
1380     //
1381     //  Walkthrough the interfaces and remove all the SNP instance
1382     //
1383     Entry     = This->InstanceList.ForwardLink;
1384 
1385     Instance  = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
1386 
1387     RemoveEntryList (Entry);
1388 
1389     This->CloseInstance (This, Instance);
1390     gBS->FreePool (Instance);
1391   }
1392 
1393   if (This->NtNetUtilityTable.Finalize != NULL) {
1394     This->NtNetUtilityTable.Finalize ();
1395   }
1396 
1397   This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);
1398 
1399   return EFI_SUCCESS;
1400 }
1401 
1402 /**
1403   This is the declaration of an EFI image entry point. This entry point is
1404   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
1405   both device drivers and bus drivers.
1406 
1407   @param  ImageHandle           The firmware allocated handle for the UEFI image.
1408   @param  SystemTable           A pointer to the EFI System Table.
1409 
1410   @retval EFI_SUCCESS           The operation completed successfully.
1411   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
1412 
1413 **/
1414 EFI_STATUS
InitializeSnpNt32Driver(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1415 InitializeSnpNt32Driver (
1416   IN EFI_HANDLE        ImageHandle,
1417   IN EFI_SYSTEM_TABLE  *SystemTable
1418   )
1419 {
1420 
1421   EFI_STATUS  Status;
1422 
1423   //
1424   // Install the Driver Protocols
1425   //
1426 
1427   Status = EfiLibInstallDriverBindingComponentName2 (
1428              ImageHandle,
1429              SystemTable,
1430              &gSnpNt32DriverBinding,
1431              ImageHandle,
1432              &gSnpNt32DriverComponentName,
1433              &gSnpNt32DriverComponentName2
1434              );
1435   if (EFI_ERROR (Status)) {
1436     return Status;
1437   }
1438 
1439   //
1440   //  Initialize the global data
1441   //
1442   Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);
1443   if (EFI_ERROR (Status)) {
1444     SnpNt32Unload (ImageHandle);
1445   }
1446 
1447   return Status;
1448 }
1449