Home | History | Annotate | Download | only in Lan91xDxe
      1 /** @file
      2 *  SMSC LAN91x series Network Controller Driver.
      3 *
      4 *  Copyright (c) 2013 Linaro.org
      5 *
      6 *  Derived from the LAN9118 driver. Original sources
      7 *  Copyright (c) 2012-2013, ARM Limited. All rights reserved.
      8 *
      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
     13 *
     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.
     16 *
     17 **/
     18 
     19 #include <Uefi.h>
     20 #include <Uefi/UefiSpec.h>
     21 #include <Base.h>
     22 
     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>
     28 
     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>
     38 
     39 // Hardware register definitions
     40 #include "Lan91xDxeHw.h"
     41 
     42 // Debugging output options
     43 //#define LAN91X_PRINT_REGISTERS 1
     44 //#define LAN91X_PRINT_PACKET_HEADERS 1
     45 //#define LAN91X_PRINT_RECEIVE_FILTERS 1
     46 
     47 // Chip power-down option -- UNTESTED
     48 //#define LAN91X_POWER_DOWN 1
     49 
     50 /*---------------------------------------------------------------------------------------------------------------------
     51 
     52   LAN91x Information Structure
     53 
     54 ---------------------------------------------------------------------------------------------------------------------*/
     55 typedef struct _LAN91X_DRIVER {
     56   // Driver signature
     57   UINT32            Signature;
     58   EFI_HANDLE        ControllerHandle;
     59 
     60   // EFI SNP protocol instances
     61   EFI_SIMPLE_NETWORK_PROTOCOL Snp;
     62   EFI_SIMPLE_NETWORK_MODE SnpMode;
     63 
     64   // EFI Snp statistics instance
     65   EFI_NETWORK_STATISTICS Stats;
     66 
     67   // Transmit Buffer recycle queue
     68 #define TX_QUEUE_DEPTH 16
     69   VOID              *TxQueue[TX_QUEUE_DEPTH];
     70   UINTN             TxQueHead;
     71   UINTN             TxQueTail;
     72 
     73   // Register access variables
     74   UINTN             IoBase;             // I/O Base Address
     75   UINT8             Revision;           // Chip Revision Number
     76   INT8              PhyAd;              // Phy Address
     77   UINT8             BankSel;            // Currently selected register bank
     78 
     79 } LAN91X_DRIVER;
     80 
     81 #define LAN91X_NO_PHY (-1)              // PhyAd value if PHY not detected
     82 
     83 #define LAN91X_SIGNATURE                        SIGNATURE_32('S', 'M', '9', '1')
     84 #define INSTANCE_FROM_SNP_THIS(a)               CR(a, LAN91X_DRIVER, Snp, LAN91X_SIGNATURE)
     85 
     86 #define LAN91X_STALL              2
     87 #define LAN91X_MEMORY_ALLOC_POLLS 100   // Max times to poll for memory allocation
     88 #define LAN91X_PKT_OVERHEAD       6     // Overhead bytes in packet buffer
     89 
     90 // Synchronization TPLs
     91 #define LAN91X_TPL  TPL_CALLBACK
     92 
     93 // Most common CRC32 Polynomial for little endian machines
     94 #define CRC_POLYNOMIAL               0xEDB88320
     95 
     96 
     97 typedef struct {
     98   MAC_ADDR_DEVICE_PATH      Lan91x;
     99   EFI_DEVICE_PATH_PROTOCOL  End;
    100 } LAN91X_DEVICE_PATH;
    101 
    102 LAN91X_DEVICE_PATH Lan91xPathTemplate =  {
    103   {
    104     {
    105       MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP,
    106       { (UINT8) (sizeof(MAC_ADDR_DEVICE_PATH)), (UINT8) ((sizeof(MAC_ADDR_DEVICE_PATH)) >> 8) }
    107     },
    108     { { 0 } },
    109     0
    110   },
    111   {
    112     END_DEVICE_PATH_TYPE,
    113     END_ENTIRE_DEVICE_PATH_SUBTYPE,
    114     { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0 }
    115   }
    116 };
    117 
    118 // Chip ID numbers and name strings
    119 #define CHIP_9192       3
    120 #define CHIP_9194       4
    121 #define CHIP_9195       5
    122 #define CHIP_9196       6
    123 #define CHIP_91100      7
    124 #define CHIP_91100FD    8
    125 #define CHIP_91111FD    9
    126 
    127 STATIC CHAR16 CONST * CONST ChipIds[ 16 ] =  {
    128   NULL, NULL, NULL,
    129   /* 3 */ L"SMC91C90/91C92",
    130   /* 4 */ L"SMC91C94",
    131   /* 5 */ L"SMC91C95",
    132   /* 6 */ L"SMC91C96",
    133   /* 7 */ L"SMC91C100",
    134   /* 8 */ L"SMC91C100FD",
    135   /* 9 */ L"SMC91C11xFD",
    136   NULL, NULL, NULL,
    137   NULL, NULL, NULL
    138 };
    139 
    140 
    141 /* ------------------ TxBuffer Queue functions ------------------- */
    142 
    143 #define TxQueNext(off)  ((((off) + 1) >= TX_QUEUE_DEPTH) ? 0 : ((off) + 1))
    144 
    145 STATIC
    146 BOOLEAN
    147 TxQueInsert (
    148     IN    LAN91X_DRIVER *LanDriver,
    149     IN    VOID          *Buffer
    150     )
    151 {
    152 
    153   if (TxQueNext (LanDriver->TxQueTail) == LanDriver->TxQueHead) {
    154     return FALSE;
    155   }
    156 
    157   LanDriver->TxQueue[LanDriver->TxQueTail] = Buffer;
    158   LanDriver->TxQueTail = TxQueNext (LanDriver->TxQueTail);
    159 
    160   return TRUE;
    161 }
    162 
    163 STATIC
    164 VOID
    165 *TxQueRemove (
    166     IN    LAN91X_DRIVER *LanDriver
    167     )
    168 {
    169   VOID *Buffer;
    170 
    171   if (LanDriver->TxQueTail == LanDriver->TxQueHead) {
    172     return NULL;
    173   }
    174 
    175   Buffer = LanDriver->TxQueue[LanDriver->TxQueHead];
    176   LanDriver->TxQueue[LanDriver->TxQueHead] = NULL;
    177   LanDriver->TxQueHead = TxQueNext (LanDriver->TxQueHead);
    178 
    179   return Buffer;
    180 }
    181 
    182 /* ------------------ MAC Address Hash Calculations ------------------- */
    183 
    184 /*
    185 **  Generate a hash value from a multicast address
    186 **
    187 **  This uses the Ethernet standard CRC32 algorithm
    188 **
    189 **  INFO USED:
    190 **    1: http://en.wikipedia.org/wiki/Cyclic_redundancy_check
    191 **
    192 **    2: http://www.erg.abdn.ac.uk/~gorry/eg3567/dl-pages/crc.html
    193 **
    194 **    3: http://en.wikipedia.org/wiki/Computation_of_CRC
    195 */
    196 STATIC
    197 UINT32
    198 MulticastHash (
    199   IN    EFI_MAC_ADDRESS *Mac,
    200   IN    UINT32 AddrLen
    201   )
    202 {
    203   UINT32 Iter;
    204   UINT32 Remainder;
    205   UINT32 Crc32;
    206   UINT8 *Addr;
    207 
    208   // 0xFFFFFFFF is standard seed for Ethernet
    209   Remainder = 0xFFFFFFFF;
    210 
    211   // Generate the remainder byte-by-byte (LSB first)
    212   Addr = &Mac->Addr[0];
    213   while (AddrLen-- > 0) {
    214     Remainder ^= *Addr++;
    215     for (Iter = 0; Iter < 8; ++Iter) {
    216       // Check if exponent is set
    217       if ((Remainder & 1) != 0) {
    218         Remainder = (Remainder >> 1) ^ CRC_POLYNOMIAL;
    219       } else {
    220         Remainder = (Remainder >> 1) ^ 0;
    221       }
    222     }
    223   }
    224 
    225   // Reverse the bits of the remainder
    226   Crc32 = 0;
    227   for (Iter = 0; Iter < 32; ++Iter) {
    228     Crc32 <<= 1;
    229     Crc32 |= Remainder & 1;
    230     Remainder >>= 1;
    231   }
    232   return Crc32;
    233 }
    234 
    235 
    236 /* ---------------- Banked Register Operations ------------------ */
    237 
    238 // Select the proper I/O bank
    239 STATIC
    240 VOID
    241 SelectIoBank (
    242   LAN91X_DRIVER   *LanDriver,
    243   UINTN            Register
    244   )
    245 {
    246   UINT8   Bank;
    247 
    248   Bank = RegisterToBank (Register);
    249 
    250   // Select the proper I/O bank
    251   if (LanDriver->BankSel != Bank) {
    252     MmioWrite16 (LanDriver->IoBase + LAN91X_BANK_OFFSET, Bank);
    253     LanDriver->BankSel = Bank;
    254   }
    255 }
    256 
    257 // Read a 16-bit I/O-space register
    258 STATIC
    259 UINT16
    260 ReadIoReg16 (
    261   LAN91X_DRIVER   *LanDriver,
    262   UINTN            Register
    263   )
    264 {
    265   UINT8   Offset;
    266 
    267   // Select the proper I/O bank
    268   SelectIoBank (LanDriver, Register);
    269 
    270   // Read the requested register
    271   Offset = RegisterToOffset (Register);
    272   return MmioRead16 (LanDriver->IoBase + Offset);
    273 }
    274 
    275 // Write a 16-bit I/O-space register
    276 STATIC
    277 UINT16
    278 WriteIoReg16 (
    279   LAN91X_DRIVER   *LanDriver,
    280   UINTN            Register,
    281   UINT16           Value
    282   )
    283 {
    284   UINT8   Offset;
    285 
    286   // Select the proper I/O bank
    287   SelectIoBank (LanDriver, Register);
    288 
    289   // Write the requested register
    290   Offset = RegisterToOffset (Register);
    291   return MmioWrite16 (LanDriver->IoBase + Offset, Value);
    292 }
    293 
    294 // Read an 8-bit I/O-space register
    295 STATIC
    296 UINT8
    297 ReadIoReg8 (
    298   LAN91X_DRIVER   *LanDriver,
    299   UINTN            Register
    300   )
    301 {
    302   UINT8   Offset;
    303 
    304   // Select the proper I/O bank
    305   SelectIoBank (LanDriver, Register);
    306 
    307   // Read the requested register
    308   Offset = RegisterToOffset (Register);
    309   return MmioRead8 (LanDriver->IoBase + Offset);
    310 }
    311 
    312 // Write an 8-bit I/O-space register
    313 STATIC
    314 UINT8
    315 WriteIoReg8 (
    316   LAN91X_DRIVER   *LanDriver,
    317   UINTN            Register,
    318   UINT8            Value
    319   )
    320 {
    321   UINT8   Offset;
    322 
    323   // Select the proper I/O bank
    324   SelectIoBank (LanDriver, Register);
    325 
    326   // Write the requested register
    327   Offset = RegisterToOffset (Register);
    328   return MmioWrite8 (LanDriver->IoBase + Offset, Value);
    329 }
    330 
    331 
    332 /* ---------------- MII/PHY Access Operations ------------------ */
    333 
    334 #define LAN91X_MDIO_STALL   1
    335 
    336 STATIC
    337 VOID
    338 MdioOutput (
    339   LAN91X_DRIVER   *LanDriver,
    340   UINTN            Bits,
    341   UINT32           Value
    342   )
    343 {
    344   UINT16          MgmtReg;
    345   UINT32          Mask;
    346 
    347   MgmtReg = ReadIoReg16 (LanDriver, LAN91X_MGMT);
    348   MgmtReg &= ~MGMT_MCLK;
    349   MgmtReg |= MGMT_MDOE;
    350 
    351   for (Mask = (1 << (Bits - 1)); Mask != 0; Mask >>= 1) {
    352     if ((Value & Mask) != 0) {
    353       MgmtReg |= MGMT_MDO;
    354     } else {
    355       MgmtReg &= ~MGMT_MDO;
    356     }
    357 
    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);
    362   }
    363 }
    364 #define PHY_OUTPUT_TIME (2 * LAN91X_MDIO_STALL)
    365 
    366 STATIC
    367 UINT32
    368 MdioInput (
    369   LAN91X_DRIVER   *LanDriver,
    370   UINTN            Bits
    371   )
    372 {
    373   UINT16          MgmtReg;
    374   UINT32          Mask;
    375   UINT32          Value;
    376 
    377   MgmtReg = ReadIoReg16 (LanDriver, LAN91X_MGMT);
    378   MgmtReg &= ~(MGMT_MDOE | MGMT_MCLK | MGMT_MDO);
    379   WriteIoReg16 (LanDriver, LAN91X_MGMT, MgmtReg);
    380 
    381   Value = 0;
    382   for (Mask = (1 << (Bits - 1)); Mask != 0; Mask >>= 1) {
    383     if ((ReadIoReg16 (LanDriver, LAN91X_MGMT) & MGMT_MDI) != 0) {
    384        Value |= Mask;
    385     }
    386 
    387     WriteIoReg16 (LanDriver, LAN91X_MGMT, MgmtReg);
    388     gBS->Stall (LAN91X_MDIO_STALL);
    389     WriteIoReg16 (LanDriver, LAN91X_MGMT, MgmtReg | MGMT_MCLK);
    390     gBS->Stall (LAN91X_MDIO_STALL);
    391   }
    392 
    393   return Value;
    394 }
    395 #define PHY_INPUT_TIME (2 * LAN91X_MDIO_STALL)
    396 
    397 STATIC
    398 VOID
    399 MdioIdle (
    400   LAN91X_DRIVER   *LanDriver
    401   )
    402 {
    403   UINT16          MgmtReg;
    404 
    405   MgmtReg = ReadIoReg16 (LanDriver, LAN91X_MGMT);
    406   MgmtReg &= ~(MGMT_MDOE | MGMT_MCLK | MGMT_MDO);
    407   WriteIoReg16 (LanDriver, LAN91X_MGMT, MgmtReg);
    408 }
    409 
    410 // Write to a PHY register
    411 STATIC
    412 VOID
    413 WritePhyReg16 (
    414   LAN91X_DRIVER   *LanDriver,
    415   UINTN            RegAd,
    416   UINT16           Value
    417   )
    418 {
    419   // Bit-bang the MII Serial Frame write operation
    420   MdioOutput (LanDriver, 32, 0xffffffff);       // Send 32 Ones as a preamble
    421   MdioOutput (LanDriver,  2, 0x01);             // Send Start (01)
    422   MdioOutput (LanDriver,  2, 0x01);             // Send Write (01)
    423   MdioOutput (LanDriver,  5, LanDriver->PhyAd); // Send PHYAD[4:0]
    424   MdioOutput (LanDriver,  5, RegAd);            // Send REGAD[4:0]
    425   MdioOutput (LanDriver,  2, 0x02);             // Send TurnAround (10)
    426   MdioOutput (LanDriver, 16, Value);            // Write 16 data bits
    427 
    428   // Idle the MDIO bus
    429   MdioIdle (LanDriver);
    430 }
    431 // Calculate approximate time to write a PHY register in microseconds
    432 #define PHY_WRITE_TIME  ((32 + 2 + 2 + 5 + 5 + 2 + 16) * PHY_OUTPUT_TIME)
    433 
    434 // Read from a PHY register
    435 STATIC
    436 UINT16
    437 ReadPhyReg16 (
    438   LAN91X_DRIVER   *LanDriver,
    439   UINTN            RegAd
    440   )
    441 {
    442   UINT32 Value;
    443 
    444   // Bit-bang the MII Serial Frame read operation
    445   MdioOutput (LanDriver, 32, 0xffffffff);       // Send 32 Ones as a preamble
    446   MdioOutput (LanDriver,  2, 0x01);             // Send Start (01)
    447   MdioOutput (LanDriver,  2, 0x02);             // Send Read (10)
    448   MdioOutput (LanDriver,  5, LanDriver->PhyAd); // Send PHYAD[4:0]
    449   MdioOutput (LanDriver,  5, RegAd);            // Send REGAD[4:0]
    450 
    451   (VOID)  MdioInput (LanDriver, 2);             // Discard TurnAround bits
    452   Value = MdioInput (LanDriver, 16);            // Read 16 data bits
    453 
    454   // Idle the MDIO bus
    455   MdioIdle (LanDriver);
    456 
    457   return (Value & 0xffff);
    458 }
    459 // Calculate approximate time to read a PHY register in microseconds
    460 #define PHY_READ_TIME  (((32 + 2 + 2 + 5 + 5) * PHY_OUTPUT_TIME) + \
    461                         ((2 + 16) * PHY_INPUT_TIME))
    462 
    463 
    464 /* ---------------- Debug Functions ------------------ */
    465 
    466 #ifdef LAN91X_PRINT_REGISTERS
    467 STATIC
    468 VOID
    469 PrintIoRegisters (
    470   IN  LAN91X_DRIVER   *LanDriver
    471   )
    472 {
    473   UINTN   Bank;
    474   UINTN   Offset;
    475   UINT16  Value;
    476 
    477   DEBUG((EFI_D_ERROR, "\nLAN91x I/O Register Dump:\n"));
    478 
    479   // Print currrent bank select register
    480   Value = MmioRead16 (LanDriver->IoBase + LAN91X_BANK_OFFSET);
    481   DEBUG((EFI_D_ERROR, "  BankSel: %d  Bank Register %04x (%d)\n",
    482       LanDriver->BankSel, Value, Value & 0x0007));
    483 
    484   // Print all I/O registers
    485   for (Offset = 0; Offset < 0x0e; Offset += 2) {
    486     DEBUG((EFI_D_ERROR, "  %02x:", Offset));
    487     for (Bank = 0; Bank <= 3; ++Bank) {
    488       DEBUG((EFI_D_ERROR, "  %04x", ReadIoReg16 (LanDriver, MakeRegister (Bank, Offset))));
    489     }
    490     DEBUG((EFI_D_ERROR, "\n"));
    491   }
    492 }
    493 
    494 STATIC
    495 VOID
    496 PrintPhyRegisters (
    497   IN  LAN91X_DRIVER   *LanDriver
    498   )
    499 {
    500   UINTN   RegNum;
    501 
    502   DEBUG((EFI_D_ERROR, "\nLAN91x Phy %d Register Dump:\n", LanDriver->PhyAd));
    503 
    504   // Print all Phy registers
    505   for (RegNum = 0; RegNum <= 5; ++RegNum) {
    506     DEBUG((EFI_D_ERROR, "  %2d:  %04x\n",
    507            RegNum,
    508            ReadPhyReg16 (LanDriver, RegNum)
    509     ));
    510   }
    511   for (RegNum = 16; RegNum <= 20; ++RegNum) {
    512     DEBUG((EFI_D_ERROR, "  %2d:  %04x\n",
    513            RegNum,
    514            ReadPhyReg16 (LanDriver, RegNum)
    515     ));
    516   }
    517 }
    518 #endif
    519 
    520 #if LAN91X_PRINT_PACKET_HEADERS
    521 STATIC
    522 VOID
    523 PrintIpDgram (
    524   IN  CONST VOID  *DstMac,
    525   IN  CONST VOID  *SrcMac,
    526   IN  CONST VOID  *Proto,
    527   IN  CONST VOID  *IpDgram
    528   )
    529 {
    530   CONST UINT8   *Ptr;
    531   UINT16         SrcPort;
    532   UINT16         DstPort;
    533 
    534   Ptr = DstMac;
    535   DEBUG((EFI_D_ERROR, "  Dst: %02x-%02x-%02x",
    536          Ptr[0], Ptr[1], Ptr[2]));
    537   DEBUG((EFI_D_ERROR, "-%02x-%02x-%02x",
    538          Ptr[3], Ptr[4], Ptr[5]));
    539 
    540   Ptr = SrcMac;
    541   DEBUG((EFI_D_ERROR, "  Src: %02x-%02x-%02x",
    542          Ptr[0], Ptr[1], Ptr[2]));
    543   DEBUG((EFI_D_ERROR, "-%02x-%02x-%02x",
    544          Ptr[3], Ptr[4], Ptr[5]));
    545 
    546   Ptr = Proto;
    547   DEBUG((EFI_D_ERROR, "  Proto: %02x%02x\n",
    548          Ptr[0], Ptr[1]));
    549 
    550   Ptr = IpDgram;
    551   switch (Ptr[9]) {
    552   case EFI_IP_PROTO_ICMP:
    553     DEBUG((EFI_D_ERROR, "  ICMP"));
    554     break;
    555   case EFI_IP_PROTO_TCP:
    556     DEBUG((EFI_D_ERROR, "  TCP"));
    557     break;
    558   case EFI_IP_PROTO_UDP:
    559     DEBUG((EFI_D_ERROR, "  UDP"));
    560     break;
    561   default:
    562     DEBUG((EFI_D_ERROR, "  IpProto %d\n", Ptr[9]));
    563     return;
    564   }
    565 
    566   DEBUG((EFI_D_ERROR, "  SrcIp: %d.%d.%d.%d",
    567          Ptr[12], Ptr[13], Ptr[14], Ptr[15]));
    568   DEBUG((EFI_D_ERROR, "  DstIp: %d.%d.%d.%d",
    569          Ptr[16], Ptr[17], Ptr[18], Ptr[19]));
    570 
    571   SrcPort = (Ptr[20] << 8) | Ptr[21];
    572   DstPort = (Ptr[22] << 8) | Ptr[23];
    573   DEBUG((EFI_D_ERROR, "  SrcPort: %d  DstPort: %d\n", SrcPort, DstPort));
    574 }
    575 #endif
    576 
    577 
    578 /* ---------------- PHY Management Operations ----------------- */
    579 
    580 STATIC
    581 EFI_STATUS
    582 PhyDetect (
    583   IN  LAN91X_DRIVER *LanDriver
    584   )
    585 {
    586   UINT16  PhyId1;
    587   UINT16  PhyId2;
    588 
    589   for (LanDriver->PhyAd = 0x1f; LanDriver->PhyAd >= 0 ; --LanDriver->PhyAd) {
    590     PhyId1 = ReadPhyReg16 (LanDriver, PHY_INDEX_ID1);
    591     PhyId2 = ReadPhyReg16 (LanDriver, PHY_INDEX_ID2);
    592 
    593     if ((PhyId1 != 0x0000) && (PhyId1 != 0xffff) &&
    594         (PhyId2 != 0x0000) && (PhyId2 != 0xffff)) {
    595       if ((PhyId1 == 0x0016) && ((PhyId2 & 0xfff0) == 0xf840)) {
    596         DEBUG((EFI_D_ERROR, "LAN91x: PHY type LAN83C183 (LAN91C111 Internal)\n"));
    597       } else if ((PhyId1 == 0x0282) && ((PhyId2 & 0xfff0) == 0x1c50)) {
    598         DEBUG((EFI_D_ERROR, "LAN91x: PHY type LAN83C180\n"));
    599       } else {
    600         DEBUG((EFI_D_ERROR, "LAN91x: PHY id %04x:%04x\n", PhyId1, PhyId2));
    601       }
    602       return EFI_SUCCESS;
    603     }
    604   }
    605 
    606   DEBUG((EFI_D_ERROR, "LAN91x: PHY detection failed\n"));
    607   return EFI_NO_MEDIA;
    608 }
    609 
    610 
    611 // Check the Link Status and take appropriate action
    612 STATIC
    613 BOOLEAN
    614 CheckLinkStatus (
    615   IN  LAN91X_DRIVER *LanDriver
    616   )
    617 {
    618   UINT16  PhyStatus;
    619 
    620   // Get the PHY Status
    621   PhyStatus = ReadPhyReg16 (LanDriver, PHY_INDEX_BASIC_STATUS);
    622 
    623   return (PhyStatus & PHYSTS_LINK_STS) != 0;
    624 }
    625 
    626 
    627 // Do auto-negotiation
    628 STATIC
    629 EFI_STATUS
    630 PhyAutoNegotiate (
    631   IN  LAN91X_DRIVER *LanDriver
    632   )
    633 {
    634   UINTN  Retries;
    635   UINT16 PhyControl;
    636   UINT16 PhyStatus;
    637   UINT16 PhyAdvert;
    638 
    639   // If there isn't a PHY, don't try to reset it
    640   if (LanDriver->PhyAd == LAN91X_NO_PHY) {
    641     return EFI_SUCCESS;
    642   }
    643 
    644   // Next check that auto-negotiation is supported
    645   PhyStatus = ReadPhyReg16 (LanDriver, PHY_INDEX_BASIC_STATUS);
    646   if ((PhyStatus & PHYSTS_AUTO_CAP) == 0) {
    647     return EFI_SUCCESS;
    648   }
    649 
    650   // Translate capabilities to advertise
    651   PhyAdvert = PHYANA_CSMA;
    652 
    653   if ((PhyStatus & PHYSTS_10BASET_HDPLX) != 0) {
    654     PhyAdvert |= PHYANA_10BASET;
    655   }
    656   if ((PhyStatus & PHYSTS_10BASET_FDPLX) != 0) {
    657     PhyAdvert |= PHYANA_10BASETFD;
    658   }
    659   if ((PhyStatus & PHYSTS_100BASETX_HDPLX) != 0) {
    660     PhyAdvert |= PHYANA_100BASETX;
    661   }
    662   if ((PhyStatus & PHYSTS_100BASETX_FDPLX) != 0) {
    663     PhyAdvert |= PHYANA_100BASETXFD;
    664   }
    665   if ((PhyStatus & PHYSTS_100BASE_T4) != 0) {
    666     PhyAdvert |= PHYANA_100BASET4;
    667   }
    668 
    669   // Set the capabilities to advertise
    670   WritePhyReg16 (LanDriver, PHY_INDEX_AUTO_NEG_ADVERT, PhyAdvert);
    671   (VOID) ReadPhyReg16 (LanDriver, PHY_INDEX_AUTO_NEG_ADVERT);
    672 
    673   // Restart Auto-Negotiation
    674   PhyControl = ReadPhyReg16 (LanDriver, PHY_INDEX_BASIC_CTRL);
    675   PhyControl &= ~(PHYCR_SPEED_SEL | PHYCR_DUPLEX_MODE);
    676   PhyControl |= PHYCR_AUTO_EN | PHYCR_RST_AUTO;
    677   WritePhyReg16 (LanDriver, PHY_INDEX_BASIC_CTRL, PhyControl);
    678 
    679   // Wait up to 2 seconds for the process to complete
    680   Retries = 2000000 / (PHY_READ_TIME + 100);
    681   while ((ReadPhyReg16 (LanDriver, PHY_INDEX_BASIC_STATUS) & PHYSTS_AUTO_COMP) == 0) {
    682     if (--Retries == 0) {
    683       DEBUG((EFI_D_ERROR, "LAN91x: PHY auto-negotiation timed-out\n"));
    684       return EFI_TIMEOUT;
    685     }
    686     gBS->Stall (100);
    687   }
    688 
    689   return EFI_SUCCESS;
    690 }
    691 
    692 
    693 // Perform PHY software reset
    694 STATIC
    695 EFI_STATUS
    696 PhySoftReset (
    697   IN  LAN91X_DRIVER *LanDriver
    698   )
    699 {
    700   UINTN     Retries;
    701 
    702   // If there isn't a PHY, don't try to reset it
    703   if (LanDriver->PhyAd == LAN91X_NO_PHY) {
    704     return EFI_SUCCESS;
    705   }
    706 
    707   // Request a PHY reset
    708   WritePhyReg16 (LanDriver, PHY_INDEX_BASIC_CTRL, PHYCR_RESET);
    709 
    710   // The internal PHY will reset within 50ms. Allow 100ms.
    711   Retries = 100000 / (PHY_READ_TIME + 100);
    712   while (ReadPhyReg16 (LanDriver, PHY_INDEX_BASIC_CTRL) & PHYCR_RESET) {
    713     if (--Retries == 0) {
    714       DEBUG((EFI_D_ERROR, "LAN91x: PHY reset timed-out\n"));
    715       return EFI_TIMEOUT;
    716     }
    717     gBS->Stall (100);
    718   }
    719 
    720   return EFI_SUCCESS;
    721 }
    722 
    723 
    724 /* ---------------- General Operations ----------------- */
    725 
    726 STATIC
    727 EFI_MAC_ADDRESS
    728 GetCurrentMacAddress (
    729   IN  LAN91X_DRIVER *LanDriver
    730   )
    731 {
    732   UINTN            RegNum;
    733   UINT8           *Addr;
    734   EFI_MAC_ADDRESS  MacAddress;
    735 
    736   SetMem (&MacAddress, sizeof(MacAddress), 0);
    737 
    738   Addr = &MacAddress.Addr[0];
    739   for (RegNum = LAN91X_IAR0; RegNum <= LAN91X_IAR5; ++RegNum) {
    740     *Addr = ReadIoReg8 (LanDriver, RegNum);
    741     ++Addr;
    742   }
    743 
    744   return MacAddress;
    745 }
    746 
    747 STATIC
    748 EFI_STATUS
    749 SetCurrentMacAddress (
    750   IN  LAN91X_DRIVER   *LanDriver,
    751   IN  EFI_MAC_ADDRESS *MacAddress
    752   )
    753 {
    754   UINTN            RegNum;
    755   UINT8           *Addr;
    756 
    757   Addr = &MacAddress->Addr[0];
    758   for (RegNum = LAN91X_IAR0; RegNum <= LAN91X_IAR5; ++RegNum) {
    759     WriteIoReg8 (LanDriver, RegNum, *Addr);
    760     ++Addr;
    761   }
    762 
    763   return EFI_SUCCESS;
    764 }
    765 
    766 STATIC
    767 EFI_STATUS
    768 MmuOperation (
    769   IN  LAN91X_DRIVER *LanDriver,
    770   IN  UINTN          MmuOp
    771   )
    772 {
    773   UINTN   Polls;
    774 
    775   WriteIoReg16 (LanDriver, LAN91X_MMUCR, MmuOp);
    776   Polls = 100;
    777   while ((ReadIoReg16 (LanDriver, LAN91X_MMUCR) & MMUCR_BUSY) != 0) {
    778     if (--Polls == 0) {
    779       DEBUG((EFI_D_ERROR, "LAN91x: MMU operation %04x timed-out\n", MmuOp));
    780       return EFI_TIMEOUT;
    781     }
    782     gBS->Stall (LAN91X_STALL);
    783   }
    784 
    785   return EFI_SUCCESS;
    786 }
    787 
    788 // Read bytes from the DATA register
    789 STATIC
    790 EFI_STATUS
    791 ReadIoData (
    792   IN  LAN91X_DRIVER *LanDriver,
    793   IN  VOID          *Buffer,
    794   IN  UINTN          BufLen
    795   )
    796 {
    797   UINT8     *Ptr;
    798 
    799   Ptr = Buffer;
    800   for (; BufLen > 0; --BufLen) {
    801     *Ptr = ReadIoReg8 (LanDriver, LAN91X_DATA0);
    802     ++Ptr;
    803   }
    804 
    805   return EFI_SUCCESS;
    806 }
    807 
    808 // Write bytes to the DATA register
    809 STATIC
    810 EFI_STATUS
    811 WriteIoData (
    812   IN  LAN91X_DRIVER *LanDriver,
    813   IN  VOID          *Buffer,
    814   IN  UINTN          BufLen
    815   )
    816 {
    817   UINT8     *Ptr;
    818 
    819   Ptr = Buffer;
    820   for (; BufLen > 0; --BufLen) {
    821     WriteIoReg8 (LanDriver, LAN91X_DATA0, *Ptr);
    822     ++Ptr;
    823   }
    824 
    825   return EFI_SUCCESS;
    826 }
    827 
    828 // Disable the interface
    829 STATIC
    830 EFI_STATUS
    831 ChipDisable (
    832   IN  LAN91X_DRIVER *LanDriver
    833   )
    834 {
    835 #ifdef LAN91X_POWER_DOWN
    836   UINT16  Val16;
    837 #endif
    838 
    839   // Stop Rx and Tx operations
    840   WriteIoReg16 (LanDriver, LAN91X_RCR, RCR_CLEAR);
    841   WriteIoReg16 (LanDriver, LAN91X_TCR, TCR_CLEAR);
    842 
    843 #ifdef LAN91X_POWER_DOWN
    844   // Power-down the chip
    845   Val16 = ReadIoReg16 (LanDriver, LAN91X_CR);
    846   Val16 &= ~CR_EPH_POWER_EN;
    847   WriteIoReg16 (LanDriver, LAN91X_CR, Val16);
    848 #endif
    849 
    850   return EFI_SUCCESS;
    851 }
    852 
    853 // Enable the interface
    854 STATIC
    855 EFI_STATUS
    856 ChipEnable (
    857   IN  LAN91X_DRIVER *LanDriver
    858   )
    859 {
    860 #ifdef LAN91X_POWER_DOWN
    861   UINT16  Val16;
    862 
    863   // Power-up the chip
    864   Val16 = ReadIoReg16 (LanDriver, LAN91X_CR);
    865   Val16 |= CR_EPH_POWER_EN;
    866   WriteIoReg16 (LanDriver, LAN91X_CR, Val16);
    867   gBS->Stall (LAN91X_STALL);
    868 #endif
    869 
    870   // Start Rx and Tx operations
    871   WriteIoReg16 (LanDriver, LAN91X_TCR, TCR_DEFAULT);
    872   WriteIoReg16 (LanDriver, LAN91X_RCR, RCR_DEFAULT);
    873 
    874   return EFI_SUCCESS;
    875 }
    876 
    877 
    878 // Perform software reset on the LAN91x
    879 STATIC
    880 EFI_STATUS
    881 SoftReset (
    882   IN  LAN91X_DRIVER   *LanDriver
    883   )
    884 {
    885   UINT16  Val16;
    886 
    887   // Issue the reset
    888   WriteIoReg16 (LanDriver, LAN91X_RCR, RCR_SOFT_RST);
    889   gBS->Stall (LAN91X_STALL);
    890   WriteIoReg16 (LanDriver, LAN91X_RCR, RCR_CLEAR);
    891 
    892   // Set the configuration register
    893   WriteIoReg16 (LanDriver, LAN91X_CR, CR_DEFAULT);
    894   gBS->Stall (LAN91X_STALL);
    895 
    896   // Stop Rx and Tx
    897   WriteIoReg16 (LanDriver, LAN91X_RCR, RCR_CLEAR);
    898   WriteIoReg16 (LanDriver, LAN91X_TCR, TCR_CLEAR);
    899 
    900   // Initialize the Control Register
    901   Val16 = ReadIoReg16 (LanDriver, LAN91X_CTR);
    902   Val16 |= CTR_AUTO_REL;
    903   WriteIoReg16 (LanDriver, LAN91X_CTR, Val16);
    904 
    905   // Reset the MMU
    906   MmuOperation (LanDriver, MMUCR_OP_RESET_MMU);
    907 
    908   return EFI_SUCCESS;
    909 }
    910 
    911 /*
    912 **  Probe()
    913 **
    914 **  Validate that there is a LAN91x device.
    915 **
    916 */
    917 STATIC
    918 EFI_STATUS
    919 Probe (
    920   IN  LAN91X_DRIVER   *LanDriver
    921   )
    922 {
    923   UINT16        Bank;
    924   UINT16        Val16;
    925   CHAR16 CONST *ChipId;
    926   UINTN         ResetTime;
    927 
    928   // First check that the Bank Select register is valid
    929   Bank = MmioRead16 (LanDriver->IoBase + LAN91X_BANK_OFFSET);
    930   if ((Bank & 0xff00) != 0x3300) {
    931     DEBUG((EFI_D_ERROR, "LAN91x: signature error: expecting 33xx, read %04x\n", Bank));
    932     return EFI_DEVICE_ERROR;
    933   }
    934 
    935   // Try reading the revision register next
    936   LanDriver->BankSel = 0xff;
    937   Val16 = ReadIoReg16 (LanDriver, LAN91X_REV);
    938 
    939   Bank = MmioRead16 (LanDriver->IoBase + LAN91X_BANK_OFFSET);
    940   if ((Bank & 0xff03) != 0x3303) {
    941     DEBUG((EFI_D_ERROR, "LAN91x: signature error: expecting 33x3, read %04x\n", Bank));
    942     return EFI_DEVICE_ERROR;
    943   }
    944 
    945   // Validate the revision register
    946   if ((Val16 & 0xff00) != 0x3300) {
    947     DEBUG((EFI_D_ERROR, "LAN91x: revision error: expecting 33xx, read %04x\n", Val16));
    948     return EFI_DEVICE_ERROR;
    949   }
    950 
    951   ChipId = ChipIds[(Val16 >> 4) & 0x0f];
    952   if (ChipId == NULL) {
    953     DEBUG((EFI_D_ERROR, "LAN91x: unrecognized revision: %04x\n", Val16));
    954     return EFI_DEVICE_ERROR;
    955   }
    956   DEBUG((EFI_D_ERROR, "LAN91x: detected chip %s rev %d\n", ChipId, Val16 & 0xf));
    957   LanDriver->Revision = Val16 & 0xff;
    958 
    959   // Reload from EEPROM to get the hardware MAC address
    960   WriteIoReg16 (LanDriver, LAN91X_CTR, CTR_RESERVED | CTR_RELOAD);
    961   ResetTime = 1000;
    962   while ((ReadIoReg16 (LanDriver, LAN91X_CTR) & CTR_RELOAD) != 0) {
    963     if (--ResetTime == 0) {
    964       DEBUG((EFI_D_ERROR, "LAN91x: reload from EEPROM timed-out\n"));
    965       WriteIoReg16 (LanDriver, LAN91X_CTR, CTR_RESERVED);
    966       return EFI_DEVICE_ERROR;
    967     }
    968     gBS->Stall (LAN91X_STALL);
    969   }
    970 
    971   // Read and save the Permanent MAC Address
    972   LanDriver->SnpMode.PermanentAddress = GetCurrentMacAddress (LanDriver);
    973   LanDriver->SnpMode.CurrentAddress = LanDriver->SnpMode.PermanentAddress;
    974   DEBUG((EFI_D_ERROR, //EFI_D_NET | EFI_D_INFO,
    975          "LAN91x: HW MAC Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
    976          LanDriver->SnpMode.PermanentAddress.Addr[0],
    977          LanDriver->SnpMode.PermanentAddress.Addr[1],
    978          LanDriver->SnpMode.PermanentAddress.Addr[2],
    979          LanDriver->SnpMode.PermanentAddress.Addr[3],
    980          LanDriver->SnpMode.PermanentAddress.Addr[4],
    981          LanDriver->SnpMode.PermanentAddress.Addr[5]
    982          ));
    983 
    984   // Reset the device
    985   SoftReset (LanDriver);
    986 
    987   // Try to detect a PHY
    988   if (LanDriver->Revision > (CHIP_91100 << 4)) {
    989     PhyDetect (LanDriver);
    990   } else {
    991     LanDriver->PhyAd = LAN91X_NO_PHY;
    992   }
    993 
    994   return EFI_SUCCESS;
    995 }
    996 
    997 
    998 
    999 
   1000 /*------------------ Simple Network Driver entry point functions ------------------*/
   1001 
   1002 // Refer to the Simple Network Protocol section (21.1)
   1003 // in the UEFI 2.3.1 Specification for documentation.
   1004 
   1005 #define ReturnUnlock(s) do { Status = (s); goto exit_unlock; } while(0)
   1006 
   1007 
   1008 /*
   1009 **  UEFI Start() function
   1010 **
   1011 */
   1012 EFI_STATUS
   1013 EFIAPI
   1014 SnpStart (
   1015   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp
   1016  )
   1017 {
   1018   EFI_SIMPLE_NETWORK_MODE *Mode;
   1019   EFI_TPL                  SavedTpl;
   1020   EFI_STATUS               Status;
   1021 
   1022   // Check Snp instance
   1023   if (Snp == NULL) {
   1024     return EFI_INVALID_PARAMETER;
   1025   }
   1026 
   1027   // Serialize access to data and registers
   1028   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1029   Mode = Snp->Mode;
   1030 
   1031   // Check state of the driver
   1032   switch (Mode->State) {
   1033   case EfiSimpleNetworkStopped:
   1034     break;
   1035   case EfiSimpleNetworkStarted:
   1036   case EfiSimpleNetworkInitialized:
   1037     DEBUG((EFI_D_WARN, "LAN91x: Driver already started\n"));
   1038     ReturnUnlock (EFI_ALREADY_STARTED);
   1039   default:
   1040     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1041           (UINTN)Snp->Mode->State));
   1042     ReturnUnlock (EFI_DEVICE_ERROR);
   1043   }
   1044 
   1045 
   1046   // Change state
   1047   Mode->State = EfiSimpleNetworkStarted;
   1048   Status = EFI_SUCCESS;
   1049 
   1050   // Restore TPL and return
   1051 exit_unlock:
   1052   gBS->RestoreTPL (SavedTpl);
   1053   return Status;
   1054 }
   1055 
   1056 /*
   1057 **  UEFI Stop() function
   1058 **
   1059 */
   1060 EFI_STATUS
   1061 EFIAPI
   1062 SnpStop (
   1063   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp
   1064   )
   1065 {
   1066   LAN91X_DRIVER *LanDriver;
   1067   EFI_TPL        SavedTpl;
   1068   EFI_STATUS     Status;
   1069 
   1070   // Check Snp Instance
   1071   if (Snp == NULL) {
   1072     return EFI_INVALID_PARAMETER;
   1073   }
   1074 
   1075   // Serialize access to data and registers
   1076   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1077 
   1078   // Check state of the driver
   1079   switch (Snp->Mode->State) {
   1080   case EfiSimpleNetworkStarted:
   1081   case EfiSimpleNetworkInitialized:
   1082     break;
   1083   case EfiSimpleNetworkStopped:
   1084     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1085     ReturnUnlock (EFI_NOT_STARTED);
   1086   default:
   1087     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1088           (UINTN)Snp->Mode->State));
   1089     ReturnUnlock (EFI_DEVICE_ERROR);
   1090   }
   1091 
   1092   // Find the LanDriver structure
   1093   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1094 
   1095   // Stop the Tx and Rx
   1096   ChipDisable (LanDriver);
   1097 
   1098   // Change the state
   1099   Snp->Mode->State = EfiSimpleNetworkStopped;
   1100   Status = EFI_SUCCESS;
   1101 
   1102   // Restore TPL and return
   1103 exit_unlock:
   1104   gBS->RestoreTPL (SavedTpl);
   1105   return Status;
   1106 }
   1107 
   1108 /*
   1109 **  UEFI Initialize() function
   1110 **
   1111 */
   1112 EFI_STATUS
   1113 EFIAPI
   1114 SnpInitialize (
   1115   IN  EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
   1116   IN  UINTN                        RxBufferSize    OPTIONAL,
   1117   IN  UINTN                        TxBufferSize    OPTIONAL
   1118   )
   1119 {
   1120   LAN91X_DRIVER *LanDriver;
   1121   EFI_TPL        SavedTpl;
   1122   EFI_STATUS     Status;
   1123 
   1124   // Check Snp Instance
   1125   if (Snp == NULL) {
   1126     return EFI_INVALID_PARAMETER;
   1127   }
   1128 
   1129   // Serialize access to data and registers
   1130   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1131 
   1132   // Check that driver was started but not initialised
   1133   switch (Snp->Mode->State) {
   1134   case EfiSimpleNetworkStarted:
   1135     break;
   1136   case EfiSimpleNetworkInitialized:
   1137     DEBUG((EFI_D_WARN, "LAN91x: Driver already initialized\n"));
   1138     ReturnUnlock (EFI_SUCCESS);
   1139   case EfiSimpleNetworkStopped:
   1140     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1141     ReturnUnlock (EFI_NOT_STARTED);
   1142   default:
   1143     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1144           (UINTN)Snp->Mode->State));
   1145     ReturnUnlock (EFI_DEVICE_ERROR);
   1146   }
   1147 
   1148   // Find the LanDriver structure
   1149   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1150 
   1151   // Initiate a software reset
   1152   Status = SoftReset (LanDriver);
   1153   if (EFI_ERROR(Status)) {
   1154     DEBUG((EFI_D_WARN, "LAN91x: Soft reset failed\n"));
   1155     ReturnUnlock (EFI_DEVICE_ERROR);
   1156   }
   1157 
   1158   // Initiate a PHY reset
   1159   if (PhySoftReset (LanDriver) < 0) {
   1160     Snp->Mode->State = EfiSimpleNetworkStopped;
   1161     DEBUG((EFI_D_WARN, "LAN91x: PHY soft reset timeout\n"));
   1162     ReturnUnlock (EFI_NOT_STARTED);
   1163   }
   1164 
   1165   // Do auto-negotiation
   1166   Status = PhyAutoNegotiate (LanDriver);
   1167   if (EFI_ERROR(Status)) {
   1168     DEBUG((EFI_D_WARN, "LAN91x: PHY auto-negotiation failed\n"));
   1169   }
   1170 
   1171   // Enable the receiver and transmitter
   1172   ChipEnable (LanDriver);
   1173 
   1174   // Now acknowledge all interrupts
   1175   WriteIoReg8 (LanDriver, LAN91X_IST, 0xFF);
   1176 
   1177   // Declare the driver as initialized
   1178   Snp->Mode->State = EfiSimpleNetworkInitialized;
   1179   Status = EFI_SUCCESS;
   1180 
   1181   // Restore TPL and return
   1182 exit_unlock:
   1183   gBS->RestoreTPL (SavedTpl);
   1184   return Status;
   1185 }
   1186 
   1187 /*
   1188 **  UEFI Reset () function
   1189 **
   1190 */
   1191 EFI_STATUS
   1192 EFIAPI
   1193 SnpReset (
   1194   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
   1195   IN        BOOLEAN Verification
   1196   )
   1197 {
   1198   LAN91X_DRIVER *LanDriver;
   1199   EFI_TPL        SavedTpl;
   1200   EFI_STATUS     Status;
   1201 
   1202   // Check Snp Instance
   1203   if (Snp == NULL) {
   1204     return EFI_INVALID_PARAMETER;
   1205   }
   1206 
   1207   // Serialize access to data and registers
   1208   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1209 
   1210   // Check that driver was started and initialised
   1211   switch (Snp->Mode->State) {
   1212   case EfiSimpleNetworkInitialized:
   1213     break;
   1214   case EfiSimpleNetworkStarted:
   1215     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1216     ReturnUnlock (EFI_DEVICE_ERROR);
   1217   case EfiSimpleNetworkStopped:
   1218     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1219     ReturnUnlock (EFI_NOT_STARTED);
   1220   default:
   1221     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1222           (UINTN)Snp->Mode->State));
   1223     ReturnUnlock (EFI_DEVICE_ERROR);
   1224   }
   1225 
   1226   // Find the LanDriver structure
   1227   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1228 
   1229   // Initiate a software reset
   1230   if (EFI_ERROR (SoftReset (LanDriver))) {
   1231     DEBUG((EFI_D_WARN, "LAN91x: Soft reset failed\n"));
   1232     ReturnUnlock (EFI_DEVICE_ERROR);
   1233   }
   1234 
   1235   // Initiate a PHY reset
   1236   if (EFI_ERROR (PhySoftReset (LanDriver))) {
   1237     DEBUG((EFI_D_WARN, "LAN91x: PHY soft reset failed\n"));
   1238     ReturnUnlock (EFI_DEVICE_ERROR);
   1239   }
   1240 
   1241   // Enable the receiver and transmitter
   1242   Status = ChipEnable (LanDriver);
   1243 
   1244   // Restore TPL and return
   1245 exit_unlock:
   1246   gBS->RestoreTPL (SavedTpl);
   1247   return Status;
   1248 }
   1249 
   1250 /*
   1251 **  UEFI Shutdown () function
   1252 **
   1253 */
   1254 EFI_STATUS
   1255 EFIAPI
   1256 SnpShutdown (
   1257   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp
   1258   )
   1259 {
   1260   LAN91X_DRIVER *LanDriver;
   1261   EFI_TPL        SavedTpl;
   1262   EFI_STATUS     Status;
   1263 
   1264   // Check Snp Instance
   1265   if (Snp == NULL) {
   1266     return EFI_INVALID_PARAMETER;
   1267   }
   1268 
   1269   // Serialize access to data and registers
   1270   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1271 
   1272   // First check that driver has already been initialized
   1273   switch (Snp->Mode->State) {
   1274   case EfiSimpleNetworkInitialized:
   1275     break;
   1276   case EfiSimpleNetworkStarted:
   1277     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1278     ReturnUnlock (EFI_DEVICE_ERROR);
   1279   case EfiSimpleNetworkStopped:
   1280     DEBUG((EFI_D_WARN, "LAN91x: Driver in stopped state\n"));
   1281     ReturnUnlock (EFI_NOT_STARTED);
   1282   default:
   1283     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1284           (UINTN)Snp->Mode->State));
   1285     ReturnUnlock (EFI_DEVICE_ERROR);
   1286   }
   1287 
   1288   // Find the LanDriver structure
   1289   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1290 
   1291   // Disable the interface
   1292   Status = ChipDisable (LanDriver);
   1293 
   1294   // Restore TPL and return
   1295 exit_unlock:
   1296   gBS->RestoreTPL (SavedTpl);
   1297   return Status;
   1298 }
   1299 
   1300 
   1301 /*
   1302 **  UEFI ReceiveFilters() function
   1303 **
   1304 */
   1305 EFI_STATUS
   1306 EFIAPI
   1307 SnpReceiveFilters (
   1308   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
   1309   IN        UINT32 Enable,
   1310   IN        UINT32 Disable,
   1311   IN        BOOLEAN Reset,
   1312   IN        UINTN NumMfilter          OPTIONAL,
   1313   IN        EFI_MAC_ADDRESS *Mfilter  OPTIONAL
   1314   )
   1315 {
   1316 #define MCAST_HASH_BYTES  8
   1317 
   1318   LAN91X_DRIVER           *LanDriver;
   1319   EFI_SIMPLE_NETWORK_MODE *SnpMode;
   1320   EFI_TPL        SavedTpl;
   1321   EFI_STATUS     Status;
   1322   UINTN          i;
   1323   UINT32         Crc;
   1324   UINT16         RcvCtrl;
   1325   UINT8          McastHash[MCAST_HASH_BYTES];
   1326 
   1327   // Check Snp Instance
   1328   if (Snp == NULL) {
   1329     return EFI_INVALID_PARAMETER;
   1330   }
   1331 
   1332   // Serialize access to data and registers
   1333   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1334 
   1335   // First check that driver has already been initialized
   1336   switch (Snp->Mode->State) {
   1337   case EfiSimpleNetworkInitialized:
   1338     break;
   1339   case EfiSimpleNetworkStarted:
   1340     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1341     ReturnUnlock (EFI_DEVICE_ERROR);
   1342   case EfiSimpleNetworkStopped:
   1343     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1344     ReturnUnlock (EFI_NOT_STARTED);
   1345   default:
   1346     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1347           (UINTN)Snp->Mode->State));
   1348     ReturnUnlock (EFI_DEVICE_ERROR);
   1349   }
   1350 
   1351   // Find the LanDriver structure
   1352   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1353   SnpMode = Snp->Mode;
   1354 
   1355 #ifdef LAN91X_PRINT_RECEIVE_FILTERS
   1356   DEBUG((EFI_D_ERROR, "LAN91x:SnpReceiveFilters()\n"));
   1357   DEBUG((EFI_D_ERROR, "  Enable     = %08x\n", Enable));
   1358   DEBUG((EFI_D_ERROR, "  Disable    = %08x\n", Disable));
   1359   DEBUG((EFI_D_ERROR, "  Reset      = %d\n",  Reset));
   1360   DEBUG((EFI_D_ERROR, "  NumMfilter = %d\n",  NumMfilter));
   1361   for (i = 0; i < NumMfilter; ++i) {
   1362     DEBUG((EFI_D_ERROR,
   1363            "    [%2d] = %02x-%02x-%02x-%02x-%02x-%02x\n",
   1364            i,
   1365            Mfilter[i].Addr[0],
   1366            Mfilter[i].Addr[1],
   1367            Mfilter[i].Addr[2],
   1368            Mfilter[i].Addr[3],
   1369            Mfilter[i].Addr[4],
   1370            Mfilter[i].Addr[5]));
   1371   }
   1372 #endif
   1373 
   1374   // Update the Multicast Hash registers
   1375   if (Reset) {
   1376     // Clear the hash table
   1377     SetMem (McastHash, MCAST_HASH_BYTES, 0);
   1378     SnpMode->MCastFilterCount = 0;
   1379   } else {
   1380     // Read the current hash table
   1381     for (i = 0; i < MCAST_HASH_BYTES; ++i) {
   1382       McastHash[i] = ReadIoReg8 (LanDriver, LAN91X_MT0 + i);
   1383     }
   1384     // Set the new additions
   1385     for (i = 0; i < NumMfilter; ++i) {
   1386       Crc = MulticastHash (&Mfilter[i], NET_ETHER_ADDR_LEN);
   1387       McastHash[(Crc >> 29) & 0x3] |= 1 << ((Crc >> 26) & 0x3);
   1388     }
   1389     SnpMode->MCastFilterCount = NumMfilter;
   1390   }
   1391   // If the hash registers need updating, write them
   1392   if (Reset || NumMfilter > 0) {
   1393     for (i = 0; i < MCAST_HASH_BYTES; ++i) {
   1394       WriteIoReg8 (LanDriver, LAN91X_MT0 + i, McastHash[i]);
   1395     }
   1396   }
   1397 
   1398   RcvCtrl = ReadIoReg16 (LanDriver, LAN91X_RCR);
   1399   if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
   1400     RcvCtrl |= RCR_PRMS;
   1401     SnpMode->ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
   1402   }
   1403   if ((Disable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
   1404     RcvCtrl &= ~RCR_PRMS;
   1405     SnpMode->ReceiveFilterSetting &= ~EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
   1406   }
   1407 
   1408   if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
   1409     RcvCtrl |= RCR_ALMUL;
   1410     SnpMode->ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
   1411   }
   1412   if ((Disable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
   1413     RcvCtrl &= ~RCR_ALMUL;
   1414     SnpMode->ReceiveFilterSetting &= ~EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
   1415   }
   1416   WriteIoReg16 (LanDriver, LAN91X_RCR, RcvCtrl);
   1417 
   1418   Status = SetCurrentMacAddress (LanDriver, &SnpMode->CurrentAddress);
   1419 
   1420   // Restore TPL and return
   1421 exit_unlock:
   1422   gBS->RestoreTPL (SavedTpl);
   1423   return Status;
   1424 }
   1425 
   1426 /*
   1427 **  UEFI StationAddress() function
   1428 **
   1429 */
   1430 EFI_STATUS
   1431 EFIAPI
   1432 SnpStationAddress (
   1433   IN        EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
   1434   IN        BOOLEAN Reset,
   1435   IN        EFI_MAC_ADDRESS *NewMac
   1436 )
   1437 {
   1438   LAN91X_DRIVER *LanDriver;
   1439   EFI_TPL        SavedTpl;
   1440   EFI_STATUS     Status;
   1441 
   1442   // Check Snp instance
   1443   if (Snp == NULL) {
   1444     return EFI_INVALID_PARAMETER;
   1445   }
   1446 
   1447   // Serialize access to data and registers
   1448   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1449 
   1450   // Check that driver was started and initialised
   1451   switch (Snp->Mode->State) {
   1452   case EfiSimpleNetworkInitialized:
   1453     break;
   1454   case EfiSimpleNetworkStarted:
   1455     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1456     ReturnUnlock (EFI_DEVICE_ERROR);
   1457   case EfiSimpleNetworkStopped:
   1458     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1459     ReturnUnlock (EFI_NOT_STARTED);
   1460   default:
   1461     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1462           (UINTN)Snp->Mode->State));
   1463     ReturnUnlock (EFI_DEVICE_ERROR);
   1464   }
   1465 
   1466   // Find the LanDriver structure
   1467   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1468 
   1469   if (Reset) {
   1470     Snp->Mode->CurrentAddress = Snp->Mode->PermanentAddress;
   1471   } else {
   1472     if (NewMac == NULL) {
   1473       ReturnUnlock (EFI_INVALID_PARAMETER);
   1474     }
   1475     Snp->Mode->CurrentAddress = *NewMac;
   1476   }
   1477 
   1478   Status = SetCurrentMacAddress (LanDriver, &Snp->Mode->CurrentAddress);
   1479 
   1480   // Restore TPL and return
   1481 exit_unlock:
   1482   gBS->RestoreTPL (SavedTpl);
   1483   return Status;
   1484 }
   1485 
   1486 /*
   1487 **  UEFI Statistics() function
   1488 **
   1489 */
   1490 EFI_STATUS
   1491 EFIAPI
   1492 SnpStatistics (
   1493   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
   1494   IN        BOOLEAN Reset,
   1495   IN  OUT   UINTN *StatSize,
   1496       OUT   EFI_NETWORK_STATISTICS *Statistics
   1497   )
   1498 {
   1499   LAN91X_DRIVER *LanDriver;
   1500   EFI_TPL        SavedTpl;
   1501   EFI_STATUS     Status;
   1502 
   1503   // Check Snp instance
   1504   if (Snp == NULL) {
   1505     return EFI_INVALID_PARAMETER;
   1506   }
   1507 
   1508   // Check pointless condition
   1509   if ((!Reset) && (StatSize == NULL) && (Statistics == NULL)) {
   1510     return EFI_SUCCESS;
   1511   }
   1512 
   1513   // Check the parameters
   1514   if ((StatSize == NULL) && (Statistics != NULL)) {
   1515     return EFI_INVALID_PARAMETER;
   1516   }
   1517 
   1518   // Serialize access to data and registers
   1519   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1520 
   1521   // Check that driver was started and initialised
   1522   switch (Snp->Mode->State) {
   1523   case EfiSimpleNetworkInitialized:
   1524     break;
   1525   case EfiSimpleNetworkStarted:
   1526     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1527     ReturnUnlock (EFI_DEVICE_ERROR);
   1528   case EfiSimpleNetworkStopped:
   1529     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1530     ReturnUnlock (EFI_NOT_STARTED);
   1531   default:
   1532     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1533           (UINTN)Snp->Mode->State));
   1534     ReturnUnlock (EFI_DEVICE_ERROR);
   1535   }
   1536 
   1537   // Find the LanDriver structure
   1538   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1539 
   1540   // Do a reset if required
   1541   if (Reset) {
   1542     ZeroMem (&LanDriver->Stats, sizeof(EFI_NETWORK_STATISTICS));
   1543   }
   1544 
   1545   // Check buffer size
   1546   if (*StatSize < sizeof(EFI_NETWORK_STATISTICS)) {
   1547     *StatSize = sizeof(EFI_NETWORK_STATISTICS);
   1548     ReturnUnlock (EFI_BUFFER_TOO_SMALL);
   1549     goto exit_unlock;
   1550   }
   1551 
   1552   // Fill in the statistics
   1553   CopyMem(&Statistics, &LanDriver->Stats, sizeof(EFI_NETWORK_STATISTICS));
   1554   Status = EFI_SUCCESS;
   1555 
   1556   // Restore TPL and return
   1557 exit_unlock:
   1558   gBS->RestoreTPL (SavedTpl);
   1559   return Status;
   1560 }
   1561 
   1562 /*
   1563 **  UEFI MCastIPtoMAC() function
   1564 **
   1565 */
   1566 EFI_STATUS
   1567 EFIAPI
   1568 SnpMcastIptoMac (
   1569   IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
   1570   IN        BOOLEAN IsIpv6,
   1571   IN        EFI_IP_ADDRESS *Ip,
   1572       OUT   EFI_MAC_ADDRESS *McastMac
   1573   )
   1574 {
   1575   // Check Snp instance
   1576   if (Snp == NULL) {
   1577     return EFI_INVALID_PARAMETER;
   1578   }
   1579 
   1580   // Check parameters
   1581   if ((McastMac == NULL) || (Ip == NULL)) {
   1582     return EFI_INVALID_PARAMETER;
   1583   }
   1584 
   1585   // Make sure MAC address is empty
   1586   ZeroMem (McastMac, sizeof(EFI_MAC_ADDRESS));
   1587 
   1588   // If we need ipv4 address
   1589   if (!IsIpv6) {
   1590     // Most significant 25 bits of a multicast HW address are set
   1591     McastMac->Addr[0] = 0x01;
   1592     McastMac->Addr[1] = 0x00;
   1593     McastMac->Addr[2] = 0x5E;
   1594 
   1595     // Lower 23 bits from ipv4 address
   1596     McastMac->Addr[3] = (Ip->v4.Addr[1] & 0x7F); // Clear the ms bit (25th bit of MAC must be 0)
   1597     McastMac->Addr[4] = Ip->v4.Addr[2];
   1598     McastMac->Addr[5] = Ip->v4.Addr[3];
   1599   } else {
   1600     // Most significant 16 bits of multicast v6 HW address are set
   1601     McastMac->Addr[0] = 0x33;
   1602     McastMac->Addr[1] = 0x33;
   1603 
   1604     // lower four octets are taken from ipv6 address
   1605     McastMac->Addr[2] = Ip->v6.Addr[8];
   1606     McastMac->Addr[3] = Ip->v6.Addr[9];
   1607     McastMac->Addr[4] = Ip->v6.Addr[10];
   1608     McastMac->Addr[5] = Ip->v6.Addr[11];
   1609   }
   1610 
   1611   return EFI_SUCCESS;
   1612 }
   1613 
   1614 /*
   1615 **  UEFI NvData() function
   1616 **
   1617 */
   1618 EFI_STATUS
   1619 EFIAPI
   1620 SnpNvData (
   1621   IN        EFI_SIMPLE_NETWORK_PROTOCOL* pobj,
   1622   IN        BOOLEAN read_write,
   1623   IN        UINTN offset,
   1624   IN        UINTN buff_size,
   1625   IN  OUT   VOID *data
   1626   )
   1627 {
   1628   DEBUG((EFI_D_ERROR, "LAN91x: Non-volatile storage not supported\n"));
   1629 
   1630   return EFI_UNSUPPORTED;
   1631 }
   1632 
   1633 
   1634 /*
   1635 **  UEFI GetStatus () function
   1636 **
   1637 */
   1638 EFI_STATUS
   1639 EFIAPI
   1640 SnpGetStatus (
   1641   IN        EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
   1642       OUT   UINT32   *IrqStat   OPTIONAL,
   1643       OUT   VOID    **TxBuff    OPTIONAL
   1644   )
   1645 {
   1646   LAN91X_DRIVER   *LanDriver;
   1647   EFI_TPL          SavedTpl;
   1648   EFI_STATUS       Status;
   1649   BOOLEAN          MediaPresent;
   1650   UINT8            IstReg;
   1651 
   1652   // Check preliminaries
   1653   if (Snp == NULL) {
   1654     return EFI_INVALID_PARAMETER;
   1655   }
   1656 
   1657   // Serialize access to data and registers
   1658   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1659 
   1660   // Check that driver was started and initialised
   1661   switch (Snp->Mode->State) {
   1662   case EfiSimpleNetworkInitialized:
   1663     break;
   1664   case EfiSimpleNetworkStarted:
   1665     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1666     ReturnUnlock (EFI_DEVICE_ERROR);
   1667   case EfiSimpleNetworkStopped:
   1668     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1669     ReturnUnlock (EFI_NOT_STARTED);
   1670   default:
   1671     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1672           (UINTN)Snp->Mode->State));
   1673     ReturnUnlock (EFI_DEVICE_ERROR);
   1674   }
   1675 
   1676   // Find the LanDriver structure
   1677   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1678 
   1679   // Arbitrarily set the interrupt status to 0
   1680   if (IrqStat != NULL) {
   1681     *IrqStat = 0;
   1682     IstReg = ReadIoReg8 (LanDriver, LAN91X_IST);
   1683     if ((IstReg & IST_RCV) != 0) {
   1684       *IrqStat |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
   1685     }
   1686     if ((IstReg & IST_TX) != 0) {
   1687       *IrqStat |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
   1688     }
   1689   }
   1690 
   1691   // Pass back the completed buffer address
   1692   if (TxBuff != NULL) {
   1693     *TxBuff = TxQueRemove (LanDriver);
   1694   }
   1695 
   1696   // Update the media status
   1697   MediaPresent = CheckLinkStatus (LanDriver);
   1698   if (MediaPresent != Snp->Mode->MediaPresent) {
   1699     DEBUG((EFI_D_WARN, "LAN91x: Link %s\n", MediaPresent ? L"up" : L"down"));
   1700   }
   1701   Snp->Mode->MediaPresent = MediaPresent;
   1702   Status = EFI_SUCCESS;
   1703 
   1704   // Restore TPL and return
   1705 exit_unlock:
   1706   gBS->RestoreTPL (SavedTpl);
   1707   return Status;
   1708 }
   1709 
   1710 
   1711 /*
   1712 **  UEFI Transmit() function
   1713 **
   1714 */
   1715 EFI_STATUS
   1716 EFIAPI
   1717 SnpTransmit (
   1718   IN        EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
   1719   IN        UINTN            HdrSize,
   1720   IN        UINTN            BufSize,
   1721   IN        VOID            *BufAddr,
   1722   IN        EFI_MAC_ADDRESS *SrcAddr    OPTIONAL,
   1723   IN        EFI_MAC_ADDRESS *DstAddr    OPTIONAL,
   1724   IN        UINT16          *Protocol   OPTIONAL
   1725   )
   1726 {
   1727   LAN91X_DRIVER   *LanDriver;
   1728   EFI_TPL          SavedTpl;
   1729   EFI_STATUS       Status;
   1730   UINT8           *Ptr;
   1731   UINTN            Len;
   1732   UINTN            MmuPages;
   1733   UINTN            Retries;
   1734   UINT16           Proto;
   1735   UINT8            PktNum;
   1736 
   1737   // Check preliminaries
   1738   if ((Snp == NULL) || (BufAddr == NULL)) {
   1739     DEBUG((EFI_D_ERROR, "LAN91x: SnpTransmit(): NULL Snp (%p) or BufAddr (%p)\n",
   1740         Snp, BufAddr));
   1741     return EFI_INVALID_PARAMETER;
   1742   }
   1743 
   1744   // Serialize access to data and registers
   1745   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1746 
   1747   // Check that driver was started and initialised
   1748   switch (Snp->Mode->State) {
   1749   case EfiSimpleNetworkInitialized:
   1750     break;
   1751   case EfiSimpleNetworkStarted:
   1752     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1753     ReturnUnlock (EFI_DEVICE_ERROR);
   1754   case EfiSimpleNetworkStopped:
   1755     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1756     ReturnUnlock (EFI_NOT_STARTED);
   1757   default:
   1758     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1759           (UINTN)Snp->Mode->State));
   1760     ReturnUnlock (EFI_DEVICE_ERROR);
   1761   }
   1762 
   1763   // Find the LanDriver structure
   1764   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1765 
   1766   // Ensure header is correct size if non-zero
   1767   if (HdrSize != 0) {
   1768     if (HdrSize != Snp->Mode->MediaHeaderSize) {
   1769       DEBUG((EFI_D_ERROR, "LAN91x: SnpTransmit(): Invalid HdrSize %d\n", HdrSize));
   1770       ReturnUnlock (EFI_INVALID_PARAMETER);
   1771     }
   1772 
   1773     if ((DstAddr == NULL) || (Protocol == NULL)) {
   1774       DEBUG((EFI_D_ERROR, "LAN91x: SnpTransmit(): NULL DstAddr %p or Protocol %p\n",
   1775           DstAddr, Protocol));
   1776       ReturnUnlock (EFI_INVALID_PARAMETER);
   1777     }
   1778   }
   1779 
   1780   // Before transmitting check the link status
   1781   if (!Snp->Mode->MediaPresent) {
   1782     DEBUG((EFI_D_WARN, "LAN91x: SnpTransmit(): Link not ready\n"));
   1783     ReturnUnlock (EFI_NOT_READY);
   1784   }
   1785 
   1786   // Calculate the request size in 256-byte "pages" minus 1
   1787   // The 91C111 ignores this, but some older devices need it.
   1788   MmuPages = ((BufSize & ~1) + LAN91X_PKT_OVERHEAD - 1) >> 8;
   1789   if (MmuPages > 7) {
   1790     DEBUG((EFI_D_WARN, "LAN91x: Tx buffer too large (%d bytes)\n", BufSize));
   1791     LanDriver->Stats.TxOversizeFrames += 1;
   1792     LanDriver->Stats.TxDroppedFrames += 1;
   1793     ReturnUnlock (EFI_BAD_BUFFER_SIZE);
   1794   }
   1795 
   1796   // Request allocation of a transmit buffer
   1797   Status = MmuOperation (LanDriver, MMUCR_OP_TX_ALLOC | MmuPages);
   1798   if (EFI_ERROR (Status)) {
   1799     DEBUG((EFI_D_ERROR, "LAN91x: Tx buffer request failure: %d\n", Status));
   1800     ReturnUnlock (EFI_DEVICE_ERROR);
   1801   }
   1802 
   1803   // Wait for allocation request completion
   1804   Retries = LAN91X_MEMORY_ALLOC_POLLS;
   1805   while ((ReadIoReg8 (LanDriver, LAN91X_IST) & IST_ALLOC) == 0) {
   1806     if (--Retries == 0) {
   1807       DEBUG((EFI_D_ERROR, "LAN91x: Tx buffer allocation timeout\n"));
   1808       ReturnUnlock (EFI_TIMEOUT);
   1809     }
   1810   }
   1811 
   1812   // Check for successful allocation
   1813   PktNum = ReadIoReg8 (LanDriver, LAN91X_ARR);
   1814   if ((PktNum & ARR_FAILED) != 0) {
   1815     DEBUG((EFI_D_ERROR, "LAN91x: Tx buffer allocation failure: %02x\n", PktNum));
   1816     ReturnUnlock (EFI_NOT_READY);
   1817   }
   1818   PktNum &= ARR_PACKET;
   1819 
   1820   // Check for the nature of the frame
   1821   if (DstAddr->Addr[0] == 0xFF) {
   1822     LanDriver->Stats.TxBroadcastFrames += 1;
   1823   } else if ((DstAddr->Addr[0] & 0x1) == 1) {
   1824     LanDriver->Stats.TxMulticastFrames += 1;
   1825   } else {
   1826     LanDriver->Stats.TxUnicastFrames += 1;
   1827   }
   1828 
   1829   // Set the Packet Number and Pointer registers
   1830   WriteIoReg8 (LanDriver, LAN91X_PNR, PktNum);
   1831   WriteIoReg16 (LanDriver, LAN91X_PTR, PTR_AUTO_INCR);
   1832 
   1833   // Set up mutable buffer information variables
   1834   Ptr = BufAddr;
   1835   Len = BufSize;
   1836 
   1837   // Write Status and Byte Count first
   1838   WriteIoReg16 (LanDriver, LAN91X_DATA0, 0);
   1839   WriteIoReg16 (LanDriver, LAN91X_DATA0, (Len + LAN91X_PKT_OVERHEAD) & BCW_COUNT);
   1840 
   1841   // This packet may come with a preconfigured Ethernet header.
   1842   // If not, we need to construct one from optional parameters.
   1843   if (HdrSize) {
   1844 
   1845     // Write the destination address
   1846     WriteIoData (LanDriver, DstAddr, NET_ETHER_ADDR_LEN);
   1847 
   1848     // Write the Source Address
   1849     if (SrcAddr != NULL) {
   1850       WriteIoData (LanDriver, SrcAddr, NET_ETHER_ADDR_LEN);
   1851     } else {
   1852       WriteIoData (LanDriver, &LanDriver->SnpMode.CurrentAddress, NET_ETHER_ADDR_LEN);
   1853     }
   1854 
   1855     // Write the Protocol word
   1856     Proto = HTONS (*Protocol);
   1857     WriteIoReg16 (LanDriver, LAN91X_DATA0, Proto);
   1858 
   1859     // Adjust the data start and length
   1860     Ptr += sizeof(ETHER_HEAD);
   1861     Len -= sizeof(ETHER_HEAD);
   1862   }
   1863 
   1864   // Copy the remainder data buffer, except the odd byte
   1865   WriteIoData (LanDriver, Ptr, Len & ~1);
   1866   Ptr += Len & ~1;
   1867   Len &= 1;
   1868 
   1869   // Write the Packet Control Word and odd byte
   1870   WriteIoReg16 (LanDriver, LAN91X_DATA0,
   1871       (Len != 0) ? (PCW_ODD | PCW_CRC | *Ptr) : PCW_CRC);
   1872 
   1873   // Release the packet for transmission
   1874   Status = MmuOperation (LanDriver, MMUCR_OP_TX_PUSH);
   1875   if (EFI_ERROR (Status)) {
   1876     DEBUG((EFI_D_ERROR, "LAN91x: Tx buffer release failure: %d\n", Status));
   1877     ReturnUnlock (EFI_DEVICE_ERROR);
   1878   }
   1879 
   1880   // Update the Rx statistics
   1881   LanDriver->Stats.TxTotalBytes += BufSize;
   1882   LanDriver->Stats.TxGoodFrames += 1;
   1883 
   1884   // Update the Tx Buffer cache
   1885   if (!TxQueInsert (LanDriver, BufAddr)) {
   1886     DEBUG((EFI_D_WARN, "LAN91x: SnpTransmit(): TxQueue insert failure.\n"));
   1887   }
   1888   Status = EFI_SUCCESS;
   1889 
   1890   // Dump the packet header
   1891 #if LAN91X_PRINT_PACKET_HEADERS
   1892   Ptr = BufAddr;
   1893   DEBUG((EFI_D_ERROR, "LAN91X:SnpTransmit()\n"));
   1894   DEBUG((EFI_D_ERROR, "  HdrSize: %d, SrcAddr: %p, Length: %d, Last byte: %02x\n",
   1895          HdrSize, SrcAddr, BufSize, Ptr[BufSize - 1]));
   1896   PrintIpDgram (
   1897       (HdrSize == 0) ? (EFI_MAC_ADDRESS *)&Ptr[0] : DstAddr,
   1898       (HdrSize == 0) ? (EFI_MAC_ADDRESS *)&Ptr[6] : (SrcAddr != NULL) ? SrcAddr : &LanDriver->SnpMode.CurrentAddress,
   1899       (HdrSize == 0) ? (UINT16 *)&Ptr[12] : &Proto,
   1900       &Ptr[14]
   1901       );
   1902 #endif
   1903 
   1904   // Restore TPL and return
   1905 exit_unlock:
   1906   gBS->RestoreTPL (SavedTpl);
   1907   return Status;
   1908 }
   1909 
   1910 
   1911 /*
   1912 **  UEFI Receive() function
   1913 **
   1914 */
   1915 EFI_STATUS
   1916 EFIAPI
   1917 SnpReceive (
   1918   IN        EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
   1919       OUT   UINTN           *HdrSize      OPTIONAL,
   1920   IN  OUT   UINTN           *BuffSize,
   1921       OUT   VOID            *Data,
   1922       OUT   EFI_MAC_ADDRESS *SrcAddr      OPTIONAL,
   1923       OUT   EFI_MAC_ADDRESS *DstAddr      OPTIONAL,
   1924       OUT   UINT16 *Protocol              OPTIONAL
   1925   )
   1926 {
   1927   EFI_TPL        SavedTpl;
   1928   EFI_STATUS     Status;
   1929   LAN91X_DRIVER *LanDriver;
   1930   UINT8         *DataPtr;
   1931   UINT16         PktStatus;
   1932   UINT16         PktLength;
   1933   UINT16         PktControl;
   1934   UINT8          IstReg;
   1935 
   1936   // Check preliminaries
   1937   if ((Snp == NULL) || (Data == NULL)) {
   1938     return EFI_INVALID_PARAMETER;
   1939   }
   1940 
   1941   // Serialize access to data and registers
   1942   SavedTpl = gBS->RaiseTPL (LAN91X_TPL);
   1943 
   1944   // Check that driver was started and initialised
   1945   switch (Snp->Mode->State) {
   1946   case EfiSimpleNetworkInitialized:
   1947     break;
   1948   case EfiSimpleNetworkStarted:
   1949     DEBUG((EFI_D_WARN, "LAN91x: Driver not yet initialized\n"));
   1950     ReturnUnlock (EFI_DEVICE_ERROR);
   1951   case EfiSimpleNetworkStopped:
   1952     DEBUG((EFI_D_WARN, "LAN91x: Driver not started\n"));
   1953     ReturnUnlock (EFI_NOT_STARTED);
   1954   default:
   1955     DEBUG((EFI_D_ERROR, "LAN91x: Driver in an invalid state: %u\n",
   1956           (UINTN)Snp->Mode->State));
   1957     ReturnUnlock (EFI_DEVICE_ERROR);
   1958   }
   1959 
   1960   // Find the LanDriver structure
   1961   LanDriver = INSTANCE_FROM_SNP_THIS(Snp);
   1962 
   1963   // Check for Rx Overrun
   1964   IstReg = ReadIoReg8 (LanDriver, LAN91X_IST);
   1965   if ((IstReg & IST_RX_OVRN) != 0) {
   1966     LanDriver->Stats.RxTotalFrames += 1;
   1967     LanDriver->Stats.RxDroppedFrames += 1;
   1968     WriteIoReg8 (LanDriver, LAN91X_IST, IST_RX_OVRN);
   1969     DEBUG((EFI_D_WARN, "LAN91x: Receiver overrun\n"));
   1970   }
   1971 
   1972   // Check for Rx data available
   1973   if ((IstReg & IST_RCV) == 0) {
   1974     ReturnUnlock (EFI_NOT_READY);
   1975   }
   1976 
   1977   // Configure the PTR register for reading
   1978   WriteIoReg16 (LanDriver, LAN91X_PTR, PTR_RCV | PTR_AUTO_INCR | PTR_READ);
   1979 
   1980   // Read the Packet Status and Packet Length words
   1981   PktStatus = ReadIoReg16 (LanDriver, LAN91X_DATA0);
   1982   PktLength = ReadIoReg16 (LanDriver, LAN91X_DATA0) & BCW_COUNT;
   1983 
   1984   // Check for valid received packet
   1985   if ((PktStatus == 0) && (PktLength == 0)) {
   1986     DEBUG((EFI_D_WARN, "LAN91x: Received zero-length packet. IST=%04x\n", IstReg));
   1987     ReturnUnlock (EFI_NOT_READY);
   1988   }
   1989   LanDriver->Stats.RxTotalFrames += 1;
   1990 
   1991   // Check if we got a CRC error
   1992   if ((PktStatus & RX_BAD_CRC) != 0) {
   1993     DEBUG((EFI_D_WARN, "LAN91x: Received frame CRC error\n"));
   1994     LanDriver->Stats.RxCrcErrorFrames += 1;
   1995     LanDriver->Stats.RxDroppedFrames += 1;
   1996     Status = EFI_DEVICE_ERROR;
   1997     goto exit_release;
   1998   }
   1999 
   2000   // Check if we got a too-short frame
   2001   if ((PktStatus & RX_TOO_SHORT) != 0) {
   2002     DEBUG((EFI_D_WARN, "LAN91x: Received frame too short (%d bytes)\n", PktLength));
   2003     LanDriver->Stats.RxUndersizeFrames += 1;
   2004     LanDriver->Stats.RxDroppedFrames += 1;
   2005     Status = EFI_DEVICE_ERROR;
   2006     goto exit_release;
   2007   }
   2008 
   2009    // Check if we got a too-long frame
   2010   if ((PktStatus & RX_TOO_LONG) != 0) {
   2011     DEBUG((EFI_D_WARN, "LAN91x: Received frame too long (%d bytes)\n", PktLength));
   2012     LanDriver->Stats.RxOversizeFrames += 1;
   2013     LanDriver->Stats.RxDroppedFrames += 1;
   2014     Status = EFI_DEVICE_ERROR;
   2015     goto exit_release;
   2016   }
   2017 
   2018    // Check if we got an alignment error
   2019   if ((PktStatus & RX_ALGN_ERR) != 0) {
   2020     DEBUG((EFI_D_WARN, "LAN91x: Received frame alignment error\n"));
   2021     // Don't seem to keep track of these specifically
   2022     LanDriver->Stats.RxDroppedFrames += 1;
   2023     Status = EFI_DEVICE_ERROR;
   2024     goto exit_release;
   2025   }
   2026 
   2027   // Classify the received fram
   2028   if ((PktStatus & RX_MULTICAST) != 0) {
   2029     LanDriver->Stats.RxMulticastFrames += 1;
   2030   } else if ((PktStatus & RX_BROADCAST) != 0) {
   2031     LanDriver->Stats.RxBroadcastFrames += 1;
   2032   } else {
   2033     LanDriver->Stats.RxUnicastFrames += 1;
   2034   }
   2035 
   2036   // Calculate the received packet data length
   2037   PktLength -= LAN91X_PKT_OVERHEAD;
   2038   if ((PktStatus & RX_ODD_FRAME) != 0) {
   2039     PktLength += 1;
   2040   }
   2041 
   2042   // Check buffer size
   2043   if (*BuffSize < PktLength) {
   2044     DEBUG((EFI_D_WARN, "LAN91x: Receive buffer too small for packet (%d < %d)\n",
   2045         *BuffSize, PktLength));
   2046     *BuffSize = PktLength;
   2047     Status = EFI_BUFFER_TOO_SMALL;
   2048     goto exit_release;
   2049   }
   2050 
   2051   // Transfer the data bytes
   2052   DataPtr = Data;
   2053   ReadIoData (LanDriver, DataPtr, PktLength & ~0x0001);
   2054 
   2055   // Read the PktControl and Odd Byte from the FIFO
   2056   PktControl = ReadIoReg16 (LanDriver, LAN91X_DATA0);
   2057   if ((PktControl & PCW_ODD) != 0) {
   2058     DataPtr[PktLength - 1] = PktControl & PCW_ODD_BYTE;
   2059   }
   2060 
   2061   // Update buffer size
   2062   *BuffSize = PktLength;
   2063 
   2064   if (HdrSize != NULL) {
   2065     *HdrSize = LanDriver->SnpMode.MediaHeaderSize;
   2066   }
   2067 
   2068   // Extract the destination address
   2069   if (DstAddr != NULL) {
   2070     CopyMem (DstAddr, &DataPtr[0], NET_ETHER_ADDR_LEN);
   2071   }
   2072 
   2073   // Get the source address
   2074   if (SrcAddr != NULL) {
   2075     CopyMem (SrcAddr, &DataPtr[6], NET_ETHER_ADDR_LEN);
   2076   }
   2077 
   2078   // Get the protocol
   2079   if (Protocol != NULL) {
   2080     *Protocol = NTOHS (*(UINT16*)(&DataPtr[12]));
   2081   }
   2082 
   2083   // Update the Rx statistics
   2084   LanDriver->Stats.RxTotalBytes += PktLength;
   2085   LanDriver->Stats.RxGoodFrames += 1;
   2086   Status = EFI_SUCCESS;
   2087 
   2088 #if LAN91X_PRINT_PACKET_HEADERS
   2089   // Dump the packet header
   2090   DEBUG((EFI_D_ERROR, "LAN91X:SnpReceive()\n"));
   2091   DEBUG((EFI_D_ERROR, "  HdrSize: %p, SrcAddr: %p, DstAddr: %p, Protocol: %p\n",
   2092          HdrSize, SrcAddr, DstAddr, Protocol));
   2093   DEBUG((EFI_D_ERROR, "  Length: %d, Last byte: %02x\n", PktLength, DataPtr[PktLength - 1]));
   2094   PrintIpDgram (&DataPtr[0], &DataPtr[6], &DataPtr[12], &DataPtr[14]);
   2095 #endif
   2096 
   2097   // Release the FIFO buffer
   2098 exit_release:
   2099   MmuOperation (LanDriver, MMUCR_OP_RX_POP_REL);
   2100 
   2101   // Restore TPL and return
   2102 exit_unlock:
   2103   gBS->RestoreTPL (SavedTpl);
   2104   return Status;
   2105 }
   2106 
   2107 
   2108 /*------------------ Driver Execution Environment main entry point ------------------*/
   2109 
   2110 /*
   2111 **  Entry point for the LAN91x driver
   2112 **
   2113 */
   2114 EFI_STATUS
   2115 Lan91xDxeEntry (
   2116   IN EFI_HANDLE Handle,
   2117   IN EFI_SYSTEM_TABLE *SystemTable
   2118   )
   2119 {
   2120   EFI_STATUS Status;
   2121   LAN91X_DRIVER *LanDriver;
   2122   EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
   2123   EFI_SIMPLE_NETWORK_MODE *SnpMode;
   2124   LAN91X_DEVICE_PATH *Lan91xPath;
   2125 
   2126   // The PcdLan91xDxeBaseAddress PCD must be defined
   2127   ASSERT(PcdGet32 (PcdLan91xDxeBaseAddress) != 0);
   2128 
   2129   // Allocate Resources
   2130   LanDriver = AllocateZeroPool (sizeof(LAN91X_DRIVER));
   2131   Lan91xPath = AllocateCopyPool (sizeof(LAN91X_DEVICE_PATH), &Lan91xPathTemplate);
   2132 
   2133   // Initialize I/O Space access info
   2134   LanDriver->IoBase = PcdGet32 (PcdLan91xDxeBaseAddress);
   2135   LanDriver->PhyAd = LAN91X_NO_PHY;
   2136   LanDriver->BankSel = 0xff;
   2137 
   2138   // Initialize pointers
   2139   Snp = &(LanDriver->Snp);
   2140   SnpMode = &(LanDriver->SnpMode);
   2141   Snp->Mode = SnpMode;
   2142 
   2143   // Set the signature of the LAN Driver structure
   2144   LanDriver->Signature = LAN91X_SIGNATURE;
   2145 
   2146   // Probe the device
   2147   Status = Probe (LanDriver);
   2148   if (EFI_ERROR(Status)) {
   2149     DEBUG((EFI_D_ERROR, "LAN91x:Lan91xDxeEntry(): Probe failed with status %d\n", Status));
   2150     return Status;
   2151   }
   2152 
   2153 #ifdef LAN91X_PRINT_REGISTERS
   2154   PrintIoRegisters (LanDriver);
   2155   PrintPhyRegisters (LanDriver);
   2156 #endif
   2157 
   2158   // Assign fields and func pointers
   2159   Snp->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
   2160   Snp->WaitForPacket = NULL;
   2161   Snp->Initialize = SnpInitialize;
   2162   Snp->Start = SnpStart;
   2163   Snp->Stop = SnpStop;
   2164   Snp->Reset = SnpReset;
   2165   Snp->Shutdown = SnpShutdown;
   2166   Snp->ReceiveFilters = SnpReceiveFilters;
   2167   Snp->StationAddress = SnpStationAddress;
   2168   Snp->Statistics = SnpStatistics;
   2169   Snp->MCastIpToMac = SnpMcastIptoMac;
   2170   Snp->NvData = SnpNvData;
   2171   Snp->GetStatus = SnpGetStatus;
   2172   Snp->Transmit = SnpTransmit;
   2173   Snp->Receive = SnpReceive;
   2174 
   2175   // Fill in simple network mode structure
   2176   SnpMode->State = EfiSimpleNetworkStopped;
   2177   SnpMode->HwAddressSize = NET_ETHER_ADDR_LEN;    // HW address is 6 bytes
   2178   SnpMode->MediaHeaderSize = sizeof(ETHER_HEAD);  // Size of an Ethernet header
   2179   SnpMode->MaxPacketSize = EFI_PAGE_SIZE;         // Ethernet Frame (with VLAN tag +4 bytes)
   2180 
   2181   // Supported receive filters
   2182   SnpMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
   2183                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
   2184                                EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |
   2185                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |
   2186                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
   2187 
   2188   // Initially-enabled receive filters
   2189   SnpMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
   2190                                   EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
   2191                                   EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
   2192 
   2193   // LAN91x has 64bit hash table. We can filter an infinite MACs, but
   2194   // higher-level software must filter out any hash collisions.
   2195   SnpMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
   2196   SnpMode->MCastFilterCount = 0;
   2197   ZeroMem (&SnpMode->MCastFilter, MAX_MCAST_FILTER_CNT * sizeof(EFI_MAC_ADDRESS));
   2198 
   2199   // Set the interface type (1: Ethernet or 6: IEEE 802 Networks)
   2200   SnpMode->IfType = NET_IFTYPE_ETHERNET;
   2201 
   2202   // Mac address is changeable
   2203   SnpMode->MacAddressChangeable = TRUE;
   2204 
   2205   // We can only transmit one packet at a time
   2206   SnpMode->MultipleTxSupported = FALSE;
   2207 
   2208   // MediaPresent checks for cable connection and partner link
   2209   SnpMode->MediaPresentSupported = TRUE;
   2210   SnpMode->MediaPresent = FALSE;
   2211 
   2212   //  Set broadcast address
   2213   SetMem (&SnpMode->BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
   2214 
   2215   // Assign fields for device path
   2216   Lan91xPath->Lan91x.MacAddress = SnpMode->PermanentAddress;
   2217   Lan91xPath->Lan91x.IfType = SnpMode->IfType;
   2218 
   2219   // Initialise the protocol
   2220   Status = gBS->InstallMultipleProtocolInterfaces (
   2221                   &LanDriver->ControllerHandle,
   2222                   &gEfiSimpleNetworkProtocolGuid, Snp,
   2223                   &gEfiDevicePathProtocolGuid, Lan91xPath,
   2224                   NULL
   2225                   );
   2226 
   2227   // Say what the status of loading the protocol structure is
   2228   if (EFI_ERROR(Status)) {
   2229     FreePool (LanDriver);
   2230   }
   2231 
   2232   return Status;
   2233 }
   2234