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---------------------------------------------------------------------------------------------------------------------*/
55typedef 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
97typedef struct {
98  MAC_ADDR_DEVICE_PATH      Lan91x;
99  EFI_DEVICE_PATH_PROTOCOL  End;
100} LAN91X_DEVICE_PATH;
101
102LAN91X_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
127STATIC 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
145STATIC
146BOOLEAN
147TxQueInsert (
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
163STATIC
164VOID
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*/
196STATIC
197UINT32
198MulticastHash (
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
239STATIC
240VOID
241SelectIoBank (
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
258STATIC
259UINT16
260ReadIoReg16 (
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
276STATIC
277UINT16
278WriteIoReg16 (
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
295STATIC
296UINT8
297ReadIoReg8 (
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
313STATIC
314UINT8
315WriteIoReg8 (
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
336STATIC
337VOID
338MdioOutput (
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
366STATIC
367UINT32
368MdioInput (
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
397STATIC
398VOID
399MdioIdle (
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
411STATIC
412VOID
413WritePhyReg16 (
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
435STATIC
436UINT16
437ReadPhyReg16 (
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
467STATIC
468VOID
469PrintIoRegisters (
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
494STATIC
495VOID
496PrintPhyRegisters (
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
521STATIC
522VOID
523PrintIpDgram (
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
580STATIC
581EFI_STATUS
582PhyDetect (
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
612STATIC
613BOOLEAN
614CheckLinkStatus (
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
628STATIC
629EFI_STATUS
630PhyAutoNegotiate (
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
694STATIC
695EFI_STATUS
696PhySoftReset (
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
726STATIC
727EFI_MAC_ADDRESS
728GetCurrentMacAddress (
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
747STATIC
748EFI_STATUS
749SetCurrentMacAddress (
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
766STATIC
767EFI_STATUS
768MmuOperation (
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
789STATIC
790EFI_STATUS
791ReadIoData (
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
809STATIC
810EFI_STATUS
811WriteIoData (
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
829STATIC
830EFI_STATUS
831ChipDisable (
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
854STATIC
855EFI_STATUS
856ChipEnable (
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
879STATIC
880EFI_STATUS
881SoftReset (
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*/
917STATIC
918EFI_STATUS
919Probe (
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*/
1012EFI_STATUS
1013EFIAPI
1014SnpStart (
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
1051exit_unlock:
1052  gBS->RestoreTPL (SavedTpl);
1053  return Status;
1054}
1055
1056/*
1057**  UEFI Stop() function
1058**
1059*/
1060EFI_STATUS
1061EFIAPI
1062SnpStop (
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
1103exit_unlock:
1104  gBS->RestoreTPL (SavedTpl);
1105  return Status;
1106}
1107
1108/*
1109**  UEFI Initialize() function
1110**
1111*/
1112EFI_STATUS
1113EFIAPI
1114SnpInitialize (
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
1182exit_unlock:
1183  gBS->RestoreTPL (SavedTpl);
1184  return Status;
1185}
1186
1187/*
1188**  UEFI Reset () function
1189**
1190*/
1191EFI_STATUS
1192EFIAPI
1193SnpReset (
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
1245exit_unlock:
1246  gBS->RestoreTPL (SavedTpl);
1247  return Status;
1248}
1249
1250/*
1251**  UEFI Shutdown () function
1252**
1253*/
1254EFI_STATUS
1255EFIAPI
1256SnpShutdown (
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
1295exit_unlock:
1296  gBS->RestoreTPL (SavedTpl);
1297  return Status;
1298}
1299
1300
1301/*
1302**  UEFI ReceiveFilters() function
1303**
1304*/
1305EFI_STATUS
1306EFIAPI
1307SnpReceiveFilters (
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
1421exit_unlock:
1422  gBS->RestoreTPL (SavedTpl);
1423  return Status;
1424}
1425
1426/*
1427**  UEFI StationAddress() function
1428**
1429*/
1430EFI_STATUS
1431EFIAPI
1432SnpStationAddress (
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
1481exit_unlock:
1482  gBS->RestoreTPL (SavedTpl);
1483  return Status;
1484}
1485
1486/*
1487**  UEFI Statistics() function
1488**
1489*/
1490EFI_STATUS
1491EFIAPI
1492SnpStatistics (
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
1557exit_unlock:
1558  gBS->RestoreTPL (SavedTpl);
1559  return Status;
1560}
1561
1562/*
1563**  UEFI MCastIPtoMAC() function
1564**
1565*/
1566EFI_STATUS
1567EFIAPI
1568SnpMcastIptoMac (
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*/
1618EFI_STATUS
1619EFIAPI
1620SnpNvData (
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*/
1638EFI_STATUS
1639EFIAPI
1640SnpGetStatus (
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
1705exit_unlock:
1706  gBS->RestoreTPL (SavedTpl);
1707  return Status;
1708}
1709
1710
1711/*
1712**  UEFI Transmit() function
1713**
1714*/
1715EFI_STATUS
1716EFIAPI
1717SnpTransmit (
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
1905exit_unlock:
1906  gBS->RestoreTPL (SavedTpl);
1907  return Status;
1908}
1909
1910
1911/*
1912**  UEFI Receive() function
1913**
1914*/
1915EFI_STATUS
1916EFIAPI
1917SnpReceive (
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
2098exit_release:
2099  MmuOperation (LanDriver, MMUCR_OP_RX_POP_REL);
2100
2101  // Restore TPL and return
2102exit_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*/
2114EFI_STATUS
2115Lan91xDxeEntry (
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