]> git.proxmox.com Git - mirror_edk2.git/blob - OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
OptionRomPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / OptionRomPkg / Bus / Usb / UsbNetworking / Ax88772b / SimpleNetwork.c
1 /** @file
2 Provides the Simple Network functions.
3
4 Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "Ax88772.h"
10
11 /**
12 This function updates the filtering on the receiver.
13
14 This support routine calls ::Ax88772MacAddressSet to update
15 the MAC address. This routine then rebuilds the multicast
16 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
17 Finally this routine enables the receiver by calling
18 ::Ax88772RxControl.
19
20 @param [in] pSimpleNetwork Simple network mode pointer
21
22 @retval EFI_SUCCESS This operation was successful.
23 @retval EFI_NOT_STARTED The network interface was not started.
24 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
25 EFI_SIMPLE_NETWORK_PROTOCOL structure.
26 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
27 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
28
29 **/
30 EFI_STATUS
31 ReceiveFilterUpdate (
32 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
33 )
34 {
35 EFI_SIMPLE_NETWORK_MODE * pMode;
36 NIC_DEVICE * pNicDevice;
37 EFI_STATUS Status;
38 UINT32 Index;
39
40 //
41 // Set the MAC address
42 //
43 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
44 pMode = pSimpleNetwork->Mode;
45
46 //
47 // Clear the multicast hash table
48 //
49 Ax88772MulticastClear ( pNicDevice );
50
51 //
52 // Load the multicast hash table
53 //
54 if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
55 for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
56 //
57 // Enable the next multicast address
58 //
59 Ax88772MulticastSet ( pNicDevice,
60 &pMode->MCastFilter[ Index ].Addr[0]);
61 }
62 }
63
64 Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
65
66 return Status;
67 }
68
69
70 /**
71 This function updates the SNP driver status.
72
73 This function gets the current interrupt and recycled transmit
74 buffer status from the network interface. The interrupt status
75 and the media status are returned as a bit mask in InterruptStatus.
76 If InterruptStatus is NULL, the interrupt status will not be read.
77 Upon successful return of the media status, the MediaPresent field
78 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
79 of media status. If TxBuf is not NULL, a recycled transmit buffer
80 address will be retrived. If a recycled transmit buffer address
81 is returned in TxBuf, then the buffer has been successfully
82 transmitted, and the status for that buffer is cleared.
83
84 This function calls ::Ax88772Rx to update the media status and
85 queue any receive packets.
86
87 @param [in] pSimpleNetwork Protocol instance pointer
88 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
89 If this is NULL, the interrupt status will not be read from
90 the device. If this is not NULL, the interrupt status will
91 be read from teh device. When the interrupt status is read,
92 it will also be cleared. Clearing the transmit interrupt
93 does not empty the recycled transmit buffer array.
94 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
95 not transmit if its internal recycled transmit buffer array is
96 full. Reading the transmit buffer does not clear the transmit
97 interrupt. If this is NULL, then the transmit buffer status
98 will not be read. If there are not transmit buffers to recycle
99 and TxBuf is not NULL, *TxBuf will be set to NULL.
100
101 @retval EFI_SUCCESS This operation was successful.
102 @retval EFI_NOT_STARTED The network interface was not started.
103 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
104 EFI_SIMPLE_NETWORK_PROTOCOL structure.
105 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
106
107 **/
108 EFI_STATUS
109 EFIAPI
110 SN_GetStatus (
111 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
112 OUT UINT32 * pInterruptStatus,
113 OUT VOID ** ppTxBuf
114 )
115 {
116 EFI_SIMPLE_NETWORK_MODE * pMode;
117 NIC_DEVICE * pNicDevice;
118 EFI_STATUS Status;
119 BOOLEAN bFullDuplex;
120 BOOLEAN bLinkUp;
121 BOOLEAN bSpeed100;
122 EFI_TPL TplPrevious;
123
124 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
125 //
126 // Verify the parameters
127 //
128 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
129 //
130 // Return the transmit buffer
131 //
132
133 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
134 if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
135 *ppTxBuf = pNicDevice->pTxBuffer;
136 pNicDevice->pTxBuffer = NULL;
137 }
138
139 //
140 // Determine if interface is running
141 //
142 pMode = pSimpleNetwork->Mode;
143 if ( EfiSimpleNetworkInitialized == pMode->State ) {
144
145 if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
146
147 bLinkUp = pNicDevice->bLinkUp;
148 bSpeed100 = pNicDevice->b100Mbps;
149 bFullDuplex = pNicDevice->bFullDuplex;
150 Status = Ax88772NegotiateLinkComplete ( pNicDevice,
151 &pNicDevice->PollCount,
152 &pNicDevice->bComplete,
153 &pNicDevice->bLinkUp,
154 &pNicDevice->b100Mbps,
155 &pNicDevice->bFullDuplex );
156
157 //
158 // Determine if the autonegotiation is complete
159 //
160 if ( pNicDevice->bComplete ) {
161 if ( pNicDevice->bLinkUp ) {
162 if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
163 || (( !bSpeed100 ) && pNicDevice->b100Mbps )
164 || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
165 || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
166 pNicDevice->PollCount = 0;
167 DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
168 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
169 Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
170 }
171 if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
172 //
173 // Display the autonegotiation status
174 //
175 DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
176 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
177
178 }
179 pNicDevice->LinkIdleCnt = 0;
180 }
181 }
182 //
183 // Update the link status
184 //
185 if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
186 DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
187 }
188 }
189
190 pMode->MediaPresent = pNicDevice->bLinkUp;
191 //
192 // Return the interrupt status
193 //
194 if ( NULL != pInterruptStatus ) {
195 *pInterruptStatus = 0;
196 }
197 Status = EFI_SUCCESS;
198 }
199 else {
200 if ( EfiSimpleNetworkStarted == pMode->State ) {
201 Status = EFI_DEVICE_ERROR;
202 }
203 else {
204 Status = EFI_NOT_STARTED;
205 }
206 }
207
208 }
209 else {
210 Status = EFI_INVALID_PARAMETER;
211 }
212 gBS->RestoreTPL(TplPrevious) ;
213
214 return Status;
215 }
216
217
218 /**
219 Resets the network adapter and allocates the transmit and receive buffers
220 required by the network interface; optionally, also requests allocation of
221 additional transmit and receive buffers. This routine must be called before
222 any other routine in the Simple Network protocol is called.
223
224 @param [in] pSimpleNetwork Protocol instance pointer
225 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
226 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
227
228 @retval EFI_SUCCESS This operation was successful.
229 @retval EFI_NOT_STARTED The network interface was not started.
230 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers
231 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
232 EFI_SIMPLE_NETWORK_PROTOCOL structure.
233 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
234 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
235
236 **/
237 EFI_STATUS
238 EFIAPI
239 SN_Initialize (
240 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
241 IN UINTN ExtraRxBufferSize,
242 IN UINTN ExtraTxBufferSize
243 )
244 {
245 EFI_SIMPLE_NETWORK_MODE * pMode;
246 EFI_STATUS Status;
247 UINT32 TmpState;
248 EFI_TPL TplPrevious;
249
250 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
251 //
252 // Verify the parameters
253 //
254 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
255 //
256 // Determine if the interface is already started
257 //
258 pMode = pSimpleNetwork->Mode;
259 if ( EfiSimpleNetworkStarted == pMode->State ) {
260 if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
261 //
262 // Start the adapter
263 //
264 TmpState = pMode->State;
265 pMode->State = EfiSimpleNetworkInitialized;
266 Status = SN_Reset ( pSimpleNetwork, FALSE );
267 if ( EFI_ERROR ( Status )) {
268 //
269 // Update the network state
270 //
271 pMode->State = TmpState;
272 DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
273 }
274 }
275 else {
276 DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n",
277 ExtraRxBufferSize, ExtraTxBufferSize));
278 Status = EFI_UNSUPPORTED;
279 }
280 }
281 else {
282 Status = EFI_NOT_STARTED;
283 }
284 }
285 else {
286 Status = EFI_INVALID_PARAMETER;
287 }
288 gBS->RestoreTPL (TplPrevious);
289
290 return Status;
291 }
292
293
294 /**
295 This function converts a multicast IP address to a multicast HW MAC address
296 for all packet transactions.
297
298 @param [in] pSimpleNetwork Protocol instance pointer
299 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
300 Set to FALSE if the multicast IP address is IPv4 [RFC 791].
301 @param [in] pIP The multicast IP address that is to be converted to a
302 multicast HW MAC address.
303 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
304
305 @retval EFI_SUCCESS This operation was successful.
306 @retval EFI_NOT_STARTED The network interface was not started.
307 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
308 EFI_SIMPLE_NETWORK_PROTOCOL structure.
309 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
310 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
311
312 **/
313 EFI_STATUS
314 EFIAPI
315 SN_MCastIPtoMAC (
316 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
317 IN BOOLEAN bIPv6,
318 IN EFI_IP_ADDRESS * pIP,
319 OUT EFI_MAC_ADDRESS * pMAC
320 )
321 {
322 EFI_STATUS Status;
323 EFI_TPL TplPrevious;
324
325 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
326 //
327 // Get pointer to SNP driver instance for *this.
328 //
329 if (pSimpleNetwork == NULL) {
330 gBS->RestoreTPL(TplPrevious);
331 return EFI_INVALID_PARAMETER;
332 }
333
334 if (pIP == NULL || pMAC == NULL) {
335 gBS->RestoreTPL(TplPrevious);
336 return EFI_INVALID_PARAMETER;
337 }
338
339 if (bIPv6){
340 Status = EFI_UNSUPPORTED;
341 }
342 else {
343 //
344 // check if the ip given is a mcast IP
345 //
346 if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
347 gBS->RestoreTPL(TplPrevious);
348 return EFI_INVALID_PARAMETER;
349 }
350 else {
351 if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)
352 {
353 pMAC->Addr[0] = 0x01;
354 pMAC->Addr[1] = 0x00;
355 pMAC->Addr[2] = 0x5e;
356 pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
357 pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
358 pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
359 Status = EFI_SUCCESS;
360 }
361 else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {
362 Status = EFI_DEVICE_ERROR;
363 }
364 else {
365 Status = EFI_NOT_STARTED;
366 }
367 gBS->RestoreTPL(TplPrevious);
368 }
369 }
370 return Status;
371 }
372
373
374 /**
375 This function performs read and write operations on the NVRAM device
376 attached to a network interface.
377
378 @param [in] pSimpleNetwork Protocol instance pointer
379 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
380 @param [in] Offset Byte offset in the NVRAM device at which to start the
381 read or write operation. This must be a multiple of
382 NvRamAccessSize and less than NvRamSize.
383 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
384 This must also be a multiple of NvramAccessSize.
385 @param [in, out] pBuffer A pointer to the data buffer.
386
387 @retval EFI_SUCCESS This operation was successful.
388 @retval EFI_NOT_STARTED The network interface was not started.
389 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
390 EFI_SIMPLE_NETWORK_PROTOCOL structure.
391 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
392 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
393
394 **/
395 EFI_STATUS
396 EFIAPI
397 SN_NvData (
398 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
399 IN BOOLEAN ReadWrite,
400 IN UINTN Offset,
401 IN UINTN BufferSize,
402 IN OUT VOID * pBuffer
403 )
404 {
405 EFI_STATUS Status;
406 //
407 // This is not currently supported
408 //
409 Status = EFI_UNSUPPORTED;
410 return Status;
411 }
412
413 VOID
414 FillPkt2Queue (
415 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
416 IN UINTN BufLength)
417 {
418
419 UINT16 * pLength;
420 UINT16 * pLengthBar;
421 UINT8* pData;
422 UINT32 offset;
423 NIC_DEVICE * pNicDevice;
424
425 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
426 for ( offset = 0; offset < BufLength; ){
427 pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
428 pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
429
430 *pLength &= 0x7ff;
431 *pLengthBar &= 0x7ff;
432 *pLengthBar |= 0xf800;
433
434 if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
435 DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
436 return;
437 }
438
439 if (TRUE == pNicDevice->pNextFill->f_Used) {
440 return;
441 }
442 else {
443 pData = pNicDevice->pBulkInBuff + offset + 4;
444 pNicDevice->pNextFill->f_Used = TRUE;
445 pNicDevice->pNextFill->Length = *pLength;
446 CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
447
448 pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
449 offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
450 pNicDevice->PktCntInQueue++;
451 }
452
453 }
454 }
455
456 EFI_STATUS
457 EFIAPI
458 SN_Receive (
459 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
460 OUT UINTN * pHeaderSize,
461 OUT UINTN * pBufferSize,
462 OUT VOID * pBuffer,
463 OUT EFI_MAC_ADDRESS * pSrcAddr,
464 OUT EFI_MAC_ADDRESS * pDestAddr,
465 OUT UINT16 * pProtocol
466 )
467 {
468 EFI_SIMPLE_NETWORK_MODE * pMode;
469 NIC_DEVICE * pNicDevice;
470 EFI_STATUS Status;
471 EFI_TPL TplPrevious;
472 UINT16 Type;
473 EFI_USB_IO_PROTOCOL *pUsbIo;
474 UINTN LengthInBytes;
475 UINT32 TransferStatus;
476 RX_PKT * pFirstFill;
477 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
478
479 //
480 // Verify the parameters
481 //
482 if (( NULL != pSimpleNetwork ) &&
483 ( NULL != pSimpleNetwork->Mode ) &&
484 (NULL != pBufferSize) &&
485 (NULL != pBuffer)) {
486 //
487 // The interface must be running
488 //
489 pMode = pSimpleNetwork->Mode;
490 if ( EfiSimpleNetworkInitialized == pMode->State ) {
491 //
492 // Update the link status
493 //
494 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
495 pNicDevice->LinkIdleCnt++;
496 pMode->MediaPresent = pNicDevice->bLinkUp;
497
498 if ( pMode->MediaPresent && pNicDevice->bComplete) {
499
500
501 if (pNicDevice->PktCntInQueue != 0 ) {
502 DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
503 pNicDevice->PktCntInQueue));
504 }
505
506 LengthInBytes = MAX_BULKIN_SIZE;
507 if (pNicDevice->PktCntInQueue == 0 ){
508 //
509 // Attempt to do bulk in
510 //
511 SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
512 pUsbIo = pNicDevice->pUsbIo;
513 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
514 USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
515 &pNicDevice->pBulkInBuff[0],
516 &LengthInBytes,
517 BULKIN_TIMEOUT,
518 &TransferStatus );
519
520 if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){
521 FillPkt2Queue(pSimpleNetwork, LengthInBytes);
522 }
523 }
524
525 pFirstFill = pNicDevice->pFirstFill;
526
527 if (TRUE == pFirstFill->f_Used) {
528 ETHERNET_HEADER * pHeader;
529 pNicDevice->LinkIdleCnt = 0;
530 CopyMem (pBuffer, &pFirstFill->Data[0], pFirstFill->Length);
531 pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
532
533 DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
534 "%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
535 pFirstFill->Data[0],
536 pFirstFill->Data[1],
537 pFirstFill->Data[2],
538 pFirstFill->Data[3],
539 pFirstFill->Data[4],
540 pFirstFill->Data[5],
541 pFirstFill->Data[6],
542 pFirstFill->Data[7],
543 pFirstFill->Data[8],
544 pFirstFill->Data[9],
545 pFirstFill->Data[10],
546 pFirstFill->Data[11],
547 pFirstFill->Data[12],
548 pFirstFill->Data[13],
549 pFirstFill->Length));
550
551 if ( NULL != pHeaderSize ) {
552 *pHeaderSize = sizeof ( *pHeader );
553 }
554 if ( NULL != pDestAddr ) {
555 CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
556 }
557 if ( NULL != pSrcAddr ) {
558 CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
559 }
560 if ( NULL != pProtocol ) {
561 Type = pHeader->type;
562 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
563 *pProtocol = Type;
564 }
565 Status = EFI_SUCCESS;
566 if (*pBufferSize < pFirstFill->Length) {
567 DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
568 Status = EFI_BUFFER_TOO_SMALL;
569 }
570 *pBufferSize = pFirstFill->Length;
571 pFirstFill->f_Used = FALSE;
572 pNicDevice->pFirstFill = pFirstFill->pNext;
573 pNicDevice->PktCntInQueue--;
574 }
575 else {
576 pNicDevice->LinkIdleCnt++;
577 Status = EFI_NOT_READY;
578 }
579 }
580 else {
581 //
582 // Link no up
583 //
584 pNicDevice->LinkIdleCnt++;
585 Status = EFI_NOT_READY;
586 }
587
588 }
589 else {
590 if (EfiSimpleNetworkStarted == pMode->State) {
591 Status = EFI_DEVICE_ERROR;
592 }
593 else {
594 Status = EFI_NOT_STARTED;
595 }
596 }
597 }
598 else {
599 Status = EFI_INVALID_PARAMETER;
600 }
601 gBS->RestoreTPL (TplPrevious);
602 return Status;
603 }
604
605 /**
606 This function is used to enable and disable the hardware and software receive
607 filters for the underlying network device.
608
609 The receive filter change is broken down into three steps:
610
611 1. The filter mask bits that are set (ON) in the Enable parameter
612 are added to the current receive filter settings.
613
614 2. The filter mask bits that are set (ON) in the Disable parameter
615 are subtracted from the updated receive filter settins.
616
617 3. If the resulting filter settigns is not supported by the hardware
618 a more liberal setting is selected.
619
620 If the same bits are set in the Enable and Disable parameters, then the bits
621 in the Disable parameter takes precedence.
622
623 If the ResetMCastFilter parameter is TRUE, then the multicast address list
624 filter is disabled (irregardless of what other multicast bits are set in
625 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
626 is set to zero. The SNP->Mode->MCastFilter contents are undefined.
627
628 After enableing or disabling receive filter settings, software should
629 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
630 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
631
632 Note: Some network drivers and/or devices will automatically promote
633 receive filter settings if the requested setting can not be honored.
634 For example, if a request for four multicast addresses is made and
635 the underlying hardware only supports two multicast addresses the
636 driver might set the promiscuous or promiscuous multicast receive filters
637 instead. The receiving software is responsible for discarding any extra
638 packets that get through the hardware receive filters.
639
640 If ResetMCastFilter is TRUE, then the multicast receive filter list
641 on the network interface will be reset to the default multicast receive
642 filter list. If ResetMCastFilter is FALSE, and this network interface
643 allows the multicast receive filter list to be modified, then the
644 MCastFilterCnt and MCastFilter are used to update the current multicast
645 receive filter list. The modified receive filter list settings can be
646 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
647
648 This routine calls ::ReceiveFilterUpdate to update the receive
649 state in the network adapter.
650
651 @param [in] pSimpleNetwork Protocol instance pointer
652 @param [in] Enable A bit mask of receive filters to enable on the network interface.
653 @param [in] Disable A bit mask of receive filters to disable on the network interface.
654 For backward compatibility with EFI 1.1 platforms, the
655 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
656 when the ResetMCastFilter parameter is TRUE.
657 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
658 filters on the network interface to their default values.
659 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
660 This value must be less than or equal to the MaxMCastFilterCnt
661 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
662 ResetMCastFilter is TRUE.
663 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
664 addresses. This list will replace any existing multicast
665 HW MAC address list. This field is optional if ResetMCastFilter
666 is TRUE.
667
668 @retval EFI_SUCCESS This operation was successful.
669 @retval EFI_NOT_STARTED The network interface was not started.
670 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
671 EFI_SIMPLE_NETWORK_PROTOCOL structure.
672 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
673 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
674
675 **/
676 EFI_STATUS
677 EFIAPI
678 SN_ReceiveFilters (
679 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
680 IN UINT32 Enable,
681 IN UINT32 Disable,
682 /*
683 #define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
684 #define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
685 #define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
686 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
687 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
688 */
689 IN BOOLEAN bResetMCastFilter,
690 IN UINTN MCastFilterCnt,
691 IN EFI_MAC_ADDRESS * pMCastFilter
692 )
693 {
694 EFI_SIMPLE_NETWORK_MODE * pMode;
695 EFI_STATUS Status = EFI_SUCCESS;
696 EFI_TPL TplPrevious;
697
698 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
699 pMode = pSimpleNetwork->Mode;
700
701 if (pSimpleNetwork == NULL) {
702 gBS->RestoreTPL(TplPrevious);
703 return EFI_INVALID_PARAMETER;
704 }
705
706 switch (pMode->State) {
707 case EfiSimpleNetworkInitialized:
708 break;
709 case EfiSimpleNetworkStopped:
710 Status = EFI_NOT_STARTED;
711 gBS->RestoreTPL(TplPrevious);
712 return Status;
713 default:
714 Status = EFI_DEVICE_ERROR;
715 gBS->RestoreTPL(TplPrevious);
716 return Status;
717 }
718
719 //
720 // check if we are asked to enable or disable something that the UNDI
721 // does not even support!
722 //
723 if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
724 ((Disable &~pMode->ReceiveFilterMask) != 0)) {
725 Status = EFI_INVALID_PARAMETER;
726 gBS->RestoreTPL(TplPrevious);
727 return Status;
728 }
729
730 if (bResetMCastFilter) {
731 Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
732 pMode->MCastFilterCount = 0;
733 if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST))
734 && Enable == 0 && Disable == 2) {
735 gBS->RestoreTPL(TplPrevious);
736 return EFI_SUCCESS;
737 }
738 }
739 else {
740 if (MCastFilterCnt != 0) {
741 UINTN i;
742 EFI_MAC_ADDRESS * pMulticastAddress;
743 pMulticastAddress = pMCastFilter;
744
745 if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
746 (pMCastFilter == NULL)) {
747 Status = EFI_INVALID_PARAMETER;
748 gBS->RestoreTPL(TplPrevious);
749 return Status;
750 }
751
752 for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
753 UINT8 tmp;
754 tmp = pMulticastAddress->Addr[0];
755 if ( (tmp & 0x01) != 0x01 ) {
756 gBS->RestoreTPL(TplPrevious);
757 return EFI_INVALID_PARAMETER;
758 }
759 pMulticastAddress++;
760 }
761
762 pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
763 CopyMem (&pMode->MCastFilter[0],
764 pMCastFilter,
765 MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
766 }
767 }
768
769 if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
770 Status = EFI_SUCCESS;
771 gBS->RestoreTPL(TplPrevious);
772 return Status;
773 }
774
775 if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
776 Status = EFI_INVALID_PARAMETER;
777 gBS->RestoreTPL(TplPrevious);
778 return Status;
779 }
780
781 pMode->ReceiveFilterSetting |= Enable;
782 pMode->ReceiveFilterSetting &= ~Disable;
783 Status = ReceiveFilterUpdate (pSimpleNetwork);
784
785 if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
786 Status = EFI_SUCCESS;
787
788 gBS->RestoreTPL(TplPrevious);
789 return Status;
790 }
791
792 /**
793 Reset the network adapter.
794
795 Resets a network adapter and reinitializes it with the parameters that
796 were provided in the previous call to Initialize (). The transmit and
797 receive queues are cleared. Receive filters, the station address, the
798 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
799 this call.
800
801 This routine calls ::Ax88772Reset to perform the adapter specific
802 reset operation. This routine also starts the link negotiation
803 by calling ::Ax88772NegotiateLinkStart.
804
805 @param [in] pSimpleNetwork Protocol instance pointer
806 @param [in] bExtendedVerification Indicates that the driver may perform a more
807 exhaustive verification operation of the device
808 during reset.
809
810 @retval EFI_SUCCESS This operation was successful.
811 @retval EFI_NOT_STARTED The network interface was not started.
812 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
813 EFI_SIMPLE_NETWORK_PROTOCOL structure.
814 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
815 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
816
817 **/
818 EFI_STATUS
819 EFIAPI
820 SN_Reset (
821 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
822 IN BOOLEAN bExtendedVerification
823 )
824 {
825 EFI_SIMPLE_NETWORK_MODE * pMode;
826 NIC_DEVICE * pNicDevice;
827 EFI_STATUS Status;
828 EFI_TPL TplPrevious;
829
830 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
831 //
832 // Verify the parameters
833 //
834 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
835 pMode = pSimpleNetwork->Mode;
836 if ( EfiSimpleNetworkInitialized == pMode->State ) {
837 //
838 // Update the device state
839 //
840 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
841 pNicDevice->bComplete = FALSE;
842 pNicDevice->bLinkUp = FALSE;
843 pNicDevice->bHavePkt = FALSE;
844 pMode = pSimpleNetwork->Mode;
845 pMode->MediaPresent = FALSE;
846
847 //
848 // Reset the device
849 //
850 Status = Ax88772Reset ( pNicDevice );
851 if ( !EFI_ERROR ( Status )) {
852 //
853 // Update the receive filters in the adapter
854 //
855 Status = ReceiveFilterUpdate ( pSimpleNetwork );
856
857 //
858 // Try to get a connection to the network
859 //
860 if ( !EFI_ERROR ( Status )) {
861 //
862 // Start the autonegotiation
863 //
864 Status = Ax88772NegotiateLinkStart ( pNicDevice );
865 }
866 }
867 }
868 else {
869 if (EfiSimpleNetworkStarted == pMode->State) {
870 Status = EFI_DEVICE_ERROR;
871 }
872 else {
873 Status = EFI_NOT_STARTED;
874 }
875 }
876 }
877 else {
878 Status = EFI_INVALID_PARAMETER;
879 }
880 gBS->RestoreTPL ( TplPrevious );
881 return Status;
882 }
883
884 /**
885 Initialize the simple network protocol.
886
887 This routine calls ::Ax88772MacAddressGet to obtain the
888 MAC address.
889
890 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
891
892 @retval EFI_SUCCESS Setup was successful
893
894 **/
895 EFI_STATUS
896 SN_Setup (
897 IN NIC_DEVICE * pNicDevice
898 )
899 {
900
901
902 EFI_SIMPLE_NETWORK_MODE * pMode;
903 EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
904 EFI_STATUS Status;
905 RX_PKT * pCurr = NULL;
906 RX_PKT * pPrev = NULL;
907
908 pSimpleNetwork = &pNicDevice->SimpleNetwork;
909 pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
910 pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
911 pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
912 pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
913 pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
914 pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
915 pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
916 pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
917 pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
918 pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
919 pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
920 pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
921 pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
922 pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
923 pSimpleNetwork->WaitForPacket = NULL;
924 pMode = &pNicDevice->SimpleNetworkData;
925 pSimpleNetwork->Mode = pMode;
926 pMode->State = EfiSimpleNetworkStopped;
927 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
928 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
929 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
930 pMode->NvRamSize = 0;
931 pMode->NvRamAccessSize = 0;
932 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
933 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
934 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
935 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
936 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
937 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
938 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
939 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
940 pMode->MCastFilterCount = 0;
941 SetMem ( &pMode->BroadcastAddress,
942 PXE_HWADDR_LEN_ETHER,
943 0xff );
944 pMode->IfType = EfiNetworkInterfaceUndi;
945 pMode->MacAddressChangeable = TRUE;
946 pMode->MultipleTxSupported = FALSE;
947 pMode->MediaPresentSupported = TRUE;
948 pMode->MediaPresent = FALSE;
949 pNicDevice->LinkIdleCnt = 0;
950 //
951 // Read the MAC address
952 //
953 pNicDevice->PhyId = PHY_ID_INTERNAL;
954 pNicDevice->b100Mbps = TRUE;
955 pNicDevice->bFullDuplex = TRUE;
956
957 Status = Ax88772MacAddressGet (
958 pNicDevice,
959 &pMode->PermanentAddress.Addr[0]);
960
961 if ( !EFI_ERROR ( Status )) {
962 int i;
963 //
964 // Use the hardware address as the current address
965 //
966
967 CopyMem ( &pMode->CurrentAddress,
968 &pMode->PermanentAddress,
969 PXE_HWADDR_LEN_ETHER );
970
971 CopyMem ( &pNicDevice->MAC,
972 &pMode->PermanentAddress,
973 PXE_HWADDR_LEN_ETHER );
974
975 pNicDevice->PktCntInQueue = 0;
976
977 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
978 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
979 sizeof (RX_PKT),
980 (VOID **) &pCurr);
981 if ( EFI_ERROR(Status)) {
982 DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
983 return Status;
984 }
985 pCurr->f_Used = FALSE;
986
987 if ( i ) {
988 pPrev->pNext = pCurr;
989 }
990 else {
991 pNicDevice->QueueHead = pCurr;
992 }
993
994 if (MAX_QUEUE_SIZE - 1 == i) {
995 pCurr->pNext = pNicDevice->QueueHead;
996 }
997
998 pPrev = pCurr;
999 }
1000
1001 pNicDevice->pNextFill = pNicDevice->QueueHead;
1002 pNicDevice->pFirstFill = pNicDevice->QueueHead;
1003
1004 Status = gBS->AllocatePool (EfiRuntimeServicesData,
1005 MAX_BULKIN_SIZE,
1006 (VOID **) &pNicDevice->pBulkInBuff);
1007
1008 if (EFI_ERROR(Status)) {
1009 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
1010 Status));
1011 return Status;
1012 }
1013 }
1014 else {
1015 DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
1016 return Status;
1017 }
1018
1019 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1020 sizeof ( RX_TX_PACKET ),
1021 (VOID **) &pNicDevice->pRxTest );
1022
1023 if (EFI_ERROR (Status)) {
1024 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
1025 Status));
1026 return Status;
1027 }
1028
1029 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1030 sizeof ( RX_TX_PACKET ),
1031 (VOID **) &pNicDevice->pTxTest );
1032
1033 if (EFI_ERROR (Status)) {
1034 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
1035 Status));
1036 gBS->FreePool (pNicDevice->pRxTest);
1037 }
1038
1039 return Status;
1040 }
1041
1042
1043 /**
1044 This routine starts the network interface.
1045
1046 @param [in] pSimpleNetwork Protocol instance pointer
1047
1048 @retval EFI_SUCCESS This operation was successful.
1049 @retval EFI_ALREADY_STARTED The network interface was already started.
1050 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1051 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1052 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1053 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1054
1055 **/
1056 EFI_STATUS
1057 EFIAPI
1058 SN_Start (
1059 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1060 )
1061 {
1062 NIC_DEVICE * pNicDevice;
1063 EFI_SIMPLE_NETWORK_MODE * pMode;
1064 EFI_STATUS Status;
1065 EFI_TPL TplPrevious;
1066 int i = 0;
1067 RX_PKT * pCurr = NULL;
1068
1069 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1070 //
1071 // Verify the parameters
1072 //
1073 Status = EFI_INVALID_PARAMETER;
1074 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1075 pMode = pSimpleNetwork->Mode;
1076 if ( EfiSimpleNetworkStopped == pMode->State ) {
1077 //
1078 // Initialize the mode structuref
1079 // NVRAM access is not supported
1080 //
1081 ZeroMem ( pMode, sizeof ( *pMode ));
1082
1083 pMode->State = EfiSimpleNetworkStarted;
1084 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
1085 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
1086 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
1087 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
1088 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
1089 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
1090 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
1091 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
1092 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
1093 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
1094 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1095 Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
1096 CopyMem ( &pMode->CurrentAddress,
1097 &pMode->PermanentAddress,
1098 sizeof ( pMode->CurrentAddress ));
1099 SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
1100 pMode->IfType = EfiNetworkInterfaceUndi;
1101 pMode->MacAddressChangeable = TRUE;
1102 pMode->MultipleTxSupported = FALSE;
1103 pMode->MediaPresentSupported = TRUE;
1104 pMode->MediaPresent = FALSE;
1105 pNicDevice->PktCntInQueue = 0;
1106 pNicDevice->pNextFill = pNicDevice->QueueHead;
1107 pNicDevice->pFirstFill = pNicDevice->QueueHead;
1108 pCurr = pNicDevice->QueueHead;
1109
1110 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
1111 pCurr->f_Used = FALSE;
1112 pCurr = pCurr->pNext;
1113 }
1114
1115 }
1116 else {
1117 Status = EFI_ALREADY_STARTED;
1118 }
1119 }
1120 gBS->RestoreTPL ( TplPrevious );
1121 return Status;
1122 }
1123
1124
1125 /**
1126 Set the MAC address.
1127
1128 This function modifies or resets the current station address of a
1129 network interface. If Reset is TRUE, then the current station address
1130 is set ot the network interface's permanent address. If Reset if FALSE
1131 then the current station address is changed to the address specified by
1132 pNew.
1133
1134 This routine calls ::Ax88772MacAddressSet to update the MAC address
1135 in the network adapter.
1136
1137 @param [in] pSimpleNetwork Protocol instance pointer
1138 @param [in] bReset Flag used to reset the station address to the
1139 network interface's permanent address.
1140 @param [in] pNew New station address to be used for the network
1141 interface.
1142
1143 @retval EFI_SUCCESS This operation was successful.
1144 @retval EFI_NOT_STARTED The network interface was not started.
1145 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1146 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1147 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1148 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1149
1150 **/
1151 EFI_STATUS
1152 EFIAPI
1153 SN_StationAddress (
1154 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1155 IN BOOLEAN bReset,
1156 IN EFI_MAC_ADDRESS * pNew
1157 )
1158 {
1159 NIC_DEVICE * pNicDevice;
1160 EFI_SIMPLE_NETWORK_MODE * pMode;
1161 EFI_STATUS Status;
1162 EFI_TPL TplPrevious;
1163
1164 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1165 //
1166 // Verify the parameters
1167 //
1168 if (( NULL != pSimpleNetwork )
1169 && ( NULL != pSimpleNetwork->Mode )
1170 && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
1171 //
1172 // Verify that the adapter is already started
1173 //
1174 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1175 pMode = pSimpleNetwork->Mode;
1176 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1177 //
1178 // Determine the adapter MAC address
1179 //
1180 if ( bReset ) {
1181 //
1182 // Use the permanent address
1183 //
1184 CopyMem ( &pMode->CurrentAddress,
1185 &pMode->PermanentAddress,
1186 sizeof ( pMode->CurrentAddress ));
1187 }
1188 else {
1189 //
1190 // Use the specified address
1191 //
1192 CopyMem ( &pMode->CurrentAddress,
1193 pNew,
1194 sizeof ( pMode->CurrentAddress ));
1195 }
1196
1197 //
1198 // Update the address on the adapter
1199 //
1200 Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
1201 }
1202 else {
1203 if (EfiSimpleNetworkStarted == pMode->State) {
1204 Status = EFI_DEVICE_ERROR;
1205 }
1206 else {
1207 Status = EFI_NOT_STARTED;
1208 }
1209 }
1210 }
1211 else {
1212 Status = EFI_INVALID_PARAMETER;
1213 }
1214 gBS->RestoreTPL ( TplPrevious );
1215 return Status;
1216 }
1217
1218
1219 /**
1220 This function resets or collects the statistics on a network interface.
1221 If the size of the statistics table specified by StatisticsSize is not
1222 big enough for all of the statistics that are collected by the network
1223 interface, then a partial buffer of statistics is returned in
1224 StatisticsTable.
1225
1226 @param [in] pSimpleNetwork Protocol instance pointer
1227 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1228 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1229 the size, in bytes, of the resulting table of statistics.
1230 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1231 conains the statistics.
1232
1233 @retval EFI_SUCCESS This operation was successful.
1234 @retval EFI_NOT_STARTED The network interface was not started.
1235 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1236 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1237 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1238 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1239 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1240
1241 typedef struct {
1242 UINT64 RxTotalFrames;
1243 UINT64 RxGoodFrames;
1244 UINT64 RxUndersizeFrames;
1245 UINT64 RxOversizeFrames;
1246 UINT64 RxDroppedFrames;
1247 UINT64 RxUnicastFrames;
1248 UINT64 RxBroadcastFrames;
1249 UINT64 RxMulticastFrames;
1250 UINT64 RxCrcErrorFrames;
1251 UINT64 RxTotalBytes;
1252 UINT64 TxTotalFrames;
1253 UINT64 TxGoodFrames;
1254 UINT64 TxUndersizeFrames;
1255 UINT64 TxOversizeFrames;
1256 UINT64 TxDroppedFrames;
1257 UINT64 TxUnicastFrames;
1258 UINT64 TxBroadcastFrames;
1259 UINT64 TxMulticastFrames;
1260 UINT64 TxCrcErrorFrames;
1261 UINT64 TxTotalBytes;
1262 UINT64 Collisions;
1263 UINT64 UnsupportedProtocol;
1264 } EFI_NETWORK_STATISTICS;
1265 **/
1266 EFI_STATUS
1267 EFIAPI
1268 SN_Statistics (
1269 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1270 IN BOOLEAN bReset,
1271 IN OUT UINTN * pStatisticsSize,
1272 OUT EFI_NETWORK_STATISTICS * pStatisticsTable
1273 )
1274 {
1275 EFI_STATUS Status;
1276 EFI_SIMPLE_NETWORK_MODE * pMode;
1277 //
1278 // Verify the prarameters
1279 //
1280 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1281 pMode = pSimpleNetwork->Mode;
1282 //
1283 // Determine if the interface is started
1284 //
1285 if (EfiSimpleNetworkInitialized == pMode->State){
1286 //
1287 // Determine if the StatisticsSize is big enough
1288 //
1289 if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
1290 if (bReset) {
1291 Status = EFI_SUCCESS;
1292 }
1293 else {
1294 Status = EFI_UNSUPPORTED;
1295 }
1296 }
1297 else {
1298 Status = EFI_BUFFER_TOO_SMALL;
1299 }
1300 }
1301 else{
1302 if (EfiSimpleNetworkStarted == pMode->State) {
1303 Status = EFI_DEVICE_ERROR;
1304 }
1305 else {
1306 Status = EFI_NOT_STARTED;
1307 }
1308 }
1309 }
1310 else {
1311 Status = EFI_INVALID_PARAMETER;
1312 }
1313
1314 return Status;
1315 }
1316
1317
1318 /**
1319 This function stops a network interface. This call is only valid
1320 if the network interface is in the started state.
1321
1322 @param [in] pSimpleNetwork Protocol instance pointer
1323
1324 @retval EFI_SUCCESS This operation was successful.
1325 @retval EFI_NOT_STARTED The network interface was not started.
1326 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1327 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1328 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1329 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1330
1331 **/
1332 EFI_STATUS
1333 EFIAPI
1334 SN_Stop (
1335 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1336 )
1337 {
1338 EFI_SIMPLE_NETWORK_MODE * pMode;
1339 EFI_STATUS Status;
1340 EFI_TPL TplPrevious;
1341
1342 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1343 //
1344 // Verify the parameters
1345 //
1346 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1347 //
1348 // Determine if the interface is started
1349 //
1350 pMode = pSimpleNetwork->Mode;
1351 if ( EfiSimpleNetworkStarted == pMode->State ) {
1352 pMode->State = EfiSimpleNetworkStopped;
1353 Status = EFI_SUCCESS;
1354 }
1355 else {
1356 Status = EFI_NOT_STARTED;
1357 }
1358 }
1359 else {
1360 Status = EFI_INVALID_PARAMETER;
1361 }
1362
1363 gBS->RestoreTPL ( TplPrevious );
1364 return Status;
1365 }
1366
1367
1368 /**
1369 This function releases the memory buffers assigned in the Initialize() call.
1370 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1371 After this call, only Initialize() and Stop() calls may be used.
1372
1373 @param [in] pSimpleNetwork Protocol instance pointer
1374
1375 @retval EFI_SUCCESS This operation was successful.
1376 @retval EFI_NOT_STARTED The network interface was not started.
1377 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1378 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1379 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1380 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1381
1382 **/
1383 EFI_STATUS
1384 EFIAPI
1385 SN_Shutdown (
1386 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1387 )
1388 {
1389 EFI_SIMPLE_NETWORK_MODE * pMode;
1390 UINT32 RxFilter;
1391 EFI_STATUS Status;
1392 EFI_TPL TplPrevious;
1393
1394 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1395 //
1396 // Verify the parameters
1397 //
1398 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1399 //
1400 // Determine if the interface is already started
1401 //
1402 pMode = pSimpleNetwork->Mode;
1403 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1404 //
1405 // Stop the adapter
1406 //
1407 RxFilter = pMode->ReceiveFilterSetting;
1408 pMode->ReceiveFilterSetting = 0;
1409 Status = SN_Reset ( pSimpleNetwork, FALSE );
1410 pMode->ReceiveFilterSetting = RxFilter;
1411 if ( !EFI_ERROR ( Status )) {
1412
1413 //
1414 // Update the network state
1415 //
1416 pMode->State = EfiSimpleNetworkStarted;
1417 }
1418 else if ( EFI_DEVICE_ERROR == Status ) {
1419 pMode->State = EfiSimpleNetworkStopped;
1420 }
1421 }
1422 else {
1423 Status = EFI_NOT_STARTED;
1424 }
1425 }
1426 else {
1427 Status = EFI_INVALID_PARAMETER;
1428 }
1429 gBS->RestoreTPL ( TplPrevious );
1430 return Status;
1431 }
1432
1433
1434 /**
1435 Send a packet over the network.
1436
1437 This function places the packet specified by Header and Buffer on
1438 the transmit queue. This function performs a non-blocking transmit
1439 operation. When the transmit is complete, the buffer is returned
1440 via the GetStatus() call.
1441
1442 This routine calls ::Ax88772Rx to empty the network adapter of
1443 receive packets. The routine then passes the transmit packet
1444 to the network adapter.
1445
1446 @param [in] pSimpleNetwork Protocol instance pointer
1447 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1448 the Transmit() function. If HeaderSize is non-zero, then
1449 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1450 and DestAddr and Protocol parameters must not be NULL.
1451 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1452 data) to be transmitted through the network interface.
1453 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1454 to be transmitted. This parameter can not be NULL. If
1455 HeaderSize is zero, then the media header is Buffer must
1456 already be filled in by the caller. If HeaderSize is nonzero,
1457 then the media header will be filled in by the Transmit()
1458 function.
1459 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1460 this parameter is ignored. If HeaderSize is nonzero and
1461 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1462 is used for the source HW MAC address.
1463 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1464 this parameter is ignored.
1465 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1466 this parameter is ignored.
1467
1468 @retval EFI_SUCCESS This operation was successful.
1469 @retval EFI_NOT_STARTED The network interface was not started.
1470 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1471 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1472 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1473 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1474 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1475
1476 **/
1477 EFI_STATUS
1478 EFIAPI
1479 SN_Transmit (
1480 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1481 IN UINTN HeaderSize,
1482 IN UINTN BufferSize,
1483 IN VOID * pBuffer,
1484 IN EFI_MAC_ADDRESS * pSrcAddr,
1485 IN EFI_MAC_ADDRESS * pDestAddr,
1486 IN UINT16 * pProtocol
1487 )
1488 {
1489 ETHERNET_HEADER * pHeader;
1490 EFI_SIMPLE_NETWORK_MODE * pMode;
1491 NIC_DEVICE * pNicDevice;
1492 EFI_USB_IO_PROTOCOL * pUsbIo;
1493 EFI_STATUS Status;
1494 UINTN TransferLength;
1495 UINT32 TransferStatus;
1496 UINT16 Type;
1497 EFI_TPL TplPrevious;
1498
1499 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1500
1501 // Verify the parameters
1502 //
1503 if (( NULL != pSimpleNetwork ) &&
1504 ( NULL != pSimpleNetwork->Mode ) &&
1505 ( NULL != pBuffer) &&
1506 ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
1507 //
1508 // The interface must be running
1509 //
1510 pMode = pSimpleNetwork->Mode;
1511 //
1512 // Verify parameter of HeaderSize
1513 //
1514 if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
1515 //
1516 // Determine if BufferSize is big enough
1517 //
1518 if (BufferSize >= pMode->MediaHeaderSize){
1519 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1520 //
1521 // Update the link status
1522 //
1523 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1524 pMode->MediaPresent = pNicDevice->bLinkUp;
1525
1526 //
1527 // Release the synchronization with Ax88772Timer
1528 //
1529 if ( pMode->MediaPresent && pNicDevice->bComplete) {
1530 //
1531 // Copy the packet into the USB buffer
1532 //
1533
1534 CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize );
1535 pNicDevice->pTxTest->Length = (UINT16) BufferSize;
1536
1537 //
1538 // Transmit the packet
1539 //
1540 pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
1541 if ( 0 != HeaderSize ) {
1542 if ( NULL != pDestAddr ) {
1543 CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
1544 }
1545 if ( NULL != pSrcAddr ) {
1546 CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
1547 }
1548 else {
1549 CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
1550 }
1551 if ( NULL != pProtocol ) {
1552 Type = *pProtocol;
1553 }
1554 else {
1555 Type = pNicDevice->pTxTest->Length;
1556 }
1557 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
1558 pHeader->type = Type;
1559 }
1560 if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
1561 pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
1562 ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
1563 pNicDevice->pTxTest->Length - BufferSize );
1564 }
1565
1566 DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"
1567 " %02x-%02x %d bytes\r\n",
1568 pNicDevice->pTxTest->Data[0],
1569 pNicDevice->pTxTest->Data[1],
1570 pNicDevice->pTxTest->Data[2],
1571 pNicDevice->pTxTest->Data[3],
1572 pNicDevice->pTxTest->Data[4],
1573 pNicDevice->pTxTest->Data[5],
1574 pNicDevice->pTxTest->Data[6],
1575 pNicDevice->pTxTest->Data[7],
1576 pNicDevice->pTxTest->Data[8],
1577 pNicDevice->pTxTest->Data[9],
1578 pNicDevice->pTxTest->Data[10],
1579 pNicDevice->pTxTest->Data[11],
1580 pNicDevice->pTxTest->Data[12],
1581 pNicDevice->pTxTest->Data[13],
1582 pNicDevice->pTxTest->Length ));
1583
1584 pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
1585 TransferLength = sizeof ( pNicDevice->pTxTest->Length )
1586 + sizeof ( pNicDevice->pTxTest->LengthBar )
1587 + pNicDevice->pTxTest->Length;
1588
1589 if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
1590 TransferLength +=4;
1591
1592 //
1593 // Work around USB bus driver bug where a timeout set by receive
1594 // succeeds but the timeout expires immediately after, causing the
1595 // transmit operation to timeout.
1596 //
1597 pUsbIo = pNicDevice->pUsbIo;
1598 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
1599 BULK_OUT_ENDPOINT,
1600 &pNicDevice->pTxTest->Length,
1601 &TransferLength,
1602 0xfffffffe,
1603 &TransferStatus );
1604 if ( !EFI_ERROR ( Status )) {
1605 Status = TransferStatus;
1606 }
1607
1608 if ( !EFI_ERROR ( Status )) {
1609 pNicDevice->pTxBuffer = pBuffer;
1610 }
1611 else {
1612 if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
1613 (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
1614 DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
1615 }
1616 //
1617 // Reset the controller to fix the error
1618 //
1619 if ( EFI_DEVICE_ERROR == Status ) {
1620 SN_Reset ( pSimpleNetwork, FALSE );
1621 }
1622 Status = EFI_NOT_READY;
1623 }
1624 }
1625 else {
1626 //
1627 // No packets available.
1628 //
1629 Status = EFI_NOT_READY;
1630 }
1631
1632 }
1633 else {
1634 if (EfiSimpleNetworkStarted == pMode->State) {
1635 Status = EFI_DEVICE_ERROR;
1636 }
1637 else {
1638 Status = EFI_NOT_STARTED ;
1639 }
1640 }
1641 }
1642 else {
1643 Status = EFI_BUFFER_TOO_SMALL;
1644 }
1645 }
1646 else {
1647 Status = EFI_INVALID_PARAMETER;
1648 }
1649 }
1650 else {
1651 Status = EFI_INVALID_PARAMETER;
1652 }
1653
1654 gBS->RestoreTPL (TplPrevious);
1655
1656 return Status;
1657 }