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