]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/ether82557.c
perms
[plan9front.git] / sys / src / boot / 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 none of them are in the right place.
5  * To do:
6  *      the PCI scanning code could be made common to other adapters;
7  *      PCI code needs rewritten to handle byte, word, dword accesses
8  *        and using the devno as a bus+dev+function triplet.
9  */
10 #include "u.h"
11 #include "lib.h"
12 #include "mem.h"
13 #include "dat.h"
14 #include "fns.h"
15 #include "io.h"
16
17 #include "etherif.h"
18
19 enum {
20         Nrfd            = 4,            /* receive frame area */
21
22         NullPointer     = 0xFFFFFFFF,   /* 82557 NULL pointer */
23 };
24
25 enum {                                  /* CSR */
26         Status          = 0x00,         /* byte or word (word includes Ack) */
27         Ack             = 0x01,         /* byte */
28         CommandR        = 0x02,         /* byte or word (word includes Interrupt) */
29         Interrupt       = 0x03,         /* byte */
30         Pointer         = 0x04,         /* dword */
31         Port            = 0x08,         /* dword */
32         Fcr             = 0x0C,         /* Flash control register */
33         Ecr             = 0x0E,         /* EEPROM control register */
34         Mcr             = 0x10,         /* MDI control register */
35 };
36
37 enum {                                  /* Status */
38         RUidle          = 0x0000,
39         RUsuspended     = 0x0004,
40         RUnoresources   = 0x0008,
41         RUready         = 0x0010,
42         RUrbd           = 0x0020,       /* bit */
43         RUstatus        = 0x003F,       /* mask */
44
45         CUidle          = 0x0000,
46         CUsuspended     = 0x0040,
47         CUactive        = 0x0080,
48         CUstatus        = 0x00C0,       /* mask */
49
50         StatSWI         = 0x0400,       /* SoftWare generated Interrupt */
51         StatMDI         = 0x0800,       /* MDI r/w done */
52         StatRNR         = 0x1000,       /* Receive unit Not Ready */
53         StatCNA         = 0x2000,       /* Command unit Not Active (Active->Idle) */
54         StatFR          = 0x4000,       /* Finished Receiving */
55         StatCX          = 0x8000,       /* Command eXecuted */
56         StatTNO         = 0x8000,       /* Transmit NOT OK */
57 };
58
59 enum {                                  /* Command (byte) */
60         CUnop           = 0x00,
61         CUstart         = 0x10,
62         CUresume        = 0x20,
63         LoadDCA         = 0x40,         /* Load Dump Counters Address */
64         DumpSC          = 0x50,         /* Dump Statistical Counters */
65         LoadCUB         = 0x60,         /* Load CU Base */
66         ResetSA         = 0x70,         /* Dump and Reset Statistical Counters */
67
68         RUstart         = 0x01,
69         RUresume        = 0x02,
70         RUabort         = 0x04,
71         LoadHDS         = 0x05,         /* Load Header Data Size */
72         LoadRUB         = 0x06,         /* Load RU Base */
73         RBDresume       = 0x07,         /* Resume frame reception */
74 };
75
76 enum {                                  /* Interrupt (byte) */
77         InterruptM      = 0x01,         /* interrupt Mask */
78         InterruptSI     = 0x02,         /* Software generated Interrupt */
79 };
80
81 enum {                                  /* Ecr */
82         EEsk            = 0x01,         /* serial clock */
83         EEcs            = 0x02,         /* chip select */
84         EEdi            = 0x04,         /* serial data in */
85         EEdo            = 0x08,         /* serial data out */
86
87         EEstart         = 0x04,         /* start bit */
88         EEread          = 0x02,         /* read opcode */
89 };
90
91 enum {                                  /* Mcr */
92         MDIread         = 0x08000000,   /* read opcode */
93         MDIwrite        = 0x04000000,   /* write opcode */
94         MDIready        = 0x10000000,   /* ready bit */
95         MDIie           = 0x20000000,   /* interrupt enable */
96 };
97
98 typedef struct Rfd {
99         int     field;
100         ulong   link;
101         ulong   rbd;
102         ushort  count;
103         ushort  size;
104
105         Etherpkt;
106 } Rfd;
107
108 enum {                                  /* field */
109         RfdCollision    = 0x00000001,
110         RfdIA           = 0x00000002,   /* IA match */
111         RfdRxerr        = 0x00000010,   /* PHY character error */
112         RfdType         = 0x00000020,   /* Type frame */
113         RfdRunt         = 0x00000080,
114         RfdOverrun      = 0x00000100,
115         RfdBuffer       = 0x00000200,
116         RfdAlignment    = 0x00000400,
117         RfdCRC          = 0x00000800,
118
119         RfdOK           = 0x00002000,   /* frame received OK */
120         RfdC            = 0x00008000,   /* reception Complete */
121         RfdSF           = 0x00080000,   /* Simplified or Flexible (1) Rfd */
122         RfdH            = 0x00100000,   /* Header RFD */
123
124         RfdI            = 0x20000000,   /* Interrupt after completion */
125         RfdS            = 0x40000000,   /* Suspend after completion */
126         RfdEL           = 0x80000000,   /* End of List */
127 };
128
129 enum {                                  /* count */
130         RfdF            = 0x00004000,
131         RfdEOF          = 0x00008000,
132 };
133
134 typedef struct Cb {
135         int     command;
136         ulong   link;
137         uchar   data[24];       /* CbIAS + CbConfigure */
138 } Cb;
139
140 typedef struct TxCB {
141         int     command;
142         ulong   link;
143         ulong   tbd;
144         ushort  count;
145         uchar   threshold;
146         uchar   number;
147 } TxCB;
148
149 enum {                                  /* action command */
150         CbOK            = 0x00002000,   /* DMA completed OK */
151         CbC             = 0x00008000,   /* execution Complete */
152
153         CbNOP           = 0x00000000,
154         CbIAS           = 0x00010000,   /* Indvidual Address Setup */
155         CbConfigure     = 0x00020000,
156         CbMAS           = 0x00030000,   /* Multicast Address Setup */
157         CbTransmit      = 0x00040000,
158         CbDump          = 0x00060000,
159         CbDiagnose      = 0x00070000,
160         CbCommand       = 0x00070000,   /* mask */
161
162         CbSF            = 0x00080000,   /* CbTransmit */
163
164         CbI             = 0x20000000,   /* Interrupt after completion */
165         CbS             = 0x40000000,   /* Suspend after completion */
166         CbEL            = 0x80000000,   /* End of List */
167 };
168
169 enum {                                  /* CbTransmit count */
170         CbEOF           = 0x00008000,
171 };
172
173 typedef struct Ctlr Ctlr;
174 typedef struct Ctlr {
175         int     port;
176         Pcidev* pcidev;
177         Ctlr*   next;
178         int     active;
179
180         int     eepromsz;               /* address size in bits */
181         ushort* eeprom;
182
183         int     ctlrno;
184         char*   type;
185
186         uchar   configdata[24];
187
188         Rfd     rfd[Nrfd];
189         int     rfdl;
190         int     rfdx;
191
192         Block*  cbqhead;
193         Block*  cbqtail;
194         int     cbqbusy;
195 } Ctlr;
196
197 static Ctlr* ctlrhead;
198 static Ctlr* ctlrtail;
199
200 static uchar configdata[24] = {
201         0x16,                           /* byte count */
202         0x44,                           /* Rx/Tx FIFO limit */
203         0x00,                           /* adaptive IFS */
204         0x00,   
205         0x04,                           /* Rx DMA maximum byte count */
206         0x84,                           /* Tx DMA maximum byte count */
207         0x33,                           /* late SCB, CNA interrupts */
208         0x01,                           /* discard short Rx frames */
209         0x00,                           /* 503/MII */
210
211         0x00,   
212         0x2E,                           /* normal operation, NSAI */
213         0x00,                           /* linear priority */
214         0x60,                           /* inter-frame spacing */
215         0x00,   
216         0xF2,   
217         0x48,                           /* promiscuous mode off */
218         0x00,   
219         0x40,   
220         0xF2,                           /* transmit padding enable */
221         0x80,                           /* full duplex pin enable */
222         0x3F,                           /* no Multi IA */
223         0x05,                           /* no Multi Cast ALL */
224 };
225
226 #define csr8r(c, r)     (inb((c)->port+(r)))
227 #define csr16r(c, r)    (ins((c)->port+(r)))
228 #define csr32r(c, r)    (inl((c)->port+(r)))
229 #define csr8w(c, r, b)  (outb((c)->port+(r), (int)(b)))
230 #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
231 #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
232
233 static void
234 custart(Ctlr* ctlr)
235 {
236         if(ctlr->cbqhead == 0){
237                 ctlr->cbqbusy = 0;
238                 return;
239         }
240         ctlr->cbqbusy = 1;
241
242         csr32w(ctlr, Pointer, PADDR(ctlr->cbqhead->rp));
243         while(csr8r(ctlr, CommandR))
244                 ;
245         csr8w(ctlr, CommandR, CUstart);
246 }
247
248 static void
249 action(Ctlr* ctlr, Block* bp)
250 {
251         Cb *cb;
252
253         cb = (Cb*)bp->rp;
254         cb->command |= CbEL;
255
256         if(ctlr->cbqhead){
257                 ctlr->cbqtail->next = bp;
258                 cb = (Cb*)ctlr->cbqtail->rp;
259                 cb->link = PADDR(bp->rp);
260                 cb->command &= ~CbEL;
261         }
262         else
263                 ctlr->cbqhead = bp;
264         ctlr->cbqtail = bp;
265
266         if(ctlr->cbqbusy == 0)
267                 custart(ctlr);
268 }
269
270 static void
271 attach(Ether* ether)
272 {
273         int status;
274         Ctlr *ctlr;
275
276         ctlr = ether->ctlr;
277         status = csr16r(ctlr, Status);
278         if((status & RUstatus) == RUidle){
279                 csr32w(ctlr, Pointer, PADDR(&ctlr->rfd[ctlr->rfdx]));
280                 while(csr8r(ctlr, CommandR))
281                         ;
282                 csr8w(ctlr, CommandR, RUstart);
283         }
284 }
285
286 static void
287 configure(void* arg, int promiscuous)
288 {
289         Ctlr *ctlr;
290         Block *bp;
291         Cb *cb;
292
293         ctlr = ((Ether*)arg)->ctlr;
294
295         bp = allocb(sizeof(Cb));
296         cb = (Cb*)bp->rp;
297         bp->wp += sizeof(Cb);
298
299         cb->command = CbConfigure;
300         cb->link = NullPointer;
301         memmove(cb->data, ctlr->configdata, sizeof(ctlr->configdata));
302         if(promiscuous)
303                 cb->data[15] |= 0x01;
304         action(ctlr, bp);
305 }
306
307 static void
308 transmit(Ether* ether)
309 {
310         Block *bp;
311         TxCB *txcb;
312         RingBuf *tb;
313
314         for(tb = &ether->tb[ether->ti]; tb->owner == Interface; tb = &ether->tb[ether->ti]){
315                 bp = allocb(tb->len+sizeof(TxCB));
316                 txcb = (TxCB*)bp->wp;
317                 bp->wp += sizeof(TxCB);
318
319                 txcb->command = CbTransmit;
320                 txcb->link = NullPointer;
321                 txcb->tbd = NullPointer;
322                 txcb->count = CbEOF|tb->len;
323                 txcb->threshold = 2;
324                 txcb->number = 0;
325
326                 memmove(bp->wp, tb->pkt, tb->len);
327                 memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
328                 bp->wp += tb->len;
329
330                 action(ether->ctlr, bp);
331
332                 tb->owner = Host;
333                 ether->ti = NEXT(ether->ti, ether->ntb);
334         }
335 }
336
337 static void
338 interrupt(Ureg*, void* arg)
339 {
340         Rfd *rfd;
341         Block *bp;
342         Ctlr *ctlr;
343         Ether *ether;
344         int status;
345         RingBuf *rb;
346
347         ether = arg;
348         ctlr = ether->ctlr;
349
350         for(;;){
351                 status = csr16r(ctlr, Status);
352                 csr8w(ctlr, Ack, (status>>8) & 0xFF);
353
354                 if((status & (StatCX|StatFR|StatCNA|StatRNR)) == 0)
355                         return;
356
357                 if(status & StatFR){
358                         rfd = &ctlr->rfd[ctlr->rfdx];
359                         while(rfd->field & RfdC){
360                                 rb = &ether->rb[ether->ri];
361                                 if(rb->owner == Interface){
362                                         rb->owner = Host;
363                                         rb->len = rfd->count & 0x3FFF;
364                                         memmove(rb->pkt, rfd->d, rfd->count & 0x3FFF);
365                                         ether->ri = NEXT(ether->ri, ether->nrb);
366                                 }
367
368                                 /*
369                                  * Reinitialise the frame for reception and bump
370                                  * the receive frame processing index;
371                                  * bump the sentinel index, mark the new sentinel
372                                  * and clear the old sentinel suspend bit;
373                                  * set bp and rfd for the next receive frame to
374                                  * process.
375                                  */
376                                 rfd->field = 0;
377                                 rfd->count = 0;
378                                 ctlr->rfdx = NEXT(ctlr->rfdx, Nrfd);
379
380                                 rfd = &ctlr->rfd[ctlr->rfdl];
381                                 ctlr->rfdl = NEXT(ctlr->rfdl, Nrfd);
382                                 ctlr->rfd[ctlr->rfdl].field |= RfdS;
383                                 rfd->field &= ~RfdS;
384
385                                 rfd = &ctlr->rfd[ctlr->rfdx];
386                         }
387                         status &= ~StatFR;
388                 }
389
390                 if(status & StatRNR){
391                         while(csr8r(ctlr, CommandR))
392                                 ;
393                         csr8w(ctlr, CommandR, RUresume);
394
395                         status &= ~StatRNR;
396                 }
397
398                 if(status & StatCNA){
399                         while(bp = ctlr->cbqhead){
400                                 if((((Cb*)bp->rp)->command & CbC) == 0)
401                                         break;
402                                 ctlr->cbqhead = bp->next;
403                                 freeb(bp);
404                         }
405                         custart(ctlr);
406
407                         status &= ~StatCNA;
408                 }
409
410                 if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
411                         panic("%s#%d: status %uX", ctlr->type,  ctlr->ctlrno, status);
412         }
413 }
414
415 static void
416 ctlrinit(Ctlr* ctlr)
417 {
418         int i;
419         Rfd *rfd;
420         ulong link;
421
422         link = NullPointer;
423         for(i = Nrfd-1; i >= 0; i--){
424                 rfd = &ctlr->rfd[i];
425
426                 rfd->field = 0;
427                 rfd->link = link;
428                 link = PADDR(rfd);
429                 rfd->rbd = NullPointer;
430                 rfd->count = 0;
431                 rfd->size = sizeof(Etherpkt);
432         }
433         ctlr->rfd[Nrfd-1].link = PADDR(&ctlr->rfd[0]);
434
435         ctlr->rfdl = 0;
436         ctlr->rfd[0].field |= RfdS;
437         ctlr->rfdx = 2;
438
439         memmove(ctlr->configdata, configdata, sizeof(configdata));
440 }
441
442 static int
443 miir(Ctlr* ctlr, int phyadd, int regadd)
444 {
445         int mcr, timo;
446
447         csr32w(ctlr, Mcr, MDIread|(phyadd<<21)|(regadd<<16));
448         mcr = 0;
449         for(timo = 64; timo; timo--){
450                 mcr = csr32r(ctlr, Mcr);
451                 if(mcr & MDIready)
452                         break;
453                 microdelay(1);
454         }
455
456         if(mcr & MDIready)
457                 return mcr & 0xFFFF;
458
459         return -1;
460 }
461
462 static int
463 miiw(Ctlr* ctlr, int phyadd, int regadd, int data)
464 {
465         int mcr, timo;
466
467         csr32w(ctlr, Mcr, MDIwrite|(phyadd<<21)|(regadd<<16)|(data & 0xFFFF));
468         mcr = 0;
469         for(timo = 64; timo; timo--){
470                 mcr = csr32r(ctlr, Mcr);
471                 if(mcr & MDIready)
472                         break;
473                 microdelay(1);
474         }
475
476         if(mcr & MDIready)
477                 return 0;
478
479         return -1;
480 }
481
482 static int
483 hy93c46r(Ctlr* ctlr, int r)
484 {
485         int data, i, op, size;
486
487         /*
488          * Hyundai HY93C46 or equivalent serial EEPROM.
489          * This sequence for reading a 16-bit register 'r'
490          * in the EEPROM is taken straight from Section
491          * 3.3.4.2 of the Intel 82557 User's Guide.
492          */
493 reread:
494         csr16w(ctlr, Ecr, EEcs);
495         op = EEstart|EEread;
496         for(i = 2; i >= 0; i--){
497                 data = (((op>>i) & 0x01)<<2)|EEcs;
498                 csr16w(ctlr, Ecr, data);
499                 csr16w(ctlr, Ecr, data|EEsk);
500                 microdelay(1);
501                 csr16w(ctlr, Ecr, data);
502                 microdelay(1);
503         }
504
505         /*
506          * First time through must work out the EEPROM size.
507          */
508         if((size = ctlr->eepromsz) == 0)
509                 size = 8;
510
511         for(size = size-1; size >= 0; size--){
512                 data = (((r>>size) & 0x01)<<2)|EEcs;
513                 csr16w(ctlr, Ecr, data);
514                 csr16w(ctlr, Ecr, data|EEsk);
515                 delay(1);
516                 csr16w(ctlr, Ecr, data);
517                 microdelay(1);
518                 if(!(csr16r(ctlr, Ecr) & EEdo))
519                         break;
520         }
521
522         data = 0;
523         for(i = 15; i >= 0; i--){
524                 csr16w(ctlr, Ecr, EEcs|EEsk);
525                 microdelay(1);
526                 if(csr16r(ctlr, Ecr) & EEdo)
527                         data |= (1<<i);
528                 csr16w(ctlr, Ecr, EEcs);
529                 microdelay(1);
530         }
531
532         csr16w(ctlr, Ecr, 0);
533
534         if(ctlr->eepromsz == 0){
535                 ctlr->eepromsz = 8-size;
536                 ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
537                 goto reread;
538         }
539
540         return data;
541 }
542
543 static void
544 i82557pci(void)
545 {
546         Pcidev *p;
547         Ctlr *ctlr;
548
549         p = nil;
550         while(p = pcimatch(p, 0x8086, 0)){
551                 switch(p->did){
552                 default:
553                         continue;
554                 case 0x1031:            /* Intel 82562EM */
555                 case 0x103B:            /* Intel 82562EM */
556                 case 0x103C:            /* Intel 82562EM */
557                 case 0x1050:            /* Intel 82562EZ */
558                 case 0x1039:            /* Intel 82801BD PRO/100 VE */
559                 case 0x103A:            /* Intel 82562 PRO/100 VE */
560                 case 0x1064:            /* Intel 82562 PRO/100 VE */
561                 case 0x2449:            /* Intel 82562ET */
562                 case 0x27DC:            /* Intel 82801G PRO/100 VE */
563                 case 0x1209:            /* Intel 82559ER */
564                 case 0x1229:            /* Intel 8255[789] */
565                 case 0x1030:            /* Intel 82559 InBusiness 10/100  */
566                         break;
567                 }
568
569                 /*
570                  * bar[0] is the memory-mapped register address (4KB),
571                  * bar[1] is the I/O port register address (32 bytes) and
572                  * bar[2] is for the flash ROM (1MB).
573                  */
574                 ctlr = malloc(sizeof(Ctlr));
575                 ctlr->port = p->mem[1].bar & ~0x01;
576                 ctlr->pcidev = p;
577
578                 if(ctlrhead != nil)
579                         ctlrtail->next = ctlr;
580                 else
581                         ctlrhead = ctlr;
582                 ctlrtail = ctlr;
583
584                 pcisetbme(p);
585         }
586 }
587
588 static void
589 detach(Ether* ether)
590 {
591         Ctlr *ctlr;
592
593         ctlr = ether->ctlr;
594
595         csr32w(ctlr, Port, 0);
596         delay(1);
597
598         while(csr8r(ctlr, CommandR))
599                 ;
600 }
601
602 static int
603 scanphy(Ctlr* ctlr)
604 {
605         int i, oui, x;
606
607         for(i = 0; i < 32; i++){
608                 if((oui = miir(ctlr, i, 2)) == -1 || oui == 0 || oui == 0xFFFF)
609                         continue;
610                 oui <<= 6;
611                 x = miir(ctlr, i, 3);
612                 oui |= x>>10;
613                 //print("phy%d: oui %uX reg1 %uX\n", i, oui, miir(ctlr, i, 1));
614
615                 if(oui == 0xAA00)
616                         ctlr->eeprom[6] = 0x07<<8;
617                 else if(oui == 0x80017){
618                         if(x & 0x01)
619                                 ctlr->eeprom[6] = 0x0A<<8;
620                         else
621                                 ctlr->eeprom[6] = 0x04<<8;
622                 }
623                 return i;
624         }
625         return -1;
626 }
627
628 int
629 i82557reset(Ether* ether)
630 {
631         int anar, anlpar, bmcr, bmsr, force, i, phyaddr, x;
632         unsigned short sum;
633         Block *bp;
634         uchar ea[Eaddrlen];
635         Ctlr *ctlr;
636         Cb *cb;
637
638
639         if(ctlrhead == nil)
640                 i82557pci();
641
642         /*
643          * Any adapter matches if no ether->port is supplied,
644          * otherwise the ports must match.
645          */
646         for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
647                 if(ctlr->active)
648                         continue;
649                 if(ether->port == 0 || ether->port == ctlr->port){
650                         ctlr->active = 1;
651                         break;
652                 }
653         }
654         if(ctlr == nil)
655                 return -1;
656
657         /*
658          * Initialise the Ctlr structure.
659          * Perform a software reset after which need to ensure busmastering
660          * is still enabled. The EtherExpress PRO/100B appears to leave
661          * the PCI configuration alone (see the 'To do' list above) so punt
662          * for now.
663          * Load the RUB and CUB registers for linear addressing (0).
664          */
665         ether->ctlr = ctlr;
666         ether->port = ctlr->port;
667         ether->irq = ctlr->pcidev->intl;
668         ether->tbdf = ctlr->pcidev->tbdf;
669         ctlr->ctlrno = ether->ctlrno;
670         ctlr->type = ether->type;
671
672         csr32w(ctlr, Port, 0);
673         delay(1);
674
675         while(csr8r(ctlr, CommandR))
676                 ;
677         csr32w(ctlr, Pointer, 0);
678         csr8w(ctlr, CommandR, LoadRUB);
679         while(csr8r(ctlr, CommandR))
680                 ;
681         csr8w(ctlr, CommandR, LoadCUB);
682
683         /*
684          * Initialise the action and receive frame areas.
685          */
686         ctlrinit(ctlr);
687
688         /*
689          * Read the EEPROM.
690          * Do a dummy read first to get the size
691          * and allocate ctlr->eeprom.
692          */
693         hy93c46r(ctlr, 0);
694         sum = 0;
695         for(i = 0; i < (1<<ctlr->eepromsz); i++){
696                 x = hy93c46r(ctlr, i);
697                 ctlr->eeprom[i] = x;
698                 sum += x;
699         }
700         if(sum != 0xBABA)
701                 print("#l%d: EEPROM checksum - 0x%4.4uX\n", ether->ctlrno, sum);
702
703         /*
704          * Eeprom[6] indicates whether there is a PHY and whether
705          * it's not 10Mb-only, in which case use the given PHY address
706          * to set any PHY specific options and determine the speed.
707          * Unfortunately, sometimes the EEPROM is blank except for
708          * the ether address and checksum; in this case look at the
709          * controller type and if it's am 82558 or 82559 it has an
710          * embedded PHY so scan for that.
711          * If no PHY, assume 82503 (serial) operation.
712          */
713         if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
714                 phyaddr = ctlr->eeprom[6] & 0x00FF;
715         else
716         switch(ctlr->pcidev->rid){
717         case 0x01:                      /* 82557 A-step */
718         case 0x02:                      /* 82557 B-step */
719         case 0x03:                      /* 82557 C-step */
720         default:
721                 phyaddr = -1;
722                 break;
723         case 0x04:                      /* 82558 A-step */
724         case 0x05:                      /* 82558 B-step */
725         case 0x06:                      /* 82559 A-step */
726         case 0x07:                      /* 82559 B-step */
727         case 0x08:                      /* 82559 C-step */
728         case 0x09:                      /* 82559ER A-step */
729                 phyaddr = scanphy(ctlr);
730                 break;
731         }
732         if(phyaddr >= 0){
733                 /*
734                  * Resolve the highest common ability of the two
735                  * link partners. In descending order:
736                  *      0x0100          100BASE-TX Full Duplex
737                  *      0x0200          100BASE-T4
738                  *      0x0080          100BASE-TX
739                  *      0x0040          10BASE-T Full Duplex
740                  *      0x0020          10BASE-T
741                  */
742                 anar = miir(ctlr, phyaddr, 0x04);
743                 anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
744                 anar &= anlpar;
745                 bmcr = 0;
746                 if(anar & 0x380)
747                         bmcr = 0x2000;
748                 if(anar & 0x0140)
749                         bmcr |= 0x0100;
750
751                 switch((ctlr->eeprom[6]>>8) & 0x001F){
752
753                 case 0x04:                              /* DP83840 */
754                 case 0x0A:                              /* DP83840A */
755                         /*
756                          * The DP83840[A] requires some tweaking for
757                          * reliable operation.
758                          * The manual says bit 10 should be unconditionally
759                          * set although it supposedly only affects full-duplex
760                          * operation (an & 0x0140).
761                          */
762                         x = miir(ctlr, phyaddr, 0x17) & ~0x0520;
763                         x |= 0x0420;
764                         for(i = 0; i < ether->nopt; i++){
765                                 if(cistrcmp(ether->opt[i], "congestioncontrol"))
766                                         continue;
767                                 x |= 0x0100;
768                                 break;
769                         }
770                         miiw(ctlr, phyaddr, 0x17, x);
771
772                         /*
773                          * If the link partner can't autonegotiate, determine
774                          * the speed from elsewhere.
775                          */
776                         if(anlpar == 0){
777                                 miir(ctlr, phyaddr, 0x01);
778                                 bmsr = miir(ctlr, phyaddr, 0x01);
779                                 x = miir(ctlr, phyaddr, 0x19);
780                                 if((bmsr & 0x0004) && !(x & 0x0040))
781                                         bmcr = 0x2000;
782                         }
783                         break;
784
785                 case 0x07:                              /* Intel 82555 */
786                         /*
787                          * Auto-negotiation may fail if the other end is
788                          * a DP83840A and the cable is short.
789                          */
790                         bmsr = miir(ctlr, phyaddr, 0x01);
791                         if((miir(ctlr, phyaddr, 0) & 0x1000) && !(bmsr & 0x0020)){
792                                 miiw(ctlr, phyaddr, 0x1A, 0x2010);
793                                 x = miir(ctlr, phyaddr, 0);
794                                 miiw(ctlr, phyaddr, 0, 0x0200|x);
795                                 for(i = 0; i < 3000; i++){
796                                         delay(1);
797                                         if(miir(ctlr, phyaddr, 0x01) & 0x0020)
798                                                 break;
799                                 }
800                                 miiw(ctlr, phyaddr, 0x1A, 0x2000);
801                                         
802                                 anar = miir(ctlr, phyaddr, 0x04);
803                                 anlpar = miir(ctlr, phyaddr, 0x05) & 0x03E0;
804                                 anar &= anlpar;
805                                 bmcr = 0;
806                                 if(anar & 0x380)
807                                         bmcr = 0x2000;
808                                 if(anar & 0x0140)
809                                         bmcr |= 0x0100;
810                         }
811                         break;
812                 }
813
814                 /*
815                  * Force speed and duplex if no auto-negotiation.
816                  */
817                 if(anlpar == 0){
818                         force = 0;
819                         for(i = 0; i < ether->nopt; i++){
820                                 if(cistrcmp(ether->opt[i], "fullduplex") == 0){
821                                         force = 1;
822                                         bmcr |= 0x0100;
823                                         ctlr->configdata[19] |= 0x40;
824                                 }
825                                 else if(cistrcmp(ether->opt[i], "speed") == 0){
826                                         force = 1;
827                                         x = strtol(&ether->opt[i][6], 0, 0);
828                                         if(x == 10)
829                                                 bmcr &= ~0x2000;
830                                         else if(x == 100)
831                                                 bmcr |= 0x2000;
832                                         else
833                                                 force = 0;
834                                 }
835                         }
836                         if(force)
837                                 miiw(ctlr, phyaddr, 0x00, bmcr);
838                 }
839
840                 ctlr->configdata[8] = 1;
841                 ctlr->configdata[15] &= ~0x80;
842         }
843         else{
844                 ctlr->configdata[8] = 0;
845                 ctlr->configdata[15] |= 0x80;
846         }
847
848         /*
849          * Load the chip configuration
850          */
851         configure(ether, 0);
852
853         /*
854          * Check if the adapter's station address is to be overridden.
855          * If not, read it from the EEPROM and set in ether->ea prior to loading
856          * the station address with the Individual Address Setup command.
857          */
858         memset(ea, 0, Eaddrlen);
859         if(memcmp(ea, ether->ea, Eaddrlen) == 0){
860                 for(i = 0; i < Eaddrlen/2; i++){
861                         x = ctlr->eeprom[i];
862                         ether->ea[2*i] = x & 0xFF;
863                         ether->ea[2*i+1] = (x>>8) & 0xFF;
864                 }
865         }
866
867         bp = allocb(sizeof(Cb));
868         cb = (Cb*)bp->rp;
869         bp->wp += sizeof(Cb);
870
871         cb->command = CbIAS;
872         cb->link = NullPointer;
873         memmove(cb->data, ether->ea, Eaddrlen);
874         action(ctlr, bp);
875
876         /*
877          * Linkage to the generic ethernet driver.
878          */
879         ether->attach = attach;
880         ether->transmit = transmit;
881         ether->interrupt = interrupt;
882         ether->detach = detach;
883
884         return 0;
885 }