1 /**  <at> file
2 Provides the Simple Network functions.
3 
4 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2011 - 2016, ARM Limited. All rights reserved.
6 
7 This program and the accompanying materials are licensed
8 and made available under the terms and conditions of the BSD License which
9 accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include "MarvellYukon.h"
18 #include "if_msk.h"
19 
20 EFI_STATUS
InitializeSNPProtocol(IN OUT YUKON_DRIVER * YukonDriver)21 InitializeSNPProtocol (
22     IN OUT  YUKON_DRIVER *YukonDriver
23     )
24 {
25   EFI_STATUS    Status;
26 
27   Status = RETURN_SUCCESS;
28 
29   YukonDriver->Snp.Revision       = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
30   YukonDriver->Snp.Start          = SnpStart;
31   YukonDriver->Snp.Stop           = SnpStop;
32   YukonDriver->Snp.Initialize     = SnpInitialize;
33   YukonDriver->Snp.Reset          = SnpReset;
34   YukonDriver->Snp.Shutdown       = SnpShutdown;
35   YukonDriver->Snp.ReceiveFilters = SnpReceiveFilters;
36   YukonDriver->Snp.StationAddress = SnpStationAddress;
37   YukonDriver->Snp.Statistics     = SnpStatistics;
38   YukonDriver->Snp.MCastIpToMac   = SnpMcastIpToMac;
39   YukonDriver->Snp.NvData         = SnpNvData;
40   YukonDriver->Snp.GetStatus      = SnpGetStatus;
41   YukonDriver->Snp.Transmit       = SnpTransmit;
42   YukonDriver->Snp.Receive        = SnpReceive;
43   YukonDriver->Snp.WaitForPacket  = NULL;
44 
45   YukonDriver->Snp.Mode           = &YukonDriver->SnpMode;
46 
47   //
48   //  Initialize simple network protocol mode structure
49   //
50   YukonDriver->SnpMode.State               = EfiSimpleNetworkStopped;
51   YukonDriver->SnpMode.HwAddressSize       = NET_ETHER_ADDR_LEN;
52   YukonDriver->SnpMode.MediaHeaderSize     = sizeof (ETHER_HEAD);
53   YukonDriver->SnpMode.MaxPacketSize       = MAX_SUPPORTED_PACKET_SIZE;
54   YukonDriver->SnpMode.NvRamAccessSize     = 0;
55   YukonDriver->SnpMode.NvRamSize           = 0;
56   YukonDriver->SnpMode.IfType              = NET_IFTYPE_ETHERNET;
57   YukonDriver->SnpMode.MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
58   YukonDriver->SnpMode.MCastFilterCount    = 0;
59   gBS->SetMem (&YukonDriver->SnpMode.MCastFilter, MAX_MCAST_FILTER_CNT * sizeof(EFI_MAC_ADDRESS), 0);
60 
61   //
62   //  Set broadcast address
63   //
64   gBS->SetMem (&YukonDriver->SnpMode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
65 
66   YukonDriver->SnpMode.MediaPresentSupported = FALSE;
67   YukonDriver->SnpMode.MacAddressChangeable = FALSE;
68   YukonDriver->SnpMode.MultipleTxSupported = FALSE;
69   YukonDriver->SnpMode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
70   YukonDriver->SnpMode.ReceiveFilterSetting = 0;
71 
72   YukonDriver->SnpMode.MediaPresent = TRUE;
73 
74   return Status;
75 }
76 
77 /**
78   Reads the current interrupt status and recycled transmit buffer status from a
79   network interface.
80 
81   This function gets the current interrupt and recycled transmit buffer status
82   from the network interface. The interrupt status is returned as a bit mask in
83   InterruptStatus. If InterruptStatus is NULL, the interrupt status will not be
84   read. If TxBuf is not NULL, a recycled transmit buffer address will be retrieved.
85   If a recycled transmit buffer address is returned in TxBuf, then the buffer has
86   been successfully transmitted, and the status for that buffer is cleared. If
87   the status of the network interface is successfully collected, EFI_SUCCESS
88   will be returned. If the driver has not been initialized, EFI_DEVICE_ERROR will
89   be returned.
90 
91    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
92    <at> param InterruptStatus         A pointer to the bit mask of the currently active
93                                       interrupts (see "Related Definitions"). If this is NULL,
94                                       the interrupt status will not be read from the device.
95                                       If this is not NULL, the interrupt status will be read
96                                       from the device. When the interrupt status is read, it
97                                       will also be cleared. Clearing the transmit interrupt does
98                                       not empty the recycled transmit buffer array.
99    <at> param TxBuf                   Recycled transmit buffer address. The network interface
100                                       will not transmit if its internal recycled transmit
101                                       buffer array is full. Reading the transmit buffer does
102                                       not clear the transmit interrupt. If this is NULL, then
103                                       the transmit buffer status will not be read. If there
104                                       are no transmit buffers to recycle and TxBuf is not NULL,
105                                       TxBuf will be set to NULL.
106 
107    <at> retval EFI_SUCCESS            The status of the network interface was retrieved.
108    <at> retval EFI_NOT_STARTED        The network interface has not been started.
109    <at> retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid
110                                       EFI_SIMPLE_NETWORK_PROTOCOL structure.
111    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network
112                                       interface.
113 
114 **/
115 EFI_STATUS
116 EFIAPI
SnpGetStatus(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,OUT UINT32 * InterruptStatus,OPTIONAL OUT VOID ** TxBuf OPTIONAL)117 SnpGetStatus (
118     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
119     OUT UINT32                     *InterruptStatus, OPTIONAL
120     OUT VOID                       **TxBuf           OPTIONAL
121     )
122 {
123   EFI_STATUS    Status;
124   YUKON_DRIVER    *Snp;
125   EFI_TPL       OldTpl;
126   struct msk_softc *ScData;
127 
128   if (This == NULL) {
129     return EFI_INVALID_PARAMETER;
130   }
131 
132   Snp = YUKON_DEV_FROM_THIS_SNP (This);
133   if (Snp == NULL) {
134     return EFI_INVALID_PARAMETER;
135   }
136 
137   Status = MarvellYukonGetControllerData (Snp->Controller, &ScData);
138   if (EFI_ERROR (Status)) {
139     return Status;
140   }
141 
142   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
143 
144   switch (Snp->SnpMode.State) {
145     case EfiSimpleNetworkInitialized:
146       break;
147 
148     case EfiSimpleNetworkStopped:
149       Status = EFI_NOT_STARTED;
150       goto ON_EXIT;
151 
152     default:
153       Status = EFI_DEVICE_ERROR;
154       goto ON_EXIT;
155   }
156 
157   mskc_getstatus (ScData->msk_if[Snp->Port], InterruptStatus, TxBuf);
158   Status = EFI_SUCCESS;
159 
160 ON_EXIT:
161   gBS->RestoreTPL (OldTpl);
162 
163   return Status;
164 }
165 
166 /**
167   Resets a network adapter and allocates the transmit and receive buffers
168   required by the network interface; optionally, also requests allocation of
169   additional transmit and receive buffers.
170 
171   This function allocates the transmit and receive buffers required by the network
172   interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.
173   If the allocation succeeds and the network interface is successfully initialized,
174   then EFI_SUCCESS will be returned.
175 
176    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
177 
178    <at> param ExtraRxBufferSize       The size, in bytes, of the extra receive buffer space
179                                       that the driver should allocate for the network interface.
180                                       Some network interfaces will not be able to use the
181                                       extra buffer, and the caller will not know if it is
182                                       actually being used.
183    <at> param ExtraTxBufferSize       The size, in bytes, of the extra transmit buffer space
184                                       that the driver should allocate for the network interface.
185                                       Some network interfaces will not be able to use the
186                                       extra buffer, and the caller will not know if it is
187                                       actually being used.
188 
189    <at> retval EFI_SUCCESS            The network interface was initialized.
190    <at> retval EFI_NOT_STARTED        The network interface has not been started.
191    <at> retval EFI_OUT_OF_RESOURCES   There was not enough memory for the transmit and
192                                       receive buffers.
193    <at> retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid
194                                                                    EFI_SIMPLE_NETWORK_PROTOCOL structure.
195    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
196    <at> retval EFI_UNSUPPORTED        The increased buffer size feature is not supported.
197 
198 **/
199 EFI_STATUS
200 EFIAPI
SnpInitialize(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN UINTN ExtraRxBufferSize OPTIONAL,IN UINTN ExtraTxBufferSize OPTIONAL)201 SnpInitialize (
202     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
203     IN UINTN                       ExtraRxBufferSize OPTIONAL,
204     IN UINTN                       ExtraTxBufferSize OPTIONAL
205     )
206 {
207   EFI_STATUS    Status;
208   YUKON_DRIVER    *YukonDriver;
209   EFI_TPL       OldTpl;
210   struct msk_softc *ScData;
211 
212   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n"));
213   if (This == NULL) {
214     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpInitialize() failed with Status = %r\n", EFI_INVALID_PARAMETER));
215     return EFI_INVALID_PARAMETER;
216   }
217 
218   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
219 
220   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
221   if (EFI_ERROR (Status)) {
222     return Status;
223   }
224 
225   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
226 
227   switch (YukonDriver->SnpMode.State) {
228     case EfiSimpleNetworkStarted:
229       break;
230 
231     case EfiSimpleNetworkStopped:
232       Status = EFI_NOT_STARTED;
233       goto ON_ERROR_RESTORE_TPL;
234 
235     default:
236       Status = EFI_DEVICE_ERROR;
237       goto ON_ERROR_RESTORE_TPL;
238   }
239 
240   YukonDriver->SnpMode.MCastFilterCount      = 0;
241   YukonDriver->SnpMode.ReceiveFilterSetting  = 0;
242   gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0);
243   gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
244 
245   Status = mskc_init (ScData->msk_if[YukonDriver->Port]);
246 
247   if (EFI_ERROR (Status)) {
248      goto ON_ERROR_RESTORE_TPL;
249   }
250 
251   YukonDriver->SnpMode.State = EfiSimpleNetworkInitialized;
252   goto ON_EXIT;
253 
254 ON_ERROR_RESTORE_TPL:
255   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpInitialize() failed with Status = %r\n", Status));
256 
257 ON_EXIT:
258   gBS->RestoreTPL (OldTpl);
259   return Status;
260 }
261 
262 /**
263   Converts a multicast IP address to a multicast HW MAC address.
264 
265   This function converts a multicast IP address to a multicast HW MAC address
266   for all packet transactions. If the mapping is accepted, then EFI_SUCCESS will
267   be returned.
268 
269    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
270    <at> param IPv6                    Set to TRUE if the multicast IP address is IPv6 [RFC 2460].
271                                       Set to FALSE if the multicast IP address is IPv4 [RFC 791].
272    <at> param IP                      The multicast IP address that is to be converted to a multicast
273                                       HW MAC address.
274    <at> param MAC                     The multicast HW MAC address that is to be generated from IP.
275 
276    <at> retval EFI_SUCCESS            The multicast IP address was mapped to the
277                                       multicast HW MAC address.
278    <at> retval EFI_NOT_STARTED        The Simple Network Protocol interface has not
279                                       been started by calling Start().
280    <at> retval EFI_INVALID_PARAMETER  IP is NULL.
281    <at> retval EFI_INVALID_PARAMETER  MAC is NULL.
282    <at> retval EFI_INVALID_PARAMETER  IP does not point to a valid IPv4 or IPv6
283                                       multicast address.
284    <at> retval EFI_DEVICE_ERROR       The Simple Network Protocol interface has not
285                                       been initialized by calling Initialize().
286    <at> retval EFI_UNSUPPORTED        IPv6 is TRUE and the implementation does not
287                                       support IPv6 multicast to MAC address conversion.
288 
289 **/
290 EFI_STATUS
291 EFIAPI
SnpMcastIpToMac(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN IPv6,IN EFI_IP_ADDRESS * IP,OUT EFI_MAC_ADDRESS * MAC)292 SnpMcastIpToMac (
293     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
294     IN BOOLEAN                     IPv6,
295     IN EFI_IP_ADDRESS              *IP,
296     OUT EFI_MAC_ADDRESS            *MAC
297     )
298 {
299   EFI_STATUS    Status;
300   YUKON_DRIVER    *YukonDriver;
301   EFI_TPL       OldTpl;
302 
303   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpMcastIpToMac()\n"));
304 
305   //
306   // Get pointer to SNP driver instance for *this.
307   //
308   if (This == NULL) {
309     return EFI_INVALID_PARAMETER;
310   }
311 
312   if (IP == NULL || MAC == NULL) {
313     return EFI_INVALID_PARAMETER;
314   }
315 
316   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
317 
318   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
319 
320   switch (YukonDriver->SnpMode.State) {
321     case EfiSimpleNetworkInitialized:
322       break;
323 
324     case EfiSimpleNetworkStopped:
325       Status = EFI_NOT_STARTED;
326       goto ON_EXIT;
327 
328     default:
329       Status = EFI_DEVICE_ERROR;
330       goto ON_EXIT;
331   }
332 
333   Status = EFI_UNSUPPORTED;
334 
335 ON_EXIT:
336   gBS->RestoreTPL (OldTpl);
337 
338   return Status;
339 }
340 
341 /**
342   Performs read and write operations on the NVRAM device attached to a network
343   interface.
344 
345   This function performs read and write operations on the NVRAM device attached
346   to a network interface. If ReadWrite is TRUE, a read operation is performed.
347   If ReadWrite is FALSE, a write operation is performed. Offset specifies the
348   byte offset at which to start either operation. Offset must be a multiple of
349   NvRamAccessSize , and it must have a value between zero and NvRamSize.
350   BufferSize specifies the length of the read or write operation. BufferSize must
351   also be a multiple of NvRamAccessSize, and Offset + BufferSize must not exceed
352   NvRamSize.
353   If any of the above conditions is not met, then EFI_INVALID_PARAMETER will be
354   returned.
355   If all the conditions are met and the operation is "read," the NVRAM device
356   attached to the network interface will be read into Buffer and EFI_SUCCESS
357   will be returned. If this is a write operation, the contents of Buffer will be
358   used to update the contents of the NVRAM device attached to the network
359   interface and EFI_SUCCESS will be returned.
360 
361   It does the basic checking on the input parameters and retrieves snp structure
362   and then calls the read_nvdata() call which does the actual reading
363 
364    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
365    <at> param ReadWrite               TRUE for read operations, FALSE for write operations.
366    <at> param Offset                  Byte offset in the NVRAM device at which to start the read or
367                                       write operation. This must be a multiple of NvRamAccessSize
368                                       and less than NvRamSize. (See EFI_SIMPLE_NETWORK_MODE)
369    <at> param BufferSize              The number of bytes to read or write from the NVRAM device.
370                                       This must also be a multiple of NvramAccessSize.
371    <at> param Buffer                  A pointer to the data buffer.
372 
373    <at> retval EFI_SUCCESS            The NVRAM access was performed.
374    <at> retval EFI_NOT_STARTED        The network interface has not been started.
375    <at> retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
376                                       * The This parameter is NULL
377                                       * The This parameter does not point to a valid
378                                         EFI_SIMPLE_NETWORK_PROTOCOL  structure
379                                       * The Offset parameter is not a multiple of
380                                         EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize
381                                       * The Offset parameter is not less than
382                                         EFI_SIMPLE_NETWORK_MODE.NvRamSize
383                                       * The BufferSize parameter is not a multiple of
384                                         EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize
385                                       * The Buffer parameter is NULL
386    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network
387                                       interface.
388    <at> retval EFI_UNSUPPORTED        This function is not supported by the network
389                                       interface.
390 
391 **/
392 EFI_STATUS
393 EFIAPI
SnpNvData(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN ReadWrite,IN UINTN Offset,IN UINTN BufferSize,IN OUT VOID * Buffer)394 SnpNvData (
395     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
396     IN BOOLEAN                     ReadWrite,
397     IN UINTN                       Offset,
398     IN UINTN                       BufferSize,
399     IN OUT VOID                    *Buffer
400     )
401 {
402   EFI_STATUS    Status;
403   YUKON_DRIVER    *YukonDriver;
404   EFI_TPL       OldTpl;
405 
406   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpNvData()\n"));
407   //
408   // Get pointer to SNP driver instance for *this.
409   //
410   if (This == NULL) {
411     return EFI_INVALID_PARAMETER;
412   }
413 
414   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
415 
416   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
417 
418   //
419   // Return error if the SNP is not initialized.
420   //
421   switch (YukonDriver->SnpMode.State) {
422     case EfiSimpleNetworkInitialized:
423       break;
424 
425     case EfiSimpleNetworkStopped:
426       Status = EFI_NOT_STARTED;
427       goto ON_EXIT;
428 
429     case EfiSimpleNetworkStarted:
430     default:
431       Status = EFI_DEVICE_ERROR;
432       goto ON_EXIT;
433   }
434   //
435   // Return error if non-volatile memory variables are not valid.
436   //
437   if (YukonDriver->SnpMode.NvRamSize == 0 || YukonDriver->SnpMode.NvRamAccessSize == 0) {
438     Status = EFI_UNSUPPORTED;
439     goto ON_EXIT;
440   }
441   //
442   // Check for invalid parameter combinations.
443   //
444   if ((BufferSize == 0) ||
445       (Buffer == NULL) ||
446       (Offset >= YukonDriver->SnpMode.NvRamSize) ||
447       (Offset + BufferSize > YukonDriver->SnpMode.NvRamSize) ||
448       (BufferSize % YukonDriver->SnpMode.NvRamAccessSize != 0) ||
449       (Offset % YukonDriver->SnpMode.NvRamAccessSize != 0)
450       ) {
451     Status = EFI_INVALID_PARAMETER;
452     goto ON_EXIT;
453   }
454 
455   Status = EFI_UNSUPPORTED;
456 
457 ON_EXIT:
458   gBS->RestoreTPL (OldTpl);
459 
460   return Status;
461 }
462 
463 /**
464   Receives a packet from a network interface.
465 
466   This function retrieves one packet from the receive queue of a network interface.
467   If there are no packets on the receive queue, then EFI_NOT_READY will be
468   returned. If there is a packet on the receive queue, and the size of the packet
469   is smaller than BufferSize, then the contents of the packet will be placed in
470   Buffer, and BufferSize will be updated with the actual size of the packet.
471   In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values
472   will be extracted from the media header and returned. EFI_SUCCESS will be
473   returned if a packet was successfully received.
474   If BufferSize is smaller than the received packet, then the size of the receive
475   packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.
476   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
477 
478    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
479    <at> param HeaderSize              The size, in bytes, of the media header received on the network
480                                       interface. If this parameter is NULL, then the media header size
481                                       will not be returned.
482    <at> param BufferSize              On entry, the size, in bytes, of Buffer. On exit, the size, in
483                                       bytes, of the packet that was received on the network interface.
484    <at> param Buffer                  A pointer to the data buffer to receive both the media
485                                       header and the data.
486    <at> param SrcAddr                 The source HW MAC address. If this parameter is NULL, the HW
487                                       MAC source address will not be extracted from the media header.
488    <at> param DestAddr                The destination HW MAC address. If this parameter is NULL,
489                                       the HW MAC destination address will not be extracted from
490                                       the media header.
491    <at> param Protocol                The media header type. If this parameter is NULL, then the
492                                       protocol will not be extracted from the media header. See
493                                       RFC 1700 section "Ether Types" for examples.
494 
495    <at> retval EFI_SUCCESS            The received data was stored in Buffer, and
496                                       BufferSize has been updated to the number of
497                                       bytes received.
498    <at> retval EFI_NOT_STARTED        The network interface has not been started.
499    <at> retval EFI_NOT_READY          No packets have been received on the network interface.
500    <at> retval EFI_BUFFER_TOO_SMALL   BufferSize is too small for the received packets.
501                                       BufferSize has been updated to the required size.
502    <at> retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
503                                       * The This parameter is NULL
504                                       * The This parameter does not point to a valid
505                                         EFI_SIMPLE_NETWORK_PROTOCOL structure.
506                                       * The BufferSize parameter is NULL
507                                       * The Buffer parameter is NULL
508    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
509 
510 **/
511 EFI_STATUS
512 EFIAPI
SnpReceive(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,OUT UINTN * HeaderSize OPTIONAL,IN OUT UINTN * BufferSize,OUT VOID * Buffer,OUT EFI_MAC_ADDRESS * SrcAddr OPTIONAL,OUT EFI_MAC_ADDRESS * DestAddr OPTIONAL,OUT UINT16 * Protocol OPTIONAL)513 SnpReceive (
514     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
515     OUT UINTN                      *HeaderSize OPTIONAL,
516     IN OUT UINTN                   *BufferSize,
517     OUT VOID                       *Buffer,
518     OUT EFI_MAC_ADDRESS            *SrcAddr OPTIONAL,
519     OUT EFI_MAC_ADDRESS            *DestAddr OPTIONAL,
520     OUT UINT16                     *Protocol OPTIONAL
521     )
522 {
523   EFI_STATUS    Status;
524   YUKON_DRIVER    *Snp;
525   EFI_TPL       OldTpl;
526   struct msk_softc *ScData;
527 
528   if (This == NULL) {
529     return EFI_INVALID_PARAMETER;
530   }
531 
532   Snp = YUKON_DEV_FROM_THIS_SNP (This);
533 
534   Status = MarvellYukonGetControllerData (Snp->Controller, &ScData);
535   if (EFI_ERROR (Status)) {
536     return Status;
537   }
538 
539   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
540 
541   switch (Snp->SnpMode.State) {
542     case EfiSimpleNetworkInitialized:
543       break;
544 
545     case EfiSimpleNetworkStopped:
546       Status = EFI_NOT_STARTED;
547       goto ON_EXIT;
548 
549     default:
550       Status = EFI_DEVICE_ERROR;
551       goto ON_EXIT;
552   }
553 
554   if ((BufferSize == NULL) || (Buffer == NULL)) {
555     Status = EFI_INVALID_PARAMETER;
556     goto ON_EXIT;
557   }
558 
559   Status = mskc_receive (ScData->msk_if[Snp->Port], BufferSize, Buffer);
560   if (EFI_ERROR (Status)) {
561     if (Status == EFI_NOT_READY) {
562       goto ON_EXIT_NO_DEBUG;
563     }
564   } else {
565     // Extract header info
566     if (HeaderSize != NULL) {
567       *HeaderSize = sizeof (ETHER_HEAD);
568     }
569 
570     if (SrcAddr != NULL) {
571       gBS->SetMem (SrcAddr, NET_ETHER_ADDR_LEN, 0);
572       gBS->CopyMem (SrcAddr, ((UINT8 *) Buffer) + NET_ETHER_ADDR_LEN, NET_ETHER_ADDR_LEN);
573     }
574 
575     if (DestAddr != NULL) {
576       gBS->SetMem (DestAddr, NET_ETHER_ADDR_LEN, 0);
577       gBS->CopyMem (DestAddr, ((UINT8 *) Buffer), NET_ETHER_ADDR_LEN);
578     }
579 
580     if (Protocol != NULL) {
581       *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + (2 * NET_ETHER_ADDR_LEN))));
582     }
583   }
584 
585 ON_EXIT:
586   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReceive() Status = %r\n", Status));
587 
588 ON_EXIT_NO_DEBUG:
589   gBS->RestoreTPL (OldTpl);
590   return Status;
591 }
592 
593 /**
594   Manages the multicast receive filters of a network interface.
595 
596   This function is used enable and disable the hardware and software receive
597   filters for the underlying network device.
598   The receive filter change is broken down into three steps:
599   * The filter mask bits that are set (ON) in the Enable parameter are added to
600     the current receive filter settings.
601   * The filter mask bits that are set (ON) in the Disable parameter are subtracted
602     from the updated receive filter settings.
603   * If the resulting receive filter setting is not supported by the hardware a
604     more liberal setting is selected.
605   If the same bits are set in the Enable and Disable parameters, then the bits
606   in the Disable parameter takes precedence.
607   If the ResetMCastFilter parameter is TRUE, then the multicast address list
608   filter is disabled (irregardless of what other multicast bits are set in the
609   Enable and Disable parameters). The SNP->Mode->MCastFilterCount field is set
610   to zero. The Snp->Mode->MCastFilter contents are undefined.
611   After enabling or disabling receive filter settings, software should verify
612   the new settings by checking the Snp->Mode->ReceiveFilterSettings,
613   Snp->Mode->MCastFilterCount and Snp->Mode->MCastFilter fields.
614   Note: Some network drivers and/or devices will automatically promote receive
615     filter settings if the requested setting can not be honored. For example, if
616     a request for four multicast addresses is made and the underlying hardware
617     only supports two multicast addresses the driver might set the promiscuous
618     or promiscuous multicast receive filters instead. The receiving software is
619     responsible for discarding any extra packets that get through the hardware
620     receive filters.
621     Note: Note: To disable all receive filter hardware, the network driver must
622       be Shutdown() and Stopped(). Calling ReceiveFilters() with Disable set to
623       Snp->Mode->ReceiveFilterSettings will make it so no more packets are
624       returned by the Receive() function, but the receive hardware may still be
625       moving packets into system memory before inspecting and discarding them.
626       Unexpected system errors, reboots and hangs can occur if an OS is loaded
627       and the network devices are not Shutdown() and Stopped().
628   If ResetMCastFilter is TRUE, then the multicast receive filter list on the
629   network interface will be reset to the default multicast receive filter list.
630   If ResetMCastFilter is FALSE, and this network interface allows the multicast
631   receive filter list to be modified, then the MCastFilterCnt and MCastFilter
632   are used to update the current multicast receive filter list. The modified
633   receive filter list settings can be found in the MCastFilter field of
634   EFI_SIMPLE_NETWORK_MODE. If the network interface does not allow the multicast
635   receive filter list to be modified, then EFI_INVALID_PARAMETER will be returned.
636   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
637   If the receive filter mask and multicast receive filter list have been
638   successfully updated on the network interface, EFI_SUCCESS will be returned.
639 
640    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
641    <at> param Enable                  A bit mask of receive filters to enable on the network
642                                       interface.
643    <at> param Disable                 A bit mask of receive filters to disable on the network
644                                       interface. For backward compatibility with EFI 1.1
645                                       platforms, the EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit
646                                       must be set when the ResetMCastFilter parameter is TRUE.
647    <at> param ResetMCastFilter        Set to TRUE to reset the contents of the multicast
648                                       receive filters on the network interface to their
649                                       default values.
650    <at> param MCastFilterCnt          Number of multicast HW MAC addresses in the new MCastFilter
651                                       list. This value must be less than or equal to the
652                                       MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE.
653                                       This field is optional if ResetMCastFilter is TRUE.
654    <at> param MCastFilter             A pointer to a list of new multicast receive filter HW
655                                       MAC addresses. This list will replace any existing
656                                       multicast HW MAC address list. This field is optional
657                                       if ResetMCastFilter is TRUE.
658 
659    <at> retval EFI_SUCCESS            The multicast receive filter list was updated.
660    <at> retval EFI_NOT_STARTED        The network interface has not been started.
661    <at> retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
662                                       * This is NULL
663                                       * There are bits set in Enable that are not set
664                                         in Snp->Mode->ReceiveFilterMask
665                                       * There are bits set in Disable that are not set
666                                         in Snp->Mode->ReceiveFilterMask
667                                       * Multicast is being enabled (the
668                                         EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit is
669                                         set in Enable, it is not set in Disable, and
670                                         ResetMCastFilter is FALSE) and MCastFilterCount
671                                         is zero
672                                       * Multicast is being enabled and MCastFilterCount
673                                         is greater than Snp->Mode->MaxMCastFilterCount
674                                       * Multicast is being enabled and MCastFilter is NULL
675                                       * Multicast is being enabled and one or more of
676                                         the addresses in the MCastFilter list are not
677                                         valid multicast MAC addresses
678    <at> retval EFI_DEVICE_ERROR       One or more of the following conditions is TRUE:
679                                       * The network interface has been started but has
680                                         not been initialized
681                                       * An unexpected error was returned by the
682                                         underlying network driver or device
683    <at> retval EFI_UNSUPPORTED        This function is not supported by the network
684                                       interface.
685 
686 **/
687 EFI_STATUS
688 EFIAPI
SnpReceiveFilters(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN UINT32 Enable,IN UINT32 Disable,IN BOOLEAN ResetMCastFilter,IN UINTN MCastFilterCnt,OPTIONAL IN EFI_MAC_ADDRESS * MCastFilter OPTIONAL)689 SnpReceiveFilters (
690     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
691     IN UINT32                      Enable,
692     IN UINT32                      Disable,
693     IN BOOLEAN                     ResetMCastFilter,
694     IN UINTN                       MCastFilterCnt,  OPTIONAL
695     IN EFI_MAC_ADDRESS             *MCastFilter     OPTIONAL
696     )
697 {
698   EFI_STATUS    Status;
699   YUKON_DRIVER    *YukonDriver;
700   EFI_TPL       OldTpl;
701   UINT32        newReceiveFilter;
702   struct msk_softc *ScData;
703 
704   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReceiveFilters()\n"));
705   if (This == NULL) {
706     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpReceiveFilters() failed with Status = %r\n", EFI_INVALID_PARAMETER));
707     return EFI_INVALID_PARAMETER;
708   }
709 
710   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
711 
712   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
713   if (EFI_ERROR (Status)) {
714     return Status;
715   }
716 
717   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
718 
719   switch (YukonDriver->SnpMode.State) {
720     case EfiSimpleNetworkInitialized:
721       break;
722 
723     case EfiSimpleNetworkStopped:
724       Status = EFI_NOT_STARTED;
725       goto ON_ERROR_RESTORE_TPL;
726 
727     default:
728       Status = EFI_DEVICE_ERROR;
729       goto ON_ERROR_RESTORE_TPL;
730   }
731   //
732   // check if we are asked to enable or disable something that the NIC
733   // does not even support!
734   //
735   newReceiveFilter = (YukonDriver->SnpMode.ReceiveFilterSetting | Enable) & ~Disable;
736   if ((newReceiveFilter & ~YukonDriver->SnpMode.ReceiveFilterMask) != 0) {
737     DEBUG ((DEBUG_NET,
738            "Marvell Yukon: SnpReceiveFilters() NIC does not support Enable = 0x%x, Disable = 0x%x\n", Enable, Disable));
739     Status = EFI_INVALID_PARAMETER;
740     goto ON_ERROR_RESTORE_TPL;
741   }
742 
743   if (ResetMCastFilter) {
744     newReceiveFilter &= ~(EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & YukonDriver->SnpMode.ReceiveFilterMask);
745     MCastFilterCnt = 0;
746     MCastFilter    = NULL;
747   } else {
748     if (MCastFilterCnt != 0) {
749       if ((MCastFilterCnt > YukonDriver->SnpMode.MaxMCastFilterCount) ||
750           (MCastFilter == NULL)) {
751 
752         DEBUG ((DEBUG_NET,
753                "Marvell Yukon: SnpReceiveFilters() NIC does not support MCastFilterCnt = %d (Max = %d)\n",
754                MCastFilterCnt, YukonDriver->SnpMode.MaxMCastFilterCount));
755         Status = EFI_INVALID_PARAMETER;
756         goto ON_ERROR_RESTORE_TPL;
757       }
758     }
759   }
760 
761   if (newReceiveFilter == YukonDriver->SnpMode.ReceiveFilterSetting && !ResetMCastFilter && MCastFilterCnt == 0) {
762     Status = EFI_SUCCESS;
763     goto ON_EXIT;
764   }
765 
766   if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
767     Status = EFI_INVALID_PARAMETER;
768     goto ON_ERROR_RESTORE_TPL;
769   }
770 
771   YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter;
772   mskc_rxfilter (ScData->msk_if[YukonDriver->Port], YukonDriver->SnpMode.ReceiveFilterSetting,
773                  MCastFilterCnt, MCastFilter);
774 
775   Status = EFI_SUCCESS;
776   goto ON_EXIT;
777 
778 ON_ERROR_RESTORE_TPL:
779   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpReceiveFilters() failed with Status = %r\n", Status));
780 
781 ON_EXIT:
782   gBS->RestoreTPL (OldTpl);
783   return Status;
784 }
785 
786 /**
787   Resets a network adapter and reinitializes it with the parameters that were
788   provided in the previous call to Initialize().
789 
790   This function resets a network adapter and reinitializes it with the parameters
791   that were provided in the previous call to Initialize(). The transmit and
792   receive queues are emptied and all pending interrupts are cleared.
793   Receive filters, the station address, the statistics, and the multicast-IP-to-HW
794   MAC addresses are not reset by this call. If the network interface was
795   successfully reset, then EFI_SUCCESS will be returned. If the driver has not
796   been initialized, EFI_DEVICE_ERROR will be returned.
797 
798    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
799    <at> param ExtendedVerification    Indicates that the driver may perform a more
800                                       exhaustive verification operation of the device
801                                       during reset.
802 
803    <at> retval EFI_SUCCESS            The network interface was reset.
804    <at> retval EFI_NOT_STARTED        The network interface has not been started.
805    <at> retval EFI_INVALID_PARAMETER  One or more of the parameters has an unsupported value.
806    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
807    <at> retval EFI_UNSUPPORTED        This function is not supported by the network interface.
808 
809 **/
810 EFI_STATUS
811 EFIAPI
SnpReset(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN ExtendedVerification)812 SnpReset (
813     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
814     IN BOOLEAN                     ExtendedVerification
815     )
816 {
817   EFI_STATUS    Status;
818   YUKON_DRIVER    *YukonDriver;
819   EFI_TPL       OldTpl;
820 
821   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n"));
822   //
823   // Resolve Warning 4 unreferenced parameter problem
824   //
825   ExtendedVerification = 0;
826   DEBUG ((EFI_D_WARN, "Marvell Yukon: ExtendedVerification = %d is not implemented!\n", ExtendedVerification));
827 
828   if (This == NULL) {
829     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpReset() failed with Status = %r\n", EFI_INVALID_PARAMETER));
830     return EFI_INVALID_PARAMETER;
831   }
832 
833   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
834 
835   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
836 
837   switch (YukonDriver->SnpMode.State) {
838     case EfiSimpleNetworkInitialized:
839       break;
840 
841     case EfiSimpleNetworkStopped:
842       Status = EFI_NOT_STARTED;
843       goto ON_ERROR_RESTORE_TPL;
844 
845     default:
846       Status = EFI_DEVICE_ERROR;
847       goto ON_ERROR_RESTORE_TPL;
848   }
849 
850   // Always succeeds
851   Status = EFI_SUCCESS;
852   goto ON_EXIT;
853 
854 ON_ERROR_RESTORE_TPL:
855   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpReset() failed with Status = %r\n", Status));
856 
857 ON_EXIT:
858   gBS->RestoreTPL (OldTpl);
859   return Status;
860 }
861 
862 /**
863   Resets a network adapter and leaves it in a state that is safe for another
864   driver to initialize.
865 
866   This function releases the memory buffers assigned in the Initialize() call.
867   Pending transmits and receives are lost, and interrupts are cleared and disabled.
868   After this call, only the Initialize() and Stop() calls may be used. If the
869   network interface was successfully shutdown, then EFI_SUCCESS will be returned.
870   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
871 
872    <at> param  This                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
873 
874    <at> retval EFI_SUCCESS            The network interface was shutdown.
875    <at> retval EFI_NOT_STARTED        The network interface has not been started.
876    <at> retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid
877                                       EFI_SIMPLE_NETWORK_PROTOCOL structure.
878    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
879 
880 **/
881 EFI_STATUS
882 EFIAPI
SnpShutdown(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)883 SnpShutdown (
884     IN EFI_SIMPLE_NETWORK_PROTOCOL *This
885     )
886 {
887   EFI_STATUS    Status;
888   YUKON_DRIVER    *YukonDriver;
889   EFI_TPL       OldTpl;
890   struct msk_softc *ScData;
891 
892   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n"));
893   //
894   // Get pointer to SNP driver instance for *This.
895   //
896   if (This == NULL) {
897     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpShutdown() failed with Status = %r\n", EFI_INVALID_PARAMETER));
898     return EFI_INVALID_PARAMETER;
899   }
900 
901   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
902 
903   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
904   if (EFI_ERROR (Status)) {
905     return Status;
906   }
907 
908   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
909 
910   //
911   // Return error if the SNP is not initialized.
912   //
913   switch (YukonDriver->SnpMode.State) {
914     case EfiSimpleNetworkInitialized:
915       break;
916 
917     case EfiSimpleNetworkStopped:
918       Status = EFI_NOT_STARTED;
919       goto ON_ERROR_RESTORE_TPL;
920 
921     default:
922       Status = EFI_DEVICE_ERROR;
923       goto ON_ERROR_RESTORE_TPL;
924   }
925 
926   mskc_stop_if (ScData->msk_if[YukonDriver->Port]);
927   YukonDriver->SnpMode.State = EfiSimpleNetworkStarted;
928   Status = EFI_SUCCESS;
929 
930   YukonDriver->SnpMode.State                 = EfiSimpleNetworkStarted;
931   YukonDriver->SnpMode.ReceiveFilterSetting  = 0;
932 
933   YukonDriver->SnpMode.MCastFilterCount      = 0;
934   YukonDriver->SnpMode.ReceiveFilterSetting  = 0;
935   gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0);
936   gBS->CopyMem (
937         &YukonDriver->SnpMode.CurrentAddress,
938         &YukonDriver->SnpMode.PermanentAddress,
939         sizeof (EFI_MAC_ADDRESS)
940         );
941 
942   goto ON_EXIT;
943 
944 ON_ERROR_RESTORE_TPL:
945   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpShutdown() failed with Status = %r\n", Status));
946 
947 ON_EXIT:
948   gBS->RestoreTPL (OldTpl);
949   return Status;
950 }
951 
952 /**
953   Change the state of a network interface from "stopped" to "started."
954 
955   This function starts a network interface. If the network interface successfully
956   starts, then EFI_SUCCESS will be returned.
957 
958    <at> param  This                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
959 
960    <at> retval EFI_SUCCESS            The network interface was started.
961    <at> retval EFI_ALREADY_STARTED    The network interface is already in the started state.
962    <at> retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid
963                                       EFI_SIMPLE_NETWORK_PROTOCOL structure.
964    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
965    <at> retval EFI_UNSUPPORTED        This function is not supported by the network interface.
966 
967 **/
968 EFI_STATUS
969 EFIAPI
SnpStart(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)970 SnpStart (
971     IN EFI_SIMPLE_NETWORK_PROTOCOL *This
972     )
973 {
974   YUKON_DRIVER    *YukonDriver;
975   EFI_TPL       OldTpl;
976   EFI_STATUS    Status;
977   struct msk_softc  *ScData;
978 
979   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStart()\n"));
980   if (This == NULL) {
981     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpStart() failed with Status = %r\n", EFI_INVALID_PARAMETER));
982     return EFI_INVALID_PARAMETER;
983   }
984 
985   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
986 
987   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
988   if (EFI_ERROR (Status)) {
989     return Status;
990   }
991 
992   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
993 
994   switch (YukonDriver->SnpMode.State) {
995     case EfiSimpleNetworkStopped:
996       break;
997 
998     case EfiSimpleNetworkStarted:
999     case EfiSimpleNetworkInitialized:
1000       Status = EFI_ALREADY_STARTED;
1001       goto ON_EXIT;
1002 
1003     default:
1004       Status = EFI_DEVICE_ERROR;
1005       goto ON_ERROR_RESTORE_TPL;
1006   }
1007 
1008   Status = mskc_attach_if (ScData->msk_if[YukonDriver->Port], YukonDriver->Port);
1009 
1010   if (EFI_ERROR (Status)) {
1011     goto ON_ERROR_RESTORE_TPL;
1012   }
1013 
1014   YukonDriver->SnpMode.State = EfiSimpleNetworkStarted;
1015   gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
1016   YukonDriver->SnpMode.MCastFilterCount = 0;
1017   goto ON_EXIT;
1018 
1019 ON_ERROR_RESTORE_TPL:
1020   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpStart() failed with Status = %r\n", Status));
1021 
1022 ON_EXIT:
1023   gBS->RestoreTPL (OldTpl);
1024   return Status;
1025 }
1026 
1027 /**
1028   Modifies or resets the current station address, if supported.
1029 
1030   This function modifies or resets the current station address of a network
1031   interface, if supported. If Reset is TRUE, then the current station address is
1032   set to the network interface's permanent address. If Reset is FALSE, and the
1033   network interface allows its station address to be modified, then the current
1034   station address is changed to the address specified by New. If the network
1035   interface does not allow its station address to be modified, then
1036   EFI_INVALID_PARAMETER will be returned. If the station address is successfully
1037   updated on the network interface, EFI_SUCCESS will be returned. If the driver
1038   has not been initialized, EFI_DEVICE_ERROR will be returned.
1039 
1040    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
1041    <at> param Reset                   Flag used to reset the station address to the network interface's
1042                                       permanent address.
1043    <at> param New                     New station address to be used for the network interface.
1044 
1045 
1046    <at> retval EFI_SUCCESS            The network interface's station address was updated.
1047    <at> retval EFI_NOT_STARTED        The Simple Network Protocol interface has not been
1048                                                                  started by calling Start().
1049    <at> retval EFI_INVALID_PARAMETER  The New station address was not accepted by the NIC.
1050    <at> retval EFI_INVALID_PARAMETER  Reset is FALSE and New is NULL.
1051    <at> retval EFI_DEVICE_ERROR       The Simple Network Protocol interface has not
1052                                       been initialized by calling Initialize().
1053    <at> retval EFI_DEVICE_ERROR       An error occurred attempting to set the new
1054                                       station address.
1055    <at> retval EFI_UNSUPPORTED        The NIC does not support changing the network
1056                                       interface's station address.
1057 
1058 **/
1059 EFI_STATUS
1060 EFIAPI
SnpStationAddress(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN Reset,IN EFI_MAC_ADDRESS * New OPTIONAL)1061 SnpStationAddress (
1062     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
1063     IN BOOLEAN                     Reset,
1064     IN EFI_MAC_ADDRESS             *New OPTIONAL
1065     )
1066 {
1067   YUKON_DRIVER    *YukonDriver;
1068   EFI_TPL       OldTpl;
1069   EFI_STATUS    Status;
1070 
1071   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStationAddress()\n"));
1072   //
1073   // Check for invalid parameter combinations.
1074   //
1075   if ((This == NULL) || (!Reset && (New == NULL))) {
1076     return EFI_INVALID_PARAMETER;
1077   }
1078 
1079   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
1080 
1081   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1082 
1083   //
1084   // Return error if the SNP is not initialized.
1085   //
1086   switch (YukonDriver->SnpMode.State) {
1087     case EfiSimpleNetworkInitialized:
1088       break;
1089 
1090     case EfiSimpleNetworkStopped:
1091       Status = EFI_NOT_STARTED;
1092       goto ON_EXIT;
1093 
1094     default:
1095       Status = EFI_DEVICE_ERROR;
1096       goto ON_EXIT;
1097   }
1098 
1099   Status = EFI_UNSUPPORTED;
1100 
1101 ON_EXIT:
1102   gBS->RestoreTPL (OldTpl);
1103 
1104   return Status;
1105 }
1106 
1107 /**
1108   Resets or collects the statistics on a network interface.
1109 
1110   This function resets or collects the statistics on a network interface. If the
1111   size of the statistics table specified by StatisticsSize is not big enough for
1112   all the statistics that are collected by the network interface, then a partial
1113   buffer of statistics is returned in StatisticsTable, StatisticsSize is set to
1114   the size required to collect all the available statistics, and
1115   EFI_BUFFER_TOO_SMALL is returned.
1116   If StatisticsSize is big enough for all the statistics, then StatisticsTable
1117   will be filled, StatisticsSize will be set to the size of the returned
1118   StatisticsTable structure, and EFI_SUCCESS is returned.
1119   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
1120   If Reset is FALSE, and both StatisticsSize and StatisticsTable are NULL, then
1121   no operations will be performed, and EFI_SUCCESS will be returned.
1122   If Reset is TRUE, then all of the supported statistics counters on this network
1123   interface will be reset to zero.
1124 
1125    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
1126    <at> param Reset                   Set to TRUE to reset the statistics for the network interface.
1127    <at> param StatisticsSize          On input the size, in bytes, of StatisticsTable. On output
1128                                       the size, in bytes, of the resulting table of statistics.
1129    <at> param StatisticsTable         A pointer to the EFI_NETWORK_STATISTICS structure that
1130                                       contains the statistics. Type EFI_NETWORK_STATISTICS is
1131                                       defined in "Related Definitions" below.
1132 
1133    <at> retval EFI_SUCCESS            The requested operation succeeded.
1134    <at> retval EFI_NOT_STARTED        The Simple Network Protocol interface has not been
1135                                       started by calling Start().
1136    <at> retval EFI_BUFFER_TOO_SMALL   StatisticsSize is not NULL and StatisticsTable is
1137                                       NULL. The current buffer size that is needed to
1138                                       hold all the statistics is returned in StatisticsSize.
1139    <at> retval EFI_BUFFER_TOO_SMALL   StatisticsSize is not NULL and StatisticsTable is
1140                                       not NULL. The current buffer size that is needed
1141                                       to hold all the statistics is returned in
1142                                       StatisticsSize. A partial set of statistics is
1143                                       returned in StatisticsTable.
1144    <at> retval EFI_INVALID_PARAMETER  StatisticsSize is NULL and StatisticsTable is not
1145                                       NULL.
1146    <at> retval EFI_DEVICE_ERROR       The Simple Network Protocol interface has not
1147                                       been initialized by calling Initialize().
1148    <at> retval EFI_DEVICE_ERROR       An error was encountered collecting statistics
1149                                       from the NIC.
1150    <at> retval EFI_UNSUPPORTED        The NIC does not support collecting statistics
1151                                       from the network interface.
1152 
1153 **/
1154 EFI_STATUS
1155 EFIAPI
SnpStatistics(IN EFI_SIMPLE_NETWORK_PROTOCOL * This,IN BOOLEAN Reset,IN OUT UINTN * StatisticsSize,OPTIONAL IN OUT EFI_NETWORK_STATISTICS * StatisticsTable OPTIONAL)1156 SnpStatistics (
1157     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
1158     IN BOOLEAN                     Reset,
1159     IN OUT UINTN                   *StatisticsSize, OPTIONAL
1160     IN OUT EFI_NETWORK_STATISTICS  *StatisticsTable OPTIONAL
1161     )
1162 {
1163   EFI_STATUS        Status;
1164   YUKON_DRIVER        *YukonDriver;
1165   EFI_TPL           OldTpl;
1166 
1167   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n"));
1168   //
1169   // Get pointer to SNP driver instance for *This.
1170   //
1171   if (This == NULL) {
1172     return EFI_INVALID_PARAMETER;
1173   }
1174 
1175   Status = EFI_SUCCESS;
1176   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
1177 
1178   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1179 
1180   //
1181   // Return error if the SNP is not initialized.
1182   //
1183   switch (YukonDriver->SnpMode.State) {
1184     case EfiSimpleNetworkInitialized:
1185       break;
1186 
1187     case EfiSimpleNetworkStopped:
1188       Status = EFI_NOT_STARTED;
1189       goto ON_EXIT;
1190 
1191     case EfiSimpleNetworkStarted:
1192     default:
1193       Status = EFI_DEVICE_ERROR;
1194       goto ON_EXIT;
1195   }
1196 
1197   //
1198   // Error Checking
1199   //
1200 
1201   if (!Reset && (StatisticsSize == NULL) && (StatisticsTable == NULL)) {
1202     Status = EFI_SUCCESS;
1203     goto ON_EXIT;
1204   }
1205 
1206   if ((StatisticsSize == NULL) && (StatisticsTable != NULL)) {
1207     Status = EFI_INVALID_PARAMETER;
1208     goto ON_EXIT;
1209   }
1210 
1211   if ((StatisticsSize != NULL) && (StatisticsTable == NULL)) {
1212     *StatisticsSize = sizeof (EFI_NETWORK_STATISTICS);
1213     Status = EFI_BUFFER_TOO_SMALL;
1214     goto ON_EXIT;
1215   }
1216 
1217   if ((StatisticsSize != NULL) && (StatisticsTable != NULL)) {
1218     if (*StatisticsSize < sizeof (EFI_NETWORK_STATISTICS)) {
1219       if (*StatisticsSize == 0) {
1220         Status = EFI_BUFFER_TOO_SMALL;
1221         // Note: From here on, the Status value must be preserved.
1222       } else {
1223         // FixMe: Return partial statistics for the available size and also set
1224         //        Status = EFI_BUFFER_TOO_SMALL;
1225         //        but for now it is unsupported.
1226         Status = EFI_UNSUPPORTED;
1227         // Note: From here on, the Status value must be preserved.
1228       }
1229       *StatisticsSize = sizeof (EFI_NETWORK_STATISTICS);
1230     } else {
1231       // FixMe: Return full statistics and also set
1232       //        Status = EFI_SUCCESS;
1233       //        but for now it is unsupported.
1234       Status = EFI_UNSUPPORTED;
1235     }
1236   }
1237 
1238   if (Reset == TRUE) {
1239     // FixMe: Reset all statistics;
1240 
1241     // Preserve any previous errors else return success.
1242     if (!EFI_ERROR (Status)) {
1243       // FixMe: Should return success
1244       //        Status = EFI_SUCCESS;
1245       //        but for now it is unsupported.
1246       Status = EFI_UNSUPPORTED;
1247     }
1248   }
1249 
1250 ON_EXIT:
1251   gBS->RestoreTPL (OldTpl);
1252 
1253   return Status;
1254 }
1255 
1256 /**
1257   Changes the state of a network interface from "started" to "stopped."
1258 
1259   This function stops a network interface. This call is only valid if the network
1260   interface is in the started state. If the network interface was successfully
1261   stopped, then EFI_SUCCESS will be returned.
1262 
1263    <at> param  This                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL
1264                                                                   instance.
1265 
1266 
1267    <at> retval EFI_SUCCESS            The network interface was stopped.
1268    <at> retval EFI_NOT_STARTED        The network interface has not been started.
1269    <at> retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a
1270                                       valid EFI_SIMPLE_NETWORK_PROTOCOL structure.
1271    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network
1272                                       interface.
1273    <at> retval EFI_UNSUPPORTED        This function is not supported by the network
1274                                       interface.
1275 
1276 **/
1277 EFI_STATUS
1278 EFIAPI
SnpStop(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)1279 SnpStop (
1280     IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1281     )
1282 {
1283   EFI_STATUS    Status;
1284   YUKON_DRIVER    *YukonDriver;
1285   EFI_TPL       OldTpl;
1286   struct msk_softc *ScData;
1287 
1288   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n"));
1289   if (This == NULL) {
1290     DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpStop() failed with Status = %r\n", EFI_INVALID_PARAMETER));
1291     return EFI_INVALID_PARAMETER;
1292   }
1293 
1294   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
1295 
1296   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
1297   if (EFI_ERROR (Status)) {
1298     return Status;
1299   }
1300 
1301   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1302 
1303   switch (YukonDriver->SnpMode.State) {
1304     case EfiSimpleNetworkStarted:
1305       break;
1306 
1307     case EfiSimpleNetworkStopped:
1308       Status = EFI_NOT_STARTED;
1309       goto ON_ERROR_RESTORE_TPL;
1310 
1311     case EfiSimpleNetworkInitialized:
1312     default:
1313       Status = EFI_DEVICE_ERROR;
1314       goto ON_ERROR_RESTORE_TPL;
1315   }
1316 
1317   mskc_detach_if (ScData->msk_if[YukonDriver->Port]);
1318   YukonDriver->SnpMode.State = EfiSimpleNetworkStopped;
1319   gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS), 0);
1320   Status = EFI_SUCCESS;
1321   goto ON_EXIT;
1322 
1323 ON_ERROR_RESTORE_TPL:
1324   DEBUG ((EFI_D_ERROR, "Marvell Yukon: SnpStop() failed with Status = %r\n", Status));
1325 
1326 ON_EXIT:
1327   gBS->RestoreTPL (OldTpl);
1328   return Status;
1329 }
1330 
1331 /**
1332   Places a packet in the transmit queue of a network interface.
1333 
1334   This function places the packet specified by Header and Buffer on the transmit
1335   queue. If HeaderSize is nonzero and HeaderSize is not equal to
1336   This->SnpMode->MediaHeaderSize, then EFI_INVALID_PARAMETER will be returned. If
1337   BufferSize is less than This->SnpMode->MediaHeaderSize, then EFI_BUFFER_TOO_SMALL
1338   will be returned. If Buffer is NULL, then EFI_INVALID_PARAMETER will be
1339   returned. If HeaderSize is nonzero and DestAddr or Protocol is NULL, then
1340   EFI_INVALID_PARAMETER will be returned. If the transmit engine of the network
1341   interface is busy, then EFI_NOT_READY will be returned. If this packet can be
1342   accepted by the transmit engine of the network interface, the packet contents
1343   specified by Buffer will be placed on the transmit queue of the network
1344   interface, and EFI_SUCCESS will be returned. GetStatus() can be used to
1345   determine when the packet has actually been transmitted. The contents of the
1346   Buffer must not be modified until the packet has actually been transmitted.
1347   The Transmit() function performs nonblocking I/O. A caller who wants to perform
1348   blocking I/O, should call Transmit(), and then GetStatus() until the
1349   transmitted buffer shows up in the recycled transmit buffer.
1350   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
1351 
1352    <at> param This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
1353    <at> param HeaderSize              The size, in bytes, of the media header to be filled in by the
1354                                       Transmit() function. If HeaderSize is nonzero, then it must
1355                                       be equal to This->SnpMode->MediaHeaderSize and the DestAddr and
1356                                       Protocol parameters must not be NULL.
1357    <at> param BufferSize              The size, in bytes, of the entire packet (media header and
1358                                       data) to be transmitted through the network interface.
1359    <at> param Buffer                  A pointer to the packet (media header followed by data) to be
1360                                       transmitted. This parameter cannot be NULL. If HeaderSize is
1361                                       zero, then the media header in Buffer must already be filled
1362                                       in by the caller. If HeaderSize is nonzero, then the media
1363                                       header will be filled in by the Transmit() function.
1364    <at> param SrcAddr                 The source HW MAC address. If HeaderSize is zero, then this
1365                                       parameter is ignored. If HeaderSize is nonzero and SrcAddr
1366                                       is NULL, then This->SnpMode->CurrentAddress is used for the
1367                                       source HW MAC address.
1368    <at> param DestAddr                The destination HW MAC address. If HeaderSize is zero, then
1369                                       this parameter is ignored.
1370    <at> param Protocol                The type of header to build. If HeaderSize is zero, then this
1371                                       parameter is ignored. See RFC 1700, section "Ether Types,"
1372                                       for examples.
1373 
1374    <at> retval EFI_SUCCESS            The packet was placed on the transmit queue.
1375    <at> retval EFI_NOT_STARTED        The network interface has not been started.
1376    <at> retval EFI_NOT_READY          The network interface is too busy to accept this
1377                                       transmit request.
1378    <at> retval EFI_BUFFER_TOO_SMALL   The BufferSize parameter is too small.
1379    <at> retval EFI_INVALID_PARAMETER  One or more of the parameters has an unsupported
1380                                       value.
1381    <at> retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.
1382    <at> retval EFI_UNSUPPORTED        This function is not supported by the network interface.
1383 
1384 **/
1385 EFI_STATUS
1386 EFIAPI
SnpTransmit(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)1387 SnpTransmit (
1388     IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
1389     IN UINTN                       HeaderSize,
1390     IN UINTN                       BufferSize,
1391     IN VOID                        *Buffer,
1392     IN EFI_MAC_ADDRESS             *SrcAddr,  OPTIONAL
1393     IN EFI_MAC_ADDRESS             *DestAddr, OPTIONAL
1394     IN UINT16                      *Protocol  OPTIONAL
1395     )
1396 {
1397   EFI_STATUS    Status;
1398   YUKON_DRIVER    *YukonDriver;
1399   EFI_TPL       OldTpl;
1400   ETHER_HEAD    *Frame;
1401   UINT16        ProtocolNet;
1402   struct msk_softc  *ScData;
1403 
1404   DEBUG ((EFI_D_NET, "Marvell Yukon: SnpTransmit()\n"));
1405   if (This == NULL) {
1406     return EFI_INVALID_PARAMETER;
1407   }
1408 
1409   YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
1410 
1411   if (YukonDriver == NULL) {
1412     return EFI_DEVICE_ERROR;
1413   }
1414 
1415   Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
1416   if (EFI_ERROR (Status)) {
1417     return Status;
1418   }
1419 
1420   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1421 
1422   switch (YukonDriver->SnpMode.State) {
1423     case EfiSimpleNetworkInitialized:
1424       break;
1425 
1426     case EfiSimpleNetworkStopped:
1427       Status = EFI_NOT_STARTED;
1428       goto ON_EXIT;
1429 
1430     default:
1431       Status = EFI_DEVICE_ERROR;
1432       goto ON_EXIT;
1433   }
1434 
1435   if (Buffer == NULL) {
1436     Status = EFI_INVALID_PARAMETER;
1437     goto ON_EXIT;
1438   }
1439 
1440   if (BufferSize < YukonDriver->SnpMode.MediaHeaderSize) {
1441     Status = EFI_BUFFER_TOO_SMALL;
1442     goto ON_EXIT;
1443   }
1444 
1445   //
1446   // Construct the frame header if not already presented
1447   //
1448   if (HeaderSize != 0) {
1449     if (HeaderSize != YukonDriver->SnpMode.MediaHeaderSize || DestAddr == 0 || Protocol == 0) {
1450       Status = EFI_INVALID_PARAMETER;
1451       goto ON_EXIT;
1452     }
1453     Frame       = (ETHER_HEAD*)Buffer;
1454     ProtocolNet = NTOHS (*Protocol);
1455 
1456     gBS->CopyMem (Frame->SrcMac,     SrcAddr,      NET_ETHER_ADDR_LEN);
1457     gBS->CopyMem (Frame->DstMac,     DestAddr,     NET_ETHER_ADDR_LEN);
1458     gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16));
1459   }
1460 
1461   Status = mskc_transmit (ScData->msk_if[YukonDriver->Port], BufferSize, Buffer);
1462 
1463 ON_EXIT:
1464   gBS->RestoreTPL (OldTpl);
1465 
1466   return Status;
1467 }
1468 
1469