2 * SMSC LAN91x series Network Controller Driver.
4 * Copyright (c) 2013-2017 Linaro.org
6 * Derived from the LAN9118 driver. Original sources
7 * Copyright (c) 2012-2013, ARM Limited. All rights reserved.
9 * This program and the accompanying materials are licensed and
10 * made available under the terms and conditions of the BSD License
11 * which accompanies this distribution. The full text of the license
12 * may be found at: http://opensource.org/licenses/bsd-license.php
14 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include <Uefi/UefiSpec.h>
23 // Protocols used by this driver
24 #include <Protocol/SimpleNetwork.h>
25 #include <Protocol/ComponentName2.h>
26 #include <Protocol/PxeBaseCode.h>
27 #include <Protocol/DevicePath.h>
29 // Libraries used by this driver
30 #include <Library/UefiLib.h>
31 #include <Library/DebugLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/MemoryAllocationLib.h>
34 #include <Library/IoLib.h>
35 #include <Library/PcdLib.h>
36 #include <Library/NetLib.h>
37 #include <Library/DevicePathLib.h>
39 // Hardware register definitions
40 #include "Lan91xDxeHw.h"
42 // Debugging output options
43 //#define LAN91X_PRINT_REGISTERS 1
44 //#define LAN91X_PRINT_PACKET_HEADERS 1
45 //#define LAN91X_PRINT_RECEIVE_FILTERS 1
47 // Chip power-down option -- UNTESTED
48 //#define LAN91X_POWER_DOWN 1
50 /*---------------------------------------------------------------------------------------------------------------------
52 LAN91x Information Structure
54 ---------------------------------------------------------------------------------------------------------------------*/
55 typedef struct _LAN91X_DRIVER
{
58 EFI_HANDLE ControllerHandle
;
60 // EFI SNP protocol instances
61 EFI_SIMPLE_NETWORK_PROTOCOL Snp
;
62 EFI_SIMPLE_NETWORK_MODE SnpMode
;
64 // EFI Snp statistics instance
65 EFI_NETWORK_STATISTICS Stats
;
67 // Transmit Buffer recycle queue
69 LIST_ENTRY TransmitQueueHead
;
71 // Register access variables
72 UINTN IoBase
; // I/O Base Address
73 UINT8 Revision
; // Chip Revision Number
74 INT8 PhyAd
; // Phy Address
75 UINT8 BankSel
; // Currently selected register bank
79 #define LAN91X_NO_PHY (-1) // PhyAd value if PHY not detected
81 #define LAN91X_SIGNATURE SIGNATURE_32('S', 'M', '9', '1')
82 #define INSTANCE_FROM_SNP_THIS(a) CR(a, LAN91X_DRIVER, Snp, LAN91X_SIGNATURE)
84 #define LAN91X_STALL 2
85 #define LAN91X_MEMORY_ALLOC_POLLS 100 // Max times to poll for memory allocation
86 #define LAN91X_PKT_OVERHEAD 6 // Overhead bytes in packet buffer
88 // Synchronization TPLs
89 #define LAN91X_TPL TPL_CALLBACK
91 // Most common CRC32 Polynomial for little endian machines
92 #define CRC_POLYNOMIAL 0xEDB88320
96 MAC_ADDR_DEVICE_PATH Lan91x
;
97 EFI_DEVICE_PATH_PROTOCOL End
;
100 LAN91X_DEVICE_PATH Lan91xPathTemplate
= {
103 MESSAGING_DEVICE_PATH
, MSG_MAC_ADDR_DP
,
104 { (UINT8
) (sizeof(MAC_ADDR_DEVICE_PATH
)), (UINT8
) ((sizeof(MAC_ADDR_DEVICE_PATH
)) >> 8) }
110 END_DEVICE_PATH_TYPE
,
111 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
112 { sizeof(EFI_DEVICE_PATH_PROTOCOL
), 0 }
116 // Chip ID numbers and name strings
122 #define CHIP_91100FD 8
123 #define CHIP_91111FD 9
125 STATIC CHAR16 CONST
* CONST ChipIds
[ 16 ] = {
127 /* 3 */ L
"SMC91C90/91C92",
131 /* 7 */ L
"SMC91C100",
132 /* 8 */ L
"SMC91C100FD",
133 /* 9 */ L
"SMC91C11xFD",
138 /* ------------------ TxBuffer Queue structures ------------------- */
148 MSK_SYSTEM_BUF SystemBuf
;
149 } MSK_LINKED_SYSTEM_BUF
;
151 #define TX_MBUF_SIGNATURE SIGNATURE_32 ('t','x','m','b')
153 /* ------------------ MAC Address Hash Calculations ------------------- */
156 ** Generate a hash value from a multicast address
158 ** This uses the Ethernet standard CRC32 algorithm
161 ** 1: http://en.wikipedia.org/wiki/Cyclic_redundancy_check
163 ** 2: http://www.erg.abdn.ac.uk/~gorry/eg3567/dl-pages/crc.html
165 ** 3: http://en.wikipedia.org/wiki/Computation_of_CRC
170 IN EFI_MAC_ADDRESS
*Mac
,
179 // 0xFFFFFFFF is standard seed for Ethernet
180 Remainder
= 0xFFFFFFFF;
182 // Generate the remainder byte-by-byte (LSB first)
183 Addr
= &Mac
->Addr
[0];
184 while (AddrLen
-- > 0) {
185 Remainder
^= *Addr
++;
186 for (Iter
= 0; Iter
< 8; ++Iter
) {
187 // Check if exponent is set
188 if ((Remainder
& 1) != 0) {
189 Remainder
= (Remainder
>> 1) ^ CRC_POLYNOMIAL
;
191 Remainder
= (Remainder
>> 1) ^ 0;
196 // Reverse the bits of the remainder
198 for (Iter
= 0; Iter
< 32; ++Iter
) {
200 Crc32
|= Remainder
& 1;
207 /* ---------------- Banked Register Operations ------------------ */
209 // Select the proper I/O bank
213 LAN91X_DRIVER
*LanDriver
,
219 Bank
= RegisterToBank (Register
);
221 // Select the proper I/O bank
222 if (LanDriver
->BankSel
!= Bank
) {
223 MmioWrite16 (LanDriver
->IoBase
+ LAN91X_BANK_OFFSET
, Bank
);
224 LanDriver
->BankSel
= Bank
;
228 // Read a 16-bit I/O-space register
232 LAN91X_DRIVER
*LanDriver
,
238 // Select the proper I/O bank
239 SelectIoBank (LanDriver
, Register
);
241 // Read the requested register
242 Offset
= RegisterToOffset (Register
);
243 return MmioRead16 (LanDriver
->IoBase
+ Offset
);
246 // Write a 16-bit I/O-space register
250 LAN91X_DRIVER
*LanDriver
,
257 // Select the proper I/O bank
258 SelectIoBank (LanDriver
, Register
);
260 // Write the requested register
261 Offset
= RegisterToOffset (Register
);
262 return MmioWrite16 (LanDriver
->IoBase
+ Offset
, Value
);
265 // Read an 8-bit I/O-space register
269 LAN91X_DRIVER
*LanDriver
,
275 // Select the proper I/O bank
276 SelectIoBank (LanDriver
, Register
);
278 // Read the requested register
279 Offset
= RegisterToOffset (Register
);
280 return MmioRead8 (LanDriver
->IoBase
+ Offset
);
283 // Write an 8-bit I/O-space register
287 LAN91X_DRIVER
*LanDriver
,
294 // Select the proper I/O bank
295 SelectIoBank (LanDriver
, Register
);
297 // Write the requested register
298 Offset
= RegisterToOffset (Register
);
299 return MmioWrite8 (LanDriver
->IoBase
+ Offset
, Value
);
303 /* ---------------- MII/PHY Access Operations ------------------ */
305 #define LAN91X_MDIO_STALL 1
310 LAN91X_DRIVER
*LanDriver
,
318 MgmtReg
= ReadIoReg16 (LanDriver
, LAN91X_MGMT
);
319 MgmtReg
&= ~MGMT_MCLK
;
320 MgmtReg
|= MGMT_MDOE
;
322 for (Mask
= (1 << (Bits
- 1)); Mask
!= 0; Mask
>>= 1) {
323 if ((Value
& Mask
) != 0) {
326 MgmtReg
&= ~MGMT_MDO
;
329 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
);
330 gBS
->Stall (LAN91X_MDIO_STALL
);
331 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
| MGMT_MCLK
);
332 gBS
->Stall (LAN91X_MDIO_STALL
);
335 #define PHY_OUTPUT_TIME (2 * LAN91X_MDIO_STALL)
340 LAN91X_DRIVER
*LanDriver
,
348 MgmtReg
= ReadIoReg16 (LanDriver
, LAN91X_MGMT
);
349 MgmtReg
&= ~(MGMT_MDOE
| MGMT_MCLK
| MGMT_MDO
);
350 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
);
353 for (Mask
= (1 << (Bits
- 1)); Mask
!= 0; Mask
>>= 1) {
354 if ((ReadIoReg16 (LanDriver
, LAN91X_MGMT
) & MGMT_MDI
) != 0) {
358 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
);
359 gBS
->Stall (LAN91X_MDIO_STALL
);
360 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
| MGMT_MCLK
);
361 gBS
->Stall (LAN91X_MDIO_STALL
);
366 #define PHY_INPUT_TIME (2 * LAN91X_MDIO_STALL)
371 LAN91X_DRIVER
*LanDriver
376 MgmtReg
= ReadIoReg16 (LanDriver
, LAN91X_MGMT
);
377 MgmtReg
&= ~(MGMT_MDOE
| MGMT_MCLK
| MGMT_MDO
);
378 WriteIoReg16 (LanDriver
, LAN91X_MGMT
, MgmtReg
);
381 // Write to a PHY register
385 LAN91X_DRIVER
*LanDriver
,
390 // Bit-bang the MII Serial Frame write operation
391 MdioOutput (LanDriver
, 32, 0xffffffff); // Send 32 Ones as a preamble
392 MdioOutput (LanDriver
, 2, 0x01); // Send Start (01)
393 MdioOutput (LanDriver
, 2, 0x01); // Send Write (01)
394 MdioOutput (LanDriver
, 5, LanDriver
->PhyAd
); // Send PHYAD[4:0]
395 MdioOutput (LanDriver
, 5, RegAd
); // Send REGAD[4:0]
396 MdioOutput (LanDriver
, 2, 0x02); // Send TurnAround (10)
397 MdioOutput (LanDriver
, 16, Value
); // Write 16 data bits
400 MdioIdle (LanDriver
);
402 // Calculate approximate time to write a PHY register in microseconds
403 #define PHY_WRITE_TIME ((32 + 2 + 2 + 5 + 5 + 2 + 16) * PHY_OUTPUT_TIME)
405 // Read from a PHY register
409 LAN91X_DRIVER
*LanDriver
,
415 // Bit-bang the MII Serial Frame read operation
416 MdioOutput (LanDriver
, 32, 0xffffffff); // Send 32 Ones as a preamble
417 MdioOutput (LanDriver
, 2, 0x01); // Send Start (01)
418 MdioOutput (LanDriver
, 2, 0x02); // Send Read (10)
419 MdioOutput (LanDriver
, 5, LanDriver
->PhyAd
); // Send PHYAD[4:0]
420 MdioOutput (LanDriver
, 5, RegAd
); // Send REGAD[4:0]
422 (VOID
) MdioInput (LanDriver
, 2); // Discard TurnAround bits
423 Value
= MdioInput (LanDriver
, 16); // Read 16 data bits
426 MdioIdle (LanDriver
);
428 return (Value
& 0xffff);
430 // Calculate approximate time to read a PHY register in microseconds
431 #define PHY_READ_TIME (((32 + 2 + 2 + 5 + 5) * PHY_OUTPUT_TIME) + \
432 ((2 + 16) * PHY_INPUT_TIME))
435 /* ---------------- Debug Functions ------------------ */
437 #ifdef LAN91X_PRINT_REGISTERS
441 IN LAN91X_DRIVER
*LanDriver
448 DEBUG ((DEBUG_ERROR
, "\nLAN91x I/O Register Dump:\n"));
450 // Print currrent bank select register
451 Value
= MmioRead16 (LanDriver
->IoBase
+ LAN91X_BANK_OFFSET
);
452 DEBUG ((DEBUG_ERROR
, " BankSel: %d Bank Register %04x (%d)\n",
453 LanDriver
->BankSel
, Value
, Value
& 0x0007));
455 // Print all I/O registers
456 for (Offset
= 0; Offset
< 0x0e; Offset
+= 2) {
457 DEBUG ((DEBUG_ERROR
, " %02x:", Offset
));
458 for (Bank
= 0; Bank
<= 3; ++Bank
) {
459 DEBUG ((DEBUG_ERROR
, " %04x", ReadIoReg16 (LanDriver
, MakeRegister (Bank
, Offset
))));
461 DEBUG ((DEBUG_ERROR
, "\n"));
468 IN LAN91X_DRIVER
*LanDriver
473 DEBUG ((DEBUG_ERROR
, "\nLAN91x Phy %d Register Dump:\n", LanDriver
->PhyAd
));
475 // Print all Phy registers
476 for (RegNum
= 0; RegNum
<= 5; ++RegNum
) {
477 DEBUG ((DEBUG_ERROR
, " %2d: %04x\n",
479 ReadPhyReg16 (LanDriver
, RegNum
)
482 for (RegNum
= 16; RegNum
<= 20; ++RegNum
) {
483 DEBUG ((DEBUG_ERROR
, " %2d: %04x\n",
485 ReadPhyReg16 (LanDriver
, RegNum
)
491 #if LAN91X_PRINT_PACKET_HEADERS
495 IN CONST VOID
*DstMac
,
496 IN CONST VOID
*SrcMac
,
497 IN CONST VOID
*Proto
,
498 IN CONST VOID
*IpDgram
506 DEBUG ((DEBUG_ERROR
, " Dst: %02x-%02x-%02x",
507 Ptr
[0], Ptr
[1], Ptr
[2]));
508 DEBUG ((DEBUG_ERROR
, "-%02x-%02x-%02x",
509 Ptr
[3], Ptr
[4], Ptr
[5]));
512 DEBUG ((DEBUG_ERROR
, " Src: %02x-%02x-%02x",
513 Ptr
[0], Ptr
[1], Ptr
[2]));
514 DEBUG ((DEBUG_ERROR
, "-%02x-%02x-%02x",
515 Ptr
[3], Ptr
[4], Ptr
[5]));
518 DEBUG ((DEBUG_ERROR
, " Proto: %02x%02x\n",
523 case EFI_IP_PROTO_ICMP
:
524 DEBUG ((DEBUG_ERROR
, " ICMP"));
526 case EFI_IP_PROTO_TCP
:
527 DEBUG ((DEBUG_ERROR
, " TCP"));
529 case EFI_IP_PROTO_UDP
:
530 DEBUG ((DEBUG_ERROR
, " UDP"));
533 DEBUG ((DEBUG_ERROR
, " IpProto %d\n", Ptr
[9]));
537 DEBUG ((DEBUG_ERROR
, " SrcIp: %d.%d.%d.%d",
538 Ptr
[12], Ptr
[13], Ptr
[14], Ptr
[15]));
539 DEBUG ((DEBUG_ERROR
, " DstIp: %d.%d.%d.%d",
540 Ptr
[16], Ptr
[17], Ptr
[18], Ptr
[19]));
542 SrcPort
= (Ptr
[20] << 8) | Ptr
[21];
543 DstPort
= (Ptr
[22] << 8) | Ptr
[23];
544 DEBUG ((DEBUG_ERROR
, " SrcPort: %d DstPort: %d\n", SrcPort
, DstPort
));
549 /* ---------------- PHY Management Operations ----------------- */
554 IN LAN91X_DRIVER
*LanDriver
560 for (LanDriver
->PhyAd
= 0x1f; LanDriver
->PhyAd
>= 0 ; --LanDriver
->PhyAd
) {
561 PhyId1
= ReadPhyReg16 (LanDriver
, PHY_INDEX_ID1
);
562 PhyId2
= ReadPhyReg16 (LanDriver
, PHY_INDEX_ID2
);
564 if ((PhyId1
!= 0x0000) && (PhyId1
!= 0xffff) &&
565 (PhyId2
!= 0x0000) && (PhyId2
!= 0xffff)) {
566 if ((PhyId1
== 0x0016) && ((PhyId2
& 0xfff0) == 0xf840)) {
567 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY type LAN83C183 (LAN91C111 Internal)\n"));
568 } else if ((PhyId1
== 0x0282) && ((PhyId2
& 0xfff0) == 0x1c50)) {
569 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY type LAN83C180\n"));
571 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY id %04x:%04x\n", PhyId1
, PhyId2
));
577 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY detection failed\n"));
582 // Check the Link Status and take appropriate action
586 IN LAN91X_DRIVER
*LanDriver
591 // Get the PHY Status
592 PhyStatus
= ReadPhyReg16 (LanDriver
, PHY_INDEX_BASIC_STATUS
);
594 return (PhyStatus
& PHYSTS_LINK_STS
) != 0;
598 // Do auto-negotiation
602 IN LAN91X_DRIVER
*LanDriver
610 // If there isn't a PHY, don't try to reset it
611 if (LanDriver
->PhyAd
== LAN91X_NO_PHY
) {
615 // Next check that auto-negotiation is supported
616 PhyStatus
= ReadPhyReg16 (LanDriver
, PHY_INDEX_BASIC_STATUS
);
617 if ((PhyStatus
& PHYSTS_AUTO_CAP
) == 0) {
621 // Translate capabilities to advertise
622 PhyAdvert
= PHYANA_CSMA
;
624 if ((PhyStatus
& PHYSTS_10BASET_HDPLX
) != 0) {
625 PhyAdvert
|= PHYANA_10BASET
;
627 if ((PhyStatus
& PHYSTS_10BASET_FDPLX
) != 0) {
628 PhyAdvert
|= PHYANA_10BASETFD
;
630 if ((PhyStatus
& PHYSTS_100BASETX_HDPLX
) != 0) {
631 PhyAdvert
|= PHYANA_100BASETX
;
633 if ((PhyStatus
& PHYSTS_100BASETX_FDPLX
) != 0) {
634 PhyAdvert
|= PHYANA_100BASETXFD
;
636 if ((PhyStatus
& PHYSTS_100BASE_T4
) != 0) {
637 PhyAdvert
|= PHYANA_100BASET4
;
640 // Set the capabilities to advertise
641 WritePhyReg16 (LanDriver
, PHY_INDEX_AUTO_NEG_ADVERT
, PhyAdvert
);
642 (VOID
) ReadPhyReg16 (LanDriver
, PHY_INDEX_AUTO_NEG_ADVERT
);
644 // Restart Auto-Negotiation
645 PhyControl
= ReadPhyReg16 (LanDriver
, PHY_INDEX_BASIC_CTRL
);
646 PhyControl
&= ~(PHYCR_SPEED_SEL
| PHYCR_DUPLEX_MODE
);
647 PhyControl
|= PHYCR_AUTO_EN
| PHYCR_RST_AUTO
;
648 WritePhyReg16 (LanDriver
, PHY_INDEX_BASIC_CTRL
, PhyControl
);
650 // Wait up to 2 seconds for the process to complete
651 Retries
= 2000000 / (PHY_READ_TIME
+ 100);
652 while ((ReadPhyReg16 (LanDriver
, PHY_INDEX_BASIC_STATUS
) & PHYSTS_AUTO_COMP
) == 0) {
653 if (--Retries
== 0) {
654 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY auto-negotiation timed-out\n"));
664 // Perform PHY software reset
668 IN LAN91X_DRIVER
*LanDriver
673 // If there isn't a PHY, don't try to reset it
674 if (LanDriver
->PhyAd
== LAN91X_NO_PHY
) {
678 // Request a PHY reset
679 WritePhyReg16 (LanDriver
, PHY_INDEX_BASIC_CTRL
, PHYCR_RESET
);
681 // The internal PHY will reset within 50ms. Allow 100ms.
682 Retries
= 100000 / (PHY_READ_TIME
+ 100);
683 while (ReadPhyReg16 (LanDriver
, PHY_INDEX_BASIC_CTRL
) & PHYCR_RESET
) {
684 if (--Retries
== 0) {
685 DEBUG ((DEBUG_ERROR
, "LAN91x: PHY reset timed-out\n"));
695 /* ---------------- General Operations ----------------- */
699 GetCurrentMacAddress (
700 IN LAN91X_DRIVER
*LanDriver
705 EFI_MAC_ADDRESS MacAddress
;
707 SetMem (&MacAddress
, sizeof(MacAddress
), 0);
709 Addr
= &MacAddress
.Addr
[0];
710 for (RegNum
= LAN91X_IAR0
; RegNum
<= LAN91X_IAR5
; ++RegNum
) {
711 *Addr
= ReadIoReg8 (LanDriver
, RegNum
);
720 SetCurrentMacAddress (
721 IN LAN91X_DRIVER
*LanDriver
,
722 IN EFI_MAC_ADDRESS
*MacAddress
728 Addr
= &MacAddress
->Addr
[0];
729 for (RegNum
= LAN91X_IAR0
; RegNum
<= LAN91X_IAR5
; ++RegNum
) {
730 WriteIoReg8 (LanDriver
, RegNum
, *Addr
);
740 IN LAN91X_DRIVER
*LanDriver
,
746 WriteIoReg16 (LanDriver
, LAN91X_MMUCR
, MmuOp
);
748 while ((ReadIoReg16 (LanDriver
, LAN91X_MMUCR
) & MMUCR_BUSY
) != 0) {
750 DEBUG ((DEBUG_ERROR
, "LAN91x: MMU operation %04x timed-out\n", MmuOp
));
753 gBS
->Stall (LAN91X_STALL
);
759 // Read bytes from the DATA register
763 IN LAN91X_DRIVER
*LanDriver
,
771 for (; BufLen
> 0; --BufLen
) {
772 *Ptr
= ReadIoReg8 (LanDriver
, LAN91X_DATA0
);
779 // Write bytes to the DATA register
783 IN LAN91X_DRIVER
*LanDriver
,
791 for (; BufLen
> 0; --BufLen
) {
792 WriteIoReg8 (LanDriver
, LAN91X_DATA0
, *Ptr
);
799 // Disable the interface
803 IN LAN91X_DRIVER
*LanDriver
806 #ifdef LAN91X_POWER_DOWN
810 // Stop Rx and Tx operations
811 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RCR_CLEAR
);
812 WriteIoReg16 (LanDriver
, LAN91X_TCR
, TCR_CLEAR
);
814 #ifdef LAN91X_POWER_DOWN
815 // Power-down the chip
816 Val16
= ReadIoReg16 (LanDriver
, LAN91X_CR
);
817 Val16
&= ~CR_EPH_POWER_EN
;
818 WriteIoReg16 (LanDriver
, LAN91X_CR
, Val16
);
824 // Enable the interface
828 IN LAN91X_DRIVER
*LanDriver
831 #ifdef LAN91X_POWER_DOWN
835 Val16
= ReadIoReg16 (LanDriver
, LAN91X_CR
);
836 Val16
|= CR_EPH_POWER_EN
;
837 WriteIoReg16 (LanDriver
, LAN91X_CR
, Val16
);
838 gBS
->Stall (LAN91X_STALL
);
841 // Start Rx and Tx operations
842 WriteIoReg16 (LanDriver
, LAN91X_TCR
, TCR_DEFAULT
);
843 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RCR_DEFAULT
);
849 // Perform software reset on the LAN91x
853 IN LAN91X_DRIVER
*LanDriver
859 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RCR_SOFT_RST
);
860 gBS
->Stall (LAN91X_STALL
);
861 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RCR_CLEAR
);
863 // Set the configuration register
864 WriteIoReg16 (LanDriver
, LAN91X_CR
, CR_DEFAULT
);
865 gBS
->Stall (LAN91X_STALL
);
868 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RCR_CLEAR
);
869 WriteIoReg16 (LanDriver
, LAN91X_TCR
, TCR_CLEAR
);
871 // Initialize the Control Register
872 Val16
= ReadIoReg16 (LanDriver
, LAN91X_CTR
);
873 Val16
|= CTR_AUTO_REL
;
874 WriteIoReg16 (LanDriver
, LAN91X_CTR
, Val16
);
877 MmuOperation (LanDriver
, MMUCR_OP_RESET_MMU
);
885 ** Validate that there is a LAN91x device.
891 IN LAN91X_DRIVER
*LanDriver
896 CHAR16 CONST
*ChipId
;
899 // First check that the Bank Select register is valid
900 Bank
= MmioRead16 (LanDriver
->IoBase
+ LAN91X_BANK_OFFSET
);
901 if ((Bank
& 0xff00) != 0x3300) {
902 DEBUG ((DEBUG_ERROR
, "LAN91x: signature error: expecting 33xx, read %04x\n", Bank
));
903 return EFI_DEVICE_ERROR
;
906 // Try reading the revision register next
907 LanDriver
->BankSel
= 0xff;
908 Val16
= ReadIoReg16 (LanDriver
, LAN91X_REV
);
910 Bank
= MmioRead16 (LanDriver
->IoBase
+ LAN91X_BANK_OFFSET
);
911 if ((Bank
& 0xff03) != 0x3303) {
912 DEBUG ((DEBUG_ERROR
, "LAN91x: signature error: expecting 33x3, read %04x\n", Bank
));
913 return EFI_DEVICE_ERROR
;
916 // Validate the revision register
917 if ((Val16
& 0xff00) != 0x3300) {
918 DEBUG ((DEBUG_ERROR
, "LAN91x: revision error: expecting 33xx, read %04x\n", Val16
));
919 return EFI_DEVICE_ERROR
;
922 ChipId
= ChipIds
[(Val16
>> 4) & 0x0f];
923 if (ChipId
== NULL
) {
924 DEBUG ((DEBUG_ERROR
, "LAN91x: unrecognized revision: %04x\n", Val16
));
925 return EFI_DEVICE_ERROR
;
927 DEBUG ((DEBUG_ERROR
, "LAN91x: detected chip %s rev %d\n", ChipId
, Val16
& 0xf));
928 LanDriver
->Revision
= Val16
& 0xff;
930 // Reload from EEPROM to get the hardware MAC address
931 WriteIoReg16 (LanDriver
, LAN91X_CTR
, CTR_RESERVED
| CTR_RELOAD
);
933 while ((ReadIoReg16 (LanDriver
, LAN91X_CTR
) & CTR_RELOAD
) != 0) {
934 if (--ResetTime
== 0) {
935 DEBUG ((DEBUG_ERROR
, "LAN91x: reload from EEPROM timed-out\n"));
936 WriteIoReg16 (LanDriver
, LAN91X_CTR
, CTR_RESERVED
);
937 return EFI_DEVICE_ERROR
;
939 gBS
->Stall (LAN91X_STALL
);
942 // Read and save the Permanent MAC Address
943 LanDriver
->SnpMode
.PermanentAddress
= GetCurrentMacAddress (LanDriver
);
944 LanDriver
->SnpMode
.CurrentAddress
= LanDriver
->SnpMode
.PermanentAddress
;
945 DEBUG ((DEBUG_ERROR
, //DEBUG_NET | DEBUG_INFO,
946 "LAN91x: HW MAC Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
947 LanDriver
->SnpMode
.PermanentAddress
.Addr
[0],
948 LanDriver
->SnpMode
.PermanentAddress
.Addr
[1],
949 LanDriver
->SnpMode
.PermanentAddress
.Addr
[2],
950 LanDriver
->SnpMode
.PermanentAddress
.Addr
[3],
951 LanDriver
->SnpMode
.PermanentAddress
.Addr
[4],
952 LanDriver
->SnpMode
.PermanentAddress
.Addr
[5]
956 SoftReset (LanDriver
);
958 // Try to detect a PHY
959 if (LanDriver
->Revision
> (CHIP_91100
<< 4)) {
960 PhyDetect (LanDriver
);
962 LanDriver
->PhyAd
= LAN91X_NO_PHY
;
971 /*------------------ Simple Network Driver entry point functions ------------------*/
973 // Refer to the Simple Network Protocol section (21.1)
974 // in the UEFI 2.3.1 Specification for documentation.
976 #define ReturnUnlock(s) do { Status = (s); goto exit_unlock; } while(0)
980 ** UEFI Start() function
986 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
989 EFI_SIMPLE_NETWORK_MODE
*Mode
;
993 // Check Snp instance
995 return EFI_INVALID_PARAMETER
;
998 // Serialize access to data and registers
999 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1002 // Check state of the driver
1003 switch (Mode
->State
) {
1004 case EfiSimpleNetworkStopped
:
1006 case EfiSimpleNetworkStarted
:
1007 case EfiSimpleNetworkInitialized
:
1008 DEBUG ((DEBUG_WARN
, "LAN91x: Driver already started\n"));
1009 ReturnUnlock (EFI_ALREADY_STARTED
);
1011 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1012 (UINTN
)Snp
->Mode
->State
));
1013 ReturnUnlock (EFI_DEVICE_ERROR
);
1018 Mode
->State
= EfiSimpleNetworkStarted
;
1019 Status
= EFI_SUCCESS
;
1021 // Restore TPL and return
1023 gBS
->RestoreTPL (SavedTpl
);
1028 ** UEFI Stop() function
1034 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
1037 LAN91X_DRIVER
*LanDriver
;
1041 // Check Snp Instance
1043 return EFI_INVALID_PARAMETER
;
1046 // Serialize access to data and registers
1047 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1049 // Check state of the driver
1050 switch (Snp
->Mode
->State
) {
1051 case EfiSimpleNetworkStarted
:
1052 case EfiSimpleNetworkInitialized
:
1054 case EfiSimpleNetworkStopped
:
1055 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1056 ReturnUnlock (EFI_NOT_STARTED
);
1058 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1059 (UINTN
)Snp
->Mode
->State
));
1060 ReturnUnlock (EFI_DEVICE_ERROR
);
1063 // Find the LanDriver structure
1064 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1066 // Stop the Tx and Rx
1067 ChipDisable (LanDriver
);
1070 Snp
->Mode
->State
= EfiSimpleNetworkStopped
;
1071 Status
= EFI_SUCCESS
;
1073 // Restore TPL and return
1075 gBS
->RestoreTPL (SavedTpl
);
1080 ** UEFI Initialize() function
1086 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
,
1087 IN UINTN RxBufferSize OPTIONAL
,
1088 IN UINTN TxBufferSize OPTIONAL
1091 LAN91X_DRIVER
*LanDriver
;
1095 // Check Snp Instance
1097 return EFI_INVALID_PARAMETER
;
1100 // Serialize access to data and registers
1101 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1103 // Check that driver was started but not initialised
1104 switch (Snp
->Mode
->State
) {
1105 case EfiSimpleNetworkStarted
:
1107 case EfiSimpleNetworkInitialized
:
1108 DEBUG ((DEBUG_WARN
, "LAN91x: Driver already initialized\n"));
1109 ReturnUnlock (EFI_SUCCESS
);
1110 case EfiSimpleNetworkStopped
:
1111 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1112 ReturnUnlock (EFI_NOT_STARTED
);
1114 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1115 (UINTN
)Snp
->Mode
->State
));
1116 ReturnUnlock (EFI_DEVICE_ERROR
);
1119 // Find the LanDriver structure
1120 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1122 // Initiate a software reset
1123 Status
= SoftReset (LanDriver
);
1124 if (EFI_ERROR(Status
)) {
1125 DEBUG ((DEBUG_WARN
, "LAN91x: Soft reset failed\n"));
1126 ReturnUnlock (EFI_DEVICE_ERROR
);
1129 // Initiate a PHY reset
1130 if (PhySoftReset (LanDriver
) < 0) {
1131 Snp
->Mode
->State
= EfiSimpleNetworkStopped
;
1132 DEBUG ((DEBUG_WARN
, "LAN91x: PHY soft reset timeout\n"));
1133 ReturnUnlock (EFI_NOT_STARTED
);
1136 // Do auto-negotiation
1137 Status
= PhyAutoNegotiate (LanDriver
);
1138 if (EFI_ERROR(Status
)) {
1139 DEBUG ((DEBUG_WARN
, "LAN91x: PHY auto-negotiation failed\n"));
1142 // Enable the receiver and transmitter
1143 ChipEnable (LanDriver
);
1145 // Now acknowledge all interrupts
1146 WriteIoReg8 (LanDriver
, LAN91X_IST
, 0xFF);
1148 // Declare the driver as initialized
1149 Snp
->Mode
->State
= EfiSimpleNetworkInitialized
;
1150 Status
= EFI_SUCCESS
;
1152 // Restore TPL and return
1154 gBS
->RestoreTPL (SavedTpl
);
1159 ** UEFI Reset () function
1165 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
,
1166 IN BOOLEAN Verification
1169 LAN91X_DRIVER
*LanDriver
;
1173 // Check Snp Instance
1175 return EFI_INVALID_PARAMETER
;
1178 // Serialize access to data and registers
1179 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1181 // Check that driver was started and initialised
1182 switch (Snp
->Mode
->State
) {
1183 case EfiSimpleNetworkInitialized
:
1185 case EfiSimpleNetworkStarted
:
1186 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1187 ReturnUnlock (EFI_DEVICE_ERROR
);
1188 case EfiSimpleNetworkStopped
:
1189 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1190 ReturnUnlock (EFI_NOT_STARTED
);
1192 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1193 (UINTN
)Snp
->Mode
->State
));
1194 ReturnUnlock (EFI_DEVICE_ERROR
);
1197 // Find the LanDriver structure
1198 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1200 // Initiate a software reset
1201 if (EFI_ERROR (SoftReset (LanDriver
))) {
1202 DEBUG ((DEBUG_WARN
, "LAN91x: Soft reset failed\n"));
1203 ReturnUnlock (EFI_DEVICE_ERROR
);
1206 // Initiate a PHY reset
1207 if (EFI_ERROR (PhySoftReset (LanDriver
))) {
1208 DEBUG ((DEBUG_WARN
, "LAN91x: PHY soft reset failed\n"));
1209 ReturnUnlock (EFI_DEVICE_ERROR
);
1212 // Enable the receiver and transmitter
1213 Status
= ChipEnable (LanDriver
);
1215 // Restore TPL and return
1217 gBS
->RestoreTPL (SavedTpl
);
1222 ** UEFI Shutdown () function
1228 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
1231 LAN91X_DRIVER
*LanDriver
;
1235 // Check Snp Instance
1237 return EFI_INVALID_PARAMETER
;
1240 // Serialize access to data and registers
1241 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1243 // First check that driver has already been initialized
1244 switch (Snp
->Mode
->State
) {
1245 case EfiSimpleNetworkInitialized
:
1247 case EfiSimpleNetworkStarted
:
1248 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1249 ReturnUnlock (EFI_DEVICE_ERROR
);
1250 case EfiSimpleNetworkStopped
:
1251 DEBUG ((DEBUG_WARN
, "LAN91x: Driver in stopped state\n"));
1252 ReturnUnlock (EFI_NOT_STARTED
);
1254 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1255 (UINTN
)Snp
->Mode
->State
));
1256 ReturnUnlock (EFI_DEVICE_ERROR
);
1259 // Find the LanDriver structure
1260 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1262 // Disable the interface
1263 Status
= ChipDisable (LanDriver
);
1265 // Restore TPL and return
1267 gBS
->RestoreTPL (SavedTpl
);
1273 ** UEFI ReceiveFilters() function
1279 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
,
1283 IN UINTN NumMfilter OPTIONAL
,
1284 IN EFI_MAC_ADDRESS
*Mfilter OPTIONAL
1287 #define MCAST_HASH_BYTES 8
1289 LAN91X_DRIVER
*LanDriver
;
1290 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
1296 UINT8 McastHash
[MCAST_HASH_BYTES
];
1298 // Check Snp Instance
1300 return EFI_INVALID_PARAMETER
;
1303 // Serialize access to data and registers
1304 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1306 // First check that driver has already been initialized
1307 switch (Snp
->Mode
->State
) {
1308 case EfiSimpleNetworkInitialized
:
1310 case EfiSimpleNetworkStarted
:
1311 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1312 ReturnUnlock (EFI_DEVICE_ERROR
);
1313 case EfiSimpleNetworkStopped
:
1314 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1315 ReturnUnlock (EFI_NOT_STARTED
);
1317 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1318 (UINTN
)Snp
->Mode
->State
));
1319 ReturnUnlock (EFI_DEVICE_ERROR
);
1322 // Find the LanDriver structure
1323 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1324 SnpMode
= Snp
->Mode
;
1326 #ifdef LAN91X_PRINT_RECEIVE_FILTERS
1327 DEBUG ((DEBUG_ERROR
, "LAN91x:SnpReceiveFilters()\n"));
1328 DEBUG ((DEBUG_ERROR
, " Enable = %08x\n", Enable
));
1329 DEBUG ((DEBUG_ERROR
, " Disable = %08x\n", Disable
));
1330 DEBUG ((DEBUG_ERROR
, " Reset = %d\n", Reset
));
1331 DEBUG ((DEBUG_ERROR
, " NumMfilter = %d\n", NumMfilter
));
1332 for (i
= 0; i
< NumMfilter
; ++i
) {
1333 DEBUG ((DEBUG_ERROR
,
1334 " [%2d] = %02x-%02x-%02x-%02x-%02x-%02x\n",
1341 Mfilter
[i
].Addr
[5]));
1345 // Update the Multicast Hash registers
1347 // Clear the hash table
1348 SetMem (McastHash
, MCAST_HASH_BYTES
, 0);
1349 SnpMode
->MCastFilterCount
= 0;
1351 // Read the current hash table
1352 for (i
= 0; i
< MCAST_HASH_BYTES
; ++i
) {
1353 McastHash
[i
] = ReadIoReg8 (LanDriver
, LAN91X_MT0
+ i
);
1355 // Set the new additions
1356 for (i
= 0; i
< NumMfilter
; ++i
) {
1357 Crc
= MulticastHash (&Mfilter
[i
], NET_ETHER_ADDR_LEN
);
1358 McastHash
[(Crc
>> 29) & 0x3] |= 1 << ((Crc
>> 26) & 0x3);
1360 SnpMode
->MCastFilterCount
= NumMfilter
;
1362 // If the hash registers need updating, write them
1363 if (Reset
|| NumMfilter
> 0) {
1364 for (i
= 0; i
< MCAST_HASH_BYTES
; ++i
) {
1365 WriteIoReg8 (LanDriver
, LAN91X_MT0
+ i
, McastHash
[i
]);
1369 RcvCtrl
= ReadIoReg16 (LanDriver
, LAN91X_RCR
);
1370 if ((Enable
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
1371 RcvCtrl
|= RCR_PRMS
;
1372 SnpMode
->ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1374 if ((Disable
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
1375 RcvCtrl
&= ~RCR_PRMS
;
1376 SnpMode
->ReceiveFilterSetting
&= ~EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1379 if ((Enable
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
1380 RcvCtrl
|= RCR_ALMUL
;
1381 SnpMode
->ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1383 if ((Disable
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
1384 RcvCtrl
&= ~RCR_ALMUL
;
1385 SnpMode
->ReceiveFilterSetting
&= ~EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1387 WriteIoReg16 (LanDriver
, LAN91X_RCR
, RcvCtrl
);
1389 Status
= SetCurrentMacAddress (LanDriver
, &SnpMode
->CurrentAddress
);
1391 // Restore TPL and return
1393 gBS
->RestoreTPL (SavedTpl
);
1398 ** UEFI StationAddress() function
1404 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
,
1406 IN EFI_MAC_ADDRESS
*NewMac
1409 LAN91X_DRIVER
*LanDriver
;
1413 // Check Snp instance
1415 return EFI_INVALID_PARAMETER
;
1418 // Serialize access to data and registers
1419 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1421 // Check that driver was started and initialised
1422 switch (Snp
->Mode
->State
) {
1423 case EfiSimpleNetworkInitialized
:
1425 case EfiSimpleNetworkStarted
:
1426 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1427 ReturnUnlock (EFI_DEVICE_ERROR
);
1428 case EfiSimpleNetworkStopped
:
1429 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1430 ReturnUnlock (EFI_NOT_STARTED
);
1432 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1433 (UINTN
)Snp
->Mode
->State
));
1434 ReturnUnlock (EFI_DEVICE_ERROR
);
1437 // Find the LanDriver structure
1438 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1441 Snp
->Mode
->CurrentAddress
= Snp
->Mode
->PermanentAddress
;
1443 if (NewMac
== NULL
) {
1444 ReturnUnlock (EFI_INVALID_PARAMETER
);
1446 Snp
->Mode
->CurrentAddress
= *NewMac
;
1449 Status
= SetCurrentMacAddress (LanDriver
, &Snp
->Mode
->CurrentAddress
);
1451 // Restore TPL and return
1453 gBS
->RestoreTPL (SavedTpl
);
1458 ** UEFI Statistics() function
1464 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
,
1466 IN OUT UINTN
*StatSize
,
1467 OUT EFI_NETWORK_STATISTICS
*Statistics
1470 LAN91X_DRIVER
*LanDriver
;
1474 // Check Snp instance
1476 return EFI_INVALID_PARAMETER
;
1479 // Check pointless condition
1480 if ((!Reset
) && (StatSize
== NULL
) && (Statistics
== NULL
)) {
1484 // Check the parameters
1485 if ((StatSize
== NULL
) && (Statistics
!= NULL
)) {
1486 return EFI_INVALID_PARAMETER
;
1489 // Serialize access to data and registers
1490 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1492 // Check that driver was started and initialised
1493 switch (Snp
->Mode
->State
) {
1494 case EfiSimpleNetworkInitialized
:
1496 case EfiSimpleNetworkStarted
:
1497 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1498 ReturnUnlock (EFI_DEVICE_ERROR
);
1499 case EfiSimpleNetworkStopped
:
1500 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1501 ReturnUnlock (EFI_NOT_STARTED
);
1503 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1504 (UINTN
)Snp
->Mode
->State
));
1505 ReturnUnlock (EFI_DEVICE_ERROR
);
1508 // Find the LanDriver structure
1509 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1511 // Do a reset if required
1513 ZeroMem (&LanDriver
->Stats
, sizeof(EFI_NETWORK_STATISTICS
));
1516 // Check buffer size
1517 if (*StatSize
< sizeof(EFI_NETWORK_STATISTICS
)) {
1518 *StatSize
= sizeof(EFI_NETWORK_STATISTICS
);
1519 ReturnUnlock (EFI_BUFFER_TOO_SMALL
);
1523 // Fill in the statistics
1524 CopyMem(&Statistics
, &LanDriver
->Stats
, sizeof(EFI_NETWORK_STATISTICS
));
1525 Status
= EFI_SUCCESS
;
1527 // Restore TPL and return
1529 gBS
->RestoreTPL (SavedTpl
);
1534 ** UEFI MCastIPtoMAC() function
1540 IN EFI_SIMPLE_NETWORK_PROTOCOL
* Snp
,
1542 IN EFI_IP_ADDRESS
*Ip
,
1543 OUT EFI_MAC_ADDRESS
*McastMac
1546 // Check Snp instance
1548 return EFI_INVALID_PARAMETER
;
1552 if ((McastMac
== NULL
) || (Ip
== NULL
)) {
1553 return EFI_INVALID_PARAMETER
;
1556 // Make sure MAC address is empty
1557 ZeroMem (McastMac
, sizeof(EFI_MAC_ADDRESS
));
1559 // If we need ipv4 address
1561 // Most significant 25 bits of a multicast HW address are set
1562 McastMac
->Addr
[0] = 0x01;
1563 McastMac
->Addr
[1] = 0x00;
1564 McastMac
->Addr
[2] = 0x5E;
1566 // Lower 23 bits from ipv4 address
1567 McastMac
->Addr
[3] = (Ip
->v4
.Addr
[1] & 0x7F); // Clear the ms bit (25th bit of MAC must be 0)
1568 McastMac
->Addr
[4] = Ip
->v4
.Addr
[2];
1569 McastMac
->Addr
[5] = Ip
->v4
.Addr
[3];
1571 // Most significant 16 bits of multicast v6 HW address are set
1572 McastMac
->Addr
[0] = 0x33;
1573 McastMac
->Addr
[1] = 0x33;
1575 // lower four octets are taken from ipv6 address
1576 McastMac
->Addr
[2] = Ip
->v6
.Addr
[8];
1577 McastMac
->Addr
[3] = Ip
->v6
.Addr
[9];
1578 McastMac
->Addr
[4] = Ip
->v6
.Addr
[10];
1579 McastMac
->Addr
[5] = Ip
->v6
.Addr
[11];
1586 ** UEFI NvData() function
1592 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pobj
,
1593 IN BOOLEAN read_write
,
1599 DEBUG ((DEBUG_ERROR
, "LAN91x: Non-volatile storage not supported\n"));
1601 return EFI_UNSUPPORTED
;
1606 ** UEFI GetStatus () function
1612 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
,
1613 OUT UINT32
*IrqStat OPTIONAL
,
1614 OUT VOID
**TxBuff OPTIONAL
1617 LAN91X_DRIVER
*LanDriver
;
1620 BOOLEAN MediaPresent
;
1622 MSK_LINKED_SYSTEM_BUF
*LinkedTXRecycleBuff
;
1624 // Check preliminaries
1626 return EFI_INVALID_PARAMETER
;
1629 // Serialize access to data and registers
1630 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1632 // Check that driver was started and initialised
1633 switch (Snp
->Mode
->State
) {
1634 case EfiSimpleNetworkInitialized
:
1636 case EfiSimpleNetworkStarted
:
1637 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1638 ReturnUnlock (EFI_DEVICE_ERROR
);
1639 case EfiSimpleNetworkStopped
:
1640 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1641 ReturnUnlock (EFI_NOT_STARTED
);
1643 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1644 (UINTN
)Snp
->Mode
->State
));
1645 ReturnUnlock (EFI_DEVICE_ERROR
);
1648 // Find the LanDriver structure
1649 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1651 // Arbitrarily set the interrupt status to 0
1652 if (IrqStat
!= NULL
) {
1654 IstReg
= ReadIoReg8 (LanDriver
, LAN91X_IST
);
1655 if ((IstReg
& IST_RCV
) != 0) {
1656 *IrqStat
|= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
;
1658 if ((IstReg
& IST_TX
) != 0) {
1659 *IrqStat
|= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
;
1663 // Pass back the completed buffer address
1664 // The transmit buffer status is not read when TxBuf is NULL
1665 if (TxBuff
!= NULL
) {
1666 *((UINT8
**) TxBuff
) = (UINT8
*) 0;
1667 if( !IsListEmpty (&LanDriver
->TransmitQueueHead
))
1669 LinkedTXRecycleBuff
= CR (GetFirstNode (&LanDriver
->TransmitQueueHead
), MSK_LINKED_SYSTEM_BUF
, Link
, TX_MBUF_SIGNATURE
);
1670 if(LinkedTXRecycleBuff
!= NULL
) {
1671 *TxBuff
= LinkedTXRecycleBuff
->SystemBuf
.Buf
;
1672 RemoveEntryList (&LinkedTXRecycleBuff
->Link
);
1673 FreePool (LinkedTXRecycleBuff
);
1678 // Update the media status
1679 MediaPresent
= CheckLinkStatus (LanDriver
);
1680 if (MediaPresent
!= Snp
->Mode
->MediaPresent
) {
1681 DEBUG ((DEBUG_WARN
, "LAN91x: Link %s\n", MediaPresent
? L
"up" : L
"down"));
1683 Snp
->Mode
->MediaPresent
= MediaPresent
;
1684 Status
= EFI_SUCCESS
;
1686 // Restore TPL and return
1688 gBS
->RestoreTPL (SavedTpl
);
1694 ** UEFI Transmit() function
1700 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
,
1704 IN EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
1705 IN EFI_MAC_ADDRESS
*DstAddr OPTIONAL
,
1706 IN UINT16
*Protocol OPTIONAL
1709 LAN91X_DRIVER
*LanDriver
;
1718 MSK_LINKED_SYSTEM_BUF
*LinkedTXRecycleBuff
;
1721 // Check preliminaries
1722 if ((Snp
== NULL
) || (BufAddr
== NULL
)) {
1723 DEBUG ((DEBUG_ERROR
, "LAN91x: SnpTransmit(): NULL Snp (%p) or BufAddr (%p)\n",
1725 return EFI_INVALID_PARAMETER
;
1728 // Serialize access to data and registers
1729 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1731 // Check that driver was started and initialised
1732 switch (Snp
->Mode
->State
) {
1733 case EfiSimpleNetworkInitialized
:
1735 case EfiSimpleNetworkStarted
:
1736 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1737 ReturnUnlock (EFI_DEVICE_ERROR
);
1738 case EfiSimpleNetworkStopped
:
1739 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1740 ReturnUnlock (EFI_NOT_STARTED
);
1742 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1743 (UINTN
)Snp
->Mode
->State
));
1744 ReturnUnlock (EFI_DEVICE_ERROR
);
1747 // Find the LanDriver structure
1748 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1750 // Ensure header is correct size if non-zero
1752 if (HdrSize
!= Snp
->Mode
->MediaHeaderSize
) {
1753 DEBUG ((DEBUG_ERROR
, "LAN91x: SnpTransmit(): Invalid HdrSize %d\n", HdrSize
));
1754 ReturnUnlock (EFI_INVALID_PARAMETER
);
1757 if ((DstAddr
== NULL
) || (Protocol
== NULL
)) {
1758 DEBUG ((DEBUG_ERROR
, "LAN91x: SnpTransmit(): NULL DstAddr %p or Protocol %p\n",
1759 DstAddr
, Protocol
));
1760 ReturnUnlock (EFI_INVALID_PARAMETER
);
1764 // Before transmitting check the link status
1765 if (!Snp
->Mode
->MediaPresent
) {
1766 DEBUG ((DEBUG_WARN
, "LAN91x: SnpTransmit(): Link not ready\n"));
1767 ReturnUnlock (EFI_NOT_READY
);
1770 // Calculate the request size in 256-byte "pages" minus 1
1771 // The 91C111 ignores this, but some older devices need it.
1772 MmuPages
= ((BufSize
& ~1) + LAN91X_PKT_OVERHEAD
- 1) >> 8;
1774 DEBUG ((DEBUG_WARN
, "LAN91x: Tx buffer too large (%d bytes)\n", BufSize
));
1775 LanDriver
->Stats
.TxOversizeFrames
+= 1;
1776 LanDriver
->Stats
.TxDroppedFrames
+= 1;
1777 ReturnUnlock (EFI_BAD_BUFFER_SIZE
);
1780 // Request allocation of a transmit buffer
1781 Status
= MmuOperation (LanDriver
, MMUCR_OP_TX_ALLOC
| MmuPages
);
1782 if (EFI_ERROR (Status
)) {
1783 DEBUG ((DEBUG_ERROR
, "LAN91x: Tx buffer request failure: %d\n", Status
));
1784 ReturnUnlock (EFI_DEVICE_ERROR
);
1787 // Wait for allocation request completion
1788 Retries
= LAN91X_MEMORY_ALLOC_POLLS
;
1789 while ((ReadIoReg8 (LanDriver
, LAN91X_IST
) & IST_ALLOC
) == 0) {
1790 if (--Retries
== 0) {
1791 DEBUG ((DEBUG_ERROR
, "LAN91x: Tx buffer allocation timeout\n"));
1792 ReturnUnlock (EFI_TIMEOUT
);
1796 // Check for successful allocation
1797 PktNum
= ReadIoReg8 (LanDriver
, LAN91X_ARR
);
1798 if ((PktNum
& ARR_FAILED
) != 0) {
1799 DEBUG ((DEBUG_ERROR
, "LAN91x: Tx buffer allocation failure: %02x\n", PktNum
));
1800 ReturnUnlock (EFI_NOT_READY
);
1802 PktNum
&= ARR_PACKET
;
1804 // Check for the nature of the frame
1805 // If no destination address, it's ARP broadcast
1808 if (DstAddr
->Addr
[0] == 0xFF) {
1809 LanDriver
->Stats
.TxBroadcastFrames
+= 1;
1810 } else if ((DstAddr
->Addr
[0] & 0x1) == 1) {
1811 LanDriver
->Stats
.TxMulticastFrames
+= 1;
1813 LanDriver
->Stats
.TxUnicastFrames
+= 1;
1816 LanDriver
->Stats
.TxBroadcastFrames
+= 1;
1819 // Set the Packet Number and Pointer registers
1820 WriteIoReg8 (LanDriver
, LAN91X_PNR
, PktNum
);
1821 WriteIoReg16 (LanDriver
, LAN91X_PTR
, PTR_AUTO_INCR
);
1823 // Set up mutable buffer information variables
1827 // Write Status and Byte Count first
1828 WriteIoReg16 (LanDriver
, LAN91X_DATA0
, 0);
1829 WriteIoReg16 (LanDriver
, LAN91X_DATA0
, (Len
+ LAN91X_PKT_OVERHEAD
) & BCW_COUNT
);
1831 // This packet may come with a preconfigured Ethernet header.
1832 // If not, we need to construct one from optional parameters.
1835 // Write the destination address
1836 WriteIoData (LanDriver
, DstAddr
, NET_ETHER_ADDR_LEN
);
1838 // Write the Source Address
1839 if (SrcAddr
!= NULL
) {
1840 WriteIoData (LanDriver
, SrcAddr
, NET_ETHER_ADDR_LEN
);
1842 WriteIoData (LanDriver
, &LanDriver
->SnpMode
.CurrentAddress
, NET_ETHER_ADDR_LEN
);
1845 // Write the Protocol word
1846 Proto
= HTONS (*Protocol
);
1847 WriteIoReg16 (LanDriver
, LAN91X_DATA0
, Proto
);
1849 // Adjust the data start and length
1850 Ptr
+= sizeof(ETHER_HEAD
);
1851 Len
-= sizeof(ETHER_HEAD
);
1854 // Copy the remainder data buffer, except the odd byte
1855 WriteIoData (LanDriver
, Ptr
, Len
& ~1);
1859 // Write the Packet Control Word and odd byte
1860 WriteIoReg16 (LanDriver
, LAN91X_DATA0
,
1861 (Len
!= 0) ? (PCW_ODD
| PCW_CRC
| *Ptr
) : PCW_CRC
);
1863 // Release the packet for transmission
1864 Status
= MmuOperation (LanDriver
, MMUCR_OP_TX_PUSH
);
1865 if (EFI_ERROR (Status
)) {
1866 DEBUG ((DEBUG_ERROR
, "LAN91x: Tx buffer release failure: %d\n", Status
));
1867 ReturnUnlock (EFI_DEVICE_ERROR
);
1870 // Update the Tx statistics
1871 LanDriver
->Stats
.TxTotalBytes
+= BufSize
;
1872 LanDriver
->Stats
.TxGoodFrames
+= 1;
1874 // Update the Tx Buffer cache
1875 LinkedTXRecycleBuff
= AllocateZeroPool (sizeof (MSK_LINKED_SYSTEM_BUF
));
1876 if (LinkedTXRecycleBuff
== NULL
) {
1877 return EFI_OUT_OF_RESOURCES
;
1879 LinkedTXRecycleBuff
->Signature
= TX_MBUF_SIGNATURE
;
1881 // Add the passed Buffer to the transmit queue. Don't copy.
1883 LinkedTXRecycleBuff
->SystemBuf
.Buf
= BufAddr
;
1884 LinkedTXRecycleBuff
->SystemBuf
.Length
= BufSize
;
1885 InsertTailList (&LanDriver
->TransmitQueueHead
, &LinkedTXRecycleBuff
->Link
);
1887 Status
= EFI_SUCCESS
;
1889 // Dump the packet header
1890 #if LAN91X_PRINT_PACKET_HEADERS
1892 DEBUG ((DEBUG_ERROR
, "LAN91X:SnpTransmit()\n"));
1893 DEBUG ((DEBUG_ERROR
, " HdrSize: %d, SrcAddr: %p, Length: %d, Last byte: %02x\n",
1894 HdrSize
, SrcAddr
, BufSize
, Ptr
[BufSize
- 1]));
1896 (HdrSize
== 0) ? (EFI_MAC_ADDRESS
*)&Ptr
[0] : DstAddr
,
1897 (HdrSize
== 0) ? (EFI_MAC_ADDRESS
*)&Ptr
[6] : (SrcAddr
!= NULL
) ? SrcAddr
: &LanDriver
->SnpMode
.CurrentAddress
,
1898 (HdrSize
== 0) ? (UINT16
*)&Ptr
[12] : &Proto
,
1903 // Restore TPL and return
1905 gBS
->RestoreTPL (SavedTpl
);
1911 ** UEFI Receive() function
1917 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
,
1918 OUT UINTN
*HdrSize OPTIONAL
,
1919 IN OUT UINTN
*BuffSize
,
1921 OUT EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
1922 OUT EFI_MAC_ADDRESS
*DstAddr OPTIONAL
,
1923 OUT UINT16
*Protocol OPTIONAL
1928 LAN91X_DRIVER
*LanDriver
;
1935 // Check preliminaries
1936 if ((Snp
== NULL
) || (Data
== NULL
)) {
1937 return EFI_INVALID_PARAMETER
;
1940 // Serialize access to data and registers
1941 SavedTpl
= gBS
->RaiseTPL (LAN91X_TPL
);
1943 // Check that driver was started and initialised
1944 switch (Snp
->Mode
->State
) {
1945 case EfiSimpleNetworkInitialized
:
1947 case EfiSimpleNetworkStarted
:
1948 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not yet initialized\n"));
1949 ReturnUnlock (EFI_DEVICE_ERROR
);
1950 case EfiSimpleNetworkStopped
:
1951 DEBUG ((DEBUG_WARN
, "LAN91x: Driver not started\n"));
1952 ReturnUnlock (EFI_NOT_STARTED
);
1954 DEBUG ((DEBUG_ERROR
, "LAN91x: Driver in an invalid state: %u\n",
1955 (UINTN
)Snp
->Mode
->State
));
1956 ReturnUnlock (EFI_DEVICE_ERROR
);
1959 // Find the LanDriver structure
1960 LanDriver
= INSTANCE_FROM_SNP_THIS(Snp
);
1962 // Check for Rx Overrun
1963 IstReg
= ReadIoReg8 (LanDriver
, LAN91X_IST
);
1964 if ((IstReg
& IST_RX_OVRN
) != 0) {
1965 LanDriver
->Stats
.RxTotalFrames
+= 1;
1966 LanDriver
->Stats
.RxDroppedFrames
+= 1;
1967 WriteIoReg8 (LanDriver
, LAN91X_IST
, IST_RX_OVRN
);
1968 DEBUG ((DEBUG_WARN
, "LAN91x: Receiver overrun\n"));
1971 // Check for Rx data available
1972 if ((IstReg
& IST_RCV
) == 0) {
1973 ReturnUnlock (EFI_NOT_READY
);
1976 // Configure the PTR register for reading
1977 WriteIoReg16 (LanDriver
, LAN91X_PTR
, PTR_RCV
| PTR_AUTO_INCR
| PTR_READ
);
1979 // Read the Packet Status and Packet Length words
1980 PktStatus
= ReadIoReg16 (LanDriver
, LAN91X_DATA0
);
1981 PktLength
= ReadIoReg16 (LanDriver
, LAN91X_DATA0
) & BCW_COUNT
;
1983 // Check for valid received packet
1984 if ((PktStatus
== 0) && (PktLength
== 0)) {
1985 DEBUG ((DEBUG_WARN
, "LAN91x: Received zero-length packet. IST=%04x\n", IstReg
));
1986 ReturnUnlock (EFI_NOT_READY
);
1988 LanDriver
->Stats
.RxTotalFrames
+= 1;
1990 // Check if we got a CRC error
1991 if ((PktStatus
& RX_BAD_CRC
) != 0) {
1992 DEBUG ((DEBUG_WARN
, "LAN91x: Received frame CRC error\n"));
1993 LanDriver
->Stats
.RxCrcErrorFrames
+= 1;
1994 LanDriver
->Stats
.RxDroppedFrames
+= 1;
1995 Status
= EFI_DEVICE_ERROR
;
1999 // Check if we got a too-short frame
2000 if ((PktStatus
& RX_TOO_SHORT
) != 0) {
2001 DEBUG ((DEBUG_WARN
, "LAN91x: Received frame too short (%d bytes)\n", PktLength
));
2002 LanDriver
->Stats
.RxUndersizeFrames
+= 1;
2003 LanDriver
->Stats
.RxDroppedFrames
+= 1;
2004 Status
= EFI_DEVICE_ERROR
;
2008 // Check if we got a too-long frame
2009 if ((PktStatus
& RX_TOO_LONG
) != 0) {
2010 DEBUG ((DEBUG_WARN
, "LAN91x: Received frame too long (%d bytes)\n", PktLength
));
2011 LanDriver
->Stats
.RxOversizeFrames
+= 1;
2012 LanDriver
->Stats
.RxDroppedFrames
+= 1;
2013 Status
= EFI_DEVICE_ERROR
;
2017 // Check if we got an alignment error
2018 if ((PktStatus
& RX_ALGN_ERR
) != 0) {
2019 DEBUG ((DEBUG_WARN
, "LAN91x: Received frame alignment error\n"));
2020 // Don't seem to keep track of these specifically
2021 LanDriver
->Stats
.RxDroppedFrames
+= 1;
2022 Status
= EFI_DEVICE_ERROR
;
2026 // Classify the received fram
2027 if ((PktStatus
& RX_MULTICAST
) != 0) {
2028 LanDriver
->Stats
.RxMulticastFrames
+= 1;
2029 } else if ((PktStatus
& RX_BROADCAST
) != 0) {
2030 LanDriver
->Stats
.RxBroadcastFrames
+= 1;
2032 LanDriver
->Stats
.RxUnicastFrames
+= 1;
2035 // Calculate the received packet data length
2036 PktLength
-= LAN91X_PKT_OVERHEAD
;
2037 if ((PktStatus
& RX_ODD_FRAME
) != 0) {
2041 // Check buffer size
2042 if (*BuffSize
< PktLength
) {
2043 DEBUG ((DEBUG_WARN
, "LAN91x: Receive buffer too small for packet (%d < %d)\n",
2044 *BuffSize
, PktLength
));
2045 *BuffSize
= PktLength
;
2046 Status
= EFI_BUFFER_TOO_SMALL
;
2050 // Transfer the data bytes
2052 ReadIoData (LanDriver
, DataPtr
, PktLength
& ~0x0001);
2054 // Read the PktControl and Odd Byte from the FIFO
2055 PktControl
= ReadIoReg16 (LanDriver
, LAN91X_DATA0
);
2056 if ((PktControl
& PCW_ODD
) != 0) {
2057 DataPtr
[PktLength
- 1] = PktControl
& PCW_ODD_BYTE
;
2060 // Update buffer size
2061 *BuffSize
= PktLength
;
2063 if (HdrSize
!= NULL
) {
2064 *HdrSize
= LanDriver
->SnpMode
.MediaHeaderSize
;
2067 // Extract the destination address
2068 if (DstAddr
!= NULL
) {
2069 CopyMem (DstAddr
, &DataPtr
[0], NET_ETHER_ADDR_LEN
);
2072 // Get the source address
2073 if (SrcAddr
!= NULL
) {
2074 CopyMem (SrcAddr
, &DataPtr
[6], NET_ETHER_ADDR_LEN
);
2078 if (Protocol
!= NULL
) {
2079 *Protocol
= NTOHS (*(UINT16
*)(&DataPtr
[12]));
2082 // Update the Rx statistics
2083 LanDriver
->Stats
.RxTotalBytes
+= PktLength
;
2084 LanDriver
->Stats
.RxGoodFrames
+= 1;
2085 Status
= EFI_SUCCESS
;
2087 #if LAN91X_PRINT_PACKET_HEADERS
2088 // Dump the packet header
2089 DEBUG ((DEBUG_ERROR
, "LAN91X:SnpReceive()\n"));
2090 DEBUG ((DEBUG_ERROR
, " HdrSize: %p, SrcAddr: %p, DstAddr: %p, Protocol: %p\n",
2091 HdrSize
, SrcAddr
, DstAddr
, Protocol
));
2092 DEBUG ((DEBUG_ERROR
, " Length: %d, Last byte: %02x\n", PktLength
, DataPtr
[PktLength
- 1]));
2093 PrintIpDgram (&DataPtr
[0], &DataPtr
[6], &DataPtr
[12], &DataPtr
[14]);
2096 // Release the FIFO buffer
2098 MmuOperation (LanDriver
, MMUCR_OP_RX_POP_REL
);
2100 // Restore TPL and return
2102 gBS
->RestoreTPL (SavedTpl
);
2107 /*------------------ Driver Execution Environment main entry point ------------------*/
2110 ** Entry point for the LAN91x driver
2115 IN EFI_HANDLE Handle
,
2116 IN EFI_SYSTEM_TABLE
*SystemTable
2120 LAN91X_DRIVER
*LanDriver
;
2121 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
2122 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
2123 LAN91X_DEVICE_PATH
*Lan91xPath
;
2125 // The PcdLan91xDxeBaseAddress PCD must be defined
2126 ASSERT(PcdGet32 (PcdLan91xDxeBaseAddress
) != 0);
2128 // Allocate Resources
2129 LanDriver
= AllocateZeroPool (sizeof(LAN91X_DRIVER
));
2130 Lan91xPath
= AllocateCopyPool (sizeof(LAN91X_DEVICE_PATH
), &Lan91xPathTemplate
);
2132 // Initialize I/O Space access info
2133 LanDriver
->IoBase
= PcdGet32 (PcdLan91xDxeBaseAddress
);
2134 LanDriver
->PhyAd
= LAN91X_NO_PHY
;
2135 LanDriver
->BankSel
= 0xff;
2137 // Initialize pointers
2138 Snp
= &(LanDriver
->Snp
);
2139 SnpMode
= &(LanDriver
->SnpMode
);
2140 Snp
->Mode
= SnpMode
;
2142 // Set the signature of the LAN Driver structure
2143 LanDriver
->Signature
= LAN91X_SIGNATURE
;
2146 Status
= Probe (LanDriver
);
2147 if (EFI_ERROR(Status
)) {
2148 DEBUG ((DEBUG_ERROR
, "LAN91x:Lan91xDxeEntry(): Probe failed with status %d\n", Status
));
2152 #ifdef LAN91X_PRINT_REGISTERS
2153 PrintIoRegisters (LanDriver
);
2154 PrintPhyRegisters (LanDriver
);
2157 // Initialize transmit queue
2158 InitializeListHead (&LanDriver
->TransmitQueueHead
);
2160 // Assign fields and func pointers
2161 Snp
->Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
2162 Snp
->WaitForPacket
= NULL
;
2163 Snp
->Initialize
= SnpInitialize
;
2164 Snp
->Start
= SnpStart
;
2165 Snp
->Stop
= SnpStop
;
2166 Snp
->Reset
= SnpReset
;
2167 Snp
->Shutdown
= SnpShutdown
;
2168 Snp
->ReceiveFilters
= SnpReceiveFilters
;
2169 Snp
->StationAddress
= SnpStationAddress
;
2170 Snp
->Statistics
= SnpStatistics
;
2171 Snp
->MCastIpToMac
= SnpMcastIptoMac
;
2172 Snp
->NvData
= SnpNvData
;
2173 Snp
->GetStatus
= SnpGetStatus
;
2174 Snp
->Transmit
= SnpTransmit
;
2175 Snp
->Receive
= SnpReceive
;
2177 // Fill in simple network mode structure
2178 SnpMode
->State
= EfiSimpleNetworkStopped
;
2179 SnpMode
->HwAddressSize
= NET_ETHER_ADDR_LEN
; // HW address is 6 bytes
2180 SnpMode
->MediaHeaderSize
= sizeof(ETHER_HEAD
); // Size of an Ethernet header
2181 SnpMode
->MaxPacketSize
= EFI_PAGE_SIZE
; // Ethernet Frame (with VLAN tag +4 bytes)
2183 // Supported receive filters
2184 SnpMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
2185 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
|
2186 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
|
2187 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
|
2188 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
2190 // Initially-enabled receive filters
2191 SnpMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
2192 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
|
2193 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
2195 // LAN91x has 64bit hash table. We can filter an infinite MACs, but
2196 // higher-level software must filter out any hash collisions.
2197 SnpMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
2198 SnpMode
->MCastFilterCount
= 0;
2199 ZeroMem (&SnpMode
->MCastFilter
, MAX_MCAST_FILTER_CNT
* sizeof(EFI_MAC_ADDRESS
));
2201 // Set the interface type (1: Ethernet or 6: IEEE 802 Networks)
2202 SnpMode
->IfType
= NET_IFTYPE_ETHERNET
;
2204 // Mac address is changeable
2205 SnpMode
->MacAddressChangeable
= TRUE
;
2207 // We can only transmit one packet at a time
2208 SnpMode
->MultipleTxSupported
= FALSE
;
2210 // MediaPresent checks for cable connection and partner link
2211 SnpMode
->MediaPresentSupported
= TRUE
;
2212 SnpMode
->MediaPresent
= FALSE
;
2214 // Set broadcast address
2215 SetMem (&SnpMode
->BroadcastAddress
, sizeof (EFI_MAC_ADDRESS
), 0xFF);
2217 // Assign fields for device path
2218 Lan91xPath
->Lan91x
.MacAddress
= SnpMode
->PermanentAddress
;
2219 Lan91xPath
->Lan91x
.IfType
= SnpMode
->IfType
;
2221 // Initialise the protocol
2222 Status
= gBS
->InstallMultipleProtocolInterfaces (
2223 &LanDriver
->ControllerHandle
,
2224 &gEfiSimpleNetworkProtocolGuid
, Snp
,
2225 &gEfiDevicePathProtocolGuid
, Lan91xPath
,
2229 // Say what the status of loading the protocol structure is
2230 if (EFI_ERROR(Status
)) {
2231 FreePool (LanDriver
);