2 * Intel 8256[367], 8257[1-9], 8258[03]
3 * Gigabit Ethernet PCI-Express Controllers
4 * Coraid EtherDrive® hba
7 #include "../port/lib.h"
12 #include "../port/error.h"
13 #include "../port/netif.h"
18 * note: the 82575, 82576 and 82580 are operated using registers aliased
19 * to the 82563-style architecture. many features seen in the 82598
20 * are also seen in the 82575 part.
26 Ctrl = 0x0000, /* Device Control */
27 Status = 0x0008, /* Device Status */
28 Eec = 0x0010, /* EEPROM/Flash Control/Data */
29 Eerd = 0x0014, /* EEPROM Read */
30 Ctrlext = 0x0018, /* Extended Device Control */
31 Fla = 0x001c, /* Flash Access */
32 Mdic = 0x0020, /* MDI Control */
33 Fcal = 0x0028, /* Flow Control Address Low */
34 Fcah = 0x002C, /* Flow Control Address High */
35 Fct = 0x0030, /* Flow Control Type */
36 Kumctrlsta = 0x0034, /* Kumeran Control and Status Register */
37 Vet = 0x0038, /* VLAN EtherType */
38 Fcttv = 0x0170, /* Flow Control Transmit Timer Value */
39 Txcw = 0x0178, /* Transmit Configuration Word */
40 Rxcw = 0x0180, /* Receive Configuration Word */
41 Ledctl = 0x0E00, /* LED control */
42 Pba = 0x1000, /* Packet Buffer Allocation */
43 Pbs = 0x1008, /* Packet Buffer Size */
47 Icr = 0x00C0, /* Interrupt Cause Read */
48 Itr = 0x00c4, /* Interrupt Throttling Rate */
49 Ics = 0x00C8, /* Interrupt Cause Set */
50 Ims = 0x00D0, /* Interrupt Mask Set/Read */
51 Imc = 0x00D8, /* Interrupt mask Clear */
52 Iam = 0x00E0, /* Interrupt acknowledge Auto Mask */
53 Eitr = 0x1680, /* Extended itr; 82575/6 80 only */
57 Rctl = 0x0100, /* Control */
58 Ert = 0x2008, /* Early Receive Threshold (573[EVL], 82578 only) */
59 Fcrtl = 0x2160, /* Flow Control RX Threshold Low */
60 Fcrth = 0x2168, /* Flow Control Rx Threshold High */
61 Psrctl = 0x2170, /* Packet Split Receive Control */
62 Drxmxod = 0x2540, /* dma max outstanding bytes (82575) */
63 Rdbal = 0x2800, /* Rdesc Base Address Low Queue 0 */
64 Rdbah = 0x2804, /* Rdesc Base Address High Queue 0 */
65 Rdlen = 0x2808, /* Descriptor Length Queue 0 */
66 Srrctl = 0x280c, /* split and replication rx control (82575) */
67 Rdh = 0x2810, /* Descriptor Head Queue 0 */
68 Rdt = 0x2818, /* Descriptor Tail Queue 0 */
69 Rdtr = 0x2820, /* Descriptor Timer Ring */
70 Rxdctl = 0x2828, /* Descriptor Control */
71 Radv = 0x282C, /* Interrupt Absolute Delay Timer */
72 Rsrpd = 0x2c00, /* Small Packet Detect */
73 Raid = 0x2c08, /* ACK interrupt delay */
74 Cpuvec = 0x2c10, /* CPU Vector */
75 Rxcsum = 0x5000, /* Checksum Control */
76 Rmpl = 0x5004, /* rx maximum packet length (82575) */
77 Rfctl = 0x5008, /* Filter Control */
78 Mta = 0x5200, /* Multicast Table Array */
79 Ral = 0x5400, /* Receive Address Low */
80 Rah = 0x5404, /* Receive Address High */
81 Vfta = 0x5600, /* VLAN Filter Table Array */
82 Mrqc = 0x5818, /* Multiple Receive Queues Command */
86 Tctl = 0x0400, /* Transmit Control */
87 Tipg = 0x0410, /* Transmit IPG */
88 Tkabgtxd = 0x3004, /* glci afe band gap transmit ref data, or something */
89 Tdbal = 0x3800, /* Tdesc Base Address Low */
90 Tdbah = 0x3804, /* Tdesc Base Address High */
91 Tdlen = 0x3808, /* Descriptor Length */
92 Tdh = 0x3810, /* Descriptor Head */
93 Tdt = 0x3818, /* Descriptor Tail */
94 Tidv = 0x3820, /* Interrupt Delay Value */
95 Txdctl = 0x3828, /* Descriptor Control */
96 Tadv = 0x382C, /* Interrupt Absolute Delay Timer */
97 Tarc0 = 0x3840, /* Arbitration Counter Queue 0 */
101 Statistics = 0x4000, /* Start of Statistics Area */
102 Gorcl = 0x88/4, /* Good Octets Received Count */
103 Gotcl = 0x90/4, /* Good Octets Transmitted Count */
104 Torl = 0xC0/4, /* Total Octets Received */
105 Totl = 0xC8/4, /* Total Octets Transmitted */
106 Nstatistics = 0x124/4,
110 Lrst = 1<<3, /* link reset */
111 Slu = 1<<6, /* Set Link Up */
112 Devrst = 1<<26, /* Device Reset */
113 Rfce = 1<<27, /* Receive Flow Control Enable */
114 Tfce = 1<<28, /* Transmit Flow Control Enable */
115 Phyrst = 1<<31, /* Phy Reset */
119 Lu = 1<<1, /* Link Up */
120 Lanid = 3<<2, /* mask for Lan ID. */
121 Txoff = 1<<4, /* Transmission Paused */
122 Tbimode = 1<<5, /* TBI Mode Indication */
123 Phyra = 1<<10, /* PHY Reset Asserted */
124 GIOme = 1<<19, /* GIO Master Enable Status */
128 EEstart = 1<<0, /* Start Read */
129 EEdone = 1<<1, /* Read done */
133 Eerst = 1<<13, /* EEPROM Reset */
134 Linkmode = 3<<23, /* linkmode */
135 Serdes = 3<<23, /* " serdes */
138 enum { /* EEPROM content offsets */
139 Ea = 0x00, /* Ethernet Address */
143 MDIdMASK = 0x0000FFFF, /* Data */
145 MDIrMASK = 0x001F0000, /* PHY Register Address */
147 MDIpMASK = 0x03E00000, /* PHY Address */
149 MDIwop = 0x04000000, /* Write Operation */
150 MDIrop = 0x08000000, /* Read Operation */
151 MDIready = 0x10000000, /* End of Transaction */
152 MDIie = 0x20000000, /* Interrupt Enable */
153 MDIe = 0x40000000, /* Error */
156 enum { /* phy interface */
157 Phyctl = 0, /* phy ctl register */
158 Phyisr = 19, /* 82563 phy interrupt status register */
159 Phylhr = 19, /* 8257[12] link health register */
160 Physsr = 17, /* phy secondary status register */
161 Phyprst = 193<<8 | 17, /* 8256[34] phy port reset */
162 Phyier = 18, /* 82573 phy interrupt enable register */
163 Phypage = 22, /* 8256[34] page register */
164 Phystat = 26, /* 82580 phy status */
166 Rtlink = 1<<10, /* realtime link status */
167 Phyan = 1<<11, /* phy has autonegotiated */
170 Ran = 1<<9, /* restart auto negotiation */
171 Ean = 1<<12, /* enable auto negotiation */
174 Prst = 1<<0, /* reset the port */
176 /* 82573 Phyier bits */
177 Lscie = 1<<10, /* link status changed ie */
178 Ancie = 1<<11, /* auto negotiation complete ie */
179 Spdie = 1<<14, /* speed changed ie */
180 Panie = 1<<15, /* phy auto negotiation error ie */
182 /* Phylhr/Phyisr bits */
183 Anf = 1<<6, /* lhr: auto negotiation fault */
184 Ane = 1<<15, /* isr: auto negotiation error */
186 /* 82580 Phystat bits */
187 Ans = 1<<14 | 1<<15, /* 82580 autoneg. status */
188 Link = 1<<6, /* 82580 Link */
190 /* Rxcw builtin serdes */
203 enum { /* fiber (pcs) interface */
204 Pcsctl = 0x4208, /* pcs control */
205 Pcsstat = 0x420c, /* pcs status */
208 Pan = 1<<16, /* autoegotiate */
209 Prestart = 1<<17, /* restart an (self clearing) */
212 Linkok = 1<<0, /* link is okay */
213 Andone = 1<<16, /* an phase is done see below for success */
214 Anbad = 1<<19 | 1<<20, /* Anerror | Anremfault */
217 enum { /* Icr, Ics, Ims, Imc */
218 Txdw = 0x00000001, /* Transmit Descriptor Written Back */
219 Txqe = 0x00000002, /* Transmit Queue Empty */
220 Lsc = 0x00000004, /* Link Status Change */
221 Rxseq = 0x00000008, /* Receive Sequence Error */
222 Rxdmt0 = 0x00000010, /* Rdesc Minimum Threshold Reached */
223 Rxo = 0x00000040, /* Receiver Overrun */
224 Rxt0 = 0x00000080, /* Receiver Timer Interrupt; !82575/6/80 only */
225 Rxdw = 0x00000080, /* Rdesc write back; 82575/6/80 only */
226 Mdac = 0x00000200, /* MDIO Access Completed */
227 Rxcfgset = 0x00000400, /* Receiving /C/ ordered sets */
228 Ack = 0x00020000, /* Receive ACK frame */
232 TxcwFd = 0x00000020, /* Full Duplex */
233 TxcwHd = 0x00000040, /* Half Duplex */
234 TxcwPauseMASK = 0x00000180, /* Pause */
236 TxcwPs = 1<<TxcwPauseSHIFT, /* Pause Supported */
237 TxcwAs = 2<<TxcwPauseSHIFT, /* Asymmetric FC desired */
238 TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
240 TxcwNpr = 0x00008000, /* Next Page Request */
241 TxcwConfig = 0x40000000, /* Transmit COnfig Control */
242 TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
246 Rrst = 0x00000001, /* Receiver Software Reset */
247 Ren = 0x00000002, /* Receiver Enable */
248 Sbp = 0x00000004, /* Store Bad Packets */
249 Upe = 0x00000008, /* Unicast Promiscuous Enable */
250 Mpe = 0x00000010, /* Multicast Promiscuous Enable */
251 Lpe = 0x00000020, /* Long Packet Reception Enable */
252 RdtmsMASK = 0x00000300, /* Rdesc Minimum Threshold Size */
253 RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
254 RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
255 RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
256 MoMASK = 0x00003000, /* Multicast Offset */
257 Bam = 0x00008000, /* Broadcast Accept Mode */
258 BsizeMASK = 0x00030000, /* Receive Buffer Size */
259 Bsize16384 = 0x00010000, /* Bsex = 1 */
260 Bsize8192 = 0x00020000, /* Bsex = 1 */
261 Bsize2048 = 0x00000000,
262 Bsize1024 = 0x00010000,
263 Bsize512 = 0x00020000,
264 Bsize256 = 0x00030000,
265 BsizeFlex = 0x08000000, /* Flexable Bsize in 1kb increments */
266 Vfe = 0x00040000, /* VLAN Filter Enable */
267 Cfien = 0x00080000, /* Canonical Form Indicator Enable */
268 Cfi = 0x00100000, /* Canonical Form Indicator value */
269 Dpf = 0x00400000, /* Discard Pause Frames */
270 Pmcf = 0x00800000, /* Pass MAC Control Frames */
271 Bsex = 0x02000000, /* Buffer Size Extension */
272 Secrc = 0x04000000, /* Strip CRC from incoming packet */
280 Trst = 0x00000001, /* Transmitter Software Reset */
281 Ten = 0x00000002, /* Transmit Enable */
282 Psp = 0x00000008, /* Pad Short Packets */
283 Mulr = 0x10000000, /* Allow multiple concurrent requests */
284 CtMASK = 0x00000FF0, /* Collision Threshold */
286 ColdMASK = 0x003FF000, /* Collision Distance */
288 Swxoff = 0x00400000, /* Sofware XOFF Transmission */
289 Pbe = 0x00800000, /* Packet Burst Enable */
290 Rtlc = 0x01000000, /* Re-transmit on Late Collision */
291 Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
294 enum { /* [RT]xdctl */
295 PthreshMASK = 0x0000003F, /* Prefetch Threshold */
297 HthreshMASK = 0x00003F00, /* Host Threshold */
299 WthreshMASK = 0x003F0000, /* Writeback Threshold */
301 Gran = 0x01000000, /* Granularity; not 82575 */
306 Ipofl = 0x0100, /* IP Checksum Off-load Enable */
307 Tuofl = 0x0200, /* TCP/UDP Checksum Off-load Enable */
310 typedef struct Rd { /* Receive Descriptor */
319 enum { /* Rd status */
320 Rdd = 0x01, /* Descriptor Done */
321 Reop = 0x02, /* End of Packet */
322 Ixsm = 0x04, /* Ignore Checksum Indication */
323 Vp = 0x08, /* Packet is 802.1Q (matched VET) */
324 Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
325 Ipcs = 0x40, /* IP Checksum Calculated on Packet */
326 Pif = 0x80, /* Passed in-exact filter */
329 enum { /* Rd errors */
330 Ce = 0x01, /* CRC Error or Alignment Error */
331 Se = 0x02, /* Symbol Error */
332 Seq = 0x04, /* Sequence Error */
333 Cxe = 0x10, /* Carrier Extension Error */
334 Tcpe = 0x20, /* TCP/UDP Checksum Error */
335 Ipe = 0x40, /* IP Checksum Error */
336 Rxe = 0x80, /* RX Data Error */
339 typedef struct { /* Transmit Descriptor */
340 uint addr[2]; /* Data */
345 enum { /* Tdesc control */
346 LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
348 DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
349 DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
350 PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
351 Teop = 0x01000000, /* End of Packet (DD) */
352 PtypeIP = 0x02000000, /* IP Packet Type (CD) */
353 Ifcs = 0x02000000, /* Insert FCS (DD) */
354 Tse = 0x04000000, /* TCP Segmentation Enable */
355 Rs = 0x08000000, /* Report Status */
356 Rps = 0x10000000, /* Report Status Sent */
357 Dext = 0x20000000, /* Descriptor Extension */
358 Vle = 0x40000000, /* VLAN Packet Enable */
359 Ide = 0x80000000, /* Interrupt Delay Enable */
362 enum { /* Tdesc status */
363 Tdd = 0x0001, /* Descriptor Done */
364 Ec = 0x0002, /* Excess Collisions */
365 Lc = 0x0004, /* Late Collision */
366 Tu = 0x0008, /* Transmit Underrun */
367 CssMASK = 0xFF00, /* Checksum Start Field */
378 /* 16 and 32-bit flash registers for ich flash parts */
379 Bfpr = 0x00/4, /* flash base 0:12; lim 16:28 */
380 Fsts = 0x04/2, /* flash status; Hsfsts */
381 Fctl = 0x06/2, /* flash control; Hsfctl */
382 Faddr = 0x08/4, /* flash address to r/w */
383 Fdata = 0x10/4, /* data @ address */
385 /* status register */
386 Fdone = 1<<0, /* flash cycle done */
387 Fcerr = 1<<1, /* cycle error; write 1 to clear */
388 Ael = 1<<2, /* direct access error log; 1 to clear */
389 Scip = 1<<5, /* spi cycle in progress */
390 Fvalid = 1<<14, /* flash descriptor valid */
392 /* control register */
393 Fgo = 1<<0, /* start cycle */
394 Flcycle = 1<<1, /* two bits: r=0; w=2 */
395 Fdbc = 1<<8, /* bytes to read; 5 bits */
399 Nrd = 256, /* power of two */
400 Ntd = 128, /* power of two */
401 Nrb = 512+512, /* private receive buffers per Ctlr */
402 Rbalign = BY2PG, /* rx buffer alignment */
407 * cavet emptor: 82577/78 have been entered speculatitively.
408 * awating datasheet from intel.
439 typedef struct Ctlrtype Ctlrtype;
447 static Ctlrtype cttab[Nctlrtype] = {
448 i82563, 9014, Fpba, "i82563",
449 i82566, 1514, Fload, "i82566",
450 i82567, 9234, Fload, "i82567",
451 i82567m, 1514, 0, "i82567m",
452 i82571, 9234, Fpba, "i82571",
453 i82572, 9234, Fpba, "i82572",
454 i82573, 8192, Fert, "i82573", /* terrible perf above 8k */
455 i82574, 9018, 0, "i82574",
456 i82575, 9728, F75|Fflashea, "i82575",
457 i82576, 9728, F75, "i82576",
458 i82577, 4096, Fload|Fert, "i82577",
459 i82577m, 1514, Fload|Fert, "i82577",
460 i82578, 4096, Fload|Fert, "i82578",
461 i82578m, 1514, Fload|Fert, "i82578",
462 i82579, 9018, Fload|Fert, "i82579",
463 i82580, 9728, F75, "i82580",
464 i82583, 1514, 0, "i82583",
467 typedef void (*Freefn)(Block*);
469 typedef struct Ctlr Ctlr;
479 QLock alock; /* attach */
480 void *alloc; /* receive/transmit descriptors */
487 int im; /* interrupt mask */
493 uint statistics[Nstatistics];
506 uchar ra[Eaddrlen]; /* receive address */
507 ulong mta[128]; /* multicast table array */
512 Rd *rdba; /* receive descriptor base address */
513 Block **rb; /* receive buffers */
514 uint rdh; /* receive descriptor head */
515 uint rdt; /* receive descriptor tail */
516 int rdtr; /* receive delay timer ring value */
517 int radv; /* receive interrupt absolute delay timer */
522 Td *tdba; /* transmit descriptor base address */
523 Block **tb; /* transmit buffers */
524 int tdh; /* transmit descriptor head */
525 int tdt; /* transmit descriptor tail */
530 uint pba; /* packet buffer allocation */
533 typedef struct Rbpool Rbpool;
544 uchar pad[128]; /* cacheline */
552 #define csr32r(c, r) (*((c)->nic+((r)/4)))
553 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
555 static Ctlr *i82563ctlrhead;
556 static Ctlr *i82563ctlrtail;
557 static Rbpool rbtab[Npool];
559 static char *statistics[Nstatistics] = {
566 "Excessive Collisions",
567 "Multiple Collision",
575 "Carrier Extension Error",
576 "Receive Error Length",
582 "FC Received Unsupported",
583 "Packets Received (64 Bytes)",
584 "Packets Received (65-127 Bytes)",
585 "Packets Received (128-255 Bytes)",
586 "Packets Received (256-511 Bytes)",
587 "Packets Received (512-1023 Bytes)",
588 "Packets Received (1024-mtu Bytes)",
589 "Good Packets Received",
590 "Broadcast Packets Received",
591 "Multicast Packets Received",
592 "Good Packets Transmitted",
594 "Good Octets Received",
596 "Good Octets Transmitted",
600 "Receive No Buffers",
605 "Management Packets Rx",
606 "Management Packets Drop",
607 "Management Packets Tx",
608 "Total Octets Received",
610 "Total Octets Transmitted",
612 "Total Packets Received",
613 "Total Packets Transmitted",
614 "Packets Transmitted (64 Bytes)",
615 "Packets Transmitted (65-127 Bytes)",
616 "Packets Transmitted (128-255 Bytes)",
617 "Packets Transmitted (256-511 Bytes)",
618 "Packets Transmitted (512-1023 Bytes)",
619 "Packets Transmitted (1024-mtu Bytes)",
620 "Multicast Packets Transmitted",
621 "Broadcast Packets Transmitted",
622 "TCP Segmentation Context Transmitted",
623 "TCP Segmentation Context Fail",
624 "Interrupt Assertion",
625 "Interrupt Rx Pkt Timer",
626 "Interrupt Rx Abs Timer",
627 "Interrupt Tx Pkt Timer",
628 "Interrupt Tx Abs Timer",
629 "Interrupt Tx Queue Empty",
630 "Interrupt Tx Desc Low",
632 "Interrupt Rx Overrun",
638 return cttab[c->type].name;
642 i82563ifstat(Ether *edev, void *a, long n, ulong offset)
644 char *s, *p, *e, *stat;
652 p = s = malloc(READSTR);
655 for(i = 0; i < Nstatistics; i++){
656 r = csr32r(ctlr, Statistics + i*4);
657 if((stat = statistics[i]) == nil)
665 ruvl += (uvlong)csr32r(ctlr, Statistics+(i+1)*4) << 32;
667 tuvl += ctlr->statistics[i];
668 tuvl += (uvlong)ctlr->statistics[i+1] << 32;
671 ctlr->statistics[i] = tuvl;
672 ctlr->statistics[i+1] = tuvl >> 32;
673 p = seprint(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
678 ctlr->statistics[i] += r;
679 if(ctlr->statistics[i] == 0)
681 p = seprint(p, e, "%s: %ud %ud\n", stat,
682 ctlr->statistics[i], r);
687 p = seprint(p, e, "lintr: %ud %ud\n", ctlr->lintr, ctlr->lsleep);
688 p = seprint(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
689 p = seprint(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
690 p = seprint(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
691 p = seprint(p, e, "rdtr: %ud\n", ctlr->rdtr);
692 p = seprint(p, e, "radv: %ud\n", ctlr->radv);
693 p = seprint(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
694 p = seprint(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
695 p = seprint(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
696 p = seprint(p, e, "txcw: %.8ux\n", csr32r(ctlr, Txcw));
697 p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
698 p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
700 b = rbtab + ctlr->pool;
701 p = seprint(p, e, "pool: fast %ud slow %ud nstarve %ud nwakey %ud starve %ud\n",
702 b->nfast, b->nslow, b->nstarve, b->nwakey, b->starve);
703 p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
704 ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
705 p = seprint(p, e, "type: %s\n", cname(ctlr));
707 // p = seprint(p, e, "eeprom:");
708 // for(i = 0; i < 0x40; i++){
709 // if(i && ((i & 7) == 0))
710 // p = seprint(p, e, "\n ");
711 // p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
713 // p = seprint(p, e, "\n");
716 n = readstr(offset, a, n, s);
718 qunlock(&ctlr->slock);
724 i82563promiscuous(void *arg, int on)
733 rctl = csr32r(ctlr, Rctl);
739 csr32w(ctlr, Rctl, rctl);
743 i82563multicast(void *arg, uchar *addr, int on)
753 if(ctlr->type == i82566)
755 bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
757 * multiple ether addresses can hash to the same filter bit,
758 * so it's never safe to clear a filter bit.
759 * if we want to clear filter bits, we need to keep track of
760 * all the multicast addresses in use, clear all the filter bits,
761 * then set the ones corresponding to in-use addresses.
764 ctlr->mta[x] |= 1<<bit;
766 // ctlr->mta[x] &= ~(1<<bit);
768 csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
786 i82563rballoc(Rbpool *p)
791 if((b = p->x) != nil){
813 rbfree(Block *b, int t)
818 b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
819 b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
826 iprint("wakey %d; %d %d\n", t, p->nstarve, p->nwakey);
882 static Freefn freetab[Npool] = {
898 if(seq == nelem(freetab))
900 if(freetab[seq] == nil){
901 print("82563: bad freetab\n");
908 i82563im(Ctlr *ctlr, int im)
910 ilock(&ctlr->imlock);
912 csr32w(ctlr, Ims, ctlr->im);
913 iunlock(&ctlr->imlock);
917 i82563txinit(Ctlr *ctlr)
922 if(cttab[ctlr->type].flag & F75)
923 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp);
925 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
926 csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8); /* yb sez: 0x702008 */
927 csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
928 // csr32w(ctlr, Tdbah, Pciwaddrh(ctlr->tdba));
929 csr32w(ctlr, Tdbah, 0);
930 csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
931 ctlr->tdh = PREV(0, ctlr->ntd);
932 csr32w(ctlr, Tdh, 0);
934 csr32w(ctlr, Tdt, 0);
935 for(i = 0; i < ctlr->ntd; i++){
936 if((b = ctlr->tb[i]) != nil){
940 memset(&ctlr->tdba[i], 0, sizeof(Td));
942 csr32w(ctlr, Tidv, 128);
943 csr32w(ctlr, Tadv, 64);
944 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) | Ten);
945 r = csr32r(ctlr, Txdctl) & ~WthreshMASK;
946 r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
947 if(cttab[ctlr->type].flag & F75)
949 csr32w(ctlr, Txdctl, r);
952 #define Next(x, m) (((x)+1) & (m))
955 i82563cleanup(Ctlr *c)
962 while(c->tdba[n = Next(tdh, m)].status & Tdd){
964 if((b = c->tb[tdh]) != nil){
968 iprint("82563 tx underrun!\n");
969 c->tdba[tdh].status = 0;
981 return (c->im & Txdw) == 0;
1001 tdh = i82563cleanup(ctlr);
1003 if(Next(tdt, m) == tdh){
1005 i82563im(ctlr, Txdw);
1006 sleep(&ctlr->trendez, notrim, ctlr);
1008 bp = qbread(edev->oq, 100000);
1009 td = &ctlr->tdba[tdt];
1010 td->addr[0] = PCIWADDR(bp->rp);
1011 // td->addr[1] = Pciwaddrh(bp->rp);
1012 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
1015 csr32w(ctlr, Tdt, tdt);
1020 i82563replenish(Ctlr *ctlr, int maysleep)
1029 p = rbtab + ctlr->pool;
1031 for(; Next(rdt, m) != ctlr->rdh; rdt = Next(rdt, m)){
1032 rd = &ctlr->rdba[rdt];
1033 if(ctlr->rb[rdt] != nil){
1034 iprint("82563: tx overrun\n");
1038 bp = i82563rballoc(p);
1040 if(rdt - ctlr->rdh >= 16)
1042 print("i82563%d: no rx buffers\n", ctlr->pool);
1048 sleep(p, icansleep, p);
1053 rd->addr[0] = PCIWADDR(bp->rp);
1054 // rd->addr[1] = Pciwaddrh(bp->rp);
1060 csr32w(ctlr, Rdt, rdt);
1066 i82563rxinit(Ctlr *ctlr)
1071 if(ctlr->rbsz <= 2048)
1072 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
1074 i = ctlr->rbsz / 1024;
1075 if(ctlr->rbsz % 1024)
1077 if(cttab[ctlr->type].flag & F75){
1078 csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
1079 if(ctlr->type != i82575)
1080 i |= (ctlr->nrd/2>>4)<<20; /* RdmsHalf */
1081 csr32w(ctlr, Srrctl, i | Dropen);
1082 csr32w(ctlr, Rmpl, ctlr->rbsz);
1083 // csr32w(ctlr, Drxmxod, 0x7ff);
1085 csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
1088 if(cttab[ctlr->type].flag & Fert)
1089 csr32w(ctlr, Ert, 1024/8);
1091 if(ctlr->type == i82566)
1092 csr32w(ctlr, Pbs, 16);
1094 csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1095 // csr32w(ctlr, Rdbah, Pciwaddrh(ctlr->rdba));
1096 csr32w(ctlr, Rdbah, 0);
1097 csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
1099 csr32w(ctlr, Rdh, 0);
1101 csr32w(ctlr, Rdt, 0);
1104 csr32w(ctlr, Rdtr, ctlr->rdtr);
1105 csr32w(ctlr, Radv, ctlr->radv);
1107 for(i = 0; i < ctlr->nrd; i++)
1108 if((bp = ctlr->rb[i]) != nil){
1112 if(cttab[ctlr->type].flag & F75)
1113 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
1115 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
1118 * Enable checksum offload.
1120 csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
1126 return ((Ctlr*)v)->rim != 0;
1130 i82563rproc(void *arg)
1132 uint m, rdh, rim, im;
1142 csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1143 if(cttab[ctlr->type].flag & F75){
1144 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1145 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1147 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1153 i82563replenish(ctlr, 1);
1154 sleep(&ctlr->rrendez, i82563rim, ctlr);
1158 rd = &ctlr->rdba[rdh];
1161 if(!(rd->status & Rdd))
1165 * Accept eop packets with no errors.
1166 * With no errors and the Ixsm bit set,
1167 * the descriptor status Tpcs and Ipcs bits give
1168 * an indication of whether the checksums were
1169 * calculated and valid.
1172 if((rd->status & Reop) && rd->errors == 0){
1173 bp->wp += rd->length;
1174 bp->lim = bp->wp; /* lie like a dog. avoid packblock. */
1175 if(!(rd->status & Ixsm)){
1177 if(rd->status & Ipcs){
1179 * IP checksum calculated
1180 * (and valid as errors == 0).
1185 if(rd->status & Tcpcs){
1187 * TCP/UDP checksum calculated
1188 * (and valid as errors == 0).
1191 bp->flag |= Btcpck|Budpck;
1193 bp->checksum = rd->checksum;
1196 etheriq(edev, bp, 1);
1199 ctlr->rb[rdh] = nil;
1202 ctlr->rdh = rdh = Next(rdh, m);
1203 if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1204 if(i82563replenish(ctlr, 0) == -1)
1213 return ((Ctlr*)v)->lim != 0;
1216 static int speedtab[] = {
1221 phyread(Ctlr *c, int phyno, int reg)
1225 csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1227 for(i = 0; i < 64; i++){
1228 phy = csr32r(c, Mdic);
1229 if(phy & (MDIe|MDIready))
1233 if((phy & (MDIe|MDIready)) != MDIready){
1234 print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);
1237 return phy & 0xffff;
1241 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1245 csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1247 for(i = 0; i < 64; i++){
1248 phy = csr32r(c, Mdic);
1249 if(phy & (MDIe|MDIready))
1253 if((phy & (MDIe|MDIready)) != MDIready)
1259 setpage(Ctlr *c, uint phyno, uint p, uint r)
1263 if(c->type == i82563){
1264 if(r >= 16 && r <= 28 && r != 22)
1266 else if(r == 30 || r == 31)
1270 return phywrite0(c, phyno, pr, p);
1277 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1279 if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1280 panic("%s: bad phy reg %.4ux", cname(c), reg);
1281 return phywrite0(c, phyno, reg & 0xff, v);
1285 phyerrata(Ether *e, Ctlr *c)
1288 if(c->phyerrata == 0){
1290 phywrite(c, 1, Phyprst, Prst); /* try a port reset */
1291 print("%s: phy port reset\n", cname(c));
1300 uint a, i, r, phy, phyno;
1308 if(c->type == i82579)
1312 phy = phyread(c, phyno, Phystat);
1318 r = phyread(c, phyno, Phyctl);
1319 phywrite(c, phyno, Phyctl, r | Ran | Ean);
1321 e->link = (phy & Link) != 0;
1325 e->mbps = speedtab[i];
1330 sleep(&c->lrendez, i82563lim, c);
1344 if(c->type == i82573 && (phy = phyread(c, 1, Phyier)) != ~0)
1345 phywrite(c, 1, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1347 phy = phyread(c, 1, Physsr);
1359 a = phyread(c, 1, Phyisr) & Ane;
1365 a = phyread(c, 1, Phylhr) & Anf;
1370 phywrite(c, 1, Phyctl, phyread(c, 1, Phyctl) | Ran | Ean);
1371 e->link = (phy & Rtlink) != 0;
1375 e->mbps = speedtab[i];
1376 if(c->type == i82563)
1382 sleep(&c->lrendez, i82563lim, c);
1397 phy = csr32r(c, Pcsstat);
1398 e->link = phy & Linkok;
1402 else if(phy & Anbad)
1403 csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1405 e->mbps = speedtab[i];
1409 sleep(&c->lrendez, i82563lim, c);
1414 serdeslproc(void *v)
1424 rx = csr32r(c, Rxcw);
1425 tx = csr32r(c, Txcw);
1427 e->link = (rx & 1<<31) != 0;
1428 // e->link = (csr32r(c, Status) & Lu) != 0;
1433 e->mbps = speedtab[i];
1437 sleep(&c->lrendez, i82563lim, c);
1442 i82563attach(Ether *edev)
1444 char name[KNAMELEN];
1450 qlock(&ctlr->alock);
1451 if(ctlr->alloc != nil){
1452 qunlock(&ctlr->alock);
1458 ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1459 if(ctlr->alloc == nil){
1460 qunlock(&ctlr->alock);
1463 ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1464 ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1466 ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1467 ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1470 while(bp = i82563rballoc(rbtab + ctlr->pool)){
1480 qunlock(&ctlr->alock);
1484 for(i = 0; i < Nrb; i++){
1485 bp = allocb(ctlr->rbsz + Rbalign);
1486 bp->free = freetab[ctlr->pool];
1490 snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1491 if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1492 kproc(name, pcslproc, edev); /* phy based serdes */
1493 else if(csr32r(ctlr, Status) & Tbimode)
1494 kproc(name, serdeslproc, edev); /* mac based serdes */
1495 else if(ctlr->type == i82579 || ctlr->type == i82580)
1496 kproc(name, phyl79proc, edev);
1498 kproc(name, phylproc, edev);
1500 snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1501 kproc(name, i82563rproc, edev);
1503 snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1504 kproc(name, i82563tproc, edev);
1506 qunlock(&ctlr->alock);
1511 i82563interrupt(Ureg*, void *arg)
1520 ilock(&ctlr->imlock);
1521 csr32w(ctlr, Imc, ~0);
1524 while(icr = csr32r(ctlr, Icr) & ctlr->im){
1527 ctlr->lim = icr & Lsc;
1528 wakeup(&ctlr->lrendez);
1531 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1532 ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1533 im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1534 wakeup(&ctlr->rrendez);
1540 wakeup(&ctlr->trendez);
1545 csr32w(ctlr, Ims, im);
1546 iunlock(&ctlr->imlock);
1550 i82563detach(Ctlr *ctlr)
1554 /* balance rx/tx packet buffer; survives reset */
1555 if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1556 ctlr->pba = csr32r(ctlr, Pba);
1557 r = ctlr->pba >> 16;
1558 r += ctlr->pba & 0xffff;
1560 csr32w(ctlr, Pba, r);
1561 }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1562 csr32w(ctlr, Pba, 14);
1563 ctlr->pba = csr32r(ctlr, Pba);
1566 * Perform a device reset to get the chip back to the
1567 * power-on state, followed by an EEPROM reset to read
1568 * the defaults for some internal registers.
1570 csr32w(ctlr, Imc, ~0);
1571 csr32w(ctlr, Rctl, 0);
1572 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1576 r = csr32r(ctlr, Ctrl);
1577 if(ctlr->type == i82566 || ctlr->type == i82579)
1579 csr32w(ctlr, Ctrl, Devrst | r);
1581 for(timeo = 0;; timeo++){
1582 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1589 r = csr32r(ctlr, Ctrl);
1590 csr32w(ctlr, Ctrl, Slu|r);
1592 r = csr32r(ctlr, Ctrlext);
1593 csr32w(ctlr, Ctrlext, r|Eerst);
1595 for(timeo = 0; timeo < 1000; timeo++){
1596 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1600 if(csr32r(ctlr, Ctrlext) & Eerst)
1603 csr32w(ctlr, Imc, ~0);
1605 for(timeo = 0; timeo < 1000; timeo++){
1606 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1610 if(csr32r(ctlr, Icr) & ~Rxcfg)
1617 i82563shutdown(Ether *edev)
1619 i82563detach(edev->ctlr);
1623 eeread(Ctlr *ctlr, int adr)
1625 csr32w(ctlr, Eerd, EEstart | adr << 2);
1626 while ((csr32r(ctlr, Eerd) & EEdone) == 0)
1628 return csr32r(ctlr, Eerd) >> 16;
1638 for (adr = 0; adr < 0x40; adr++) {
1639 data = eeread(ctlr, adr);
1640 ctlr->eeprom[adr] = data;
1647 fcycle(Ctlr *, Flash *f)
1654 f->reg[Fsts] |= Fcerr | Ael;
1655 for(i = 0; i < 10; i++){
1665 fread(Ctlr *c, Flash *f, int ladr)
1670 if(fcycle(c, f) == -1)
1672 f->reg[Fsts] |= Fdone;
1673 f->reg32[Faddr] = ladr;
1675 /* setup flash control register */
1676 s = f->reg[Fctl] & ~0x3ff;
1677 f->reg[Fctl] = s | 1<<8 | Fgo; /* 2 byte read */
1679 while((f->reg[Fsts] & Fdone) == 0)
1681 if(f->reg[Fsts] & (Fcerr|Ael))
1683 return f->reg32[Fdata] & 0xffff;
1689 ulong data, io, r, adr;
1693 io = c->pcidev->mem[1].bar & ~0x0f;
1694 f.reg = vmap(io, c->pcidev->mem[1].size);
1697 f.reg32 = (ulong*)f.reg;
1698 f.sz = f.reg32[Bfpr];
1699 if(csr32r(c, Eec) & 1<<22){
1700 if(c->type == i82579)
1701 f.sz += 16; /* sector size: 64k */
1703 f.sz += 1; /* sector size: 4k */
1705 r = (f.sz & 0x1fff) << 12;
1707 for(adr = 0; adr < 0x40; adr++) {
1708 data = fread(c, &f, r + adr*2);
1711 c->eeprom[adr] = data;
1714 vunmap(f.reg, c->pcidev->mem[1].size);
1719 defaultea(Ctlr *ctlr, uchar *ra)
1723 static uchar nilea[Eaddrlen];
1725 if(memcmp(ra, nilea, Eaddrlen) != 0)
1727 if(cttab[ctlr->type].flag & Fflashea){
1729 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1730 for(i = 0; i < Eaddrlen; i++)
1733 if(memcmp(ra, nilea, Eaddrlen) != 0)
1735 for(i = 0; i < Eaddrlen/2; i++){
1736 ra[2*i] = ctlr->eeprom[Ea+i];
1737 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1739 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1740 ra[5] += r; /* ea ctlr[n] = ea ctlr[0]+n */
1744 i82563reset(Ctlr *ctlr)
1749 if(i82563detach(ctlr))
1751 if(cttab[ctlr->type].flag & Fload)
1755 if(r != 0 && r != 0xbaba){
1756 print("%s: bad eeprom checksum - %#.4ux\n",
1762 defaultea(ctlr, ra);
1763 csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1764 csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1765 for(i = 1; i < 16; i++){
1766 csr32w(ctlr, Ral+i*8, 0);
1767 csr32w(ctlr, Rah+i*8, 0);
1769 memset(ctlr->mta, 0, sizeof(ctlr->mta));
1770 for(i = 0; i < 128; i++)
1771 csr32w(ctlr, Mta + i*4, 0);
1772 csr32w(ctlr, Fcal, 0x00C28001);
1773 csr32w(ctlr, Fcah, 0x0100);
1774 if(ctlr->type != i82579)
1775 csr32w(ctlr, Fct, 0x8808);
1776 csr32w(ctlr, Fcttv, 0x0100);
1777 csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1778 csr32w(ctlr, Fcrth, ctlr->fcrth);
1779 if(cttab[ctlr->type].flag & F75)
1780 csr32w(ctlr, Eitr, 128<<2); /* 128 ¼ microsecond intervals */
1791 static Cmdtab i82563ctlmsg[] = {
1794 CMpause, "pause", 1,
1799 i82563ctl(Ether *edev, void *buf, long n)
1807 if((ctlr = edev->ctlr) == nil)
1810 cb = parsecmd(buf, n);
1816 ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1819 v = strtoul(cb->f[1], &p, 0);
1820 if(*p || v > 0xffff)
1823 csr32w(ctlr, Rdtr, v);
1826 v = strtoul(cb->f[1], &p, 0);
1827 if(*p || v > 0xffff)
1830 csr32w(ctlr, Radv, v);
1833 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (1<<27 | 1<<28));
1836 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1850 case 0x10ba: /* “gilgal” */
1851 // case 0x1098: /* serdes; not seen */
1852 // case 0x10bb: /* serdes */
1854 case 0x1049: /* mm */
1855 case 0x104a: /* dm */
1856 case 0x104b: /* dc */
1857 case 0x104d: /* v “ninevah” */
1858 case 0x10bd: /* dm-2 */
1859 case 0x294c: /* ich 9 */
1861 case 0x10de: /* lm ich10d */
1862 case 0x10df: /* lf ich10 */
1863 case 0x10e5: /* lm ich9 */
1864 case 0x10f5: /* lm ich9m; “boazman” */
1866 case 0x10bf: /* lf ich9m */
1867 case 0x10cb: /* v ich9m */
1868 case 0x10cd: /* lf ich10 */
1869 case 0x10ce: /* v ich10 */
1870 case 0x10cc: /* lm ich10 */
1872 case 0x105e: /* eb */
1873 case 0x105f: /* eb */
1874 case 0x1060: /* eb */
1875 case 0x10a4: /* eb */
1876 case 0x10a5: /* eb fiber */
1877 case 0x10bc: /* eb */
1878 case 0x10d9: /* eb serdes */
1879 case 0x10da: /* eb serdes “ophir” */
1881 case 0x107d: /* eb copper */
1882 case 0x107e: /* ei fiber */
1883 case 0x107f: /* ei */
1884 case 0x10b9: /* ei “rimon” */
1886 case 0x108b: /* e “vidalia” */
1887 case 0x108c: /* e (iamt) */
1888 case 0x109a: /* l “tekoa” */
1890 case 0x10d3: /* l or it; “hartwell” */
1893 case 0x10a9: /* fiber/serdes */
1895 case 0x10c9: /* copper */
1896 case 0x10e6: /* fiber */
1897 case 0x10e7: /* serdes; “kawela” */
1899 case 0x10ea: /* lc “calpella”; aka pch lan */
1901 case 0x10eb: /* lm “calpella” */
1903 case 0x10ef: /* dc “piketon” */
1905 case 0x1502: /* lm */
1906 case 0x1503: /* v */
1908 case 0x10f0: /* dm “king's creek” */
1910 case 0x150e: /* “barton hills” */
1911 case 0x150f: /* fiber */
1912 case 0x1510: /* backplane */
1913 case 0x1511: /* sfp */
1916 case 0x1506: /* v */
1927 i = pcicfgr32(p, PciSVID);
1928 if((i & 0xffff) == 0x1b52 && p->did == 1)
1939 for(p = nil; p = pcimatch(p, 0x8086, 0);){
1941 if((type = didtype(p->did)) == -1)
1943 ctlr = malloc(sizeof(Ctlr));
1946 ctlr->rbsz = cttab[type].mtu;
1947 ctlr->port = p->mem[0].bar & ~0x0F;
1948 if(i82563ctlrhead != nil)
1949 i82563ctlrtail->next = ctlr;
1951 i82563ctlrhead = ctlr;
1952 i82563ctlrtail = ctlr;
1961 if((ctlr->pool = newpool()) == -1){
1962 print("%s: no pool\n", cname(ctlr));
1966 ctlr->nic = vmap(ctlr->port, p->mem[0].size);
1967 if(ctlr->nic == nil){
1968 print("%s: can't map %#p\n", cname(ctlr), ctlr->port);
1971 if(i82563reset(ctlr)){
1972 vunmap(ctlr->nic, p->mem[0].size);
1975 pcisetbme(ctlr->pcidev);
1980 pnp(Ether *edev, int type)
1991 * Any adapter matches if no edev->port is supplied,
1992 * otherwise the ports must match.
1994 for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
1999 if(type != -1 && ctlr->type != type)
2001 if(edev->port == 0 || edev->port == ctlr->port){
2003 memmove(ctlr->ra, edev->ea, Eaddrlen);
2004 if(setup(ctlr) == 0)
2010 edev->port = ctlr->port;
2011 edev->irq = ctlr->pcidev->intl;
2012 edev->tbdf = ctlr->pcidev->tbdf;
2014 edev->maxmtu = ctlr->rbsz;
2015 memmove(edev->ea, ctlr->ra, Eaddrlen);
2018 * Linkage to the generic ethernet driver.
2020 edev->attach = i82563attach;
2021 // edev->transmit = i82563transmit;
2022 edev->interrupt = i82563interrupt;
2023 edev->ifstat = i82563ifstat;
2024 edev->ctl = i82563ctl;
2027 edev->promiscuous = i82563promiscuous;
2028 edev->shutdown = i82563shutdown;
2029 edev->multicast = i82563multicast;
2043 return pnp(e, i82563);
2049 return pnp(e, i82566);
2055 return pnp(e, i82567m) & pnp(e, i82567);
2061 return pnp(e, i82571);
2067 return pnp(e, i82572);
2073 return pnp(e, i82573);
2079 return pnp(e, i82574);
2085 return pnp(e, i82575);
2091 return pnp(e, i82576);
2097 return pnp(e, i82577m) & pnp(e, i82577);
2103 return pnp(e, i82578m) & pnp(e, i82578);
2109 return pnp(e, i82579);
2115 return pnp(e, i82580);
2121 return pnp(e, i82583);
2125 ether82563link(void)
2128 * recognise lots of model numbers for debugging
2129 * also good for forcing onboard nic(s) as ether0
2130 * try to make that unnecessary by listing lom first.
2132 addethercard("i82563", i82563pnp);
2133 addethercard("i82566", i82566pnp);
2134 addethercard("i82574", i82574pnp);
2135 addethercard("i82576", i82576pnp);
2136 addethercard("i82567", i82567pnp);
2137 addethercard("i82573", i82573pnp);
2139 addethercard("i82571", i82571pnp);
2140 addethercard("i82572", i82572pnp);
2141 addethercard("i82575", i82575pnp);
2142 addethercard("i82577", i82577pnp);
2143 addethercard("i82578", i82578pnp);
2144 addethercard("i82579", i82579pnp);
2145 addethercard("i82580", i82580pnp);
2146 addethercard("i82583", i82583pnp);
2147 addethercard("igbepcie", anypnp);