1 /*
2 * National Semiconductor DP83820
3 * 10/100/1000 Mb/s Ethernet Network Interface Controller
4 * (Gig-NIC).
5 * Driver assumes little-endian and 32-bit host throughout.
6 */
7 #include "u.h"
8 #include "../port/lib.h"
9 #include "mem.h"
10 #include "dat.h"
11 #include "fns.h"
12 #include "io.h"
13 #include "../port/error.h"
14 #include "../port/netif.h"
15
16 #include "etherif.h"
17 #include "ethermii.h"
18
19 enum { /* Registers */
20 Cr = 0x00, /* Command */
21 Cfg = 0x04, /* Configuration and Media Status */
22 Mear = 0x08, /* MII/EEPROM Access */
23 Ptscr = 0x0C, /* PCI Test Control */
24 Isr = 0x10, /* Interrupt Status */
25 Imr = 0x14, /* Interrupt Mask */
26 Ier = 0x18, /* Interrupt Enable */
27 Ihr = 0x1C, /* Interrupt Holdoff */
28 Txdp = 0x20, /* Transmit Descriptor Pointer */
29 Txdphi = 0x24, /* Transmit Descriptor Pointer Hi */
30 Txcfg = 0x28, /* Transmit Configuration */
31 Gpior = 0x2C, /* General Purpose I/O Control */
32 Rxdp = 0x30, /* Receive Descriptor Pointer */
33 Rxdphi = 0x34, /* Receive Descriptor Pointer Hi */
34 Rxcfg = 0x38, /* Receive Configuration */
35 Pqcr = 0x3C, /* Priority Queueing Control */
36 Wcsr = 0x40, /* Wake on LAN Control/Status */
37 Pcr = 0x44, /* Pause Control/Status */
38 Rfcr = 0x48, /* Receive Filter/Match Control */
39 Rfdr = 0x4C, /* Receive Filter/Match Data */
40 Brar = 0x50, /* Boot ROM Address */
41 Brdr = 0x54, /* Boot ROM Data */
42 Srr = 0x58, /* Silicon Revision */
43 Mibc = 0x5C, /* MIB Control */
44 Mibd = 0x60, /* MIB Data */
45 Txdp1 = 0xA0, /* Txdp Priority 1 */
46 Txdp2 = 0xA4, /* Txdp Priority 2 */
47 Txdp3 = 0xA8, /* Txdp Priority 3 */
48 Rxdp1 = 0xB0, /* Rxdp Priority 1 */
49 Rxdp2 = 0xB4, /* Rxdp Priority 2 */
50 Rxdp3 = 0xB8, /* Rxdp Priority 3 */
51 Vrcr = 0xBC, /* VLAN/IP Receive Control */
52 Vtcr = 0xC0, /* VLAN/IP Transmit Control */
53 Vdr = 0xC4, /* VLAN Data */
54 Ccsr = 0xCC, /* Clockrun Control/Status */
55 Tbicr = 0xE0, /* TBI Control */
56 Tbisr = 0xE4, /* TBI Status */
57 Tanar = 0xE8, /* TBI ANAR */
58 Tanlpar = 0xEC, /* TBI ANLPAR */
59 Taner = 0xF0, /* TBI ANER */
60 Tesr = 0xF4, /* TBI ESR */
61 };
62
63 enum { /* Cr */
64 Txe = 0x00000001, /* Transmit Enable */
65 Txd = 0x00000002, /* Transmit Disable */
66 Rxe = 0x00000004, /* Receiver Enable */
67 Rxd = 0x00000008, /* Receiver Disable */
68 Txr = 0x00000010, /* Transmitter Reset */
69 Rxr = 0x00000020, /* Receiver Reset */
70 Swien = 0x00000080, /* Software Interrupt Enable */
71 Rst = 0x00000100, /* Reset */
72 TxpriSHFT = 9, /* Tx Priority Queue Select */
73 TxpriMASK = 0x00001E00,
74 RxpriSHFT = 13, /* Rx Priority Queue Select */
75 RxpriMASK = 0x0001E000,
76 };
77
78 enum { /* Configuration and Media Status */
79 Bem = 0x00000001, /* Big Endian Mode */
80 Ext125 = 0x00000002, /* External 125MHz reference Select */
81 Bromdis = 0x00000004, /* Disable Boot ROM interface */
82 Pesel = 0x00000008, /* Parity Error Detection Action */
83 Exd = 0x00000010, /* Excessive Deferral Abort */
84 Pow = 0x00000020, /* Program Out of Window Timer */
85 Sb = 0x00000040, /* Single Back-off */
86 Reqalg = 0x00000080, /* PCI Bus Request Algorithm */
87 Extstsen = 0x00000100, /* Extended Status Enable */
88 Phydis = 0x00000200, /* Disable PHY */
89 Phyrst = 0x00000400, /* Reset PHY */
90 M64addren = 0x00000800, /* Master 64-bit Addressing Enable */
91 Data64en = 0x00001000, /* 64-bit Data Enable */
92 Pci64det = 0x00002000, /* PCI 64-bit Bus Detected */
93 T64addren = 0x00004000, /* Target 64-bit Addressing Enable */
94 Mwidis = 0x00008000, /* MWI Disable */
95 Mrmdis = 0x00010000, /* MRM Disable */
96 Tmrtest = 0x00020000, /* Timer Test Mode */
97 Spdstsien = 0x00040000, /* PHY Spdsts Interrupt Enable */
98 Lnkstsien = 0x00080000, /* PHY Lnksts Interrupt Enable */
99 Dupstsien = 0x00100000, /* PHY Dupsts Interrupt Enable */
100 Mode1000 = 0x00400000, /* 1000Mb/s Mode Control */
101 Tbien = 0x01000000, /* Ten-Bit Interface Enable */
102 Dupsts = 0x10000000, /* Full Duplex Status */
103 Spdsts100 = 0x20000000, /* SPEED100 Input Pin Status */
104 Spdsts1000 = 0x40000000, /* SPEED1000 Input Pin Status */
105 Lnksts = 0x80000000, /* Link Status */
106 };
107
108 enum { /* MII/EEPROM Access */
109 Eedi = 0x00000001, /* EEPROM Data In */
110 Eedo = 0x00000002, /* EEPROM Data Out */
111 Eeclk = 0x00000004, /* EEPROM Serial Clock */
112 Eesel = 0x00000008, /* EEPROM Chip Select */
113 Mdio = 0x00000010, /* MII Management Data */
114 Mddir = 0x00000020, /* MII Management Direction */
115 Mdc = 0x00000040, /* MII Management Clock */
116 };
117
118 enum { /* Interrupts */
119 Rxok = 0x00000001, /* Rx OK */
120 Rxdesc = 0x00000002, /* Rx Descriptor */
121 Rxerr = 0x00000004, /* Rx Packet Error */
122 Rxearly = 0x00000008, /* Rx Early Threshold */
123 Rxidle = 0x00000010, /* Rx Idle */
124 Rxorn = 0x00000020, /* Rx Overrun */
125 Txok = 0x00000040, /* Tx Packet OK */
126 Txdesc = 0x00000080, /* Tx Descriptor */
127 Txerr = 0x00000100, /* Tx Packet Error */
128 Txidle = 0x00000200, /* Tx Idle */
129 Txurn = 0x00000400, /* Tx Underrun */
130 Mib = 0x00000800, /* MIB Service */
131 Swi = 0x00001000, /* Software Interrupt */
132 Pme = 0x00002000, /* Power Management Event */
133 Phy = 0x00004000, /* PHY Interrupt */
134 Hibint = 0x00008000, /* High Bits Interrupt Set */
135 Rxsovr = 0x00010000, /* Rx Status FIFO Overrun */
136 Rtabt = 0x00020000, /* Received Target Abort */
137 Rmabt = 0x00040000, /* Received Master Abort */
138 Sserr = 0x00080000, /* Signalled System Error */
139 Dperr = 0x00100000, /* Detected Parity Error */
140 Rxrcmp = 0x00200000, /* Receive Reset Complete */
141 Txrcmp = 0x00400000, /* Transmit Reset Complete */
142 Rxdesc0 = 0x00800000, /* Rx Descriptor for Priority Queue 0 */
143 Rxdesc1 = 0x01000000, /* Rx Descriptor for Priority Queue 1 */
144 Rxdesc2 = 0x02000000, /* Rx Descriptor for Priority Queue 2 */
145 Rxdesc3 = 0x04000000, /* Rx Descriptor for Priority Queue 3 */
146 Txdesc0 = 0x08000000, /* Tx Descriptor for Priority Queue 0 */
147 Txdesc1 = 0x10000000, /* Tx Descriptor for Priority Queue 1 */
148 Txdesc2 = 0x20000000, /* Tx Descriptor for Priority Queue 2 */
149 Txdesc3 = 0x40000000, /* Tx Descriptor for Priority Queue 3 */
150 };
151
152 enum { /* Interrupt Enable */
153 Ien = 0x00000001, /* Interrupt Enable */
154 };
155
156 enum { /* Interrupt Holdoff */
157 IhSHFT = 0, /* Interrupt Holdoff */
158 IhMASK = 0x000000FF,
159 Ihctl = 0x00000100, /* Interrupt Holdoff Control */
160 };
161
162 enum { /* Transmit Configuration */
163 TxdrthSHFT = 0, /* Tx Drain Threshold */
164 TxdrthMASK = 0x000000FF,
165 FlthSHFT = 16, /* Tx Fill Threshold */
166 FlthMASK = 0x0000FF00,
167 Brstdis = 0x00080000, /* 1000Mb/s Burst Disable */
168 MxdmaSHFT = 20, /* Max Size per Tx DMA Burst */
169 MxdmaMASK = 0x00700000,
170 Ecretryen = 0x00800000, /* Excessive Collision Retry Enable */
171 Atp = 0x10000000, /* Automatic Transmit Padding */
172 Mlb = 0x20000000, /* MAC Loopback */
173 Hbi = 0x40000000, /* Heartbeat Ignore */
174 Csi = 0x80000000, /* Carrier Sense Ignore */
175 };
176
177 enum { /* Receive Configuration */
178 RxdrthSHFT = 1, /* Rx Drain Threshold */
179 RxdrthMASK = 0x0000003E,
180 Airl = 0x04000000, /* Accept In-Range Length Errored */
181 Alp = 0x08000000, /* Accept Long Packets */
182 Rxfd = 0x10000000, /* Receive Full Duplex */
183 Stripcrc = 0x20000000, /* Strip CRC */
184 Arp = 0x40000000, /* Accept Runt Packets */
185 Aep = 0x80000000, /* Accept Errored Packets */
186 };
187
188 enum { /* Priority Queueing Control */
189 Txpqen = 0x00000001, /* Transmit Priority Queuing Enable */
190 Txfairen = 0x00000002, /* Transmit Fairness Enable */
191 RxpqenSHFT = 2, /* Receive Priority Queue Enable */
192 RxpqenMASK = 0x0000000C,
193 };
194
195 enum { /* Pause Control/Status */
196 PscntSHFT = 0, /* Pause Counter Value */
197 PscntMASK = 0x0000FFFF,
198 Pstx = 0x00020000, /* Transmit Pause Frame */
199 PsffloSHFT = 18, /* Rx Data FIFO Lo Threshold */
200 PsffloMASK = 0x000C0000,
201 PsffhiSHFT = 20, /* Rx Data FIFO Hi Threshold */
202 PsffhiMASK = 0x00300000,
203 PsstloSHFT = 22, /* Rx Stat FIFO Hi Threshold */
204 PsstloMASK = 0x00C00000,
205 PssthiSHFT = 24, /* Rx Stat FIFO Hi Threshold */
206 PssthiMASK = 0x03000000,
207 Psrcvd = 0x08000000, /* Pause Frame Received */
208 Psact = 0x10000000, /* Pause Active */
209 Psda = 0x20000000, /* Pause on Destination Address */
210 Psmcast = 0x40000000, /* Pause on Multicast */
211 Psen = 0x80000000, /* Pause Enable */
212 };
213
214 enum { /* Receive Filter/Match Control */
215 RfaddrSHFT = 0, /* Extended Register Address */
216 RfaddrMASK = 0x000003FF,
217 Ulm = 0x00080000, /* U/L bit mask */
218 Uhen = 0x00100000, /* Unicast Hash Enable */
219 Mhen = 0x00200000, /* Multicast Hash Enable */
220 Aarp = 0x00400000, /* Accept ARP Packets */
221 ApatSHFT = 23, /* Accept on Pattern Match */
222 ApatMASK = 0x07800000,
223 Apm = 0x08000000, /* Accept on Perfect Match */
224 Aau = 0x10000000, /* Accept All Unicast */
225 Aam = 0x20000000, /* Accept All Multicast */
226 Aab = 0x40000000, /* Accept All Broadcast */
227 Rfen = 0x80000000, /* Rx Filter Enable */
228 };
229
230 enum { /* Receive Filter/Match Data */
231 RfdataSHFT = 0, /* Receive Filter Data */
232 RfdataMASK = 0x0000FFFF,
233 BmaskSHFT = 16, /* Byte Mask */
234 BmaskMASK = 0x00030000,
235 };
236
237 enum { /* MIB Control */
238 Wrn = 0x00000001, /* Warning Test Indicator */
239 Frz = 0x00000002, /* Freeze All Counters */
240 Aclr = 0x00000004, /* Clear All Counters */
241 Mibs = 0x00000008, /* MIB Counter Strobe */
242 };
243
244 enum { /* MIB Data */
245 Nmibd = 11, /* Number of MIB Data Registers */
246 };
247
248 enum { /* VLAN/IP Receive Control */
249 Vtden = 0x00000001, /* VLAN Tag Detection Enable */
250 Vtren = 0x00000002, /* VLAN Tag Removal Enable */
251 Dvtf = 0x00000004, /* Discard VLAN Tagged Frames */
252 Dutf = 0x00000008, /* Discard Untagged Frames */
253 Ipen = 0x00000010, /* IP Checksum Enable */
254 Ripe = 0x00000020, /* Reject IP Checksum Errors */
255 Rtcpe = 0x00000040, /* Reject TCP Checksum Errors */
256 Rudpe = 0x00000080, /* Reject UDP Checksum Errors */
257 };
258
259 enum { /* VLAN/IP Transmit Control */
260 Vgti = 0x00000001, /* VLAN Global Tag Insertion */
261 Vppti = 0x00000002, /* VLAN Per-Packet Tag Insertion */
262 Gchk = 0x00000004, /* Global Checksum Generation */
263 Ppchk = 0x00000008, /* Per-Packet Checksum Generation */
264 };
265
266 enum { /* VLAN Data */
267 VtypeSHFT = 0, /* VLAN Type Field */
268 VtypeMASK = 0x0000FFFF,
269 VtciSHFT = 16, /* VLAN Tag Control Information */
270 VtciMASK = 0xFFFF0000,
271 };
272
273 enum { /* Clockrun Control/Status */
274 Clkrunen = 0x00000001, /* CLKRUN Enable */
275 Pmeen = 0x00000100, /* PME Enable */
276 Pmests = 0x00008000, /* PME Status */
277 };
278
279 typedef struct {
280 u32int link; /* Link to the next descriptor */
281 u32int bufptr; /* pointer to data Buffer */
282 int cmdsts; /* Command/Status */
283 int extsts; /* optional Extended Status */
284
285 Block* bp; /* Block containing bufptr */
286 u32int unused; /* pad to 64-bit */
287 } Desc;
288
289 enum { /* Common cmdsts bits */
290 SizeMASK = 0x0000FFFF, /* Descriptor Byte Count */
291 SizeSHFT = 0,
292 Ok = 0x08000000, /* Packet OK */
293 Crc = 0x10000000, /* Suppress/Include CRC */
294 Intr = 0x20000000, /* Interrupt on ownership transfer */
295 More = 0x40000000, /* not last descriptor in a packet */
296 Own = 0x80000000, /* Descriptor Ownership */
297 };
298
299 enum { /* Transmit cmdsts bits */
300 CcntMASK = 0x000F0000, /* Collision Count */
301 CcntSHFT = 16,
302 Ec = 0x00100000, /* Excessive Collisions */
303 Owc = 0x00200000, /* Out of Window Collision */
304 Ed = 0x00400000, /* Excessive Deferral */
305 Td = 0x00800000, /* Transmit Deferred */
306 Crs = 0x01000000, /* Carrier Sense Lost */
307 Tfu = 0x02000000, /* Transmit FIFO Underrun */
308 Txa = 0x04000000, /* Transmit Abort */
309 };
310
311 enum { /* Receive cmdsts bits */
312 Irl = 0x00010000, /* In-Range Length Error */
313 Lbp = 0x00020000, /* Loopback Packet */
314 Fae = 0x00040000, /* Frame Alignment Error */
315 Crce = 0x00080000, /* CRC Error */
316 Ise = 0x00100000, /* Invalid Symbol Error */
317 Runt = 0x00200000, /* Runt Packet Received */
318 Long = 0x00400000, /* Too Long Packet Received */
319 DestMASK = 0x01800000, /* Destination Class */
320 DestSHFT = 23,
321 Rxo = 0x02000000, /* Receive Overrun */
322 Rxa = 0x04000000, /* Receive Aborted */
323 };
324
325 enum { /* extsts bits */
326 EvtciMASK = 0x0000FFFF, /* VLAN Tag Control Information */
327 EvtciSHFT = 0,
328 Vpkt = 0x00010000, /* VLAN Packet */
329 Ippkt = 0x00020000, /* IP Packet */
330 Iperr = 0x00040000, /* IP Checksum Error */
331 Tcppkt = 0x00080000, /* TCP Packet */
332 Tcperr = 0x00100000, /* TCP Checksum Error */
333 Udppkt = 0x00200000, /* UDP Packet */
334 Udperr = 0x00400000, /* UDP Checksum Error */
335 };
336
337 enum {
338 Rbsz = ROUNDUP(sizeof(Etherpkt)+8, 8),
339 /* were 256, 4*Nrd & 64, but 52, 253 and 9 are ample. */
340 Nrd = 128,
341 Nrb = 512,
342 Ntd = 32,
343 };
344
345 typedef struct Ctlr Ctlr;
346 typedef struct Ctlr {
347 int port;
348 Pcidev* pcidev;
349 Ctlr* next;
350 int active;
351 int id;
352
353 int eepromsz; /* address size in bits */
354 ushort* eeprom;
355
356 int* nic;
357 int cfg;
358 int imr;
359
360 QLock alock; /* attach */
361 Lock ilock; /* init */
362 void* alloc; /* base of per-Ctlr allocated data */
363
364 Mii* mii;
365
366 Lock rdlock; /* receive */
367 Desc* rd;
368 int nrd;
369 int nrb;
370 int rdx;
371 int rxcfg;
372
373 Lock tlock; /* transmit */
374 Desc* td;
375 int ntd;
376 int tdh;
377 int tdt;
378 int ntq;
379 int txcfg;
380
381 int rxidle;
382
383 uint mibd[Nmibd];
384
385 int ec;
386 int owc;
387 int ed;
388 int crs;
389 int tfu;
390 int txa;
391 } Ctlr;
392
393 #define csr32r(c, r) (*((c)->nic+((r)/4)))
394 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
395
396 static Ctlr* dp83820ctlrhead;
397 static Ctlr* dp83820ctlrtail;
398
399 static Lock dp83820rblock; /* free receive Blocks */
400 static Block* dp83820rbpool;
401
402 static char* dp83820mibs[Nmibd] = {
403 "RXErroredPkts",
404 "RXFCSErrors",
405 "RXMsdPktErrors",
406 "RXFAErrors",
407 "RXSymbolErrors",
408 "RXFrameToLong",
409 "RXIRLErrors",
410 "RXBadOpcodes",
411 "RXPauseFrames",
412 "TXPauseFrames",
413 "TXSQEErrors",
414 };
415
416 static int
mdior(Ctlr * ctlr,int n)417 mdior(Ctlr* ctlr, int n)
418 {
419 int data, i, mear, r;
420
421 mear = csr32r(ctlr, Mear);
422 r = ~(Mdc|Mddir) & mear;
423 data = 0;
424 for(i = n-1; i >= 0; i--){
425 if(csr32r(ctlr, Mear) & Mdio)
426 data |= (1<<i);
427 csr32w(ctlr, Mear, Mdc|r);
428 csr32w(ctlr, Mear, r);
429 }
430 csr32w(ctlr, Mear, mear);
431
432 return data;
433 }
434
435 static void
mdiow(Ctlr * ctlr,int bits,int n)436 mdiow(Ctlr* ctlr, int bits, int n)
437 {
438 int i, mear, r;
439
440 mear = csr32r(ctlr, Mear);
441 r = Mddir|(~Mdc & mear);
442 for(i = n-1; i >= 0; i--){
443 if(bits & (1<<i))
444 r |= Mdio;
445 else
446 r &= ~Mdio;
447 csr32w(ctlr, Mear, r);
448 csr32w(ctlr, Mear, Mdc|r);
449 }
450 csr32w(ctlr, Mear, mear);
451 }
452
453 static int
dp83820miimir(Mii * mii,int pa,int ra)454 dp83820miimir(Mii* mii, int pa, int ra)
455 {
456 int data;
457 Ctlr *ctlr;
458
459 ctlr = mii->ctlr;
460
461 /*
462 * MII Management Interface Read.
463 *
464 * Preamble;
465 * ST+OP+PA+RA;
466 * LT + 16 data bits.
467 */
468 mdiow(ctlr, 0xFFFFFFFF, 32);
469 mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
470 data = mdior(ctlr, 18);
471
472 if(data & 0x10000)
473 return -1;
474
475 return data & 0xFFFF;
476 }
477
478 static int
dp83820miimiw(Mii * mii,int pa,int ra,int data)479 dp83820miimiw(Mii* mii, int pa, int ra, int data)
480 {
481 Ctlr *ctlr;
482
483 ctlr = mii->ctlr;
484
485 /*
486 * MII Management Interface Write.
487 *
488 * Preamble;
489 * ST+OP+PA+RA+LT + 16 data bits;
490 * Z.
491 */
492 mdiow(ctlr, 0xFFFFFFFF, 32);
493 data &= 0xFFFF;
494 data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
495 mdiow(ctlr, data, 32);
496
497 return 0;
498 }
499
500 static Block *
dp83820rballoc(Desc * desc)501 dp83820rballoc(Desc* desc)
502 {
503 Block *bp;
504
505 if(desc->bp == nil){
506 ilock(&dp83820rblock);
507 if((bp = dp83820rbpool) == nil){
508 iunlock(&dp83820rblock);
509 desc->bp = nil;
510 desc->cmdsts = Own;
511 return nil;
512 }
513 dp83820rbpool = bp->next;
514 bp->next = nil;
515 _xinc(&bp->ref); /* prevent bp from being freed */
516 iunlock(&dp83820rblock);
517
518 desc->bufptr = PCIWADDR(bp->rp);
519 desc->bp = bp;
520 }
521 else{
522 bp = desc->bp;
523 bp->rp = bp->lim - Rbsz;
524 bp->wp = bp->rp;
525 }
526
527 coherence();
528 desc->cmdsts = Intr|Rbsz;
529
530 return bp;
531 }
532
533 static void
dp83820rbfree(Block * bp)534 dp83820rbfree(Block *bp)
535 {
536 bp->rp = bp->lim - Rbsz;
537 bp->wp = bp->rp;
538
539 ilock(&dp83820rblock);
540 bp->next = dp83820rbpool;
541 dp83820rbpool = bp;
542 iunlock(&dp83820rblock);
543 }
544
545 static void
dp83820halt(Ctlr * ctlr)546 dp83820halt(Ctlr* ctlr)
547 {
548 int i, timeo;
549
550 ilock(&ctlr->ilock);
551 csr32w(ctlr, Imr, 0);
552 csr32w(ctlr, Ier, 0);
553 csr32w(ctlr, Cr, Rxd|Txd);
554 for(timeo = 0; timeo < 1000; timeo++){
555 if(!(csr32r(ctlr, Cr) & (Rxe|Txe)))
556 break;
557 microdelay(1);
558 }
559 csr32w(ctlr, Mibc, Frz);
560 iunlock(&ctlr->ilock);
561
562 if(ctlr->rd != nil){
563 for(i = 0; i < ctlr->nrd; i++){
564 if(ctlr->rd[i].bp == nil)
565 continue;
566 freeb(ctlr->rd[i].bp);
567 ctlr->rd[i].bp = nil;
568 }
569 }
570 if(ctlr->td != nil){
571 for(i = 0; i < ctlr->ntd; i++){
572 if(ctlr->td[i].bp == nil)
573 continue;
574 freeb(ctlr->td[i].bp);
575 ctlr->td[i].bp = nil;
576 }
577 }
578 }
579
580 static void
dp83820cfg(Ctlr * ctlr)581 dp83820cfg(Ctlr* ctlr)
582 {
583 int cfg;
584
585 /*
586 * Don't know how to deal with a TBI yet.
587 */
588 if(ctlr->mii == nil)
589 return;
590
591 /*
592 * The polarity of these bits is at the mercy
593 * of the board designer.
594 * The correct answer for all speed and duplex questions
595 * should be to query the phy.
596 */
597 cfg = csr32r(ctlr, Cfg);
598 if(!(cfg & Dupsts)){
599 ctlr->rxcfg |= Rxfd;
600 ctlr->txcfg |= Csi|Hbi;
601 iprint("83820: full duplex, ");
602 }
603 else{
604 ctlr->rxcfg &= ~Rxfd;
605 ctlr->txcfg &= ~(Csi|Hbi);
606 iprint("83820: half duplex, ");
607 }
608 csr32w(ctlr, Rxcfg, ctlr->rxcfg);
609 csr32w(ctlr, Txcfg, ctlr->txcfg);
610
611 switch(cfg & (Spdsts1000|Spdsts100)){
612 case Spdsts1000: /* 100Mbps */
613 default: /* 10Mbps */
614 ctlr->cfg &= ~Mode1000;
615 if((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000)
616 iprint("100Mb/s\n");
617 else
618 iprint("10Mb/s\n");
619 break;
620 case Spdsts100: /* 1Gbps */
621 ctlr->cfg |= Mode1000;
622 iprint("1Gb/s\n");
623 break;
624 }
625 csr32w(ctlr, Cfg, ctlr->cfg);
626 }
627
628 static void
dp83820init(Ether * edev)629 dp83820init(Ether* edev)
630 {
631 int i;
632 Ctlr *ctlr;
633 Desc *desc;
634 uchar *alloc;
635
636 ctlr = edev->ctlr;
637
638 dp83820halt(ctlr);
639
640 /*
641 * Receiver
642 */
643 alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8);
644 ctlr->rd = (Desc*)alloc;
645 alloc += ctlr->nrd*sizeof(Desc);
646 memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc));
647 ctlr->rdx = 0;
648 for(i = 0; i < ctlr->nrd; i++){
649 desc = &ctlr->rd[i];
650 desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
651 if(dp83820rballoc(desc) == nil)
652 continue;
653 }
654 csr32w(ctlr, Rxdphi, 0);
655 csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd));
656
657 for(i = 0; i < Eaddrlen; i += 2){
658 csr32w(ctlr, Rfcr, i);
659 csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]);
660 }
661 csr32w(ctlr, Rfcr, Rfen|Aab|Aam|Apm);
662
663 ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT);
664 ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok;
665
666 /*
667 * Transmitter.
668 */
669 ctlr->td = (Desc*)alloc;
670 memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc));
671 ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
672 for(i = 0; i < ctlr->ntd; i++){
673 desc = &ctlr->td[i];
674 desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]);
675 }
676 csr32w(ctlr, Txdphi, 0);
677 csr32w(ctlr, Txdp, PCIWADDR(ctlr->td));
678
679 ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT);
680 ctlr->imr |= Txurn|Txidle|Txdesc|Txok;
681
682 ilock(&ctlr->ilock);
683
684 dp83820cfg(ctlr);
685
686 csr32w(ctlr, Mibc, Aclr);
687 ctlr->imr |= Mib;
688
689 csr32w(ctlr, Imr, ctlr->imr);
690
691 /* try coalescing adjacent interrupts; use hold-off interval of 100µs */
692 csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT));
693
694 csr32w(ctlr, Ier, Ien);
695 csr32w(ctlr, Cr, Rxe|Txe);
696
697 iunlock(&ctlr->ilock);
698 }
699
700 static void
dp83820attach(Ether * edev)701 dp83820attach(Ether* edev)
702 {
703 Block *bp;
704 Ctlr *ctlr;
705
706 ctlr = edev->ctlr;
707 qlock(&ctlr->alock);
708 if(ctlr->alloc != nil){
709 qunlock(&ctlr->alock);
710 return;
711 }
712
713 if(waserror()){
714 if(ctlr->mii != nil){
715 free(ctlr->mii);
716 ctlr->mii = nil;
717 }
718 if(ctlr->alloc != nil){
719 free(ctlr->alloc);
720 ctlr->alloc = nil;
721 }
722 qunlock(&ctlr->alock);
723 nexterror();
724 }
725
726 if(!(ctlr->cfg & Tbien)){
727 if((ctlr->mii = malloc(sizeof(Mii))) == nil)
728 error(Enomem);
729 ctlr->mii->ctlr = ctlr;
730 ctlr->mii->mir = dp83820miimir;
731 ctlr->mii->miw = dp83820miimiw;
732 if(mii(ctlr->mii, ~0) == 0)
733 error("no PHY");
734 ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;
735 ctlr->imr |= Phy;
736 }
737
738 ctlr->nrd = Nrd;
739 ctlr->nrb = Nrb;
740 ctlr->ntd = Ntd;
741 ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
742 if(ctlr->alloc == nil)
743 error(Enomem);
744
745 for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
746 if((bp = allocb(Rbsz)) == nil)
747 break;
748 bp->free = dp83820rbfree;
749 dp83820rbfree(bp);
750 }
751
752 dp83820init(edev);
753
754 qunlock(&ctlr->alock);
755 poperror();
756 }
757
758 static void
dp83820transmit(Ether * edev)759 dp83820transmit(Ether* edev)
760 {
761 Block *bp;
762 Ctlr *ctlr;
763 Desc *desc;
764 int cmdsts, r, x;
765
766 ctlr = edev->ctlr;
767
768 ilock(&ctlr->tlock);
769
770 bp = nil;
771 for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){
772 desc = &ctlr->td[x];
773 if((cmdsts = desc->cmdsts) & Own)
774 break;
775 if(!(cmdsts & Ok)){
776 if(cmdsts & Ec)
777 ctlr->ec++;
778 if(cmdsts & Owc)
779 ctlr->owc++;
780 if(cmdsts & Ed)
781 ctlr->ed++;
782 if(cmdsts & Crs)
783 ctlr->crs++;
784 if(cmdsts & Tfu)
785 ctlr->tfu++;
786 if(cmdsts & Txa)
787 ctlr->txa++;
788 edev->oerrs++;
789 }
790 desc->bp->next = bp;
791 bp = desc->bp;
792 desc->bp = nil;
793
794 ctlr->ntq--;
795 }
796 ctlr->tdh = x;
797 if(bp != nil)
798 freeblist(bp);
799
800 x = ctlr->tdt;
801 while(ctlr->ntq < (ctlr->ntd-1)){
802 if((bp = qget(edev->oq)) == nil)
803 break;
804
805 desc = &ctlr->td[x];
806 desc->bufptr = PCIWADDR(bp->rp);
807 desc->bp = bp;
808 ctlr->ntq++;
809 coherence();
810 desc->cmdsts = Own|Intr|BLEN(bp);
811
812 x = NEXT(x, ctlr->ntd);
813 }
814 if(x != ctlr->tdt){
815 ctlr->tdt = x;
816 r = csr32r(ctlr, Cr);
817 csr32w(ctlr, Cr, Txe|r);
818 }
819
820 iunlock(&ctlr->tlock);
821 }
822
823 static void
dp83820interrupt(Ureg *,void * arg)824 dp83820interrupt(Ureg*, void* arg)
825 {
826 Block *bp;
827 Ctlr *ctlr;
828 Desc *desc;
829 Ether *edev;
830 int cmdsts, i, isr, r, x;
831
832 edev = arg;
833 ctlr = edev->ctlr;
834
835 for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){
836 if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){
837 x = ctlr->rdx;
838 desc = &ctlr->rd[x];
839 while((cmdsts = desc->cmdsts) & Own){
840 if((cmdsts & Ok) && desc->bp != nil){
841 bp = desc->bp;
842 desc->bp = nil;
843 bp->wp += cmdsts & SizeMASK;
844 etheriq(edev, bp, 1);
845 }
846 else if(0 && !(cmdsts & Ok)){
847 iprint("dp83820: rx %8.8uX:", cmdsts);
848 bp = desc->bp;
849 for(i = 0; i < 20; i++)
850 iprint(" %2.2uX", bp->rp[i]);
851 iprint("\n");
852 }
853 dp83820rballoc(desc);
854
855 x = NEXT(x, ctlr->nrd);
856 desc = &ctlr->rd[x];
857 }
858 ctlr->rdx = x;
859
860 if(isr & Rxidle){
861 r = csr32r(ctlr, Cr);
862 csr32w(ctlr, Cr, Rxe|r);
863 ctlr->rxidle++;
864 }
865
866 isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);
867 }
868
869 if(isr & Txurn){
870 x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;
871 r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;
872 if(x < ((TxdrthMASK)>>TxdrthSHFT)
873 && x < (2048/32 - r)){
874 ctlr->txcfg &= ~TxdrthMASK;
875 x++;
876 ctlr->txcfg |= x<<TxdrthSHFT;
877 csr32w(ctlr, Txcfg, ctlr->txcfg);
878 }
879 }
880
881 if(isr & (Txurn|Txidle|Txdesc|Txok)){
882 dp83820transmit(edev);
883 isr &= ~(Txurn|Txidle|Txdesc|Txok);
884 }
885
886 if(isr & Mib){
887 for(i = 0; i < Nmibd; i++){
888 r = csr32r(ctlr, Mibd+(i*sizeof(int)));
889 ctlr->mibd[i] += r & 0xFFFF;
890 }
891 isr &= ~Mib;
892 }
893
894 if((isr & Phy) && ctlr->mii != nil){
895 ctlr->mii->mir(ctlr->mii, 1, Bmsr);
896 print("phy: cfg %8.8uX bmsr %4.4uX\n",
897 csr32r(ctlr, Cfg),
898 ctlr->mii->mir(ctlr->mii, 1, Bmsr));
899 dp83820cfg(ctlr);
900 isr &= ~Phy;
901 }
902 if(isr)
903 iprint("dp83820: isr %8.8uX\n", isr);
904 }
905 }
906
907 static long
dp83820ifstat(Ether * edev,void * a,long n,ulong offset)908 dp83820ifstat(Ether* edev, void* a, long n, ulong offset)
909 {
910 char *p;
911 Ctlr *ctlr;
912 int i, l, r;
913
914 ctlr = edev->ctlr;
915
916 edev->crcs = ctlr->mibd[Mibd+(1*sizeof(int))];
917 edev->frames = ctlr->mibd[Mibd+(3*sizeof(int))];
918 edev->buffs = ctlr->mibd[Mibd+(5*sizeof(int))];
919 edev->overflows = ctlr->mibd[Mibd+(2*sizeof(int))];
920
921 if(n == 0)
922 return 0;
923
924 p = malloc(READSTR);
925 if(p == nil)
926 error(Enomem);
927 l = 0;
928 for(i = 0; i < Nmibd; i++){
929 r = csr32r(ctlr, Mibd+(i*sizeof(int)));
930 ctlr->mibd[i] += r & 0xFFFF;
931 if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil)
932 l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
933 dp83820mibs[i], ctlr->mibd[i], r);
934 }
935 l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle);
936 l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec);
937 l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc);
938 l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed);
939 l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs);
940 l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu);
941 l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa);
942
943 l += snprint(p+l, READSTR, "rom:");
944 for(i = 0; i < 0x10; i++){
945 if(i && ((i & 0x07) == 0))
946 l += snprint(p+l, READSTR-l, "\n ");
947 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
948 }
949 l += snprint(p+l, READSTR-l, "\n");
950
951 if(ctlr->mii != nil && ctlr->mii->curphy != nil){
952 l += snprint(p+l, READSTR, "phy:");
953 for(i = 0; i < NMiiPhyr; i++){
954 if(i && ((i & 0x07) == 0))
955 l += snprint(p+l, READSTR-l, "\n ");
956 r = miimir(ctlr->mii, i);
957 l += snprint(p+l, READSTR-l, " %4.4uX", r);
958 }
959 snprint(p+l, READSTR-l, "\n");
960 }
961
962 n = readstr(offset, a, n, p);
963 free(p);
964
965 return n;
966 }
967
968 static void
dp83820promiscuous(void * arg,int on)969 dp83820promiscuous(void* arg, int on)
970 {
971 USED(arg, on);
972 }
973
974 /* multicast already on, don't need to do anything */
975 static void
dp83820multicast(void *,uchar *,int)976 dp83820multicast(void*, uchar*, int)
977 {
978 }
979
980 static int
dp83820detach(Ctlr * ctlr)981 dp83820detach(Ctlr* ctlr)
982 {
983 /*
984 * Soft reset the controller.
985 */
986 csr32w(ctlr, Cr, Rst);
987 delay(1);
988 while(csr32r(ctlr, Cr) & Rst)
989 delay(1);
990 return 0;
991 }
992
993 static void
dp83820shutdown(Ether * ether)994 dp83820shutdown(Ether* ether)
995 {
996 print("dp83820shutdown\n");
997 dp83820detach(ether->ctlr);
998 }
999
1000 static int
atc93c46r(Ctlr * ctlr,int address)1001 atc93c46r(Ctlr* ctlr, int address)
1002 {
1003 int data, i, mear, r, size;
1004
1005 /*
1006 * Analog Technology, Inc. ATC93C46
1007 * or equivalent serial EEPROM.
1008 */
1009 mear = csr32r(ctlr, Mear);
1010 mear &= ~(Eesel|Eeclk|Eedo|Eedi);
1011 r = Eesel|mear;
1012
1013 reread:
1014 csr32w(ctlr, Mear, r);
1015 data = 0x06;
1016 for(i = 3-1; i >= 0; i--){
1017 if(data & (1<<i))
1018 r |= Eedi;
1019 else
1020 r &= ~Eedi;
1021 csr32w(ctlr, Mear, r);
1022 csr32w(ctlr, Mear, Eeclk|r);
1023 microdelay(1);
1024 csr32w(ctlr, Mear, r);
1025 microdelay(1);
1026 }
1027
1028 /*
1029 * First time through must work out the EEPROM size.
1030 */
1031 if((size = ctlr->eepromsz) == 0)
1032 size = 8;
1033
1034 for(size = size-1; size >= 0; size--){
1035 if(address & (1<<size))
1036 r |= Eedi;
1037 else
1038 r &= ~Eedi;
1039 csr32w(ctlr, Mear, r);
1040 microdelay(1);
1041 csr32w(ctlr, Mear, Eeclk|r);
1042 microdelay(1);
1043 csr32w(ctlr, Mear, r);
1044 microdelay(1);
1045 if(!(csr32r(ctlr, Mear) & Eedo))
1046 break;
1047 }
1048 r &= ~Eedi;
1049
1050 data = 0;
1051 for(i = 16-1; i >= 0; i--){
1052 csr32w(ctlr, Mear, Eeclk|r);
1053 microdelay(1);
1054 if(csr32r(ctlr, Mear) & Eedo)
1055 data |= (1<<i);
1056 csr32w(ctlr, Mear, r);
1057 microdelay(1);
1058 }
1059
1060 csr32w(ctlr, Mear, mear);
1061
1062 if(ctlr->eepromsz == 0){
1063 ctlr->eepromsz = 8-size;
1064 ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
1065 if(ctlr->eeprom == nil)
1066 error(Enomem);
1067 goto reread;
1068 }
1069
1070 return data;
1071 }
1072
1073 static int
dp83820reset(Ctlr * ctlr)1074 dp83820reset(Ctlr* ctlr)
1075 {
1076 int i, r;
1077 unsigned char sum;
1078
1079 /*
1080 * Soft reset the controller;
1081 * read the EEPROM to get the initial settings
1082 * of the Cfg and Gpior bits which should be cleared by
1083 * the reset.
1084 */
1085 dp83820detach(ctlr);
1086
1087 atc93c46r(ctlr, 0);
1088 if(ctlr->eeprom == nil) {
1089 print("dp83820reset: no eeprom\n");
1090 return -1;
1091 }
1092 sum = 0;
1093 for(i = 0; i < 0x0E; i++){
1094 r = atc93c46r(ctlr, i);
1095 ctlr->eeprom[i] = r;
1096 sum += r;
1097 sum += r>>8;
1098 }
1099
1100 if(sum != 0){
1101 print("dp83820reset: bad EEPROM checksum\n");
1102 return -1;
1103 }
1104
1105 #ifdef notdef
1106 csr32w(ctlr, Gpior, ctlr->eeprom[4]);
1107
1108 cfg = Extstsen|Exd;
1109 r = csr32r(ctlr, Cfg);
1110 if(ctlr->eeprom[5] & 0x0001)
1111 cfg |= Ext125;
1112 if(ctlr->eeprom[5] & 0x0002)
1113 cfg |= M64addren;
1114 if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))
1115 cfg |= Data64en;
1116 if(ctlr->eeprom[5] & 0x0008)
1117 cfg |= T64addren;
1118 if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))
1119 cfg |= Mwidis;
1120 if(ctlr->eeprom[5] & 0x0020)
1121 cfg |= Mrmdis;
1122 if(ctlr->eeprom[5] & 0x0080)
1123 cfg |= Mode1000;
1124 if(ctlr->eeprom[5] & 0x0200)
1125 cfg |= Tbien|Mode1000;
1126 /*
1127 * What about RO bits we might have destroyed with Rst?
1128 * What about Exd, Tmrtest, Extstsen, Pintctl?
1129 * Why does it think it has detected a 64-bit bus when
1130 * it hasn't?
1131 */
1132 #else
1133 // r = csr32r(ctlr, Cfg);
1134 // r &= ~(Mode1000|T64addren|Data64en|M64addren);
1135 // csr32w(ctlr, Cfg, r);
1136 // csr32w(ctlr, Cfg, 0x2000);
1137 #endif /* notdef */
1138 ctlr->cfg = csr32r(ctlr, Cfg);
1139 print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
1140 ctlr->cfg &= ~(T64addren|Data64en|M64addren);
1141 csr32w(ctlr, Cfg, ctlr->cfg);
1142 csr32w(ctlr, Mibc, Aclr|Frz);
1143
1144 return 0;
1145 }
1146
1147 static void
dp83820pci(void)1148 dp83820pci(void)
1149 {
1150 void *mem;
1151 Pcidev *p;
1152 Ctlr *ctlr;
1153
1154 p = nil;
1155 while(p = pcimatch(p, 0, 0)){
1156 if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
1157 continue;
1158
1159 switch((p->did<<16)|p->vid){
1160 default:
1161 continue;
1162 case (0x0022<<16)|0x100B: /* DP83820 (Gig-NIC) */
1163 break;
1164 }
1165
1166 mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
1167 if(mem == 0){
1168 print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
1169 continue;
1170 }
1171
1172 ctlr = malloc(sizeof(Ctlr));
1173 if(ctlr == nil) {
1174 vunmap(mem, p->mem[1].size);
1175 error(Enomem);
1176 }
1177 ctlr->port = p->mem[1].bar & ~0x0F;
1178 ctlr->pcidev = p;
1179 ctlr->id = (p->did<<16)|p->vid;
1180
1181 ctlr->nic = mem;
1182 if(dp83820reset(ctlr)){
1183 free(ctlr);
1184 vunmap(mem, p->mem[1].size);
1185 continue;
1186 }
1187 pcisetbme(p);
1188
1189 if(dp83820ctlrhead != nil)
1190 dp83820ctlrtail->next = ctlr;
1191 else
1192 dp83820ctlrhead = ctlr;
1193 dp83820ctlrtail = ctlr;
1194 }
1195 }
1196
1197 static int
dp83820pnp(Ether * edev)1198 dp83820pnp(Ether* edev)
1199 {
1200 int i;
1201 Ctlr *ctlr;
1202 uchar ea[Eaddrlen];
1203
1204 if(dp83820ctlrhead == nil)
1205 dp83820pci();
1206
1207 /*
1208 * Any adapter matches if no edev->port is supplied,
1209 * otherwise the ports must match.
1210 */
1211 for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){
1212 if(ctlr->active)
1213 continue;
1214 if(edev->port == 0 || edev->port == ctlr->port){
1215 ctlr->active = 1;
1216 break;
1217 }
1218 }
1219 if(ctlr == nil)
1220 return -1;
1221
1222 edev->ctlr = ctlr;
1223 edev->port = ctlr->port;
1224 edev->irq = ctlr->pcidev->intl;
1225 edev->tbdf = ctlr->pcidev->tbdf;
1226 edev->mbps = 1000;
1227
1228 /*
1229 * Check if the adapter's station address is to be overridden.
1230 * If not, read it from the EEPROM and set in ether->ea prior to
1231 * loading the station address in the hardware.
1232 */
1233 memset(ea, 0, Eaddrlen);
1234 if(memcmp(ea, edev->ea, Eaddrlen) == 0)
1235 for(i = 0; i < Eaddrlen/2; i++){
1236 edev->ea[2*i] = ctlr->eeprom[0x0C-i];
1237 edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;
1238 }
1239
1240 edev->attach = dp83820attach;
1241 edev->transmit = dp83820transmit;
1242 edev->interrupt = dp83820interrupt;
1243 edev->ifstat = dp83820ifstat;
1244
1245 edev->arg = edev;
1246 edev->promiscuous = dp83820promiscuous;
1247 edev->multicast = dp83820multicast;
1248 edev->shutdown = dp83820shutdown;
1249
1250 return 0;
1251 }
1252
1253 void
etherdp83820link(void)1254 etherdp83820link(void)
1255 {
1256 addethercard("DP83820", dp83820pnp);
1257 }
1258