]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/ether82557.c
usbehci: catch interrupt in tsleep
[plan9front.git] / sys / src / 9 / pc / ether82557.c
1 /*
2  * Intel 82557 Fast Ethernet PCI Bus LAN Controller
3  * as found on the Intel EtherExpress PRO/100B. This chip is full
4  * of smarts, unfortunately they're not all in the right place.
5  * To do:
6  *      the PCI scanning code could be made common to other adapters;
7  *      auto-negotiation, full-duplex;
8  *      optionally use memory-mapped registers;
9  *      detach for PCI reset problems (also towards loadable drivers).
10  */
11 #include "u.h"
12 #include "../port/lib.h"
13 #include "mem.h"
14 #include "dat.h"
15 #include "fns.h"
16 #include "io.h"
17 #include "../port/error.h"
18 #include "../port/netif.h"
19 #include "../port/etherif.h"
20
21 enum {
22         Nrfd            = 64,           /* receive frame area */
23         Ncb             = 64,           /* maximum control blocks queued */
24
25         NullPointer     = 0xFFFFFFFF,   /* 82557 NULL pointer */
26 };
27
28 enum {                                  /* CSR */
29         Status          = 0x00,         /* byte or word (word includes Ack) */
30         Ack             = 0x01,         /* byte */
31         CommandR        = 0x02,         /* byte or word (word includes Interrupt) */
32         Interrupt       = 0x03,         /* byte */
33         General         = 0x04,         /* dword */
34         Port            = 0x08,         /* dword */
35         Fcr             = 0x0C,         /* Flash control register */
36         Ecr             = 0x0E,         /* EEPROM control register */
37         Mcr             = 0x10,         /* MDI control register */
38         Gstatus         = 0x1D,         /* General status register */
39 };
40
41 enum {                                  /* Status */
42         RUidle          = 0x0000,
43         RUsuspended     = 0x0004,
44         RUnoresources   = 0x0008,
45         RUready         = 0x0010,
46         RUrbd           = 0x0020,       /* bit */
47         RUstatus        = 0x003F,       /* mask */
48
49         CUidle          = 0x0000,
50         CUsuspended     = 0x0040,
51         CUactive        = 0x0080,
52         CUstatus        = 0x00C0,       /* mask */
53
54         StatSWI         = 0x0400,       /* SoftWare generated Interrupt */
55         StatMDI         = 0x0800,       /* MDI r/w done */
56         StatRNR         = 0x1000,       /* Receive unit Not Ready */
57         StatCNA         = 0x2000,       /* Command unit Not Active (Active->Idle) */
58         StatFR          = 0x4000,       /* Finished Receiving */
59         StatCX          = 0x8000,       /* Command eXecuted */
60         StatTNO         = 0x8000,       /* Transmit NOT OK */
61 };
62
63 enum {                                  /* Command (byte) */
64         CUnop           = 0x00,
65         CUstart         = 0x10,
66         CUresume        = 0x20,
67         LoadDCA         = 0x40,         /* Load Dump Counters Address */
68         DumpSC          = 0x50,         /* Dump Statistical Counters */
69         LoadCUB         = 0x60,         /* Load CU Base */
70         ResetSA         = 0x70,         /* Dump and Reset Statistical Counters */
71
72         RUstart         = 0x01,
73         RUresume        = 0x02,
74         RUabort         = 0x04,
75         LoadHDS         = 0x05,         /* Load Header Data Size */
76         LoadRUB         = 0x06,         /* Load RU Base */
77         RBDresume       = 0x07,         /* Resume frame reception */
78 };
79
80 enum {                                  /* Interrupt (byte) */
81         InterruptM      = 0x01,         /* interrupt Mask */
82         InterruptSI     = 0x02,         /* Software generated Interrupt */
83 };
84
85 enum {                                  /* Ecr */
86         EEsk            = 0x01,         /* serial clock */
87         EEcs            = 0x02,         /* chip select */
88         EEdi            = 0x04,         /* serial data in */
89         EEdo            = 0x08,         /* serial data out */
90
91         EEstart         = 0x04,         /* start bit */
92         EEread          = 0x02,         /* read opcode */
93 };
94
95 enum {                                  /* Mcr */
96         MDIread         = 0x08000000,   /* read opcode */
97         MDIwrite        = 0x04000000,   /* write opcode */
98         MDIready        = 0x10000000,   /* ready bit */
99         MDIie           = 0x20000000,   /* interrupt enable */
100 };
101
102 typedef struct Rfd {
103         int     field;
104         ulong   link;
105         ulong   rbd;
106         ushort  count;
107         ushort  size;
108
109         uchar   data[1700];
110 } Rfd;
111
112 enum {                                  /* field */
113         RfdCollision    = 0x00000001,
114         RfdIA           = 0x00000002,   /* IA match */
115         RfdRxerr        = 0x00000010,   /* PHY character error */
116         RfdType         = 0x00000020,   /* Type frame */
117         RfdRunt         = 0x00000080,
118         RfdOverrun      = 0x00000100,
119         RfdBuffer       = 0x00000200,
120         RfdAlignment    = 0x00000400,
121         RfdCRC          = 0x00000800,
122
123         RfdOK           = 0x00002000,   /* frame received OK */
124         RfdC            = 0x00008000,   /* reception Complete */
125         RfdSF           = 0x00080000,   /* Simplified or Flexible (1) Rfd */
126         RfdH            = 0x00100000,   /* Header RFD */
127
128         RfdI            = 0x20000000,   /* Interrupt after completion */
129         RfdS            = 0x40000000,   /* Suspend after completion */
130         RfdEL           = 0x80000000,   /* End of List */
131 };
132
133 enum {                                  /* count */
134         RfdF            = 0x4000,
135         RfdEOF          = 0x8000,
136 };
137
138 typedef struct Cb Cb;
139 typedef struct Cb {
140         ushort  status;
141         ushort  command;
142         ulong   link;
143         union {
144                 uchar   data[24];       /* CbIAS + CbConfigure */
145                 struct {
146                         ulong   tbd;
147                         ushort  count;
148                         uchar   threshold;
149                         uchar   number;
150
151                         ulong   tba;
152                         ushort  tbasz;
153                         ushort  pad;
154                 };
155         };
156
157         Block*  bp;
158         Cb*     next;
159 } Cb;
160
161 enum {                                  /* action command */
162         CbU             = 0x1000,       /* transmit underrun */
163         CbOK            = 0x2000,       /* DMA completed OK */
164         CbC             = 0x8000,       /* execution Complete */
165
166         CbNOP           = 0x0000,
167         CbIAS           = 0x0001,       /* Individual Address Setup */
168         CbConfigure     = 0x0002,
169         CbMAS           = 0x0003,       /* Multicast Address Setup */
170         CbTransmit      = 0x0004,
171         CbDump          = 0x0006,
172         CbDiagnose      = 0x0007,
173         CbCommand       = 0x0007,       /* mask */
174
175         CbSF            = 0x0008,       /* Flexible-mode CbTransmit */
176
177         CbI             = 0x2000,       /* Interrupt after completion */
178         CbS             = 0x4000,       /* Suspend after completion */
179         CbEL            = 0x8000,       /* End of List */
180 };
181
182 enum {                                  /* CbTransmit count */
183         CbEOF           = 0x8000,
184 };
185
186 typedef struct Ctlr Ctlr;
187 typedef struct Ctlr {
188         Lock    slock;                  /* attach */
189         int     state;
190
191         int     port;
192         Pcidev* pcidev;
193         Ctlr*   next;
194         int     active;
195
196         int     eepromsz;               /* address size in bits */
197         ushort* eeprom;
198
199         Lock    miilock;
200
201         int     tick;
202
203         Lock    rlock;                  /* registers */
204         int     command;                /* last command issued */
205
206         Block*  rfdhead;                /* receive side */
207         Block*  rfdtail;
208         int     nrfd;
209
210         Lock    cblock;                 /* transmit side */
211         int     action;
212         int     nop;
213         uchar   configdata[24];
214         int     threshold;
215         int     ncb;
216         Cb*     cbr;
217         Cb*     cbhead;
218         Cb*     cbtail;
219         int     cbq;
220         int     cbqmax;
221         int     cbqmaxhw;
222
223         Lock    dlock;                  /* dump statistical counters */
224         ulong   dump[17];
225 } Ctlr;
226
227 static Ctlr* ctlrhead;
228 static Ctlr* ctlrtail;
229
230 static uchar configdata[24] = {
231         0x16,                           /* byte count */
232         0x08,                           /* Rx/Tx FIFO limit */
233         0x00,                           /* adaptive IFS */
234         0x00,   
235         0x00,                           /* Rx DMA maximum byte count */
236 //      0x80,                           /* Tx DMA maximum byte count */
237         0x00,                           /* Tx DMA maximum byte count */
238         0x32,                           /* !late SCB, CNA interrupts */
239         0x03,                           /* discard short Rx frames */
240         0x00,                           /* 503/MII */
241
242         0x00,   
243         0x2E,                           /* normal operation, NSAI */
244         0x00,                           /* linear priority */
245         0x60,                           /* inter-frame spacing */
246         0x00,   
247         0xF2,   
248         0xC8,                           /* 503, promiscuous mode off */
249         0x00,   
250         0x40,   
251         0xF3,                           /* transmit padding enable */
252         0x80,                           /* full duplex pin enable */
253         0x3F,                           /* no Multi IA */
254         0x05,                           /* no Multi Cast ALL */
255 };
256
257 #define csr8r(c, r)     (inb((c)->port+(r)))
258 #define csr16r(c, r)    (ins((c)->port+(r)))
259 #define csr32r(c, r)    (inl((c)->port+(r)))
260 #define csr8w(c, r, b)  (outb((c)->port+(r), (int)(b)))
261 #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
262 #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
263
264 static void
265 command(Ctlr* ctlr, int c, int v)
266 {
267         int timeo;
268
269         ilock(&ctlr->rlock);
270
271         /*
272          * Only back-to-back CUresume can be done
273          * without waiting for any previous command to complete.
274          * This should be the common case.
275          * Unfortunately there's a chip errata where back-to-back
276          * CUresumes can be lost, the fix is to always wait.
277         if(c == CUresume && ctlr->command == CUresume){
278                 csr8w(ctlr, CommandR, c);
279                 iunlock(&ctlr->rlock);
280                 return;
281         }
282          */
283
284         for(timeo = 0; timeo < 100; timeo++){
285                 if(!csr8r(ctlr, CommandR))
286                         break;
287                 microdelay(1);
288         }
289         if(timeo >= 100){
290                 ctlr->command = -1;
291                 iunlock(&ctlr->rlock);
292                 iprint("i82557: command %#ux %#ux timeout\n", c, v);
293                 return;
294         }
295
296         switch(c){
297
298         case CUstart:
299         case LoadDCA:
300         case LoadCUB:
301         case RUstart:
302         case LoadHDS:
303         case LoadRUB:
304                 csr32w(ctlr, General, v);
305                 break;
306
307         /*
308         case CUnop:
309         case CUresume:
310         case DumpSC:
311         case ResetSA:
312         case RUresume:
313         case RUabort:
314          */
315         default:
316                 break;
317         }
318         csr8w(ctlr, CommandR, c);
319         ctlr->command = c;
320
321         iunlock(&ctlr->rlock);
322 }
323
324 static Block*
325 rfdalloc(ulong link)
326 {
327         Block *bp;
328         Rfd *rfd;
329
330         if(bp = iallocb(sizeof(Rfd))){
331                 rfd = (Rfd*)bp->rp;
332                 rfd->field = 0;
333                 rfd->link = link;
334                 rfd->rbd = NullPointer;
335                 rfd->count = 0;
336                 rfd->size = sizeof(Etherpkt);
337         }
338
339         return bp;
340 }
341
342 static void
343 watchdog(void* arg)
344 {
345         Ether *ether;
346         Ctlr *ctlr;
347         static void txstart(Ether*);
348
349         ether = arg;
350         while(waserror())
351                 ;
352         for(;;){
353                 tsleep(&up->sleep, return0, 0, 4000);
354
355                 /*
356                  * Hmmm. This doesn't seem right. Currently
357                  * the device can't be disabled but it may be in
358                  * the future.
359                  */
360                 ctlr = ether->ctlr;
361                 if(ctlr == nil || ctlr->state == 0)
362                         break;
363
364                 ilock(&ctlr->cblock);
365                 if(ctlr->tick++){
366                         ctlr->action = CbMAS;
367                         txstart(ether);
368                 }
369                 iunlock(&ctlr->cblock);
370         }
371         print("%s: exiting\n", up->text);
372         pexit("disabled", 1);
373 }
374
375 static void
376 attach(Ether* ether)
377 {
378         Ctlr *ctlr;
379         char name[KNAMELEN];
380
381         ctlr = ether->ctlr;
382         lock(&ctlr->slock);
383         if(ctlr->state == 0){
384                 ilock(&ctlr->rlock);
385                 csr8w(ctlr, Interrupt, 0);
386                 iunlock(&ctlr->rlock);
387                 command(ctlr, RUstart, PADDR(ctlr->rfdhead->rp));
388                 ctlr->state = 1;
389
390                 /*
391                  * Start the watchdog timer for the receive lockup errata
392                  * unless the EEPROM compatibility word indicates it may be
393                  * omitted.
394                  */
395                 if((ctlr->eeprom[0x03] & 0x0003) != 0x0003){
396                         snprint(name, KNAMELEN, "#l%dwatchdog", ether->ctlrno);
397                         kproc(name, watchdog, ether);
398                 }
399         }
400         unlock(&ctlr->slock);
401 }
402
403 static long
404 ifstat(Ether* ether, void* a, long n, ulong offset)
405 {
406         char *p;
407         int i, len, phyaddr;
408         Ctlr *ctlr;
409         ulong dump[17];
410
411         ctlr = ether->ctlr;
412         lock(&ctlr->dlock);
413         if(waserror()){
414                 unlock(&ctlr->dlock);
415                 nexterror();
416         }
417
418         /*
419          * Start the command then
420          * wait for completion status,
421          * should be 0xA005.
422          */
423         ctlr->dump[16] = 0;
424         command(ctlr, DumpSC, 0);
425         for(i = 0; i < 1000 && ctlr->dump[16] == 0; i++)
426                 microdelay(100);
427         if(i == 1000)
428                 error("command timeout");
429
430         memmove(dump, ctlr->dump, sizeof(dump));
431
432         ether->oerrs = dump[1]+dump[2]+dump[3];
433         ether->crcs = dump[10];
434         ether->frames = dump[11];
435         ether->buffs = dump[12]+dump[15];
436         ether->overflows = dump[13];
437
438         poperror();
439         unlock(&ctlr->dlock);
440
441         if(n == 0)
442                 return 0;
443
444         p = smalloc(READSTR);
445         len = snprint(p, READSTR, "transmit good frames: %lud\n", dump[0]);
446         len += snprint(p+len, READSTR-len, "transmit maximum collisions errors: %lud\n", dump[1]);
447         len += snprint(p+len, READSTR-len, "transmit late collisions errors: %lud\n", dump[2]);
448         len += snprint(p+len, READSTR-len, "transmit underrun errors: %lud\n", dump[3]);
449         len += snprint(p+len, READSTR-len, "transmit lost carrier sense: %lud\n", dump[4]);
450         len += snprint(p+len, READSTR-len, "transmit deferred: %lud\n", dump[5]);
451         len += snprint(p+len, READSTR-len, "transmit single collisions: %lud\n", dump[6]);
452         len += snprint(p+len, READSTR-len, "transmit multiple collisions: %lud\n", dump[7]);
453         len += snprint(p+len, READSTR-len, "transmit total collisions: %lud\n", dump[8]);
454         len += snprint(p+len, READSTR-len, "receive good frames: %lud\n", dump[9]);
455         len += snprint(p+len, READSTR-len, "receive CRC errors: %lud\n", dump[10]);
456         len += snprint(p+len, READSTR-len, "receive alignment errors: %lud\n", dump[11]);
457         len += snprint(p+len, READSTR-len, "receive resource errors: %lud\n", dump[12]);
458         len += snprint(p+len, READSTR-len, "receive overrun errors: %lud\n", dump[13]);
459         len += snprint(p+len, READSTR-len, "receive collision detect errors: %lud\n", dump[14]);
460         len += snprint(p+len, READSTR-len, "receive short frame errors: %lud\n", dump[15]);
461         len += snprint(p+len, READSTR-len, "nop: %d\n", ctlr->nop);
462         if(ctlr->cbqmax > ctlr->cbqmaxhw)
463                 ctlr->cbqmaxhw = ctlr->cbqmax;
464         len += snprint(p+len, READSTR-len, "cbqmax: %d\n", ctlr->cbqmax);
465         ctlr->cbqmax = 0;
466         len += snprint(p+len, READSTR-len, "threshold: %d\n", ctlr->threshold);
467
468         len += snprint(p+len, READSTR-len, "eeprom:");
469         for(i = 0; i < (1<<ctlr->eepromsz); i++){
470                 if(i && ((i & 0x07) == 0))
471                         len += snprint(p+len, READSTR-len, "\n       ");
472                 len += snprint(p+len, READSTR-len, " %4.4ux", ctlr->eeprom[i]);
473         }
474
475         if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
476                 phyaddr = ctlr->eeprom[6] & 0x00FF;
477                 len += snprint(p+len, READSTR-len, "\nphy %2d:", phyaddr);
478                 for(i = 0; i < 6; i++){
479                         static int miir(Ctlr*, int, int);
480
481                         len += snprint(p+len, READSTR-len, " %4.4ux",
482                                 miir(ctlr, phyaddr, i));
483                 }
484         }
485
486         snprint(p+len, READSTR-len, "\n");
487         n = readstr(offset, a, n, p);
488         free(p);
489
490         return n;
491 }
492
493 static void
494 txstart(Ether* ether)
495 {
496         Ctlr *ctlr;
497         Block *bp;
498         Cb *cb;
499
500         ctlr = ether->ctlr;
501         while(ctlr->cbq < (ctlr->ncb-1)){
502                 cb = ctlr->cbhead->next;
503                 if(ctlr->action == 0){
504                         bp = qget(ether->oq);
505                         if(bp == nil)
506                                 break;
507
508                         cb->command = CbS|CbSF|CbTransmit;
509                         cb->tbd = PADDR(&cb->tba);
510                         cb->count = 0;
511                         cb->threshold = ctlr->threshold;
512                         cb->number = 1;
513                         cb->tba = PADDR(bp->rp);
514                         cb->bp = bp;
515                         cb->tbasz = BLEN(bp);
516                 }
517                 else if(ctlr->action == CbConfigure){
518                         cb->command = CbS|CbConfigure;
519                         memmove(cb->data, ctlr->configdata, sizeof(ctlr->configdata));
520                         ctlr->action = 0;
521                 }
522                 else if(ctlr->action == CbIAS){
523                         cb->command = CbS|CbIAS;
524                         memmove(cb->data, ether->ea, Eaddrlen);
525                         ctlr->action = 0;
526                 }
527                 else if(ctlr->action == CbMAS){
528                         cb->command = CbS|CbMAS;
529                         memset(cb->data, 0, sizeof(cb->data));
530                         ctlr->action = 0;
531                 }
532                 else{
533                         print("#l%d: action %#ux\n", ether->ctlrno, ctlr->action);
534                         ctlr->action = 0;
535                         break;
536                 }
537                 cb->status = 0;
538
539                 coherence();
540                 ctlr->cbhead->command &= ~CbS;
541                 ctlr->cbhead = cb;
542                 ctlr->cbq++;
543         }
544
545         /*
546          * Workaround for some broken HUB chips
547          * when connected at 10Mb/s half-duplex.
548          */
549         if(ctlr->nop){
550                 command(ctlr, CUnop, 0);
551                 microdelay(1);
552         }
553         command(ctlr, CUresume, 0);
554
555         if(ctlr->cbq > ctlr->cbqmax)
556                 ctlr->cbqmax = ctlr->cbq;
557 }
558
559 static void
560 configure(Ether* ether, int promiscuous)
561 {
562         Ctlr *ctlr;
563
564         ctlr = ether->ctlr;
565         ilock(&ctlr->cblock);
566         if(promiscuous){
567                 ctlr->configdata[6] |= 0x80;            /* Save Bad Frames */
568                 //ctlr->configdata[6] &= ~0x40;         /* !Discard Overrun Rx Frames */
569                 ctlr->configdata[7] &= ~0x01;           /* !Discard Short Rx Frames */
570                 ctlr->configdata[15] |= 0x01;           /* Promiscuous mode */
571                 ctlr->configdata[18] &= ~0x01;          /* (!Padding enable?), !stripping enable */
572                 ctlr->configdata[21] |= 0x08;           /* Multi Cast ALL */
573         }
574         else{
575                 ctlr->configdata[6] &= ~0x80;
576                 //ctlr->configdata[6] |= 0x40;
577                 ctlr->configdata[7] |= 0x01;
578                 ctlr->configdata[15] &= ~0x01;
579                 ctlr->configdata[18] |= 0x01;           /* 0x03? */
580                 ctlr->configdata[21] &= ~0x08;
581         }
582         ctlr->action = CbConfigure;
583         txstart(ether);
584         iunlock(&ctlr->cblock);
585 }
586
587 static void
588 promiscuous(void* arg, int on)
589 {
590         Ether *ether = arg;
591         configure(ether, on || ether->nmaddr > 0);
592 }
593
594 static void
595 multicast(void* arg, uchar *, int)
596 {
597         Ether *ether = arg;
598         configure(ether, ether->prom || ether->nmaddr > 0);
599 }
600
601 static void
602 transmit(Ether* ether)
603 {
604         Ctlr *ctlr;
605
606         ctlr = ether->ctlr;
607         ilock(&ctlr->cblock);
608         txstart(ether);
609         iunlock(&ctlr->cblock);
610 }
611
612 static void
613 receive(Ether* ether)
614 {
615         Rfd *rfd;
616         Ctlr *ctlr;
617         int count;
618         Block *bp, *pbp, *xbp;
619
620         ctlr = ether->ctlr;
621         bp = ctlr->rfdhead;
622         for(rfd = (Rfd*)bp->rp; rfd->field & RfdC; rfd = (Rfd*)bp->rp){
623                 /*
624                  * If it's an OK receive frame
625                  * 1) save the count 
626                  * 2) if it's small, try to allocate a block and copy
627                  *    the data, then adjust the necessary fields for reuse;
628                  * 3) if it's big, try to allocate a new Rfd and if
629                  *    successful
630                  *      adjust the received buffer pointers for the
631                  *        actual data received;
632                  *      initialise the replacement buffer to point to
633                  *        the next in the ring;
634                  *      initialise bp to point to the replacement;
635                  * 4) if there's a good packet, pass it on for disposal.
636                  */
637                 if(rfd->field & RfdOK){
638                         pbp = nil;
639                         count = rfd->count & 0x3FFF;
640                         if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
641                                 memmove(pbp->rp, bp->rp+offsetof(Rfd, data[0]), count);
642                                 pbp->wp = pbp->rp + count;
643
644                                 rfd->count = 0;
645                                 rfd->field = 0;
646                         }
647                         else if(xbp = rfdalloc(rfd->link)){
648                                 bp->rp += offsetof(Rfd, data[0]);
649                                 bp->wp = bp->rp + count;
650
651                                 xbp->next = bp->next;
652                                 bp->next = 0;
653
654                                 pbp = bp;
655                                 bp = xbp;
656                         }
657                         if(pbp != nil)
658                                 etheriq(ether, pbp);
659                 }
660                 else{
661                         rfd->count = 0;
662                         rfd->field = 0;
663                 }
664
665                 /*
666                  * The ring tail pointer follows the head with with one
667                  * unused buffer in between to defeat hardware prefetch;
668                  * once the tail pointer has been bumped on to the next
669                  * and the new tail has the Suspend bit set, it can be
670                  * removed from the old tail buffer.
671                  * As a replacement for the current head buffer may have
672                  * been allocated above, ensure that the new tail points
673                  * to it (next and link).
674                  */
675                 rfd = (Rfd*)ctlr->rfdtail->rp;
676                 ctlr->rfdtail = ctlr->rfdtail->next;
677                 ctlr->rfdtail->next = bp;
678                 ((Rfd*)ctlr->rfdtail->rp)->link = PADDR(bp->rp);
679                 ((Rfd*)ctlr->rfdtail->rp)->field |= RfdS;
680                 coherence();
681                 rfd->field &= ~RfdS;
682
683                 /*
684                  * Finally done with the current (possibly replaced)
685                  * head, move on to the next and maintain the sentinel
686                  * between tail and head.
687                  */
688                 ctlr->rfdhead = bp->next;
689                 bp = ctlr->rfdhead;
690         }
691 }
692
693 static void
694 interrupt(Ureg*, void* arg)
695 {
696         Cb* cb;
697         Ctlr *ctlr;
698         Ether *ether;
699         int status;
700
701         ether = arg;
702         ctlr = ether->ctlr;
703
704         for(;;){
705                 ilock(&ctlr->rlock);
706                 status = csr16r(ctlr, Status);
707                 csr8w(ctlr, Ack, (status>>8) & 0xFF);
708                 iunlock(&ctlr->rlock);
709
710                 if(!(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI)))
711                         break;
712
713                 /*
714                  * If the watchdog timer for the receiver lockup errata is running,
715                  * let it know the receiver is active.
716                  */
717                 if(status & (StatFR|StatRNR)){
718                         ilock(&ctlr->cblock);
719                         ctlr->tick = 0;
720                         iunlock(&ctlr->cblock);
721                 }
722
723                 if(status & StatFR){
724                         receive(ether);
725                         status &= ~StatFR;
726                 }
727
728                 if(status & StatRNR){
729                         command(ctlr, RUresume, 0);
730                         status &= ~StatRNR;
731                 }
732
733                 if(status & StatCNA){
734                         ilock(&ctlr->cblock);
735
736                         cb = ctlr->cbtail;
737                         while(ctlr->cbq){
738                                 if(!(cb->status & CbC))
739                                         break;
740                                 if(cb->bp){
741                                         freeb(cb->bp);
742                                         cb->bp = nil;
743                                 }
744                                 if((cb->status & CbU) && ctlr->threshold < 0xE0)
745                                         ctlr->threshold++;
746
747                                 ctlr->cbq--;
748                                 cb = cb->next;
749                         }
750                         ctlr->cbtail = cb;
751
752                         txstart(ether);
753                         iunlock(&ctlr->cblock);
754
755                         status &= ~StatCNA;
756                 }
757
758                 if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
759                         panic("#l%d: status %#ux", ether->ctlrno, status);
760         }
761 }
762
763 static void
764 ctlrinit(Ctlr* ctlr)
765 {
766         int i;
767         Block *bp;
768         Rfd *rfd;
769         ulong link;
770
771         /*
772          * Create the Receive Frame Area (RFA) as a ring of allocated
773          * buffers.
774          * A sentinel buffer is maintained between the last buffer in
775          * the ring (marked with RfdS) and the head buffer to defeat the
776          * hardware prefetch of the next RFD and allow dynamic buffer
777          * allocation.
778          */
779         link = NullPointer;
780         for(i = 0; i < Nrfd; i++){
781                 bp = rfdalloc(link);
782                 if(bp == nil)
783                         panic("i82557: can't allocate rfd buffer");
784                 if(ctlr->rfdhead == nil)
785                         ctlr->rfdtail = bp;
786                 bp->next = ctlr->rfdhead;
787                 ctlr->rfdhead = bp;
788                 link = PADDR(bp->rp);
789         }
790         ctlr->rfdtail->next = ctlr->rfdhead;
791         rfd = (Rfd*)ctlr->rfdtail->rp;
792         rfd->link = PADDR(ctlr->rfdhead->rp);
793         rfd->field |= RfdS;
794         ctlr->rfdhead = ctlr->rfdhead->next;
795
796         /*
797          * Create a ring of control blocks for the
798          * transmit side.
799          */
800         ilock(&ctlr->cblock);
801         ctlr->cbr = malloc(ctlr->ncb*sizeof(Cb));
802         if(ctlr->cbr == nil)
803                 panic("i82557: can't allocate cbr");
804         for(i = 0; i < ctlr->ncb; i++){
805                 ctlr->cbr[i].status = CbC|CbOK;
806                 ctlr->cbr[i].command = CbS|CbNOP;
807                 ctlr->cbr[i].link = PADDR(&ctlr->cbr[NEXT(i, ctlr->ncb)].status);
808                 ctlr->cbr[i].next = &ctlr->cbr[NEXT(i, ctlr->ncb)];
809         }
810         ctlr->cbhead = ctlr->cbr;
811         ctlr->cbtail = ctlr->cbr;
812         ctlr->cbq = 0;
813
814         memmove(ctlr->configdata, configdata, sizeof(configdata));
815         ctlr->threshold = 80;
816         ctlr->tick = 0;
817
818         iunlock(&ctlr->cblock);
819 }
820
821 static int
822 miir(Ctlr* ctlr, int phyadd, int regadd)
823 {
824         int mcr, timo;
825
826         lock(&ctlr->miilock);
827         csr32w(ctlr, Mcr, MDIread|(phyadd<<21)|(regadd<<16));
828         mcr = 0;
829         for(timo = 64; timo; timo--){
830                 mcr = csr32r(ctlr, Mcr);
831                 if(mcr & MDIready)
832                         break;
833                 microdelay(1);
834         }
835         unlock(&ctlr->miilock);
836
837         if(mcr & MDIready)
838                 return mcr & 0xFFFF;
839
840         return -1;
841 }
842
843 static int
844 miiw(Ctlr* ctlr, int phyadd, int regadd, int data)
845 {
846         int mcr, timo;
847
848         lock(&ctlr->miilock);
849         csr32w(ctlr, Mcr, MDIwrite|(phyadd<<21)|(regadd<<16)|(data & 0xFFFF));
850         mcr = 0;
851         for(timo = 64; timo; timo--){
852                 mcr = csr32r(ctlr, Mcr);
853                 if(mcr & MDIready)
854                         break;
855                 microdelay(1);
856         }
857         unlock(&ctlr->miilock);
858
859         if(mcr & MDIready)
860                 return 0;
861
862         return -1;
863 }
864
865 static int
866 hy93c46r(Ctlr* ctlr, int r)
867 {
868         int data, i, op, size;
869
870         /*
871          * Hyundai HY93C46 or equivalent serial EEPROM.
872          * This sequence for reading a 16-bit register 'r'
873          * in the EEPROM is taken straight from Section
874          * 3.3.4.2 of the Intel 82557 User's Guide.
875          */
876 reread:
877         csr16w(ctlr, Ecr, EEcs);
878         op = EEstart|EEread;
879         for(i = 2; i >= 0; i--){
880                 data = (((op>>i) & 0x01)<<2)|EEcs;
881                 csr16w(ctlr, Ecr, data);
882                 csr16w(ctlr, Ecr, data|EEsk);
883                 microdelay(1);
884                 csr16w(ctlr, Ecr, data);
885                 microdelay(1);
886         }
887
888         /*
889          * First time through must work out the EEPROM size.
890          */
891         if((size = ctlr->eepromsz) == 0)
892                 size = 8;
893
894         for(size = size-1; size >= 0; size--){
895                 data = (((r>>size) & 0x01)<<2)|EEcs;
896                 csr16w(ctlr, Ecr, data);
897                 csr16w(ctlr, Ecr, data|EEsk);
898                 delay(1);
899                 csr16w(ctlr, Ecr, data);
900                 microdelay(1);
901                 if(!(csr16r(ctlr, Ecr) & EEdo))
902                         break;
903         }
904
905         data = 0;
906         for(i = 15; i >= 0; i--){
907                 csr16w(ctlr, Ecr, EEcs|EEsk);
908                 microdelay(1);
909                 if(csr16r(ctlr, Ecr) & EEdo)
910                         data |= (1<<i);
911                 csr16w(ctlr, Ecr, EEcs);
912                 microdelay(1);
913         }
914
915         csr16w(ctlr, Ecr, 0);
916
917         if(ctlr->eepromsz == 0){
918                 ctlr->eepromsz = 8-size;
919                 ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
920                 if(ctlr->eeprom == nil)
921                         panic("i82557: can't allocate eeprom");
922                 goto reread;
923         }
924
925         return data;
926 }
927
928 static void
929 i82557pci(void)
930 {
931         Pcidev *p;
932         Ctlr *ctlr;
933         int i, nop, port;
934
935         p = nil;
936         nop = 0;
937         while(p = pcimatch(p, 0x8086, 0)){
938                 switch(p->did){
939                 default:
940                         continue;
941                 case 0x1031:            /* Intel 82562EM */
942                 case 0x103B:            /* Intel 82562EM */
943                 case 0x103C:            /* Intel 82562EM */
944                 case 0x1050:            /* Intel 82562EZ */
945                 case 0x1039:            /* Intel 82801BD PRO/100 VE */
946                 case 0x103A:            /* Intel 82562 PRO/100 VE */
947                 case 0x103D:            /* Intel 82562 PRO/100 VE */
948                 case 0x1064:            /* Intel 82562 PRO/100 VE */
949                 case 0x2449:            /* Intel 82562ET */
950                 case 0x27DC:            /* Intel 82801G PRO/100 VE */
951                         nop = 1;
952                         /*FALLTHROUGH*/
953                 case 0x1209:            /* Intel 82559ER */
954                 case 0x1229:            /* Intel 8255[789] */
955                 case 0x1030:            /* Intel 82559 InBusiness 10/100  */
956                         break;
957                 }
958
959                 if(pcigetpms(p) > 0){
960                         pcisetpms(p, 0);
961         
962                         for(i = 0; i < 6; i++)
963                                 pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
964                         pcicfgw8(p, PciINTL, p->intl);
965                         pcicfgw8(p, PciLTR, p->ltr);
966                         pcicfgw8(p, PciCLS, p->cls);
967                         pcicfgw16(p, PciPCR, p->pcr);
968                 }
969
970                 /*
971                  * bar[0] is the memory-mapped register address (4KB),
972                  * bar[1] is the I/O port register address (32 bytes) and
973                  * bar[2] is for the flash ROM (1MB).
974                  */
975                 port = p->mem[1].bar & ~0x01;
976                 if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
977                         print("i82557: port %#ux in use\n", port);
978                         continue;
979                 }
980
981                 ctlr = malloc(sizeof(Ctlr));
982                 if(ctlr == nil){
983                         print("i82557: can't allocate memory\n");
984                         iofree(port);
985                         continue;
986                 }
987                 ctlr->port = port;
988                 ctlr->pcidev = p;
989                 ctlr->nop = nop;
990
991                 if(ctlrhead != nil)
992                         ctlrtail->next = ctlr;
993                 else
994                         ctlrhead = ctlr;
995                 ctlrtail = ctlr;
996
997                 pcisetbme(p);
998         }
999 }
1000
1001 static char* mediatable[9] = {
1002         "10BASE-T",                             /* TP */
1003         "10BASE-2",                             /* BNC */
1004         "10BASE-5",                             /* AUI */
1005         "100BASE-TX",
1006         "10BASE-TFD",
1007         "100BASE-TXFD",
1008         "100BASE-T4",
1009         "100BASE-FX",
1010         "100BASE-FXFD",
1011 };
1012
1013 static int
1014 scanphy(Ctlr* ctlr)
1015 {
1016         int i, oui, x;
1017
1018         for(i = 0; i < 32; i++){
1019                 if((oui = miir(ctlr, i, 2)) == -1 || oui == 0 || oui == 0xFFFF)
1020                         continue;
1021                 oui <<= 6;
1022                 x = miir(ctlr, i, 3);
1023                 oui |= x>>10;
1024                 //print("phy%d: oui %#ux reg1 %#ux\n", i, oui, miir(ctlr, i, 1));
1025
1026                 ctlr->eeprom[6] = i;
1027                 if(oui == 0xAA00)
1028                         ctlr->eeprom[6] |= 0x07<<8;
1029                 else if(oui == 0x80017){
1030                         if(x & 0x01)
1031                                 ctlr->eeprom[6] |= 0x0A<<8;
1032                         else
1033                                 ctlr->eeprom[6] |= 0x04<<8;
1034                 }
1035                 return i;
1036         }
1037         return -1;
1038 }
1039
1040 static void
1041 shutdown(Ether* ether)
1042 {
1043         Ctlr *ctlr = ether->ctlr;
1044
1045 print("ether82557 shutting down\n");
1046         csr32w(ctlr, Port, 0);
1047         delay(1);
1048         csr8w(ctlr, Interrupt, InterruptM);
1049 }
1050
1051
1052 static int
1053 reset(Ether* ether)
1054 {
1055         int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, x;
1056         unsigned short sum;
1057         uchar ea[Eaddrlen];
1058         Ctlr *ctlr;
1059
1060         if(ctlrhead == nil)
1061                 i82557pci();
1062
1063         /*
1064          * Any adapter matches if no ether->port is supplied,
1065          * otherwise the ports must match.
1066          */
1067         for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1068                 if(ctlr->active)
1069                         continue;
1070                 if(ether->port == 0 || ether->port == ctlr->port){
1071                         ctlr->active = 1;
1072                         break;
1073                 }
1074         }
1075         if(ctlr == nil)
1076                 return -1;
1077
1078         /*
1079          * Initialise the Ctlr structure.
1080          * Perform a software reset after which should ensure busmastering
1081          * is still enabled. The EtherExpress PRO/100B appears to leave
1082          * the PCI configuration alone (see the 'To do' list above) so punt
1083          * for now.
1084          * Load the RUB and CUB registers for linear addressing (0).
1085          */
1086         ether->ctlr = ctlr;
1087         ether->port = ctlr->port;
1088         ether->irq = ctlr->pcidev->intl;
1089         ether->tbdf = ctlr->pcidev->tbdf;
1090
1091         ilock(&ctlr->rlock);
1092         csr32w(ctlr, Port, 0);
1093         delay(1);
1094         csr8w(ctlr, Interrupt, InterruptM);
1095         iunlock(&ctlr->rlock);
1096
1097         command(ctlr, LoadRUB, 0);
1098         command(ctlr, LoadCUB, 0);
1099         command(ctlr, LoadDCA, PADDR(ctlr->dump));
1100
1101         /*
1102          * Initialise the receive frame, transmit ring and configuration areas.
1103          */
1104         ctlr->ncb = Ncb;
1105         ctlrinit(ctlr);
1106
1107         /*
1108          * Read the EEPROM.
1109          * Do a dummy read first to get the size
1110          * and allocate ctlr->eeprom.
1111          */
1112         hy93c46r(ctlr, 0);
1113         sum = 0;
1114         for(i = 0; i < (1<<ctlr->eepromsz); i++){
1115                 x = hy93c46r(ctlr, i);
1116                 ctlr->eeprom[i] = x;
1117                 sum += x;
1118         }
1119         if(sum != 0xBABA)
1120                 print("#l%d: EEPROM checksum - %#4.4ux\n", ether->ctlrno, sum);
1121
1122         /*
1123          * Eeprom[6] indicates whether there is a PHY and whether
1124          * it's not 10Mb-only, in which case use the given PHY address
1125          * to set any PHY specific options and determine the speed.
1126          * Unfortunately, sometimes the EEPROM is blank except for
1127          * the ether address and checksum; in this case look at the
1128          * controller type and if it's am 82558 or 82559 it has an
1129          * embedded PHY so scan for that.
1130          * If no PHY, assume 82503 (serial) operation.
1131          */
1132         if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
1133                 phyaddr = ctlr->eeprom[6] & 0x00FF;
1134         else
1135         switch(ctlr->pcidev->rid){
1136         case 0x01:                      /* 82557 A-step */
1137         case 0x02:                      /* 82557 B-step */
1138         case 0x03:                      /* 82557 C-step */
1139         default:
1140                 phyaddr = -1;
1141                 break;
1142         case 0x04:                      /* 82558 A-step */
1143         case 0x05:                      /* 82558 B-step */
1144         case 0x06:                      /* 82559 A-step */
1145         case 0x07:                      /* 82559 B-step */
1146         case 0x08:                      /* 82559 C-step */
1147         case 0x09:                      /* 82559ER A-step */
1148                 phyaddr = scanphy(ctlr);
1149                 break;
1150         }
1151         if(phyaddr >= 0){
1152                 /*
1153                  * Resolve the highest common ability of the two
1154                  * link partners. In descending order:
1155                  *      0x0100          100BASE-TX Full Duplex
1156                  *      0x0200          100BASE-T4
1157                  *      0x0080          100BASE-TX
1158                  *      0x0040          10BASE-T Full Duplex
1159                  *      0x0020          10BASE-T
1160                  */
1161                 anar = miir(ctlr, phyaddr, 0x04);
1162                 anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
1163                 anar &= anlpar;
1164                 bmcr = 0;
1165                 if(anar & 0x380)
1166                         bmcr = 0x2000;
1167                 if(anar & 0x0140)
1168                         bmcr |= 0x0100;
1169
1170                 switch((ctlr->eeprom[6]>>8) & 0x001F){
1171
1172                 case 0x04:                              /* DP83840 */
1173                 case 0x0A:                              /* DP83840A */
1174                         /*
1175                          * The DP83840[A] requires some tweaking for
1176                          * reliable operation.
1177                          * The manual says bit 10 should be unconditionally
1178                          * set although it supposedly only affects full-duplex
1179                          * operation (an & 0x0140).
1180                          */
1181                         x = miir(ctlr, phyaddr, 0x17) & ~0x0520;
1182                         x |= 0x0420;
1183                         for(i = 0; i < ether->nopt; i++){
1184                                 if(cistrcmp(ether->opt[i], "congestioncontrol"))
1185                                         continue;
1186                                 x |= 0x0100;
1187                                 break;
1188                         }
1189                         miiw(ctlr, phyaddr, 0x17, x);
1190
1191                         /*
1192                          * If the link partner can't autonegotiate, determine
1193                          * the speed from elsewhere.
1194                          */
1195                         if(anlpar == 0){
1196                                 miir(ctlr, phyaddr, 0x01);
1197                                 bmsr = miir(ctlr, phyaddr, 0x01);
1198                                 x = miir(ctlr, phyaddr, 0x19);
1199                                 if((bmsr & 0x0004) && !(x & 0x0040))
1200                                         bmcr = 0x2000;
1201                         }
1202                         break;
1203
1204                 case 0x07:                              /* Intel 82555 */
1205                         /*
1206                          * Auto-negotiation may fail if the other end is
1207                          * a DP83840A and the cable is short.
1208                          */
1209                         miir(ctlr, phyaddr, 0x01);
1210                         bmsr = miir(ctlr, phyaddr, 0x01);
1211                         if((miir(ctlr, phyaddr, 0) & 0x1000) && (bmsr & 0x0020))
1212                                 break;
1213                         miiw(ctlr, phyaddr, 0x1A, 0x2010);
1214                         x = miir(ctlr, phyaddr, 0);
1215                         miiw(ctlr, phyaddr, 0, 0x1200|x);
1216                         for(i = 0; i < 3000; i++){
1217                                 delay(1);
1218                                 if(miir(ctlr, phyaddr, 0x01) & 0x0020)
1219                                         break;
1220                         }
1221                         miiw(ctlr, phyaddr, 0x1A, 0x2000);
1222                                         
1223                         anar = miir(ctlr, phyaddr, 0x04);
1224                         anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
1225                         anar &= anlpar;
1226                         bmcr = 0;
1227                         if(anar & 0x380)
1228                                 bmcr = 0x2000;
1229                         if(anar & 0x0140)
1230                                 bmcr |= 0x0100;
1231                         break;
1232                 }
1233
1234                 /*
1235                  * Force speed and duplex if no auto-negotiation.
1236                  */
1237                 if(anlpar == 0){
1238                         medium = -1;
1239                         for(i = 0; i < ether->nopt; i++){
1240                                 for(k = 0; k < nelem(mediatable); k++){
1241                                         if(cistrcmp(mediatable[k], ether->opt[i]))
1242                                                 continue;
1243                                         medium = k;
1244                                         break;
1245                                 }
1246                 
1247                                 switch(medium){
1248                                 default:
1249                                         break;
1250
1251                                 case 0x00:                      /* 10BASE-T */
1252                                 case 0x01:                      /* 10BASE-2 */
1253                                 case 0x02:                      /* 10BASE-5 */
1254                                         bmcr &= ~(0x2000|0x0100);
1255                                         ctlr->configdata[19] &= ~0x40;
1256                                         break;
1257
1258                                 case 0x03:                      /* 100BASE-TX */
1259                                 case 0x06:                      /* 100BASE-T4 */
1260                                 case 0x07:                      /* 100BASE-FX */
1261                                         ctlr->configdata[19] &= ~0x40;
1262                                         bmcr |= 0x2000;
1263                                         break;
1264
1265                                 case 0x04:                      /* 10BASE-TFD */
1266                                         bmcr = (bmcr & ~0x2000)|0x0100;
1267                                         ctlr->configdata[19] |= 0x40;
1268                                         break;
1269
1270                                 case 0x05:                      /* 100BASE-TXFD */
1271                                 case 0x08:                      /* 100BASE-FXFD */
1272                                         bmcr |= 0x2000|0x0100;
1273                                         ctlr->configdata[19] |= 0x40;
1274                                         break;
1275                                 }
1276                         }
1277                         if(medium != -1)
1278                                 miiw(ctlr, phyaddr, 0x00, bmcr);
1279                 }
1280
1281                 if(bmcr & 0x2000)
1282                         ether->mbps = 100;
1283
1284                 ctlr->configdata[8] = 1;
1285                 ctlr->configdata[15] &= ~0x80;
1286         }
1287         else{
1288                 ctlr->configdata[8] = 0;
1289                 ctlr->configdata[15] |= 0x80;
1290         }
1291
1292         /*
1293          * Workaround for some broken HUB chips when connected at 10Mb/s
1294          * half-duplex.
1295          * This is a band-aid, but as there's no dynamic auto-negotiation
1296          * code at the moment, only deactivate the workaround code in txstart
1297          * if the link is 100Mb/s.
1298          */
1299         if(ether->mbps != 10)
1300                 ctlr->nop = 0;
1301
1302         /*
1303          * Load the chip configuration and start it off.
1304          */
1305         if(ether->oq == 0)
1306                 ether->oq = qopen(256*1024, Qmsg, 0, 0);
1307         configure(ether, 0);
1308         command(ctlr, CUstart, PADDR(&ctlr->cbr->status));
1309
1310         /*
1311          * Check if the adapter's station address is to be overridden.
1312          * If not, read it from the EEPROM and set in ether->ea prior to loading
1313          * the station address with the Individual Address Setup command.
1314          */
1315         memset(ea, 0, Eaddrlen);
1316         if(memcmp(ea, ether->ea, Eaddrlen) == 0){
1317                 for(i = 0; i < Eaddrlen/2; i++){
1318                         x = ctlr->eeprom[i];
1319                         ether->ea[2*i] = x;
1320                         ether->ea[2*i+1] = x>>8;
1321                 }
1322         }
1323
1324         ilock(&ctlr->cblock);
1325         ctlr->action = CbIAS;
1326         txstart(ether);
1327         iunlock(&ctlr->cblock);
1328
1329         /*
1330          * Linkage to the generic ethernet driver.
1331          */
1332         ether->attach = attach;
1333         ether->transmit = transmit;
1334         ether->ifstat = ifstat;
1335         ether->shutdown = shutdown;
1336
1337         ether->promiscuous = promiscuous;
1338         ether->multicast = multicast;
1339         ether->arg = ether;
1340
1341         intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
1342
1343         return 0;
1344 }
1345
1346 void
1347 ether82557link(void)
1348 {
1349         addethercard("i82557",  reset);
1350 }