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