Lindented 8139
[akaros.git] / kern / drivers / net / ether8139.c
1 // INFERNO
2 /*
3  * Realtek 8139 (but not the 8129).
4  * Error recovery for the various over/under -flow conditions
5  * may need work.
6  */
7 #include <vfs.h>
8 #include <kfs.h>
9 #include <slab.h>
10 #include <kmalloc.h>
11 #include <kref.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <assert.h>
15 #include <error.h>
16 #include <cpio.h>
17 #include <pmap.h>
18 #include <smp.h>
19 #include <ip.h>
20
21 #include <vfs.h>
22 #include <kfs.h>
23 #include <slab.h>
24 #include <kmalloc.h>
25 #include <kref.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <error.h>
30 #include <cpio.h>
31 #include <pmap.h>
32 #include <smp.h>
33 #include <ip.h>
34
35 enum {                                                  /* registers */
36         Idr0 = 0x0000,                          /* MAC address */
37         Mar0 = 0x0008,  /* Multicast address */
38         Tsd0 = 0x0010,  /* Transmit Status Descriptor0 */
39         Tsad0 = 0x0020, /* Transmit Start Address Descriptor0 */
40         Rbstart = 0x0030,       /* Receive Buffer Start Address */
41         Erbcr = 0x0034, /* Early Receive Byte Count */
42         Ersr = 0x0036,  /* Early Receive Status */
43         Cr = 0x0037,    /* Command Register */
44         Capr = 0x0038,  /* Current Address of Packet Read */
45         Cbr = 0x003A,   /* Current Buffer Address */
46         Imr = 0x003C,   /* Interrupt Mask */
47         Isr = 0x003E,   /* Interrupt Status */
48         Tcr = 0x0040,   /* Transmit Configuration */
49         Rcr = 0x0044,   /* Receive Configuration */
50         Tctr = 0x0048,  /* Timer Count */
51         Mpc = 0x004C,   /* Missed Packet Counter */
52         Cr9346 = 0x0050,        /* 9346 Command Register */
53         Config0 = 0x0051,       /* Configuration Register 0 */
54         Config1 = 0x0052,       /* Configuration Register 1 */
55         TimerInt = 0x0054,      /* Timer Interrupt */
56         Msr = 0x0058,   /* Media Status */
57         Config3 = 0x0059,       /* Configuration Register 3 */
58         Config4 = 0x005A,       /* Configuration Register 4 */
59         Mulint = 0x005C,        /* Multiple Interrupt Select */
60         RerID = 0x005E, /* PCI Revision ID */
61         Tsad = 0x0060,  /* Transmit Status of all Descriptors */
62
63         Bmcr = 0x0062,  /* Basic Mode Control */
64         Bmsr = 0x0064,  /* Basic Mode Status */
65         Anar = 0x0066,  /* Auto-Negotiation Advertisment */
66         Anlpar = 0x0068,        /* Auto-Negotiation Link Partner */
67         Aner = 0x006A,  /* Auto-Negotiation Expansion */
68         Dis = 0x006C,   /* Disconnect Counter */
69         Fcsc = 0x006E,  /* False Carrier Sense Counter */
70         Nwaytr = 0x0070,        /* N-way Test */
71         Rec = 0x0072,   /* RX_ER Counter */
72         Cscr = 0x0074,  /* CS Configuration */
73         Phy1parm = 0x0078,      /* PHY Parameter 1 */
74         Twparm = 0x007C,        /* Twister Parameter */
75         Phy2parm = 0x0080,      /* PHY Parameter 2 */
76 };
77
78 enum {                                                  /* Cr */
79         Bufe = 0x01,                            /* Rx Buffer Empty */
80         Te = 0x04,      /* Transmitter Enable */
81         Re = 0x08,      /* Receiver Enable */
82         Rst = 0x10,     /* Software Reset */
83 };
84
85 enum {                                                  /* Imr/Isr */
86         Rok = 0x0001,                           /* Receive OK */
87         Rer = 0x0002,   /* Receive Error */
88         Tok = 0x0004,   /* Transmit OK */
89         Ter = 0x0008,   /* Transmit Error */
90         Rxovw = 0x0010, /* Receive Buffer Overflow */
91         PunLc = 0x0020, /* Packet Underrun or Link Change */
92         Fovw = 0x0040,  /* Receive FIFO Overflow */
93         Clc = 0x2000,   /* Cable Length Change */
94         Timerbit = 0x4000,      /* Timer */
95         Serr = 0x8000,  /* System Error */
96 };
97
98 enum {                                                  /* Tcr */
99         Clrabt = 0x00000001,            /* Clear Abort */
100         TxrrSHIFT = 4,  /* Transmit Retry Count */
101         TxrrMASK = 0x000000F0,
102         MtxdmaSHIFT = 8,        /* Max. DMA Burst Size */
103         MtxdmaMASK = 0x00000700,
104         Mtxdma2048 = 0x00000700,
105         Acrc = 0x00010000,      /* Append CRC (not) */
106         LbkSHIFT = 17,  /* Loopback Test */
107         LbkMASK = 0x00060000,
108         Rtl8139ArevG = 0x00800000,      /* RTL8139A Rev. G ID */
109         IfgSHIFT = 24,  /* Interframe Gap */
110         IfgMASK = 0x03000000,
111         HwveridSHIFT = 26,      /* Hardware Version ID */
112         HwveridMASK = 0x7C000000,
113 };
114
115 enum {                                                  /* Rcr */
116         Aap = 0x00000001,                       /* Accept All Packets */
117         Apm = 0x00000002,       /* Accept Physical Match */
118         Am = 0x00000004,        /* Accept Multicast */
119         Ab = 0x00000008,        /* Accept Broadcast */
120         Ar = 0x00000010,        /* Accept Runt */
121         Aer = 0x00000020,       /* Accept Error */
122         Sel9356 = 0x00000040,   /* 9356 EEPROM used */
123         Wrap = 0x00000080,      /* Rx Buffer Wrap Control */
124         MrxdmaSHIFT = 8,        /* Max. DMA Burst Size */
125         MrxdmaMASK = 0x00000700,
126         Mrxdmaunlimited = 0x00000700,
127         RblenSHIFT = 11,        /* Receive Buffer Length */
128         RblenMASK = 0x00001800,
129         Rblen8K = 0x00000000,   /* 8KB+16 */
130         Rblen16K = 0x00000800,  /* 16KB+16 */
131         Rblen32K = 0x00001000,  /* 32KB+16 */
132         Rblen64K = 0x00001800,  /* 64KB+16 */
133         RxfthSHIFT = 13,        /* Receive Buffer Length */
134         RxfthMASK = 0x0000E000,
135         Rxfth256 = 0x00008000,
136         Rxfthnone = 0x0000E000,
137         Rer8 = 0x00010000,      /* Accept Error Packets > 8 bytes */
138         MulERINT = 0x00020000,  /* Multiple Early Interrupt Select */
139         ErxthSHIFT = 24,        /* Early Rx Threshold */
140         ErxthMASK = 0x0F000000,
141         Erxthnone = 0x00000000,
142 };
143
144 enum {                                                  /* Received Packet Status */
145         Rcok = 0x0001,                          /* Receive Completed OK */
146         Fae = 0x0002,   /* Frame Alignment Error */
147         Crc = 0x0004,   /* CRC Error */
148         Long = 0x0008,  /* Long Packet */
149         Runt = 0x0010,  /* Runt Packet Received */
150         Ise = 0x0020,   /* Invalid Symbol Error */
151         Bar = 0x2000,   /* Broadcast Address Received */
152         Pam = 0x4000,   /* Physical Address Matched */
153         Mar = 0x8000,   /* Multicast Address Received */
154 };
155
156 enum {                                                  /* Media Status Register */
157         Rxpf = 0x01,                            /* Pause Flag */
158         Txpf = 0x02,    /* Pause Flag */
159         Linkb = 0x04,   /* Inverse of Link Status */
160         Speed10 = 0x08, /* 10Mbps */
161         Auxstatus = 0x10,       /* Aux. Power Present Status */
162         Rxfce = 0x40,   /* Receive Flow Control Enable */
163         Txfce = 0x80,   /* Transmit Flow Control Enable */
164 };
165
166 typedef struct Td Td;
167 struct Td {                                             /* Soft Transmit Descriptor */
168         int tsd;
169         int tsad;
170         uint8_t *data;
171         struct block *bp;
172 };
173
174 enum {                                                  /* Tsd0 */
175         SizeSHIFT = 0,                          /* Descriptor Size */
176         SizeMASK = 0x00001FFF,
177         Own = 0x00002000,
178         Tun = 0x00004000,       /* Transmit FIFO Underrun */
179         Tcok = 0x00008000,      /* Transmit COmpleted OK */
180         EtxthSHIFT = 16,        /* Early Tx Threshold */
181         EtxthMASK = 0x001F0000,
182         NccSHIFT = 24,  /* Number of Collisions Count */
183         NccMASK = 0x0F000000,
184         Cdh = 0x10000000,       /* CD Heartbeat */
185         Owc = 0x20000000,       /* Out of Window Collision */
186         Tabt = 0x40000000,      /* Transmit Abort */
187         Crs = 0x80000000,       /* Carrier Sense Lost */
188 };
189
190 enum {
191         Rblen = Rblen64K,                       /* Receive Buffer Length */
192         Ntd = 4,        /* Number of Transmit Descriptors */
193         Tdbsz = ROUNDUP(sizeof(Etherpkt), 4),
194 };
195
196 typedef struct Ctlr Ctlr;
197 typedef struct Ctlr {
198         int port;
199         Pcidev *pcidev;
200         struct ctlr *next;
201         int active;
202         int id;
203
204         qlock_t alock;                          /* attach */
205         spinlock_t ilock;                       /* init */
206         void *alloc;                            /* base of per-Ctlr allocated data */
207
208         int rcr;                                        /* receive configuration register */
209         uint8_t *rbstart;                       /* receive buffer */
210         int rblen;                                      /* receive buffer length */
211         int ierrs;                                      /* receive errors */
212
213         spinlock_t tlock;                       /* transmit */
214         Td td[Ntd];
215         int ntd;                                        /* descriptors active */
216         int tdh;                                        /* host index into td */
217         int tdi;                                        /* interface index into td */
218         int etxth;                                      /* early transmit threshold */
219         int taligned;                           /* packet required no alignment */
220         int tunaligned;                         /* packet required alignment */
221
222         int dis;                                        /* disconnect counter */
223         int fcsc;                                       /* false carrier sense counter */
224         int rec;                                        /* RX_ER counter */
225 } Ctlr;
226
227 static struct ctlr *ctlrhead;
228 static struct ctlr *ctlrtail;
229
230 #define csr8r(c, r)     (inb((c)->port+(r)))
231 #define csr16r(c, r)    (ins((c)->port+(r)))
232 #define csr32r(c, r)    (inl((c)->port+(r)))
233 #define csr8w(c, r, b)  (outb((c)->port+(r), (int)(b)))
234 #define csr16w(c, r, w) (outs((c)->port+(r), (uint16_t)(w)))
235 #define csr32w(c, r, l) (outl((c)->port+(r), (uint32_t)(l)))
236
237 static void rtl8139promiscuous(void *arg, int on)
238 {
239         struct ether *edev;
240         struct ctlr *ctlr;
241
242         edev = arg;
243         ctlr = edev->ctlr;
244         spin_lock_irqsave(&(&ctlr->ilock)->lock);
245
246         if (on)
247                 ctlr->rcr |= Aap;
248         else
249                 ctlr->rcr &= ~Aap;
250         csr32w(ctlr, Rcr, ctlr->rcr);
251         spin_unlock_irqsave(&(&ctlr->ilock)->lock);
252 }
253
254 static long rtl8139ifstat(struct ether *edev, void *a, long n, uint32_t offset)
255 {
256         int l;
257         char *p;
258         struct ctlr *ctlr;
259
260         ctlr = edev->ctlr;
261         p = kzmalloc(READSTR, 0);
262         l = snprintf(p, READSTR, "rcr 0x%8.8x\n", ctlr->rcr);
263         l += snprintf(p + l, READSTR - l, "ierrs %d\n", ctlr->ierrs);
264         l += snprintf(p + l, READSTR - l, "etxth %d\n", ctlr->etxth);
265         l += snprintf(p + l, READSTR - l, "taligned %d\n", ctlr->taligned);
266         l += snprintf(p + l, READSTR - l, "tunaligned %d\n", ctlr->tunaligned);
267         ctlr->dis += csr16r(ctlr, Dis);
268         l += snprintf(p + l, READSTR - l, "dis %d\n", ctlr->dis);
269         ctlr->fcsc += csr16r(ctlr, Fcsc);
270         l += snprintf(p + l, READSTR - l, "fcscnt %d\n", ctlr->fcsc);
271         ctlr->rec += csr16r(ctlr, Rec);
272         l += snprintf(p + l, READSTR - l, "rec %d\n", ctlr->rec);
273
274         l += snprintf(p + l, READSTR - l, "Tcr 0x%8.8lx\n", csr32r(ctlr, Tcr));
275         l += snprintf(p + l, READSTR - l, "Config0 0x%2.2x\n",
276                                   csr8r(ctlr, Config0));
277         l += snprintf(p + l, READSTR - l, "Config1 0x%2.2x\n",
278                                   csr8r(ctlr, Config1));
279         l += snprintf(p + l, READSTR - l, "Msr 0x%2.2x\n", csr8r(ctlr, Msr));
280         l += snprintf(p + l, READSTR - l, "Config3 0x%2.2x\n",
281                                   csr8r(ctlr, Config3));
282         l += snprintf(p + l, READSTR - l, "Config4 0x%2.2x\n",
283                                   csr8r(ctlr, Config4));
284
285         l += snprintf(p + l, READSTR - l, "Bmcr 0x%4.4x\n", csr16r(ctlr, Bmcr));
286         l += snprintf(p + l, READSTR - l, "Bmsr 0x%4.4x\n", csr16r(ctlr, Bmsr));
287         l += snprintf(p + l, READSTR - l, "Anar 0x%4.4x\n", csr16r(ctlr, Anar));
288         l += snprintf(p + l, READSTR - l, "Anlpar 0x%4.4x\n", csr16r(ctlr, Anlpar));
289         l += snprintf(p + l, READSTR - l, "Aner 0x%4.4x\n", csr16r(ctlr, Aner));
290         l += snprintf(p + l, READSTR - l, "Nwaytr 0x%4.4x\n", csr16r(ctlr, Nwaytr));
291         snprintf(p + l, READSTR - l, "Cscr 0x%4.4x\n", csr16r(ctlr, Cscr));
292         n = readstr(offset, a, n, p);
293         kfree(p);
294
295         return n;
296 }
297
298 static int rtl8139reset(struct ctlr *ctlr)
299 {
300         int timeo;
301
302         /*
303          * Soft reset the controller.
304          */
305         csr8w(ctlr, Cr, Rst);
306         for (timeo = 0; timeo < 1000; timeo++) {
307                 if (!(csr8r(ctlr, Cr) & Rst))
308                         return 0;
309                 delay(1);
310         }
311
312         return -1;
313 }
314
315 static void rtl8139halt(struct ctlr *ctlr)
316 {
317         int i;
318
319         csr8w(ctlr, Cr, 0);
320         csr16w(ctlr, Imr, 0);
321         csr16w(ctlr, Isr, ~0);
322
323         for (i = 0; i < Ntd; i++) {
324                 if (ctlr->td[i].bp == NULL)
325                         continue;
326                 freeb(ctlr->td[i].bp);
327                 ctlr->td[i].bp = NULL;
328         }
329 }
330
331 static void rtl8139init(struct ether *edev)
332 {
333         int i;
334         uint32_t r;
335         struct ctlr *ctlr;
336         uint8_t *alloc;
337
338         ctlr = edev->ctlr;
339         spin_lock_irqsave(&(&ctlr->ilock)->lock);
340
341         rtl8139halt(ctlr);
342
343         /*
344          * MAC Address.
345          */
346         r = (edev->ea[3] << 24) | (edev->ea[2] << 16) | (edev->ea[1] << 8) | edev->
347                 ea[0];
348         csr32w(ctlr, Idr0, r);
349         r = (edev->ea[5] << 8) | edev->ea[4];
350         csr32w(ctlr, Idr0 + 4, r);
351
352         /*
353          * Receiver
354          */
355         alloc =
356                 mmucacheinhib((char *unused_char_p_t)
357                                           ROUNDUP((uint32_t) ctlr->alloc, CACHELINESZ),
358                                           ctlr->rblen + 16 + Ntd * Tdbsz);
359         ctlr->rbstart = alloc;
360         alloc += ctlr->rblen + 16;
361         memset(ctlr->rbstart, 0, ctlr->rblen + 16);
362         csr32w(ctlr, Rbstart, PCIWADDR(ctlr->rbstart));
363         ctlr->rcr = Rxfth256 | Rblen | Mrxdmaunlimited | Ab | Apm;
364
365         /*
366          * Transmitter.
367          */
368         for (i = 0; i < Ntd; i++) {
369                 ctlr->td[i].tsd = Tsd0 + i * 4;
370                 ctlr->td[i].tsad = Tsad0 + i * 4;
371                 ctlr->td[i].data = alloc;
372                 alloc += Tdbsz;
373                 ctlr->td[i].bp = NULL;
374         }
375         ctlr->ntd = ctlr->tdh = ctlr->tdi = 0;
376         ctlr->etxth = 128 / 32;
377
378         /*
379          * Interrupts.
380          */
381         csr32w(ctlr, TimerInt, 0);
382         csr16w(ctlr, Imr,
383                    Serr | Timerbit | Fovw | PunLc | Rxovw | Ter | Tok | Rer | Rok);
384         csr32w(ctlr, Mpc, 0);
385
386         /*
387          * Enable receiver/transmitter.
388          * Need to enable before writing the Rcr or it won't take.
389          */
390         csr8w(ctlr, Cr, Te | Re);
391         csr32w(ctlr, Tcr, Mtxdma2048);
392         csr32w(ctlr, Rcr, ctlr->rcr);
393
394         spin_unlock_irqsave(&(&ctlr->ilock)->lock);
395 }
396
397 static void rtl8139attach(struct ether *edev)
398 {
399         struct ctlr *ctlr;
400
401         ctlr = edev->ctlr;
402         qlock(&(&ctlr->alock)->qlock);
403         if (ctlr->alloc == NULL) {
404                 ctlr->rblen = 1 << ((Rblen >> RblenSHIFT) + 13);
405                 ctlr->alloc = mallocz(ctlr->rblen + 16 + Ntd * Tdbsz + CACHELINESZ, 0);
406                 rtl8139init(edev);
407         }
408         qunlock(&(&ctlr->alock)->qlock);
409 }
410
411 static void rtl8139txstart(struct ether *edev)
412 {
413         Td *td;
414         int size;
415         struct block *bp;
416         struct ctlr *ctlr;
417
418         ctlr = edev->ctlr;
419         while (ctlr->ntd < Ntd) {
420                 bp = qget(edev->oq);
421                 if (bp == NULL)
422                         break;
423                 size = BLEN(bp);
424
425                 td = &ctlr->td[ctlr->tdh];
426                 if (((int)bp->rp) & 0x03) {
427                         memmove(td->data, bp->rp, size);
428                         dcflush(td->data, size);
429                         freeb(bp);
430                         csr32w(ctlr, td->tsad, PCIWADDR(td->data));
431                         ctlr->tunaligned++;
432                 } else {
433                         td->bp = bp;
434                         csr32w(ctlr, td->tsad, PCIWADDR(bp->rp));
435                         dcflush(bp->rp, size);
436                         ctlr->taligned++;
437                 }
438                 csr32w(ctlr, td->tsd, (ctlr->etxth << EtxthSHIFT) | size);
439
440                 ctlr->ntd++;
441                 ctlr->tdh = NEXT(ctlr->tdh, Ntd);
442         }
443 }
444
445 static void rtl8139transmit(struct ether *edev)
446 {
447         struct ctlr *ctlr;
448
449         ctlr = edev->ctlr;
450         spin_lock_irqsave(&(&ctlr->tlock)->lock);
451         rtl8139txstart(edev);
452         spin_unlock_irqsave(&(&ctlr->tlock)->lock);
453 }
454
455 static void rtl8139receive(struct ether *edev)
456 {
457         struct block *bp;
458         struct ctlr *ctlr;
459         uint16_t capr;
460         uint8_t cr, *p;
461         int l, length, status;
462
463         ctlr = edev->ctlr;
464
465         /*
466          * Capr is where the host is reading from,
467          * Cbr is where the NIC is currently writing.
468          */
469         capr = (csr16r(ctlr, Capr) + 16) % ctlr->rblen;
470         while (!(csr8r(ctlr, Cr) & Bufe)) {
471                 p = ctlr->rbstart + capr;
472
473                 /*
474                  * Apparently the packet length may be 0xFFF0 if
475                  * the NIC is still copying the packet into memory.
476                  */
477                 length = (*(p + 3) << 8) | *(p + 2);
478                 if (length == 0xFFF0)
479                         break;
480                 status = (*(p + 1) << 8) | *p;
481                 if (!(status & Rcok)) {
482                         if (status & (Ise | Fae))
483                                 edev->frames++;
484                         if (status & Crc)
485                                 edev->crcs++;
486                         if (status & (Runt | Long))
487                                 edev->buffs++;
488
489                         /*
490                          * Reset the receiver.
491                          * Also may have to restore the multicast list
492                          * here too if it ever gets used.
493                          */
494                         cr = csr8r(ctlr, Cr);
495                         csr8w(ctlr, Cr, cr & ~Re);
496                         csr32w(ctlr, Rbstart, PCIWADDR(ctlr->rbstart));
497                         csr8w(ctlr, Cr, cr);
498                         csr32w(ctlr, Rcr, ctlr->rcr);
499
500                         continue;
501                 }
502
503                 /*
504                  * Receive Completed OK.
505                  * Very simplistic; there are ways this could be done
506                  * without copying, but the juice probably isn't worth
507                  * the squeeze.
508                  * The packet length includes a 4 byte CRC on the end.
509                  */
510                 capr = (capr + 4) % ctlr->rblen;
511                 p = ctlr->rbstart + capr;
512                 capr = (capr + length) % ctlr->rblen;
513
514                 if ((bp = iallocb(length)) != NULL) {
515                         if (p + length >= ctlr->rbstart + ctlr->rblen) {
516                                 l = ctlr->rbstart + ctlr->rblen - p;
517                                 memmove(bp->wp, p, l);
518                                 bp->wp += l;
519                                 length -= l;
520                                 p = ctlr->rbstart;
521                         }
522                         if (length > 0) {
523                                 memmove(bp->wp, p, length);
524                                 bp->wp += length;
525                         }
526                         bp->wp -= 4;
527                         etheriq(edev, bp, 1);
528                 }
529
530                 capr = ROUNDUP(capr, 4);
531                 csr16w(ctlr, Capr, capr - 16);
532         }
533 }
534
535 static void rtl8139interrupt(Ureg *, void *arg)
536 {
537         Td *td;
538         struct ctlr *ctlr;
539         struct ether *edev;
540         int isr, msr, tsd;
541
542         edev = arg;
543         ctlr = edev->ctlr;
544
545         while ((isr = csr16r(ctlr, Isr)) != 0) {
546                 csr16w(ctlr, Isr, isr);
547                 if (isr & (Fovw | PunLc | Rxovw | Rer | Rok)) {
548                         rtl8139receive(edev);
549                         if (!(isr & Rok))
550                                 ctlr->ierrs++;
551                         isr &= ~(Fovw | Rxovw | Rer | Rok);
552                 }
553
554                 if (isr & (Ter | Tok)) {
555                         spin_lock_irqsave(&(&ctlr->tlock)->lock);
556                         while (ctlr->ntd) {
557                                 td = &ctlr->td[ctlr->tdi];
558                                 tsd = csr32r(ctlr, td->tsd);
559                                 if (!(tsd & (Tabt | Tun | Tcok)))
560                                         break;
561
562                                 if (!(tsd & Tcok)) {
563                                         if (tsd & Tun) {
564                                                 if (ctlr->etxth < ETHERMAXTU / 32)
565                                                         ctlr->etxth++;
566                                         }
567                                         edev->oerrs++;
568                                 }
569
570                                 if (td->bp != NULL) {
571                                         freeb(td->bp);
572                                         td->bp = NULL;
573                                 }
574
575                                 ctlr->ntd--;
576                                 ctlr->tdi = NEXT(ctlr->tdi, Ntd);
577                         }
578                         rtl8139txstart(edev);
579                         spin_unlock_irqsave(&(&ctlr->tlock)->lock);
580                         isr &= ~(Ter | Tok);
581                 }
582
583                 if (isr & PunLc) {
584                         /*
585                          * Maybe the link changed - do we care very much?
586                          */
587                         msr = csr8r(ctlr, Msr);
588                         if (!(msr & Linkb)) {
589                                 if (!(msr & Speed10) && edev->mbps != 100) {
590                                         edev->mbps = 100;
591                                         qsetlimit(edev->oq, 256 * 1024);
592                                 } else if ((msr & Speed10) && edev->mbps != 10) {
593                                         edev->mbps = 10;
594                                         qsetlimit(edev->oq, 65 * 1024);
595                                 }
596                         }
597                         isr &= ~(Clc | PunLc);
598                 }
599
600                 /*
601                  * Only Serr|Timer should be left by now.
602                  * Should anything be done to tidy up? TimerInt isn't
603                  * used so that can be cleared. A PCI bus error is indicated
604                  * by Serr, that's pretty serious; is there anyhing to do
605                  * other than try to reinitialise the chip?
606                  */
607                 if (isr != 0) {
608                         iprint("rtl8139interrupt: imr 0x%4.4x isr 0x%4.4x\n",
609                                    csr16r(ctlr, Imr), isr);
610                         if (isr & Timerbit)
611                                 csr32w(ctlr, TimerInt, 0);
612                         if (isr & Serr)
613                                 rtl8139init(edev);
614                 }
615         }
616 }
617
618 static struct ctlr *rtl8139match(struct ether *edev, int id)
619 {
620         int port;
621         Pcidev *p;
622         struct ctlr *ctlr;
623
624         /*
625          * Any adapter matches if no edev->port is supplied,
626          * otherwise the ports must match.
627          */
628         for (ctlr = ctlrhead; ctlr != NULL; ctlr = ctlr->next) {
629                 if (ctlr->active)
630                         continue;
631                 p = ctlr->pcidev;
632                 if (((p->did << 16) | p->vid) != id)
633                         continue;
634                 port = p->mem[0].bar & ~0x01;
635                 if (edev->port != 0 && edev->port != port)
636                         continue;
637
638                 if (ioalloc(port, p->mem[0].size, 0, "rtl8139") < 0) {
639                         printd("rtl8139: port 0x%x in use\n", port);
640                         continue;
641                 }
642
643                 ctlr->port = port;
644                 if (rtl8139reset(ctlr))
645                         continue;
646                 pcisetbme(p);
647
648                 ctlr->active = 1;
649                 return ctlr;
650         }
651         return NULL;
652 }
653
654 static struct {
655         char *name;
656         int id;
657 } rtl8139pci[] = {
658         {
659         "rtl8139", (0x8139 << 16) | 0x10EC,},   /* generic */
660         {
661         "smc1211", (0x1211 << 16) | 0x1113,},   /* SMC EZ-Card */
662         {
663         "dfe-538tx", (0x1300 << 16) | 0x1186,}, /* D-Link DFE-538TX */
664         {
665         "dfe-560txd", (0x1340 << 16) | 0x1186,},        /* D-Link DFE-560TXD */
666         {
667 NULL},};
668
669 static int rtl8139pnp(struct ether *edev)
670 {
671         int i, id;
672         Pcidev *p;
673         struct ctlr *ctlr;
674         uint8_t ea[Eaddrlen];
675
676         /*
677          * Make a list of all ethernet controllers
678          * if not already done.
679          */
680         if (ctlrhead == NULL) {
681                 p = NULL;
682                 while (p = pcimatch(p, 0, 0)) {
683                         if (p->ccrb != 0x02 || p->ccru != 0)
684                                 continue;
685                         ctlr = kzmalloc(sizeof(struct ctlr), 0);
686                         ctlr->pcidev = p;
687                         ctlr->id = (p->did << 16) | p->vid;
688
689                         if (ctlrhead != NULL)
690                                 ctlrtail->next = ctlr;
691                         else
692                                 ctlrhead = ctlr;
693                         ctlrtail = ctlr;
694                 }
695         }
696
697         /*
698          * Is it an RTL8139 under a different name?
699          * Normally a search is made through all the found controllers
700          * for one which matches any of the known vid+did pairs.
701          * If a vid+did pair is specified a search is made for that
702          * specific controller only.
703          */
704         id = 0;
705         for (i = 0; i < edev->nopt; i++) {
706                 if (cistrncmp(edev->opt[i], "id=", 3) == 0)
707                         id = strtol(&edev->opt[i][3], NULL, 0);
708         }
709
710         ctlr = NULL;
711         if (id != 0)
712                 ctlr = rtl8139match(edev, id);
713         else
714                 for (i = 0; rtl8139pci[i].name; i++) {
715                         if ((ctlr = rtl8139match(edev, rtl8139pci[i].id)) != NULL)
716                                 break;
717                 }
718         if (ctlr == NULL)
719                 return -1;
720
721         edev->ctlr = ctlr;
722         edev->port = ctlr->port;
723         edev->irq = ctlr->pcidev->intl;
724         edev->tbdf = ctlr->pcidev->tbdf;
725
726         /*
727          * Check if the adapter's station address is to be overridden.
728          * If not, read it from the device and set in edev->ea.
729          */
730         memset(ea, 0, Eaddrlen);
731         if (memcmp(ea, edev->ea, Eaddrlen) == 0) {
732                 i = csr32r(ctlr, Idr0);
733                 edev->ea[0] = i;
734                 edev->ea[1] = i >> 8;
735                 edev->ea[2] = i >> 16;
736                 edev->ea[3] = i >> 24;
737                 i = csr32r(ctlr, Idr0 + 4);
738                 edev->ea[4] = i;
739                 edev->ea[5] = i >> 8;
740         }
741         edev->attach = rtl8139attach;
742         edev->transmit = rtl8139transmit;
743         edev->interrupt = rtl8139interrupt;
744         edev->ifstat = rtl8139ifstat;
745
746         edev->arg = edev;
747         edev->promiscuous = rtl8139promiscuous;
748
749         /*
750          * This should be much more dynamic but will do for now.
751          */
752         if ((csr8r(ctlr, Msr) & (Speed10 | Linkb)) == 0)
753                 edev->mbps = 100;
754
755         return 0;
756 }
757
758 void __etherlink ether8139link(void)
759 {
760         addethercard("rtl8139", rtl8139pnp);
761 }