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;
650 p = s = smalloc(READSTR);
656 for(i = 0; i < Nstatistics; i++){
657 r = csr32r(ctlr, Statistics + i*4);
658 if((stat = statistics[i]) == nil)
666 ruvl += (uvlong)csr32r(ctlr, Statistics+(i+1)*4) << 32;
668 tuvl += ctlr->statistics[i];
669 tuvl += (uvlong)ctlr->statistics[i+1] << 32;
672 ctlr->statistics[i] = tuvl;
673 ctlr->statistics[i+1] = tuvl >> 32;
674 p = seprint(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
679 ctlr->statistics[i] += r;
680 if(ctlr->statistics[i] == 0)
682 p = seprint(p, e, "%s: %ud %ud\n", stat,
683 ctlr->statistics[i], r);
688 p = seprint(p, e, "lintr: %ud %ud\n", ctlr->lintr, ctlr->lsleep);
689 p = seprint(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
690 p = seprint(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
691 p = seprint(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
692 p = seprint(p, e, "rdtr: %ud\n", ctlr->rdtr);
693 p = seprint(p, e, "radv: %ud\n", ctlr->radv);
694 p = seprint(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
695 p = seprint(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
696 p = seprint(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
697 p = seprint(p, e, "txcw: %.8ux\n", csr32r(ctlr, Txcw));
698 p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
699 p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
701 b = rbtab + ctlr->pool;
702 p = seprint(p, e, "pool: fast %ud slow %ud nstarve %ud nwakey %ud starve %ud\n",
703 b->nfast, b->nslow, b->nstarve, b->nwakey, b->starve);
704 p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
705 ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
706 p = seprint(p, e, "type: %s\n", cname(ctlr));
708 // p = seprint(p, e, "eeprom:");
709 // for(i = 0; i < 0x40; i++){
710 // if(i && ((i & 7) == 0))
711 // p = seprint(p, e, "\n ");
712 // p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
714 // p = seprint(p, e, "\n");
717 n = readstr(offset, a, n, s);
719 qunlock(&ctlr->slock);
725 i82563promiscuous(void *arg, int on)
734 rctl = csr32r(ctlr, Rctl);
740 csr32w(ctlr, Rctl, rctl);
744 i82563multicast(void *arg, uchar *addr, int on)
754 if(ctlr->type == i82566)
756 bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
758 * multiple ether addresses can hash to the same filter bit,
759 * so it's never safe to clear a filter bit.
760 * if we want to clear filter bits, we need to keep track of
761 * all the multicast addresses in use, clear all the filter bits,
762 * then set the ones corresponding to in-use addresses.
765 ctlr->mta[x] |= 1<<bit;
767 // ctlr->mta[x] &= ~(1<<bit);
769 csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
787 i82563rballoc(Rbpool *p)
792 if((b = p->x) != nil){
815 rbfree(Block *b, int t)
820 b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
821 b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
828 iprint("wakey %d; %d %d\n", t, p->nstarve, p->nwakey);
884 static Freefn freetab[Npool] = {
900 if(seq == nelem(freetab))
902 if(freetab[seq] == nil){
903 print("82563: bad freetab\n");
910 i82563im(Ctlr *ctlr, int im)
912 ilock(&ctlr->imlock);
914 csr32w(ctlr, Ims, ctlr->im);
915 iunlock(&ctlr->imlock);
919 i82563txinit(Ctlr *ctlr)
924 if(cttab[ctlr->type].flag & F75)
925 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp);
927 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
928 csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8); /* yb sez: 0x702008 */
929 csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
930 // csr32w(ctlr, Tdbah, Pciwaddrh(ctlr->tdba));
931 csr32w(ctlr, Tdbah, 0);
932 csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
933 ctlr->tdh = PREV(0, ctlr->ntd);
934 csr32w(ctlr, Tdh, 0);
936 csr32w(ctlr, Tdt, 0);
937 for(i = 0; i < ctlr->ntd; i++){
938 if((b = ctlr->tb[i]) != nil){
942 memset(&ctlr->tdba[i], 0, sizeof(Td));
944 csr32w(ctlr, Tidv, 128);
945 csr32w(ctlr, Tadv, 64);
946 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) | Ten);
947 r = csr32r(ctlr, Txdctl) & ~WthreshMASK;
948 r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
949 if(cttab[ctlr->type].flag & F75)
951 csr32w(ctlr, Txdctl, r);
954 #define Next(x, m) (((x)+1) & (m))
957 i82563cleanup(Ctlr *c)
964 while(c->tdba[n = Next(tdh, m)].status & Tdd){
966 if((b = c->tb[tdh]) != nil){
970 iprint("82563 tx underrun!\n");
971 c->tdba[tdh].status = 0;
983 return (c->im & Txdw) == 0;
1003 tdh = i82563cleanup(ctlr);
1005 if(Next(tdt, m) == tdh){
1007 i82563im(ctlr, Txdw);
1008 sleep(&ctlr->trendez, notrim, ctlr);
1010 bp = qbread(edev->oq, 100000);
1011 td = &ctlr->tdba[tdt];
1012 td->addr[0] = PCIWADDR(bp->rp);
1013 // td->addr[1] = Pciwaddrh(bp->rp);
1014 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
1017 csr32w(ctlr, Tdt, tdt);
1022 i82563replenish(Ctlr *ctlr, int maysleep)
1031 p = rbtab + ctlr->pool;
1033 for(; Next(rdt, m) != ctlr->rdh; rdt = Next(rdt, m)){
1034 rd = &ctlr->rdba[rdt];
1035 if(ctlr->rb[rdt] != nil){
1036 iprint("82563: tx overrun\n");
1040 bp = i82563rballoc(p);
1042 if(rdt - ctlr->rdh >= 16)
1044 print("i82563%d: no rx buffers\n", ctlr->pool);
1050 sleep(p, icansleep, p);
1055 rd->addr[0] = PCIWADDR(bp->rp);
1056 // rd->addr[1] = Pciwaddrh(bp->rp);
1062 csr32w(ctlr, Rdt, rdt);
1068 i82563rxinit(Ctlr *ctlr)
1073 if(ctlr->rbsz <= 2048)
1074 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
1076 i = ctlr->rbsz / 1024;
1077 if(ctlr->rbsz % 1024)
1079 if(cttab[ctlr->type].flag & F75){
1080 csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
1081 if(ctlr->type != i82575)
1082 i |= (ctlr->nrd/2>>4)<<20; /* RdmsHalf */
1083 csr32w(ctlr, Srrctl, i | Dropen);
1084 csr32w(ctlr, Rmpl, ctlr->rbsz);
1085 // csr32w(ctlr, Drxmxod, 0x7ff);
1087 csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
1090 if(cttab[ctlr->type].flag & Fert)
1091 csr32w(ctlr, Ert, 1024/8);
1093 if(ctlr->type == i82566)
1094 csr32w(ctlr, Pbs, 16);
1096 csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1097 // csr32w(ctlr, Rdbah, Pciwaddrh(ctlr->rdba));
1098 csr32w(ctlr, Rdbah, 0);
1099 csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
1101 csr32w(ctlr, Rdh, 0);
1103 csr32w(ctlr, Rdt, 0);
1106 csr32w(ctlr, Rdtr, ctlr->rdtr);
1107 csr32w(ctlr, Radv, ctlr->radv);
1109 for(i = 0; i < ctlr->nrd; i++)
1110 if((bp = ctlr->rb[i]) != nil){
1114 if(cttab[ctlr->type].flag & F75)
1115 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
1117 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
1120 * Enable checksum offload.
1122 csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
1128 return ((Ctlr*)v)->rim != 0;
1132 i82563rproc(void *arg)
1134 uint m, rdh, rim, im;
1144 csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1145 if(cttab[ctlr->type].flag & F75){
1146 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1147 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1149 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1155 i82563replenish(ctlr, 1);
1156 sleep(&ctlr->rrendez, i82563rim, ctlr);
1160 rd = &ctlr->rdba[rdh];
1163 if(!(rd->status & Rdd))
1167 * Accept eop packets with no errors.
1168 * With no errors and the Ixsm bit set,
1169 * the descriptor status Tpcs and Ipcs bits give
1170 * an indication of whether the checksums were
1171 * calculated and valid.
1174 if((rd->status & Reop) && rd->errors == 0){
1175 bp->wp += rd->length;
1176 bp->lim = bp->wp; /* lie like a dog. avoid packblock. */
1177 if(!(rd->status & Ixsm)){
1179 if(rd->status & Ipcs){
1181 * IP checksum calculated
1182 * (and valid as errors == 0).
1187 if(rd->status & Tcpcs){
1189 * TCP/UDP checksum calculated
1190 * (and valid as errors == 0).
1193 bp->flag |= Btcpck|Budpck;
1195 bp->checksum = rd->checksum;
1198 etheriq(edev, bp, 1);
1201 ctlr->rb[rdh] = nil;
1204 ctlr->rdh = rdh = Next(rdh, m);
1205 if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1206 if(i82563replenish(ctlr, 0) == -1)
1215 return ((Ctlr*)v)->lim != 0;
1218 static int speedtab[] = {
1223 phyread(Ctlr *c, int phyno, int reg)
1227 csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1229 for(i = 0; i < 64; i++){
1230 phy = csr32r(c, Mdic);
1231 if(phy & (MDIe|MDIready))
1235 if((phy & (MDIe|MDIready)) != MDIready){
1236 print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);
1239 return phy & 0xffff;
1243 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1247 csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1249 for(i = 0; i < 64; i++){
1250 phy = csr32r(c, Mdic);
1251 if(phy & (MDIe|MDIready))
1255 if((phy & (MDIe|MDIready)) != MDIready)
1261 setpage(Ctlr *c, uint phyno, uint p, uint r)
1265 if(c->type == i82563){
1266 if(r >= 16 && r <= 28 && r != 22)
1268 else if(r == 30 || r == 31)
1272 return phywrite0(c, phyno, pr, p);
1279 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1281 if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1282 panic("%s: bad phy reg %.4ux", cname(c), reg);
1283 return phywrite0(c, phyno, reg & 0xff, v);
1287 phyerrata(Ether *e, Ctlr *c)
1290 if(c->phyerrata == 0){
1292 phywrite(c, 1, Phyprst, Prst); /* try a port reset */
1293 print("%s: phy port reset\n", cname(c));
1302 uint a, i, r, phy, phyno;
1310 if(c->type == i82579)
1314 phy = phyread(c, phyno, Phystat);
1320 r = phyread(c, phyno, Phyctl);
1321 phywrite(c, phyno, Phyctl, r | Ran | Ean);
1323 e->link = (phy & Link) != 0;
1327 e->mbps = speedtab[i];
1332 sleep(&c->lrendez, i82563lim, c);
1346 if(c->type == i82573 && (phy = phyread(c, 1, Phyier)) != ~0)
1347 phywrite(c, 1, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1349 phy = phyread(c, 1, Physsr);
1361 a = phyread(c, 1, Phyisr) & Ane;
1367 a = phyread(c, 1, Phylhr) & Anf;
1372 phywrite(c, 1, Phyctl, phyread(c, 1, Phyctl) | Ran | Ean);
1373 e->link = (phy & Rtlink) != 0;
1377 e->mbps = speedtab[i];
1378 if(c->type == i82563)
1384 sleep(&c->lrendez, i82563lim, c);
1399 phy = csr32r(c, Pcsstat);
1400 e->link = phy & Linkok;
1404 else if(phy & Anbad)
1405 csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1407 e->mbps = speedtab[i];
1411 sleep(&c->lrendez, i82563lim, c);
1416 serdeslproc(void *v)
1426 rx = csr32r(c, Rxcw);
1427 tx = csr32r(c, Txcw);
1429 e->link = (rx & 1<<31) != 0;
1430 // e->link = (csr32r(c, Status) & Lu) != 0;
1435 e->mbps = speedtab[i];
1439 sleep(&c->lrendez, i82563lim, c);
1444 i82563attach(Ether *edev)
1446 char name[KNAMELEN];
1452 qlock(&ctlr->alock);
1453 if(ctlr->alloc != nil){
1454 qunlock(&ctlr->alock);
1460 ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1461 if(ctlr->alloc == nil){
1462 qunlock(&ctlr->alock);
1465 ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1466 ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1468 ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1469 ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1472 while(bp = i82563rballoc(rbtab + ctlr->pool)){
1482 qunlock(&ctlr->alock);
1486 for(i = 0; i < Nrb; i++){
1487 bp = allocb(ctlr->rbsz + Rbalign);
1488 bp->free = freetab[ctlr->pool];
1492 snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1493 if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1494 kproc(name, pcslproc, edev); /* phy based serdes */
1495 else if(csr32r(ctlr, Status) & Tbimode)
1496 kproc(name, serdeslproc, edev); /* mac based serdes */
1497 else if(ctlr->type == i82579 || ctlr->type == i82580)
1498 kproc(name, phyl79proc, edev);
1500 kproc(name, phylproc, edev);
1502 snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1503 kproc(name, i82563rproc, edev);
1505 snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1506 kproc(name, i82563tproc, edev);
1508 qunlock(&ctlr->alock);
1513 i82563interrupt(Ureg*, void *arg)
1522 ilock(&ctlr->imlock);
1523 csr32w(ctlr, Imc, ~0);
1526 while(icr = csr32r(ctlr, Icr) & ctlr->im){
1529 ctlr->lim = icr & Lsc;
1530 wakeup(&ctlr->lrendez);
1533 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1534 ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1535 im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1536 wakeup(&ctlr->rrendez);
1542 wakeup(&ctlr->trendez);
1547 csr32w(ctlr, Ims, im);
1548 iunlock(&ctlr->imlock);
1552 i82563detach(Ctlr *ctlr)
1556 /* balance rx/tx packet buffer; survives reset */
1557 if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1558 ctlr->pba = csr32r(ctlr, Pba);
1559 r = ctlr->pba >> 16;
1560 r += ctlr->pba & 0xffff;
1562 csr32w(ctlr, Pba, r);
1563 }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1564 csr32w(ctlr, Pba, 14);
1565 ctlr->pba = csr32r(ctlr, Pba);
1568 * Perform a device reset to get the chip back to the
1569 * power-on state, followed by an EEPROM reset to read
1570 * the defaults for some internal registers.
1572 csr32w(ctlr, Imc, ~0);
1573 csr32w(ctlr, Rctl, 0);
1574 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1578 r = csr32r(ctlr, Ctrl);
1579 if(ctlr->type == i82566 || ctlr->type == i82579)
1581 csr32w(ctlr, Ctrl, Devrst | r);
1583 for(timeo = 0;; timeo++){
1584 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1591 r = csr32r(ctlr, Ctrl);
1592 csr32w(ctlr, Ctrl, Slu|r);
1594 r = csr32r(ctlr, Ctrlext);
1595 csr32w(ctlr, Ctrlext, r|Eerst);
1597 for(timeo = 0; timeo < 1000; timeo++){
1598 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1602 if(csr32r(ctlr, Ctrlext) & Eerst)
1605 csr32w(ctlr, Imc, ~0);
1607 for(timeo = 0; timeo < 1000; timeo++){
1608 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1612 if(csr32r(ctlr, Icr) & ~Rxcfg)
1619 i82563shutdown(Ether *edev)
1621 i82563detach(edev->ctlr);
1625 eeread(Ctlr *ctlr, int adr)
1627 csr32w(ctlr, Eerd, EEstart | adr << 2);
1628 while ((csr32r(ctlr, Eerd) & EEdone) == 0)
1630 return csr32r(ctlr, Eerd) >> 16;
1640 for (adr = 0; adr < 0x40; adr++) {
1641 data = eeread(ctlr, adr);
1642 ctlr->eeprom[adr] = data;
1649 fcycle(Ctlr *, Flash *f)
1656 f->reg[Fsts] |= Fcerr | Ael;
1657 for(i = 0; i < 10; i++){
1667 fread(Ctlr *c, Flash *f, int ladr)
1672 if(fcycle(c, f) == -1)
1674 f->reg[Fsts] |= Fdone;
1675 f->reg32[Faddr] = ladr;
1677 /* setup flash control register */
1678 s = f->reg[Fctl] & ~0x3ff;
1679 f->reg[Fctl] = s | 1<<8 | Fgo; /* 2 byte read */
1681 while((f->reg[Fsts] & Fdone) == 0)
1683 if(f->reg[Fsts] & (Fcerr|Ael))
1685 return f->reg32[Fdata] & 0xffff;
1691 ulong data, io, r, adr;
1695 io = c->pcidev->mem[1].bar & ~0x0f;
1696 f.reg = vmap(io, c->pcidev->mem[1].size);
1699 f.reg32 = (ulong*)f.reg;
1700 f.sz = f.reg32[Bfpr];
1701 if(csr32r(c, Eec) & 1<<22){
1702 if(c->type == i82579)
1703 f.sz += 16; /* sector size: 64k */
1705 f.sz += 1; /* sector size: 4k */
1707 r = (f.sz & 0x1fff) << 12;
1709 for(adr = 0; adr < 0x40; adr++) {
1710 data = fread(c, &f, r + adr*2);
1713 c->eeprom[adr] = data;
1716 vunmap(f.reg, c->pcidev->mem[1].size);
1721 defaultea(Ctlr *ctlr, uchar *ra)
1725 static uchar nilea[Eaddrlen];
1727 if(memcmp(ra, nilea, Eaddrlen) != 0)
1729 if(cttab[ctlr->type].flag & Fflashea){
1731 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1732 for(i = 0; i < Eaddrlen; i++)
1735 if(memcmp(ra, nilea, Eaddrlen) != 0)
1737 for(i = 0; i < Eaddrlen/2; i++){
1738 ra[2*i] = ctlr->eeprom[Ea+i];
1739 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1741 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1742 ra[5] += r; /* ea ctlr[n] = ea ctlr[0]+n */
1746 i82563reset(Ctlr *ctlr)
1751 if(i82563detach(ctlr))
1753 if(cttab[ctlr->type].flag & Fload)
1757 if(r != 0 && r != 0xbaba){
1758 print("%s: bad eeprom checksum - %#.4ux\n",
1764 defaultea(ctlr, ra);
1765 csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1766 csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1767 for(i = 1; i < 16; i++){
1768 csr32w(ctlr, Ral+i*8, 0);
1769 csr32w(ctlr, Rah+i*8, 0);
1771 memset(ctlr->mta, 0, sizeof(ctlr->mta));
1772 for(i = 0; i < 128; i++)
1773 csr32w(ctlr, Mta + i*4, 0);
1774 csr32w(ctlr, Fcal, 0x00C28001);
1775 csr32w(ctlr, Fcah, 0x0100);
1776 if(ctlr->type != i82579)
1777 csr32w(ctlr, Fct, 0x8808);
1778 csr32w(ctlr, Fcttv, 0x0100);
1779 csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1780 csr32w(ctlr, Fcrth, ctlr->fcrth);
1781 if(cttab[ctlr->type].flag & F75)
1782 csr32w(ctlr, Eitr, 128<<2); /* 128 ¼ microsecond intervals */
1793 static Cmdtab i82563ctlmsg[] = {
1796 CMpause, "pause", 1,
1801 i82563ctl(Ether *edev, void *buf, long n)
1809 if((ctlr = edev->ctlr) == nil)
1812 cb = parsecmd(buf, n);
1818 ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1821 v = strtoul(cb->f[1], &p, 0);
1822 if(*p || v > 0xffff)
1825 csr32w(ctlr, Rdtr, v);
1828 v = strtoul(cb->f[1], &p, 0);
1829 if(*p || v > 0xffff)
1832 csr32w(ctlr, Radv, v);
1835 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (1<<27 | 1<<28));
1838 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1852 case 0x10ba: /* “gilgal” */
1853 // case 0x1098: /* serdes; not seen */
1854 // case 0x10bb: /* serdes */
1856 case 0x1049: /* mm */
1857 case 0x104a: /* dm */
1858 case 0x104b: /* dc */
1859 case 0x104d: /* v “ninevah” */
1860 case 0x10bd: /* dm-2 */
1861 case 0x294c: /* ich 9 */
1863 case 0x10de: /* lm ich10d */
1864 case 0x10df: /* lf ich10 */
1865 case 0x10e5: /* lm ich9 */
1866 case 0x10f5: /* lm ich9m; “boazman” */
1868 case 0x10bf: /* lf ich9m */
1869 case 0x10cb: /* v ich9m */
1870 case 0x10cd: /* lf ich10 */
1871 case 0x10ce: /* v ich10 */
1872 case 0x10cc: /* lm ich10 */
1874 case 0x105e: /* eb */
1875 case 0x105f: /* eb */
1876 case 0x1060: /* eb */
1877 case 0x10a4: /* eb */
1878 case 0x10a5: /* eb fiber */
1879 case 0x10bc: /* eb */
1880 case 0x10d9: /* eb serdes */
1881 case 0x10da: /* eb serdes “ophir” */
1883 case 0x107d: /* eb copper */
1884 case 0x107e: /* ei fiber */
1885 case 0x107f: /* ei */
1886 case 0x10b9: /* ei “rimon” */
1888 case 0x108b: /* e “vidalia” */
1889 case 0x108c: /* e (iamt) */
1890 case 0x109a: /* l “tekoa” */
1892 case 0x10d3: /* l or it; “hartwell” */
1895 case 0x10a9: /* fiber/serdes */
1897 case 0x10c9: /* copper */
1898 case 0x10e6: /* fiber */
1899 case 0x10e7: /* serdes; “kawela” */
1901 case 0x10ea: /* lc “calpella”; aka pch lan */
1903 case 0x10eb: /* lm “calpella” */
1905 case 0x10ef: /* dc “piketon” */
1907 case 0x1502: /* lm */
1908 case 0x1503: /* v */
1910 case 0x10f0: /* dm “king's creek” */
1912 case 0x150e: /* “barton hills” */
1913 case 0x150f: /* fiber */
1914 case 0x1510: /* backplane */
1915 case 0x1511: /* sfp */
1918 case 0x1506: /* v */
1929 i = pcicfgr32(p, PciSVID);
1930 if((i & 0xffff) == 0x1b52 && p->did == 1)
1941 for(p = nil; p = pcimatch(p, 0x8086, 0);){
1943 if((type = didtype(p->did)) == -1)
1945 ctlr = malloc(sizeof(Ctlr));
1948 ctlr->rbsz = cttab[type].mtu;
1949 ctlr->port = p->mem[0].bar & ~0x0F;
1950 if(i82563ctlrhead != nil)
1951 i82563ctlrtail->next = ctlr;
1953 i82563ctlrhead = ctlr;
1954 i82563ctlrtail = ctlr;
1963 if((ctlr->pool = newpool()) == -1){
1964 print("%s: no pool\n", cname(ctlr));
1968 ctlr->nic = vmap(ctlr->port, p->mem[0].size);
1969 if(ctlr->nic == nil){
1970 print("%s: can't map %#p\n", cname(ctlr), ctlr->port);
1973 if(i82563reset(ctlr)){
1974 vunmap(ctlr->nic, p->mem[0].size);
1977 pcisetbme(ctlr->pcidev);
1982 pnp(Ether *edev, int type)
1993 * Any adapter matches if no edev->port is supplied,
1994 * otherwise the ports must match.
1996 for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
2001 if(type != -1 && ctlr->type != type)
2003 if(edev->port == 0 || edev->port == ctlr->port){
2005 memmove(ctlr->ra, edev->ea, Eaddrlen);
2006 if(setup(ctlr) == 0)
2012 edev->port = ctlr->port;
2013 edev->irq = ctlr->pcidev->intl;
2014 edev->tbdf = ctlr->pcidev->tbdf;
2016 edev->maxmtu = ctlr->rbsz;
2017 memmove(edev->ea, ctlr->ra, Eaddrlen);
2020 * Linkage to the generic ethernet driver.
2022 edev->attach = i82563attach;
2023 // edev->transmit = i82563transmit;
2024 edev->interrupt = i82563interrupt;
2025 edev->ifstat = i82563ifstat;
2026 edev->ctl = i82563ctl;
2029 edev->promiscuous = i82563promiscuous;
2030 edev->shutdown = i82563shutdown;
2031 edev->multicast = i82563multicast;
2045 return pnp(e, i82563);
2051 return pnp(e, i82566);
2057 return pnp(e, i82567m) & pnp(e, i82567);
2063 return pnp(e, i82571);
2069 return pnp(e, i82572);
2075 return pnp(e, i82573);
2081 return pnp(e, i82574);
2087 return pnp(e, i82575);
2093 return pnp(e, i82576);
2099 return pnp(e, i82577m) & pnp(e, i82577);
2105 return pnp(e, i82578m) & pnp(e, i82578);
2111 return pnp(e, i82579);
2117 return pnp(e, i82580);
2123 return pnp(e, i82583);
2127 ether82563link(void)
2130 * recognise lots of model numbers for debugging
2131 * also good for forcing onboard nic(s) as ether0
2132 * try to make that unnecessary by listing lom first.
2134 addethercard("i82563", i82563pnp);
2135 addethercard("i82566", i82566pnp);
2136 addethercard("i82574", i82574pnp);
2137 addethercard("i82576", i82576pnp);
2138 addethercard("i82567", i82567pnp);
2139 addethercard("i82573", i82573pnp);
2141 addethercard("i82571", i82571pnp);
2142 addethercard("i82572", i82572pnp);
2143 addethercard("i82575", i82575pnp);
2144 addethercard("i82577", i82577pnp);
2145 addethercard("i82578", i82578pnp);
2146 addethercard("i82579", i82579pnp);
2147 addethercard("i82580", i82580pnp);
2148 addethercard("i82583", i82583pnp);
2149 addethercard("igbepcie", anypnp);