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){
814 rbfree(Block *b, int t)
819 b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
820 b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
827 iprint("wakey %d; %d %d\n", t, p->nstarve, p->nwakey);
883 static Freefn freetab[Npool] = {
899 if(seq == nelem(freetab))
901 if(freetab[seq] == nil){
902 print("82563: bad freetab\n");
909 i82563im(Ctlr *ctlr, int im)
911 ilock(&ctlr->imlock);
913 csr32w(ctlr, Ims, ctlr->im);
914 iunlock(&ctlr->imlock);
918 i82563txinit(Ctlr *ctlr)
923 if(cttab[ctlr->type].flag & F75)
924 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp);
926 csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
927 csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8); /* yb sez: 0x702008 */
928 csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
929 // csr32w(ctlr, Tdbah, Pciwaddrh(ctlr->tdba));
930 csr32w(ctlr, Tdbah, 0);
931 csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
932 ctlr->tdh = PREV(0, ctlr->ntd);
933 csr32w(ctlr, Tdh, 0);
935 csr32w(ctlr, Tdt, 0);
936 for(i = 0; i < ctlr->ntd; i++){
937 if((b = ctlr->tb[i]) != nil){
941 memset(&ctlr->tdba[i], 0, sizeof(Td));
943 csr32w(ctlr, Tidv, 128);
944 csr32w(ctlr, Tadv, 64);
945 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) | Ten);
946 r = csr32r(ctlr, Txdctl) & ~WthreshMASK;
947 r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
948 if(cttab[ctlr->type].flag & F75)
950 csr32w(ctlr, Txdctl, r);
953 #define Next(x, m) (((x)+1) & (m))
956 i82563cleanup(Ctlr *c)
963 while(c->tdba[n = Next(tdh, m)].status & Tdd){
965 if((b = c->tb[tdh]) != nil){
969 iprint("82563 tx underrun!\n");
970 c->tdba[tdh].status = 0;
982 return (c->im & Txdw) == 0;
1002 tdh = i82563cleanup(ctlr);
1004 if(Next(tdt, m) == tdh){
1006 i82563im(ctlr, Txdw);
1007 sleep(&ctlr->trendez, notrim, ctlr);
1009 bp = qbread(edev->oq, 100000);
1010 td = &ctlr->tdba[tdt];
1011 td->addr[0] = PCIWADDR(bp->rp);
1012 // td->addr[1] = Pciwaddrh(bp->rp);
1013 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
1016 csr32w(ctlr, Tdt, tdt);
1021 i82563replenish(Ctlr *ctlr, int maysleep)
1030 p = rbtab + ctlr->pool;
1032 for(; Next(rdt, m) != ctlr->rdh; rdt = Next(rdt, m)){
1033 rd = &ctlr->rdba[rdt];
1034 if(ctlr->rb[rdt] != nil){
1035 iprint("82563: tx overrun\n");
1039 bp = i82563rballoc(p);
1041 if(rdt - ctlr->rdh >= 16)
1043 print("i82563%d: no rx buffers\n", ctlr->pool);
1049 sleep(p, icansleep, p);
1054 rd->addr[0] = PCIWADDR(bp->rp);
1055 // rd->addr[1] = Pciwaddrh(bp->rp);
1061 csr32w(ctlr, Rdt, rdt);
1067 i82563rxinit(Ctlr *ctlr)
1072 if(ctlr->rbsz <= 2048)
1073 csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
1075 i = ctlr->rbsz / 1024;
1076 if(ctlr->rbsz % 1024)
1078 if(cttab[ctlr->type].flag & F75){
1079 csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
1080 if(ctlr->type != i82575)
1081 i |= (ctlr->nrd/2>>4)<<20; /* RdmsHalf */
1082 csr32w(ctlr, Srrctl, i | Dropen);
1083 csr32w(ctlr, Rmpl, ctlr->rbsz);
1084 // csr32w(ctlr, Drxmxod, 0x7ff);
1086 csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
1089 if(cttab[ctlr->type].flag & Fert)
1090 csr32w(ctlr, Ert, 1024/8);
1092 if(ctlr->type == i82566)
1093 csr32w(ctlr, Pbs, 16);
1095 csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
1096 // csr32w(ctlr, Rdbah, Pciwaddrh(ctlr->rdba));
1097 csr32w(ctlr, Rdbah, 0);
1098 csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
1100 csr32w(ctlr, Rdh, 0);
1102 csr32w(ctlr, Rdt, 0);
1105 csr32w(ctlr, Rdtr, ctlr->rdtr);
1106 csr32w(ctlr, Radv, ctlr->radv);
1108 for(i = 0; i < ctlr->nrd; i++)
1109 if((bp = ctlr->rb[i]) != nil){
1113 if(cttab[ctlr->type].flag & F75)
1114 csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
1116 csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
1119 * Enable checksum offload.
1121 csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE);
1127 return ((Ctlr*)v)->rim != 0;
1131 i82563rproc(void *arg)
1133 uint m, rdh, rim, im;
1143 csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
1144 if(cttab[ctlr->type].flag & F75){
1145 csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
1146 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1148 im = Rxt0|Rxo|Rxdmt0|Rxseq|Ack;
1154 i82563replenish(ctlr, 1);
1155 sleep(&ctlr->rrendez, i82563rim, ctlr);
1159 rd = &ctlr->rdba[rdh];
1162 if(!(rd->status & Rdd))
1166 * Accept eop packets with no errors.
1167 * With no errors and the Ixsm bit set,
1168 * the descriptor status Tpcs and Ipcs bits give
1169 * an indication of whether the checksums were
1170 * calculated and valid.
1173 if((rd->status & Reop) && rd->errors == 0){
1174 bp->wp += rd->length;
1175 bp->lim = bp->wp; /* lie like a dog. avoid packblock. */
1176 if(!(rd->status & Ixsm)){
1178 if(rd->status & Ipcs){
1180 * IP checksum calculated
1181 * (and valid as errors == 0).
1186 if(rd->status & Tcpcs){
1188 * TCP/UDP checksum calculated
1189 * (and valid as errors == 0).
1192 bp->flag |= Btcpck|Budpck;
1194 bp->checksum = rd->checksum;
1197 etheriq(edev, bp, 1);
1200 ctlr->rb[rdh] = nil;
1203 ctlr->rdh = rdh = Next(rdh, m);
1204 if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
1205 if(i82563replenish(ctlr, 0) == -1)
1214 return ((Ctlr*)v)->lim != 0;
1217 static int speedtab[] = {
1222 phyread(Ctlr *c, int phyno, int reg)
1226 csr32w(c, Mdic, MDIrop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT);
1228 for(i = 0; i < 64; i++){
1229 phy = csr32r(c, Mdic);
1230 if(phy & (MDIe|MDIready))
1234 if((phy & (MDIe|MDIready)) != MDIready){
1235 print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);
1238 return phy & 0xffff;
1242 phywrite0(Ctlr *c, int phyno, int reg, ushort val)
1246 csr32w(c, Mdic, MDIwop | phyno<<MDIpSHIFT | reg<<MDIrSHIFT | val);
1248 for(i = 0; i < 64; i++){
1249 phy = csr32r(c, Mdic);
1250 if(phy & (MDIe|MDIready))
1254 if((phy & (MDIe|MDIready)) != MDIready)
1260 setpage(Ctlr *c, uint phyno, uint p, uint r)
1264 if(c->type == i82563){
1265 if(r >= 16 && r <= 28 && r != 22)
1267 else if(r == 30 || r == 31)
1271 return phywrite0(c, phyno, pr, p);
1278 phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
1280 if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
1281 panic("%s: bad phy reg %.4ux", cname(c), reg);
1282 return phywrite0(c, phyno, reg & 0xff, v);
1286 phyerrata(Ether *e, Ctlr *c)
1289 if(c->phyerrata == 0){
1291 phywrite(c, 1, Phyprst, Prst); /* try a port reset */
1292 print("%s: phy port reset\n", cname(c));
1301 uint a, i, r, phy, phyno;
1309 if(c->type == i82579)
1313 phy = phyread(c, phyno, Phystat);
1319 r = phyread(c, phyno, Phyctl);
1320 phywrite(c, phyno, Phyctl, r | Ran | Ean);
1322 e->link = (phy & Link) != 0;
1326 e->mbps = speedtab[i];
1331 sleep(&c->lrendez, i82563lim, c);
1345 if(c->type == i82573 && (phy = phyread(c, 1, Phyier)) != ~0)
1346 phywrite(c, 1, Phyier, phy | Lscie | Ancie | Spdie | Panie);
1348 phy = phyread(c, 1, Physsr);
1360 a = phyread(c, 1, Phyisr) & Ane;
1366 a = phyread(c, 1, Phylhr) & Anf;
1371 phywrite(c, 1, Phyctl, phyread(c, 1, Phyctl) | Ran | Ean);
1372 e->link = (phy & Rtlink) != 0;
1376 e->mbps = speedtab[i];
1377 if(c->type == i82563)
1383 sleep(&c->lrendez, i82563lim, c);
1398 phy = csr32r(c, Pcsstat);
1399 e->link = phy & Linkok;
1403 else if(phy & Anbad)
1404 csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
1406 e->mbps = speedtab[i];
1410 sleep(&c->lrendez, i82563lim, c);
1415 serdeslproc(void *v)
1425 rx = csr32r(c, Rxcw);
1426 tx = csr32r(c, Txcw);
1428 e->link = (rx & 1<<31) != 0;
1429 // e->link = (csr32r(c, Status) & Lu) != 0;
1434 e->mbps = speedtab[i];
1438 sleep(&c->lrendez, i82563lim, c);
1443 i82563attach(Ether *edev)
1445 char name[KNAMELEN];
1451 qlock(&ctlr->alock);
1452 if(ctlr->alloc != nil){
1453 qunlock(&ctlr->alock);
1459 ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
1460 if(ctlr->alloc == nil){
1461 qunlock(&ctlr->alock);
1464 ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
1465 ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
1467 ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
1468 ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
1471 while(bp = i82563rballoc(rbtab + ctlr->pool)){
1481 qunlock(&ctlr->alock);
1485 for(i = 0; i < Nrb; i++){
1486 bp = allocb(ctlr->rbsz + Rbalign);
1487 bp->free = freetab[ctlr->pool];
1491 snprint(name, sizeof name, "#l%dl", edev->ctlrno);
1492 if((csr32r(ctlr, Ctrlext) & Linkmode) == Serdes)
1493 kproc(name, pcslproc, edev); /* phy based serdes */
1494 else if(csr32r(ctlr, Status) & Tbimode)
1495 kproc(name, serdeslproc, edev); /* mac based serdes */
1496 else if(ctlr->type == i82579 || ctlr->type == i82580)
1497 kproc(name, phyl79proc, edev);
1499 kproc(name, phylproc, edev);
1501 snprint(name, sizeof name, "#l%dr", edev->ctlrno);
1502 kproc(name, i82563rproc, edev);
1504 snprint(name, sizeof name, "#l%dt", edev->ctlrno);
1505 kproc(name, i82563tproc, edev);
1507 qunlock(&ctlr->alock);
1512 i82563interrupt(Ureg*, void *arg)
1521 ilock(&ctlr->imlock);
1522 csr32w(ctlr, Imc, ~0);
1525 while(icr = csr32r(ctlr, Icr) & ctlr->im){
1528 ctlr->lim = icr & Lsc;
1529 wakeup(&ctlr->lrendez);
1532 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
1533 ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1534 im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
1535 wakeup(&ctlr->rrendez);
1541 wakeup(&ctlr->trendez);
1546 csr32w(ctlr, Ims, im);
1547 iunlock(&ctlr->imlock);
1551 i82563detach(Ctlr *ctlr)
1555 /* balance rx/tx packet buffer; survives reset */
1556 if(ctlr->rbsz > 8192 && cttab[ctlr->type].flag & Fpba){
1557 ctlr->pba = csr32r(ctlr, Pba);
1558 r = ctlr->pba >> 16;
1559 r += ctlr->pba & 0xffff;
1561 csr32w(ctlr, Pba, r);
1562 }else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
1563 csr32w(ctlr, Pba, 14);
1564 ctlr->pba = csr32r(ctlr, Pba);
1567 * Perform a device reset to get the chip back to the
1568 * power-on state, followed by an EEPROM reset to read
1569 * the defaults for some internal registers.
1571 csr32w(ctlr, Imc, ~0);
1572 csr32w(ctlr, Rctl, 0);
1573 csr32w(ctlr, Tctl, csr32r(ctlr, Tctl) & ~Ten);
1577 r = csr32r(ctlr, Ctrl);
1578 if(ctlr->type == i82566 || ctlr->type == i82579)
1580 csr32w(ctlr, Ctrl, Devrst | r);
1582 for(timeo = 0;; timeo++){
1583 if((csr32r(ctlr, Ctrl) & (Devrst|Phyrst)) == 0)
1590 r = csr32r(ctlr, Ctrl);
1591 csr32w(ctlr, Ctrl, Slu|r);
1593 r = csr32r(ctlr, Ctrlext);
1594 csr32w(ctlr, Ctrlext, r|Eerst);
1596 for(timeo = 0; timeo < 1000; timeo++){
1597 if(!(csr32r(ctlr, Ctrlext) & Eerst))
1601 if(csr32r(ctlr, Ctrlext) & Eerst)
1604 csr32w(ctlr, Imc, ~0);
1606 for(timeo = 0; timeo < 1000; timeo++){
1607 if((csr32r(ctlr, Icr) & ~Rxcfg) == 0)
1611 if(csr32r(ctlr, Icr) & ~Rxcfg)
1618 i82563shutdown(Ether *edev)
1620 i82563detach(edev->ctlr);
1624 eeread(Ctlr *ctlr, int adr)
1626 csr32w(ctlr, Eerd, EEstart | adr << 2);
1627 while ((csr32r(ctlr, Eerd) & EEdone) == 0)
1629 return csr32r(ctlr, Eerd) >> 16;
1639 for (adr = 0; adr < 0x40; adr++) {
1640 data = eeread(ctlr, adr);
1641 ctlr->eeprom[adr] = data;
1648 fcycle(Ctlr *, Flash *f)
1655 f->reg[Fsts] |= Fcerr | Ael;
1656 for(i = 0; i < 10; i++){
1666 fread(Ctlr *c, Flash *f, int ladr)
1671 if(fcycle(c, f) == -1)
1673 f->reg[Fsts] |= Fdone;
1674 f->reg32[Faddr] = ladr;
1676 /* setup flash control register */
1677 s = f->reg[Fctl] & ~0x3ff;
1678 f->reg[Fctl] = s | 1<<8 | Fgo; /* 2 byte read */
1680 while((f->reg[Fsts] & Fdone) == 0)
1682 if(f->reg[Fsts] & (Fcerr|Ael))
1684 return f->reg32[Fdata] & 0xffff;
1690 ulong data, io, r, adr;
1694 io = c->pcidev->mem[1].bar & ~0x0f;
1695 f.reg = vmap(io, c->pcidev->mem[1].size);
1698 f.reg32 = (ulong*)f.reg;
1699 f.sz = f.reg32[Bfpr];
1700 if(csr32r(c, Eec) & 1<<22){
1701 if(c->type == i82579)
1702 f.sz += 16; /* sector size: 64k */
1704 f.sz += 1; /* sector size: 4k */
1706 r = (f.sz & 0x1fff) << 12;
1708 for(adr = 0; adr < 0x40; adr++) {
1709 data = fread(c, &f, r + adr*2);
1712 c->eeprom[adr] = data;
1715 vunmap(f.reg, c->pcidev->mem[1].size);
1720 defaultea(Ctlr *ctlr, uchar *ra)
1724 static uchar nilea[Eaddrlen];
1726 if(memcmp(ra, nilea, Eaddrlen) != 0)
1728 if(cttab[ctlr->type].flag & Fflashea){
1730 u = (uvlong)csr32r(ctlr, Rah)<<32u | (ulong)csr32r(ctlr, Ral);
1731 for(i = 0; i < Eaddrlen; i++)
1734 if(memcmp(ra, nilea, Eaddrlen) != 0)
1736 for(i = 0; i < Eaddrlen/2; i++){
1737 ra[2*i] = ctlr->eeprom[Ea+i];
1738 ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
1740 r = (csr32r(ctlr, Status) & Lanid) >> 2;
1741 ra[5] += r; /* ea ctlr[n] = ea ctlr[0]+n */
1745 i82563reset(Ctlr *ctlr)
1750 if(i82563detach(ctlr))
1752 if(cttab[ctlr->type].flag & Fload)
1756 if(r != 0 && r != 0xbaba){
1757 print("%s: bad eeprom checksum - %#.4ux\n",
1763 defaultea(ctlr, ra);
1764 csr32w(ctlr, Ral, ra[3]<<24 | ra[2]<<16 | ra[1]<<8 | ra[0]);
1765 csr32w(ctlr, Rah, 1<<31 | ra[5]<<8 | ra[4]);
1766 for(i = 1; i < 16; i++){
1767 csr32w(ctlr, Ral+i*8, 0);
1768 csr32w(ctlr, Rah+i*8, 0);
1770 memset(ctlr->mta, 0, sizeof(ctlr->mta));
1771 for(i = 0; i < 128; i++)
1772 csr32w(ctlr, Mta + i*4, 0);
1773 csr32w(ctlr, Fcal, 0x00C28001);
1774 csr32w(ctlr, Fcah, 0x0100);
1775 if(ctlr->type != i82579)
1776 csr32w(ctlr, Fct, 0x8808);
1777 csr32w(ctlr, Fcttv, 0x0100);
1778 csr32w(ctlr, Fcrtl, ctlr->fcrtl);
1779 csr32w(ctlr, Fcrth, ctlr->fcrth);
1780 if(cttab[ctlr->type].flag & F75)
1781 csr32w(ctlr, Eitr, 128<<2); /* 128 ¼ microsecond intervals */
1792 static Cmdtab i82563ctlmsg[] = {
1795 CMpause, "pause", 1,
1800 i82563ctl(Ether *edev, void *buf, long n)
1808 if((ctlr = edev->ctlr) == nil)
1811 cb = parsecmd(buf, n);
1817 ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
1820 v = strtoul(cb->f[1], &p, 0);
1821 if(*p || v > 0xffff)
1824 csr32w(ctlr, Rdtr, v);
1827 v = strtoul(cb->f[1], &p, 0);
1828 if(*p || v > 0xffff)
1831 csr32w(ctlr, Radv, v);
1834 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) ^ (1<<27 | 1<<28));
1837 csr32w(ctlr, Ctrl, csr32r(ctlr, Ctrl) | Lrst | Phyrst);
1851 case 0x10ba: /* “gilgal” */
1852 // case 0x1098: /* serdes; not seen */
1853 // case 0x10bb: /* serdes */
1855 case 0x1049: /* mm */
1856 case 0x104a: /* dm */
1857 case 0x104b: /* dc */
1858 case 0x104d: /* v “ninevah” */
1859 case 0x10bd: /* dm-2 */
1860 case 0x294c: /* ich 9 */
1862 case 0x10de: /* lm ich10d */
1863 case 0x10df: /* lf ich10 */
1864 case 0x10e5: /* lm ich9 */
1865 case 0x10f5: /* lm ich9m; “boazman” */
1867 case 0x10bf: /* lf ich9m */
1868 case 0x10cb: /* v ich9m */
1869 case 0x10cd: /* lf ich10 */
1870 case 0x10ce: /* v ich10 */
1871 case 0x10cc: /* lm ich10 */
1873 case 0x105e: /* eb */
1874 case 0x105f: /* eb */
1875 case 0x1060: /* eb */
1876 case 0x10a4: /* eb */
1877 case 0x10a5: /* eb fiber */
1878 case 0x10bc: /* eb */
1879 case 0x10d9: /* eb serdes */
1880 case 0x10da: /* eb serdes “ophir” */
1882 case 0x107d: /* eb copper */
1883 case 0x107e: /* ei fiber */
1884 case 0x107f: /* ei */
1885 case 0x10b9: /* ei “rimon” */
1887 case 0x108b: /* e “vidalia” */
1888 case 0x108c: /* e (iamt) */
1889 case 0x109a: /* l “tekoa” */
1891 case 0x10d3: /* l or it; “hartwell” */
1894 case 0x10a9: /* fiber/serdes */
1896 case 0x10c9: /* copper */
1897 case 0x10e6: /* fiber */
1898 case 0x10e7: /* serdes; “kawela” */
1900 case 0x10ea: /* lc “calpella”; aka pch lan */
1902 case 0x10eb: /* lm “calpella” */
1904 case 0x10ef: /* dc “piketon” */
1906 case 0x1502: /* lm */
1907 case 0x1503: /* v */
1909 case 0x10f0: /* dm “king's creek” */
1911 case 0x150e: /* “barton hills” */
1912 case 0x150f: /* fiber */
1913 case 0x1510: /* backplane */
1914 case 0x1511: /* sfp */
1917 case 0x1506: /* v */
1928 i = pcicfgr32(p, PciSVID);
1929 if((i & 0xffff) == 0x1b52 && p->did == 1)
1940 for(p = nil; p = pcimatch(p, 0x8086, 0);){
1942 if((type = didtype(p->did)) == -1)
1944 ctlr = malloc(sizeof(Ctlr));
1947 ctlr->rbsz = cttab[type].mtu;
1948 ctlr->port = p->mem[0].bar & ~0x0F;
1949 if(i82563ctlrhead != nil)
1950 i82563ctlrtail->next = ctlr;
1952 i82563ctlrhead = ctlr;
1953 i82563ctlrtail = ctlr;
1962 if((ctlr->pool = newpool()) == -1){
1963 print("%s: no pool\n", cname(ctlr));
1967 ctlr->nic = vmap(ctlr->port, p->mem[0].size);
1968 if(ctlr->nic == nil){
1969 print("%s: can't map %#p\n", cname(ctlr), ctlr->port);
1972 if(i82563reset(ctlr)){
1973 vunmap(ctlr->nic, p->mem[0].size);
1976 pcisetbme(ctlr->pcidev);
1981 pnp(Ether *edev, int type)
1992 * Any adapter matches if no edev->port is supplied,
1993 * otherwise the ports must match.
1995 for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
2000 if(type != -1 && ctlr->type != type)
2002 if(edev->port == 0 || edev->port == ctlr->port){
2004 memmove(ctlr->ra, edev->ea, Eaddrlen);
2005 if(setup(ctlr) == 0)
2011 edev->port = ctlr->port;
2012 edev->irq = ctlr->pcidev->intl;
2013 edev->tbdf = ctlr->pcidev->tbdf;
2015 edev->maxmtu = ctlr->rbsz;
2016 memmove(edev->ea, ctlr->ra, Eaddrlen);
2019 * Linkage to the generic ethernet driver.
2021 edev->attach = i82563attach;
2022 // edev->transmit = i82563transmit;
2023 edev->interrupt = i82563interrupt;
2024 edev->ifstat = i82563ifstat;
2025 edev->ctl = i82563ctl;
2028 edev->promiscuous = i82563promiscuous;
2029 edev->shutdown = i82563shutdown;
2030 edev->multicast = i82563multicast;
2044 return pnp(e, i82563);
2050 return pnp(e, i82566);
2056 return pnp(e, i82567m) & pnp(e, i82567);
2062 return pnp(e, i82571);
2068 return pnp(e, i82572);
2074 return pnp(e, i82573);
2080 return pnp(e, i82574);
2086 return pnp(e, i82575);
2092 return pnp(e, i82576);
2098 return pnp(e, i82577m) & pnp(e, i82577);
2104 return pnp(e, i82578m) & pnp(e, i82578);
2110 return pnp(e, i82579);
2116 return pnp(e, i82580);
2122 return pnp(e, i82583);
2126 ether82563link(void)
2129 * recognise lots of model numbers for debugging
2130 * also good for forcing onboard nic(s) as ether0
2131 * try to make that unnecessary by listing lom first.
2133 addethercard("i82563", i82563pnp);
2134 addethercard("i82566", i82566pnp);
2135 addethercard("i82574", i82574pnp);
2136 addethercard("i82576", i82576pnp);
2137 addethercard("i82567", i82567pnp);
2138 addethercard("i82573", i82573pnp);
2140 addethercard("i82571", i82571pnp);
2141 addethercard("i82572", i82572pnp);
2142 addethercard("i82575", i82575pnp);
2143 addethercard("i82577", i82577pnp);
2144 addethercard("i82578", i82578pnp);
2145 addethercard("i82579", i82579pnp);
2146 addethercard("i82580", i82580pnp);
2147 addethercard("i82583", i82583pnp);
2148 addethercard("igbepcie", anypnp);