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