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