]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/mtx/ether2114x.c
pci: add intel qm67 pch
[plan9front.git] / sys / src / 9 / mtx / ether2114x.c
1 /*
2  * Digital Semiconductor DECchip 2114x PCI Fast Ethernet LAN Controller.
3  * To do:
4  *      thresholds;
5  *      ring sizing;
6  *      handle more error conditions;
7  *      tidy setup packet mess;
8  *      push initialisation back to attach;
9  *      full SROM decoding.
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
20 #include "etherif.h"
21
22 #define DEBUG           (0)
23 #define debug           if(DEBUG)print
24
25 enum {
26         Nrde            = 64,
27         Ntde            = 64,
28 };
29
30 #define Rbsz            ROUNDUP(sizeof(Etherpkt)+4, 4)
31
32 enum {                                  /* CRS0 - Bus Mode */
33         Swr             = 0x00000001,   /* Software Reset */
34         Bar             = 0x00000002,   /* Bus Arbitration */
35         Dsl             = 0x0000007C,   /* Descriptor Skip Length (field) */
36         Ble             = 0x00000080,   /* Big/Little Endian */
37         Pbl             = 0x00003F00,   /* Programmable Burst Length (field) */
38         Cal             = 0x0000C000,   /* Cache Alignment (field) */
39         Cal8            = 0x00004000,   /* 8 longword boundary alignment */
40         Cal16           = 0x00008000,   /* 16 longword boundary alignment */
41         Cal32           = 0x0000C000,   /* 32 longword boundary alignment */
42         Tap             = 0x000E0000,   /* Transmit Automatic Polling (field) */
43         Dbo             = 0x00100000,   /* Descriptor Byte Ordering Mode */
44         Rml             = 0x00200000,   /* Read Multiple */
45 }; 
46
47 enum {                                  /* CSR[57] - Status and Interrupt Enable */
48         Ti              = 0x00000001,   /* Transmit Interrupt */
49         Tps             = 0x00000002,   /* Transmit Process Stopped */
50         Tu              = 0x00000004,   /* Transmit buffer Unavailable */
51         Tjt             = 0x00000008,   /* Transmit Jabber Timeout */
52         Unf             = 0x00000020,   /* transmit UNderFlow */
53         Ri              = 0x00000040,   /* Receive Interrupt */
54         Ru              = 0x00000080,   /* Receive buffer Unavailable */
55         Rps             = 0x00000100,   /* Receive Process Stopped */
56         Rwt             = 0x00000200,   /* Receive Watchdog Timeout */
57         Eti             = 0x00000400,   /* Early Transmit Interrupt */
58         Gte             = 0x00000800,   /* General purpose Timer Expired */
59         Fbe             = 0x00002000,   /* Fatal Bus Error */
60         Ais             = 0x00008000,   /* Abnormal Interrupt Summary */
61         Nis             = 0x00010000,   /* Normal Interrupt Summary */
62         Rs              = 0x000E0000,   /* Receive process State (field) */
63         Ts              = 0x00700000,   /* Transmit process State (field) */
64         Eb              = 0x03800000,   /* Error bits */
65 };
66
67 enum {                                  /* CSR6 - Operating Mode */
68         Hp              = 0x00000001,   /* Hash/Perfect receive filtering mode */
69         Sr              = 0x00000002,   /* Start/stop Receive */
70         Ho              = 0x00000004,   /* Hash-Only filtering mode */
71         Pb              = 0x00000008,   /* Pass Bad frames */
72         If              = 0x00000010,   /* Inverse Filtering */
73         Sb              = 0x00000020,   /* Start/stop Backoff counter */
74         Pr              = 0x00000040,   /* Promiscuous Mode */
75         Pm              = 0x00000080,   /* Pass all Multicast */
76         Fd              = 0x00000200,   /* Full Duplex mode */
77         Om              = 0x00000C00,   /* Operating Mode (field) */
78         Fc              = 0x00001000,   /* Force Collision */
79         St              = 0x00002000,   /* Start/stop Transmission Command */
80         Tr              = 0x0000C000,   /* ThReshold control bits (field) */
81         Tr128           = 0x00000000,
82         Tr256           = 0x00004000,
83         Tr512           = 0x00008000,
84         Tr1024          = 0x0000C000,
85         Ca              = 0x00020000,   /* CApture effect enable */
86         Ps              = 0x00040000,   /* Port Select */
87         Hbd             = 0x00080000,   /* HeartBeat Disable */
88         Imm             = 0x00100000,   /* IMMediate mode */
89         Sf              = 0x00200000,   /* Store and Forward */
90         Ttm             = 0x00400000,   /* Transmit Threshold Mode */
91         Pcs             = 0x00800000,   /* PCS function */
92         Scr             = 0x01000000,   /* SCRambler mode */
93         Mbo             = 0x02000000,   /* Must Be One */
94         Ra              = 0x40000000,   /* Receive All */
95         Sc              = 0x80000000,   /* Special Capture effect enable */
96
97         TrMODE          = Tr512,        /* default transmission threshold */
98 };
99
100 enum {                                  /* CSR9 - ROM and MII Management */
101         Scs             = 0x00000001,   /* serial ROM chip select */
102         Sclk            = 0x00000002,   /* serial ROM clock */
103         Sdi             = 0x00000004,   /* serial ROM data in */
104         Sdo             = 0x00000008,   /* serial ROM data out */
105         Ss              = 0x00000800,   /* serial ROM select */
106         Wr              = 0x00002000,   /* write */
107         Rd              = 0x00004000,   /* read */
108
109         Mdc             = 0x00010000,   /* MII management clock */
110         Mdo             = 0x00020000,   /* MII management write data */
111         Mii             = 0x00040000,   /* MII management operation mode (W) */
112         Mdi             = 0x00080000,   /* MII management data in */
113 };
114
115 enum {                                  /* CSR12 - General-Purpose Port */
116         Gpc             = 0x00000100,   /* General Purpose Control */
117 };
118
119 typedef struct Des {
120         int     status;
121         int     control;
122         ulong   addr;
123         Block*  bp;
124 } Des;
125
126 enum {                                  /* status */
127         Of              = 0x00000001,   /* Rx: OverFlow */
128         Ce              = 0x00000002,   /* Rx: CRC Error */
129         Db              = 0x00000004,   /* Rx: Dribbling Bit */
130         Re              = 0x00000008,   /* Rx: Report on MII Error */
131         Rw              = 0x00000010,   /* Rx: Receive Watchdog */
132         Ft              = 0x00000020,   /* Rx: Frame Type */
133         Cs              = 0x00000040,   /* Rx: Collision Seen */
134         Tl              = 0x00000080,   /* Rx: Frame too Long */
135         Ls              = 0x00000100,   /* Rx: Last deScriptor */
136         Fs              = 0x00000200,   /* Rx: First deScriptor */
137         Mf              = 0x00000400,   /* Rx: Multicast Frame */
138         Rf              = 0x00000800,   /* Rx: Runt Frame */
139         Dt              = 0x00003000,   /* Rx: Data Type (field) */
140         De              = 0x00004000,   /* Rx: Descriptor Error */
141         Fl              = 0x3FFF0000,   /* Rx: Frame Length (field) */
142         Ff              = 0x40000000,   /* Rx: Filtering Fail */
143
144         Def             = 0x00000001,   /* Tx: DEFerred */
145         Uf              = 0x00000002,   /* Tx: UnderFlow error */
146         Lf              = 0x00000004,   /* Tx: Link Fail report */
147         Cc              = 0x00000078,   /* Tx: Collision Count (field) */
148         Hf              = 0x00000080,   /* Tx: Heartbeat Fail */
149         Ec              = 0x00000100,   /* Tx: Excessive Collisions */
150         Lc              = 0x00000200,   /* Tx: Late Collision */
151         Nc              = 0x00000400,   /* Tx: No Carrier */
152         Lo              = 0x00000800,   /* Tx: LOss of carrier */
153         To              = 0x00004000,   /* Tx: Transmission jabber timeOut */
154
155         Es              = 0x00008000,   /* [RT]x: Error Summary */
156         Own             = 0x80000000,   /* [RT]x: OWN bit */
157 };
158
159 enum {                                  /* control */
160         Bs1             = 0x000007FF,   /* [RT]x: Buffer 1 Size */
161         Bs2             = 0x003FF800,   /* [RT]x: Buffer 2 Size */
162
163         Ch              = 0x01000000,   /* [RT]x: second address CHained */
164         Er              = 0x02000000,   /* [RT]x: End of Ring */
165
166         Ft0             = 0x00400000,   /* Tx: Filtering Type 0 */
167         Dpd             = 0x00800000,   /* Tx: Disabled PaDding */
168         Ac              = 0x04000000,   /* Tx: Add CRC disable */
169         Set             = 0x08000000,   /* Tx: SETup packet */
170         Ft1             = 0x10000000,   /* Tx: Filtering Type 1 */
171         Fseg            = 0x20000000,   /* Tx: First SEGment */
172         Lseg            = 0x40000000,   /* Tx: Last SEGment */
173         Ic              = 0x80000000,   /* Tx: Interrupt on Completion */
174 };
175
176 enum {                                  /* PHY registers */
177         Bmcr            = 0,            /* Basic Mode Control */
178         Bmsr            = 1,            /* Basic Mode Status */
179         Phyidr1         = 2,            /* PHY Identifier #1 */
180         Phyidr2         = 3,            /* PHY Identifier #2 */
181         Anar            = 4,            /* Auto-Negotiation Advertisment */
182         Anlpar          = 5,            /* Auto-Negotiation Link Partner Ability */
183         Aner            = 6,            /* Auto-Negotiation Expansion */
184 };
185
186 enum {                                  /* Variants */
187         Tulip0          = (0x0009<<16)|0x1011,
188         Tulip3          = (0x0019<<16)|0x1011,
189         Pnic            = (0x0002<<16)|0x11AD,
190         Pnic2           = (0xC115<<16)|0x11AD,
191 };
192
193 typedef struct Ctlr Ctlr;
194 typedef struct Ctlr {
195         int     port;
196         Pcidev* pcidev;
197         Ctlr*   next;
198         int     active;
199         int     id;                     /* (pcidev->did<<16)|pcidev->vid */
200
201         uchar*  srom;
202         int     sromsz;                 /* address size in bits */
203         uchar*  sromea;                 /* MAC address */
204         uchar*  leaf;
205         int     sct;                    /* selected connection type */
206         int     k;                      /* info block count */
207         uchar*  infoblock[16];
208         int     sctk;                   /* sct block index */
209         int     curk;                   /* current block index */
210         uchar*  type5block;
211
212         int     phy[32];                /* logical to physical map */
213         int     phyreset;               /* reset bitmap */
214         int     curphyad;
215         int     fdx;
216         int     ttm;
217
218         uchar   fd;                     /* option */
219         int     medium;                 /* option */
220
221         int     csr6;                   /* CSR6 - operating mode */
222         int     mask;                   /* CSR[57] - interrupt mask */
223         int     mbps;
224
225         Lock    lock;
226
227         Des*    rdr;                    /* receive descriptor ring */
228         int     nrdr;                   /* size of rdr */
229         int     rdrx;                   /* index into rdr */
230
231         Lock    tlock;
232         Des*    tdr;                    /* transmit descriptor ring */
233         int     ntdr;                   /* size of tdr */
234         int     tdrh;                   /* host index into tdr */
235         int     tdri;                   /* interface index into tdr */
236         int     ntq;                    /* descriptors active */
237         int     ntqmax;
238         Block*  setupbp;
239
240         ulong   of;                     /* receive statistics */
241         ulong   ce;
242         ulong   cs;
243         ulong   tl;
244         ulong   rf;
245         ulong   de;
246
247         ulong   ru;
248         ulong   rps;
249         ulong   rwt;
250
251         ulong   uf;                     /* transmit statistics */
252         ulong   ec;
253         ulong   lc;
254         ulong   nc;
255         ulong   lo;
256         ulong   to;
257
258         ulong   tps;
259         ulong   tu;
260         ulong   tjt;
261         ulong   unf;
262 } Ctlr;
263
264 static Ctlr* ctlrhead;
265 static Ctlr* ctlrtail;
266
267 #define csr32r(c, r)    (inl((c)->port+((r)*8)))
268 #define csr32w(c, r, l) (outl((c)->port+((r)*8), (ulong)(l)))
269
270 static void
271 promiscuous(void* arg, int on)
272 {
273         Ctlr *ctlr;
274
275         ctlr = ((Ether*)arg)->ctlr;
276         ilock(&ctlr->lock);
277         if(on)
278                 ctlr->csr6 |= Pr;
279         else
280                 ctlr->csr6 &= ~Pr;
281         csr32w(ctlr, 6, ctlr->csr6);
282         iunlock(&ctlr->lock);
283 }
284
285 static void
286 attach(Ether* ether)
287 {
288         Ctlr *ctlr;
289
290         ctlr = ether->ctlr;
291         ilock(&ctlr->lock);
292         if(!(ctlr->csr6 & Sr)){
293                 ctlr->csr6 |= Sr;
294                 csr32w(ctlr, 6, ctlr->csr6);
295         }
296         iunlock(&ctlr->lock);
297 }
298
299 static long
300 ifstat(Ether* ether, void* a, long n, ulong offset)
301 {
302         Ctlr *ctlr;
303         char *buf, *p;
304         int i, l, len;
305
306         ctlr = ether->ctlr;
307
308         ether->crcs = ctlr->ce;
309         ether->frames = ctlr->rf+ctlr->cs;
310         ether->buffs = ctlr->de+ctlr->tl;
311         ether->overflows = ctlr->of;
312
313         if(n == 0)
314                 return 0;
315
316         p = malloc(READSTR);
317         l = snprint(p, READSTR, "Overflow: %lud\n", ctlr->of);
318         l += snprint(p+l, READSTR-l, "Ru: %lud\n", ctlr->ru);
319         l += snprint(p+l, READSTR-l, "Rps: %lud\n", ctlr->rps);
320         l += snprint(p+l, READSTR-l, "Rwt: %lud\n", ctlr->rwt);
321         l += snprint(p+l, READSTR-l, "Tps: %lud\n", ctlr->tps);
322         l += snprint(p+l, READSTR-l, "Tu: %lud\n", ctlr->tu);
323         l += snprint(p+l, READSTR-l, "Tjt: %lud\n", ctlr->tjt);
324         l += snprint(p+l, READSTR-l, "Unf: %lud\n", ctlr->unf);
325         l += snprint(p+l, READSTR-l, "CRC Error: %lud\n", ctlr->ce);
326         l += snprint(p+l, READSTR-l, "Collision Seen: %lud\n", ctlr->cs);
327         l += snprint(p+l, READSTR-l, "Frame Too Long: %lud\n", ctlr->tl);
328         l += snprint(p+l, READSTR-l, "Runt Frame: %lud\n", ctlr->rf);
329         l += snprint(p+l, READSTR-l, "Descriptor Error: %lud\n", ctlr->de);
330         l += snprint(p+l, READSTR-l, "Underflow Error: %lud\n", ctlr->uf);
331         l += snprint(p+l, READSTR-l, "Excessive Collisions: %lud\n", ctlr->ec);
332         l += snprint(p+l, READSTR-l, "Late Collision: %lud\n", ctlr->lc);
333         l += snprint(p+l, READSTR-l, "No Carrier: %lud\n", ctlr->nc);
334         l += snprint(p+l, READSTR-l, "Loss of Carrier: %lud\n", ctlr->lo);
335         l += snprint(p+l, READSTR-l, "Transmit Jabber Timeout: %lud\n",
336                 ctlr->to);
337         l += snprint(p+l, READSTR-l, "csr6: %luX %uX\n", csr32r(ctlr, 6),
338                 ctlr->csr6);
339         snprint(p+l, READSTR-l, "ntqmax: %d\n", ctlr->ntqmax);
340         ctlr->ntqmax = 0;
341         buf = a;
342         len = readstr(offset, buf, n, p);
343         if(offset > l)
344                 offset -= l;
345         else
346                 offset = 0;
347         buf += len;
348         n -= len;
349
350         l = snprint(p, READSTR, "srom:");
351         for(i = 0; i < (1<<(ctlr->sromsz)*sizeof(ushort)); i++){
352                 if(i && ((i & 0x0F) == 0))
353                         l += snprint(p+l, READSTR-l, "\n     ");
354                 l += snprint(p+l, READSTR-l, " %2.2uX", ctlr->srom[i]);
355         }
356
357         snprint(p+l, READSTR-l, "\n");
358         len += readstr(offset, buf, n, p);
359         free(p);
360
361         return len;
362 }
363
364 static void
365 txstart(Ether* ether)
366 {
367         Ctlr *ctlr;
368         Block *bp;
369         Des *des;
370         int control;
371
372         ctlr = ether->ctlr;
373         while(ctlr->ntq < (ctlr->ntdr-1)){
374                 if(ctlr->setupbp){
375                         bp = ctlr->setupbp;
376                         ctlr->setupbp = 0;
377                         control = Ic|Set|BLEN(bp);
378                 }
379                 else{
380                         bp = qget(ether->oq);
381                         if(bp == nil)
382                                 break;
383                         control = Ic|Lseg|Fseg|BLEN(bp);
384                 }
385
386                 ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
387                 des = &ctlr->tdr[ctlr->tdrh];
388                 des->bp = bp;
389                 des->addr = PCIWADDR(bp->rp);
390                 des->control |= control;
391                 ctlr->ntq++;
392                 coherence();
393                 des->status = Own;
394                 csr32w(ctlr, 1, 0);
395                 ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
396         }
397
398         if(ctlr->ntq > ctlr->ntqmax)
399                 ctlr->ntqmax = ctlr->ntq;
400 }
401
402 static void
403 transmit(Ether* ether)
404 {
405         Ctlr *ctlr;
406
407         ctlr = ether->ctlr;
408         ilock(&ctlr->tlock);
409         txstart(ether);
410         iunlock(&ctlr->tlock);
411 }
412
413 static void
414 interrupt(Ureg*, void* arg)
415 {
416         Ctlr *ctlr;
417         Ether *ether;
418         int len, status;
419         Des *des;
420         Block *bp;
421
422         ether = arg;
423         ctlr = ether->ctlr;
424
425         while((status = csr32r(ctlr, 5)) & (Nis|Ais)){
426                 /*
427                  * Acknowledge the interrupts and mask-out
428                  * the ones that are implicitly handled.
429                  */
430                 csr32w(ctlr, 5, status);
431                 status &= (ctlr->mask & ~(Nis|Ti));
432
433                 if(status & Ais){
434                         if(status & Tps)
435                                 ctlr->tps++;
436                         if(status & Tu)
437                                 ctlr->tu++;
438                         if(status & Tjt)
439                                 ctlr->tjt++;
440                         if(status & Ru)
441                                 ctlr->ru++;
442                         if(status & Rps)
443                                 ctlr->rps++;
444                         if(status & Rwt)
445                                 ctlr->rwt++;
446                         status &= ~(Ais|Rwt|Rps|Ru|Tjt|Tu|Tps);
447                 }
448
449                 /*
450                  * Received packets.
451                  */
452                 if(status & Ri){
453                         des = &ctlr->rdr[ctlr->rdrx];
454                         while(!(des->status & Own)){
455                                 if(des->status & Es){
456                                         if(des->status & Of)
457                                                 ctlr->of++;
458                                         if(des->status & Ce)
459                                                 ctlr->ce++;
460                                         if(des->status & Cs)
461                                                 ctlr->cs++;
462                                         if(des->status & Tl)
463                                                 ctlr->tl++;
464                                         if(des->status & Rf)
465                                                 ctlr->rf++;
466                                         if(des->status & De)
467                                                 ctlr->de++;
468                                 }
469                                 else if(bp = iallocb(Rbsz)){
470                                         len = ((des->status & Fl)>>16)-4;
471                                         des->bp->wp = des->bp->rp+len;
472                                         etheriq(ether, des->bp, 1);
473                                         des->bp = bp;
474                                         des->addr = PCIWADDR(bp->rp);
475                                 }
476
477                                 des->control &= Er;
478                                 des->control |= Rbsz;
479                                 coherence();
480                                 des->status = Own;
481
482                                 ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
483                                 des = &ctlr->rdr[ctlr->rdrx];
484                         }
485                         status &= ~Ri;
486                 }
487
488                 /*
489                  * Check the transmit side:
490                  *      check for Transmit Underflow and Adjust
491                  *      the threshold upwards;
492                  *      free any transmitted buffers and try to
493                  *      top-up the ring.
494                  */
495                 if(status & Unf){
496                         ctlr->unf++;
497                         ilock(&ctlr->lock);
498                         csr32w(ctlr, 6, ctlr->csr6 & ~St);
499                         switch(ctlr->csr6 & Tr){
500                         case Tr128:
501                                 len = Tr256;
502                                 break;
503                         case Tr256:
504                                 len = Tr512;
505                                 break;
506                         case Tr512:
507                                 len = Tr1024;
508                                 break;
509                         default:
510                         case Tr1024:
511                                 len = Sf;
512                                 break;
513                         }
514                         ctlr->csr6 = (ctlr->csr6 & ~Tr)|len;
515                         csr32w(ctlr, 6, ctlr->csr6);
516                         iunlock(&ctlr->lock);
517                         csr32w(ctlr, 5, Tps);
518                         status &= ~(Unf|Tps);
519                 }
520
521                 ilock(&ctlr->tlock);
522                 while(ctlr->ntq){
523                         des = &ctlr->tdr[ctlr->tdri];
524                         if(des->status & Own)
525                                 break;
526
527                         if(des->status & Es){
528                                 if(des->status & Uf)
529                                         ctlr->uf++;
530                                 if(des->status & Ec)
531                                         ctlr->ec++;
532                                 if(des->status & Lc)
533                                         ctlr->lc++;
534                                 if(des->status & Nc)
535                                         ctlr->nc++;
536                                 if(des->status & Lo)
537                                         ctlr->lo++;
538                                 if(des->status & To)
539                                         ctlr->to++;
540                                 ether->oerrs++;
541                         }
542
543                         freeb(des->bp);
544                         des->control &= Er;
545
546                         ctlr->ntq--;
547                         ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
548                 }
549                 txstart(ether);
550                 iunlock(&ctlr->tlock);
551
552                 /*
553                  * Anything left not catered for?
554                  */
555                 if(status)
556                         panic("#l%d: status %8.8uX\n", ether->ctlrno, status);
557         }
558 }
559
560 static void
561 ctlrinit(Ether* ether)
562 {
563         Ctlr *ctlr;
564         Des *des;
565         Block *bp;
566         int i;
567         uchar bi[Eaddrlen*2];
568
569         ctlr = ether->ctlr;
570
571         /*
572          * Allocate and initialise the receive ring;
573          * allocate and initialise the transmit ring;
574          * unmask interrupts and start the transmit side;
575          * create and post a setup packet to initialise
576          * the physical ethernet address.
577          */
578         ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
579         for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
580                 des->bp = iallocb(Rbsz);
581                 if(des->bp == nil)
582                         panic("can't allocate ethernet receive ring\n");
583                 des->status = Own;
584                 des->control = Rbsz;
585                 des->addr = PCIWADDR(des->bp->rp);
586         }
587         ctlr->rdr[ctlr->nrdr-1].control |= Er;
588         ctlr->rdrx = 0;
589         csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
590
591         ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
592         ctlr->tdr[ctlr->ntdr-1].control |= Er;
593         ctlr->tdrh = 0;
594         ctlr->tdri = 0;
595         csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
596
597         /*
598          * Clear any bits in the Status Register (CSR5) as
599          * the PNIC has a different reset value from a true 2114x.
600          */
601         ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
602         csr32w(ctlr, 5, ctlr->mask);
603         csr32w(ctlr, 7, ctlr->mask);
604         ctlr->csr6 |= St;
605         csr32w(ctlr, 6, ctlr->csr6);
606
607         for(i = 0; i < Eaddrlen/2; i++){
608                 bi[i*4] = ether->ea[i*2];
609                 bi[i*4+1] = ether->ea[i*2+1];
610                 bi[i*4+2] = ether->ea[i*2+1];
611                 bi[i*4+3] = ether->ea[i*2];
612         }
613         bp = iallocb(Eaddrlen*2*16);
614         if(bp == nil)
615                 panic("can't allocate ethernet setup buffer\n");
616         memset(bp->rp, 0xFF, sizeof(bi));
617         for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
618                 memmove(bp->rp+i, bi, sizeof(bi));
619         bp->wp += sizeof(bi)*16;
620
621         ctlr->setupbp = bp;
622         ether->oq = qopen(256*1024, Qmsg, 0, 0);
623         transmit(ether);
624 }
625
626 static void
627 csr9w(Ctlr* ctlr, int data)
628 {
629         csr32w(ctlr, 9, data);
630         microdelay(1);
631 }
632
633 static int
634 miimdi(Ctlr* ctlr, int n)
635 {
636         int data, i;
637
638         /*
639          * Read n bits from the MII Management Register.
640          */
641         data = 0;
642         for(i = n-1; i >= 0; i--){
643                 if(csr32r(ctlr, 9) & Mdi)
644                         data |= (1<<i);
645                 csr9w(ctlr, Mii|Mdc);
646                 csr9w(ctlr, Mii);
647         }
648         csr9w(ctlr, 0);
649
650         return data;
651 }
652
653 static void
654 miimdo(Ctlr* ctlr, int bits, int n)
655 {
656         int i, mdo;
657
658         /*
659          * Write n bits to the MII Management Register.
660          */
661         for(i = n-1; i >= 0; i--){
662                 if(bits & (1<<i))
663                         mdo = Mdo;
664                 else
665                         mdo = 0;
666                 csr9w(ctlr, mdo);
667                 csr9w(ctlr, mdo|Mdc);
668                 csr9w(ctlr, mdo);
669         }
670 }
671
672 static int
673 miir(Ctlr* ctlr, int phyad, int regad)
674 {
675         int data, i;
676
677         if(ctlr->id == Pnic){
678                 i = 1000;
679                 csr32w(ctlr, 20, 0x60020000|(phyad<<23)|(regad<<18));
680                 do{
681                         microdelay(1);
682                         data = csr32r(ctlr, 20);
683                 }while((data & 0x80000000) && --i);
684
685                 if(i == 0)
686                         return -1;
687                 return data & 0xFFFF;
688         }
689
690         /*
691          * Preamble;
692          * ST+OP+PHYAD+REGAD;
693          * TA + 16 data bits.
694          */
695         miimdo(ctlr, 0xFFFFFFFF, 32);
696         miimdo(ctlr, 0x1800|(phyad<<5)|regad, 14);
697         data = miimdi(ctlr, 18);
698
699         if(data & 0x10000)
700                 return -1;
701
702         return data & 0xFFFF;
703 }
704
705 static void
706 miiw(Ctlr* ctlr, int phyad, int regad, int data)
707 {
708         /*
709          * Preamble;
710          * ST+OP+PHYAD+REGAD+TA + 16 data bits;
711          * Z.
712          */
713         miimdo(ctlr, 0xFFFFFFFF, 32);
714         data &= 0xFFFF;
715         data |= (0x05<<(5+5+2+16))|(phyad<<(5+2+16))|(regad<<(2+16))|(0x02<<16);
716         miimdo(ctlr, data, 32);
717         csr9w(ctlr, Mdc);
718         csr9w(ctlr, 0);
719 }
720
721 static int
722 sromr(Ctlr* ctlr, int r)
723 {
724         int i, op, data, size;
725
726         if(ctlr->id == Pnic){
727                 i = 1000;
728                 csr32w(ctlr, 19, 0x600|r);
729                 do{
730                         microdelay(1);
731                         data = csr32r(ctlr, 19);
732                 }while((data & 0x80000000) && --i);
733
734                 if(ctlr->sromsz == 0)
735                         ctlr->sromsz = 6;
736
737                 return csr32r(ctlr, 9) & 0xFFFF;
738         }
739
740         /*
741          * This sequence for reading a 16-bit register 'r'
742          * in the EEPROM is taken straight from Section
743          * 7.4 of the 21140 Hardware Reference Manual.
744          */
745 reread:
746         csr9w(ctlr, Rd|Ss);
747         csr9w(ctlr, Rd|Ss|Scs);
748         csr9w(ctlr, Rd|Ss|Sclk|Scs);
749         csr9w(ctlr, Rd|Ss);
750
751         op = 0x06;
752         for(i = 3-1; i >= 0; i--){
753                 data = Rd|Ss|(((op>>i) & 0x01)<<2)|Scs;
754                 csr9w(ctlr, data);
755                 csr9w(ctlr, data|Sclk);
756                 csr9w(ctlr, data);
757         }
758
759         /*
760          * First time through must work out the EEPROM size.
761          */
762         if((size = ctlr->sromsz) == 0)
763                 size = 8;
764
765         for(size = size-1; size >= 0; size--){
766                 data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs;
767                 csr9w(ctlr, data);
768                 csr9w(ctlr, data|Sclk);
769                 csr9w(ctlr, data);
770                 microdelay(1);
771                 if(!(csr32r(ctlr, 9) & Sdo))
772                         break;
773         }
774
775         data = 0;
776         for(i = 16-1; i >= 0; i--){
777                 csr9w(ctlr, Rd|Ss|Sclk|Scs);
778                 if(csr32r(ctlr, 9) & Sdo)
779                         data |= (1<<i);
780                 csr9w(ctlr, Rd|Ss|Scs);
781         }
782
783         csr9w(ctlr, 0);
784
785         if(ctlr->sromsz == 0){
786                 ctlr->sromsz = 8-size;
787                 goto reread;
788         }
789
790         return data & 0xFFFF;
791 }
792
793 static void
794 softreset(Ctlr* ctlr)
795 {
796         /*
797          * Soft-reset the controller and initialise bus mode.
798          * Delay should be >= 50 PCI cycles (2×S @ 25MHz).
799          */
800         csr32w(ctlr, 0, Swr);
801         microdelay(10);
802         csr32w(ctlr, 0, Rml|Cal16|Dbo);
803         delay(1);
804 }
805
806 static int
807 type5block(Ctlr* ctlr, uchar* block)
808 {
809         int csr15, i, len;
810
811         /*
812          * Reset or GPR sequence. Reset should be once only,
813          * before the GPR sequence.
814          * Note 'block' is not a pointer to the block head but
815          * a pointer to the data in the block starting at the
816          * reset length value so type5block can be used for the
817          * sequences contained in type 1 and type 3 blocks.
818          * The SROM docs state the 21140 type 5 block is the
819          * same as that for the 21143, but the two controllers
820          * use different registers and sequence-element lengths
821          * so the 21140 code here is a guess for a real type 5
822          * sequence.
823          */
824         len = *block++;
825         if(ctlr->id != Tulip3){
826                 for(i = 0; i < len; i++){
827                         csr32w(ctlr, 12, *block);
828                         block++;
829                 }
830                 return len;
831         }
832
833         for(i = 0; i < len; i++){
834                 csr15 = *block++<<16;
835                 csr15 |= *block++<<24;
836                 csr32w(ctlr, 15, csr15);
837                 debug("%8.8uX ", csr15);
838         }
839         return 2*len;
840 }
841
842 static int
843 typephylink(Ctlr* ctlr, uchar*)
844 {
845         int an, bmcr, bmsr, csr6, x;
846
847         /*
848          * Fail if
849          *      auto-negotiataion enabled but not complete;
850          *      no valid link established.
851          */
852         bmcr = miir(ctlr, ctlr->curphyad, Bmcr);
853         miir(ctlr, ctlr->curphyad, Bmsr);
854         bmsr = miir(ctlr, ctlr->curphyad, Bmsr);
855         debug("bmcr 0x%2.2uX bmsr 0x%2.2uX\n", bmcr, bmsr);
856         if(((bmcr & 0x1000) && !(bmsr & 0x0020)) || !(bmsr & 0x0004))
857                 return 0;
858
859         if(bmcr & 0x1000){
860                 an = miir(ctlr, ctlr->curphyad, Anar);
861                 an &= miir(ctlr, ctlr->curphyad, Anlpar) & 0x3E0;
862                 debug("an 0x%2.uX 0x%2.2uX 0x%2.2uX\n",
863                         miir(ctlr, ctlr->curphyad, Anar),
864                         miir(ctlr, ctlr->curphyad, Anlpar),
865                         an);
866         
867                 if(an & 0x0100)
868                         x = 0x4000;
869                 else if(an & 0x0080)
870                         x = 0x2000;
871                 else if(an & 0x0040)
872                         x = 0x1000;
873                 else if(an & 0x0020)
874                         x = 0x0800;
875                 else
876                         x = 0;
877         }
878         else if((bmcr & 0x2100) == 0x2100)
879                 x = 0x4000;
880         else if(bmcr & 0x2000){
881                 /*
882                  * If FD capable, force it if necessary.
883                  */
884                 if((bmsr & 0x4000) && ctlr->fd){
885                         miiw(ctlr, ctlr->curphyad, Bmcr, 0x2100);
886                         x = 0x4000;
887                 }
888                 else
889                         x = 0x2000;
890         }
891         else if(bmcr & 0x0100)
892                 x = 0x1000;
893         else
894                 x = 0x0800;
895
896         csr6 = Sc|Mbo|Hbd|Ps|Ca|Sb|TrMODE;
897         if(ctlr->fdx & x)
898                 csr6 |= Fd;
899         if(ctlr->ttm & x)
900                 csr6 |= Ttm;
901         debug("csr6 0x%8.8uX 0x%8.8uX 0x%8.8luX\n",
902                 csr6, ctlr->csr6, csr32r(ctlr, 6));
903         if(csr6 != ctlr->csr6){
904                 ctlr->csr6 = csr6;
905                 csr32w(ctlr, 6, csr6);
906         }
907
908         return 1;
909 }
910
911 static int
912 typephymode(Ctlr* ctlr, uchar* block, int wait)
913 {
914         uchar *p;
915         int len, mc, nway, phyx, timeo;
916
917         if(DEBUG){
918                 int i;
919
920                 len = (block[0] & ~0x80)+1;
921                 for(i = 0; i < len; i++)
922                         debug("%2.2uX ", block[i]);
923                 debug("\n");
924         }
925
926         if(block[1] == 1)
927                 len = 1;
928         else if(block[1] == 3)
929                 len = 2;
930         else
931                 return -1;
932
933         /*
934          * Snarf the media capabilities, nway advertisment,
935          * FDX and TTM bitmaps.
936          */
937         p = &block[5+len*block[3]+len*block[4+len*block[3]]];
938         mc = *p++;
939         mc |= *p++<<8;
940         nway = *p++;
941         nway |= *p++<<8;
942         ctlr->fdx = *p++;
943         ctlr->fdx |= *p++<<8;
944         ctlr->ttm = *p++;
945         ctlr->ttm |= *p<<8;
946         debug("mc %4.4uX nway %4.4uX fdx %4.4uX ttm %4.4uX\n",
947                 mc, nway, ctlr->fdx, ctlr->ttm);
948         USED(mc);
949
950         phyx = block[2];
951         ctlr->curphyad = ctlr->phy[phyx];
952
953         ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|Sb|TrMODE;
954         //csr32w(ctlr, 6, ctlr->csr6);
955         if(typephylink(ctlr, block))
956                 return 0;
957
958         if(!(ctlr->phyreset & (1<<phyx))){
959                 debug("reset seq: len %d: ", block[3]);
960                 if(ctlr->type5block)
961                         type5block(ctlr, &ctlr->type5block[2]);
962                 else
963                         type5block(ctlr, &block[4+len*block[3]]);
964                 debug("\n");
965                 ctlr->phyreset |= (1<<phyx);
966         }
967
968         /*
969          * GPR sequence.
970          */
971         debug("gpr seq: len %d: ", block[3]);
972         type5block(ctlr, &block[3]);
973         debug("\n");
974
975         ctlr->csr6 = 0;//Sc|Mbo|Hbd|Ps|Ca|Sb|TrMODE;
976         //csr32w(ctlr, 6, ctlr->csr6);
977         if(typephylink(ctlr, block))
978                 return 0;
979
980         /*
981          * Turn off auto-negotiation, set the auto-negotiation
982          * advertisment register then start the auto-negotiation
983          * process again.
984          */
985         miiw(ctlr, ctlr->curphyad, Bmcr, 0);
986         miiw(ctlr, ctlr->curphyad, Anar, nway|1);
987         miiw(ctlr, ctlr->curphyad, Bmcr, 0x1000);
988
989         if(!wait)
990                 return 0;
991
992         for(timeo = 0; timeo < 30; timeo++){
993                 if(typephylink(ctlr, block))
994                         return 0;
995                 delay(100);
996         }
997
998         return -1;
999 }
1000
1001 static int
1002 typesymmode(Ctlr *ctlr, uchar *block, int wait)
1003 {
1004         uint gpmode, gpdata, command;
1005
1006         USED(wait);
1007         gpmode = block[3] | ((uint) block[4] << 8);
1008         gpdata = block[5] | ((uint) block[6] << 8);
1009         command = (block[7] | ((uint) block[8] << 8)) & 0x71;
1010         if (command & 0x8000) {
1011                 print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n");
1012                 return -1;
1013         }
1014         csr32w(ctlr, 15, gpmode);
1015         csr32w(ctlr, 15, gpdata);
1016         ctlr->csr6 = (command & 0x71) << 18;
1017         csr32w(ctlr, 6, ctlr->csr6);
1018         return 0;
1019 }
1020
1021 static int
1022 type2mode(Ctlr* ctlr, uchar* block, int)
1023 {
1024         uchar *p;
1025         int csr6, csr13, csr14, csr15, gpc, gpd;
1026
1027         csr6 = Sc|Mbo|Ca|Sb|TrMODE;
1028         debug("type2mode: medium 0x%2.2uX\n", block[2]);
1029
1030         /*
1031          * Don't attempt full-duplex
1032          * unless explicitly requested.
1033          */
1034         if((block[2] & 0x3F) == 0x04){  /* 10BASE-TFD */
1035                 if(!ctlr->fd)
1036                         return -1;
1037                 csr6 |= Fd;
1038         }
1039
1040         /*
1041          * Operating mode programming values from the datasheet
1042          * unless media specific data is explicitly given.
1043          */
1044         p = &block[3];
1045         if(block[2] & 0x40){
1046                 csr13 = (block[4]<<8)|block[3];
1047                 csr14 = (block[6]<<8)|block[5];
1048                 csr15 = (block[8]<<8)|block[7];
1049                 p += 6;
1050         }
1051         else switch(block[2] & 0x3F){
1052         default:
1053                 return -1;
1054         case 0x00:                      /* 10BASE-T */
1055                 csr13 = 0x00000001;
1056                 csr14 = 0x00007F3F;
1057                 csr15 = 0x00000008;
1058                 break;
1059         case 0x01:                      /* 10BASE-2 */
1060                 csr13 = 0x00000009;
1061                 csr14 = 0x00000705;
1062                 csr15 = 0x00000006;
1063                 break;
1064         case 0x02:                      /* 10BASE-5 (AUI) */
1065                 csr13 = 0x00000009;
1066                 csr14 = 0x00000705;
1067                 csr15 = 0x0000000E;
1068                 break;
1069         case 0x04:                      /* 10BASE-TFD */
1070                 csr13 = 0x00000001;
1071                 csr14 = 0x00007F3D;
1072                 csr15 = 0x00000008;
1073                 break;
1074         }
1075         gpc = *p++<<16;
1076         gpc |= *p++<<24;
1077         gpd = *p++<<16;
1078         gpd |= *p<<24;
1079
1080         csr32w(ctlr, 13, 0);
1081         csr32w(ctlr, 14, csr14);
1082         csr32w(ctlr, 15, gpc|csr15);
1083         delay(10);
1084         csr32w(ctlr, 15, gpd|csr15);
1085         csr32w(ctlr, 13, csr13);
1086
1087         ctlr->csr6 = csr6;
1088         csr32w(ctlr, 6, ctlr->csr6);
1089
1090         debug("type2mode: csr13 %8.8uX csr14 %8.8uX csr15 %8.8uX\n",
1091                 csr13, csr14, csr15);
1092         debug("type2mode: gpc %8.8uX gpd %8.8uX csr6 %8.8uX\n",
1093                 gpc, gpd, csr6);
1094
1095         return 0;
1096 }
1097
1098 static int
1099 type0link(Ctlr* ctlr, uchar* block)
1100 {
1101         int m, polarity, sense;
1102
1103         m = (block[3]<<8)|block[2];
1104         sense = 1<<((m & 0x000E)>>1);
1105         if(m & 0x0080)
1106                 polarity = sense;
1107         else
1108                 polarity = 0;
1109
1110         return (csr32r(ctlr, 12) & sense)^polarity;
1111 }
1112
1113 static int
1114 type0mode(Ctlr* ctlr, uchar* block, int wait)
1115 {
1116         int csr6, m, timeo;
1117
1118         csr6 = Sc|Mbo|Hbd|Ca|Sb|TrMODE;
1119 debug("type0: medium 0x%uX, fd %d: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
1120     ctlr->medium, ctlr->fd, block[0], block[1], block[2], block[3]); 
1121         switch(block[0]){
1122         default:
1123                 break;
1124
1125         case 0x04:                      /* 10BASE-TFD */
1126         case 0x05:                      /* 100BASE-TXFD */
1127         case 0x08:                      /* 100BASE-FXFD */
1128                 /*
1129                  * Don't attempt full-duplex
1130                  * unless explicitly requested.
1131                  */
1132                 if(!ctlr->fd)
1133                         return -1;
1134                 csr6 |= Fd;
1135                 break;
1136         }
1137
1138         m = (block[3]<<8)|block[2];
1139         if(m & 0x0001)
1140                 csr6 |= Ps;
1141         if(m & 0x0010)
1142                 csr6 |= Ttm;
1143         if(m & 0x0020)
1144                 csr6 |= Pcs;
1145         if(m & 0x0040)
1146                 csr6 |= Scr;
1147
1148         csr32w(ctlr, 12, block[1]);
1149         microdelay(10);
1150         csr32w(ctlr, 6, csr6);
1151         ctlr->csr6 = csr6;
1152
1153         if(!wait)
1154                 return 0;
1155
1156         for(timeo = 0; timeo < 30; timeo++){
1157                 if(type0link(ctlr, block))
1158                         return 0;
1159                 delay(100);
1160         }
1161
1162         return -1;
1163 }
1164
1165 static int
1166 mediaxx(Ether* ether, int wait)
1167 {
1168         Ctlr* ctlr;
1169         uchar *block;
1170
1171         ctlr = ether->ctlr;
1172         block = ctlr->infoblock[ctlr->curk];
1173         if(block[0] & 0x80){
1174                 switch(block[1]){
1175                 default:
1176                         return -1;
1177                 case 0:
1178                         if(ctlr->medium >= 0 && block[2] != ctlr->medium)
1179                                 return 0;
1180 /* need this test? */   if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[2])
1181                                 return 0;
1182                         if(type0mode(ctlr, block+2, wait))
1183                                 return 0;
1184                         break;
1185                 case 1:
1186                         if(typephymode(ctlr, block, wait))
1187                                 return 0;
1188                         break;
1189                 case 2:
1190                         debug("type2: medium %d block[2] %d\n",
1191                                 ctlr->medium, block[2]);
1192                         if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
1193                                 return 0;
1194                         if(type2mode(ctlr, block, wait))
1195                                 return 0;
1196                         break;
1197                 case 3:
1198                         if(typephymode(ctlr, block, wait))
1199                                 return 0;
1200                         break;
1201                 case 4:
1202                         debug("type4: medium %d block[2] %d\n",
1203                                 ctlr->medium, block[2]);
1204                         if(ctlr->medium >= 0 && ((block[2] & 0x3F) != ctlr->medium))
1205                                 return 0;
1206                         if(typesymmode(ctlr, block, wait))
1207                                 return 0;
1208                         break;
1209                 }
1210         }
1211         else{
1212                 if(ctlr->medium >= 0 && block[0] != ctlr->medium)
1213                         return 0;
1214 /* need this test? */if(ctlr->sct != 0x0800 && (ctlr->sct & 0x3F) != block[0])
1215                         return 0;
1216                 if(type0mode(ctlr, block, wait))
1217                         return 0;
1218         }
1219
1220         if(ctlr->csr6){
1221                 if(!(ctlr->csr6 & Ps) || (ctlr->csr6 & Ttm))
1222                         return 10;
1223                 return 100;
1224         }
1225
1226         return 0;
1227 }
1228
1229 static int
1230 media(Ether* ether, int wait)
1231 {
1232         Ctlr* ctlr;
1233         int k, mbps;
1234
1235         ctlr = ether->ctlr;
1236         for(k = 0; k < ctlr->k; k++){
1237                 mbps = mediaxx(ether, wait);
1238                 if(mbps > 0)
1239                         return mbps;
1240                 if(ctlr->curk == 0)
1241                         ctlr->curk = ctlr->k-1;
1242                 else
1243                         ctlr->curk--;
1244         }
1245
1246         return 0;
1247 }
1248
1249 static char* mediatable[9] = {
1250         "10BASE-T",                             /* TP */
1251         "10BASE-2",                             /* BNC */
1252         "10BASE-5",                             /* AUI */
1253         "100BASE-TX",
1254         "10BASE-TFD",
1255         "100BASE-TXFD",
1256         "100BASE-T4",
1257         "100BASE-FX",
1258         "100BASE-FXFD",
1259 };
1260
1261 static uchar en1207[] = {               /* Accton EN1207-COMBO */
1262         0x00, 0x00, 0xE8,               /* [0]  vendor ethernet code */
1263         0x00,                           /* [3]  spare */
1264
1265         0x00, 0x08,                     /* [4]  connection (LSB+MSB = 0x0800) */
1266         0x1F,                           /* [6]  general purpose control */
1267         2,                              /* [7]  block count */
1268
1269         0x00,                           /* [8]  media code (10BASE-TX) */
1270         0x0B,                           /* [9]  general purpose port data */
1271         0x9E, 0x00,                     /* [10] command (LSB+MSB = 0x009E) */
1272
1273         0x03,                           /* [8]  media code (100BASE-TX) */
1274         0x1B,                           /* [9]  general purpose port data */
1275         0x6D, 0x00,                     /* [10] command (LSB+MSB = 0x006D) */
1276
1277                                         /* There is 10BASE-2 as well, but... */
1278 };
1279
1280 static uchar ana6910fx[] = {            /* Adaptec (Cogent) ANA-6910FX */
1281         0x00, 0x00, 0x92,               /* [0]  vendor ethernet code */
1282         0x00,                           /* [3]  spare */
1283
1284         0x00, 0x08,                     /* [4]  connection (LSB+MSB = 0x0800) */
1285         0x3F,                           /* [6]  general purpose control */
1286         1,                              /* [7]  block count */
1287
1288         0x07,                           /* [8]  media code (100BASE-FX) */
1289         0x03,                           /* [9]  general purpose port data */
1290         0x2D, 0x00                      /* [10] command (LSB+MSB = 0x000D) */
1291 };
1292
1293 static uchar smc9332[] = {              /* SMC 9332 */
1294         0x00, 0x00, 0xC0,               /* [0]  vendor ethernet code */
1295         0x00,                           /* [3]  spare */
1296
1297         0x00, 0x08,                     /* [4]  connection (LSB+MSB = 0x0800) */
1298         0x1F,                           /* [6]  general purpose control */
1299         2,                              /* [7]  block count */
1300
1301         0x00,                           /* [8]  media code (10BASE-TX) */
1302         0x00,                           /* [9]  general purpose port data */
1303         0x9E, 0x00,                     /* [10] command (LSB+MSB = 0x009E) */
1304
1305         0x03,                           /* [8]  media code (100BASE-TX) */
1306         0x09,                           /* [9]  general purpose port data */
1307         0x6D, 0x00,                     /* [10] command (LSB+MSB = 0x006D) */
1308 };
1309
1310 static uchar* leaf21140[] = {
1311         en1207,                         /* Accton EN1207-COMBO */
1312         ana6910fx,                      /* Adaptec (Cogent) ANA-6910FX */
1313         smc9332,                        /* SMC 9332 */
1314         nil,
1315 };
1316
1317 /*
1318  * Copied to ctlr->srom at offset 20.
1319  */
1320 static uchar leafpnic[] = {
1321         0x00, 0x00, 0x00, 0x00,         /* MAC address */
1322         0x00, 0x00,
1323         0x00,                           /* controller 0 device number */
1324         0x1E, 0x00,                     /* controller 0 info leaf offset */
1325         0x00,                           /* reserved */
1326         0x00, 0x08,                     /* selected connection type */
1327         0x00,                           /* general purpose control */
1328         0x01,                           /* block count */
1329
1330         0x8C,                           /* format indicator and count */
1331         0x01,                           /* block type */
1332         0x00,                           /* PHY number */
1333         0x00,                           /* GPR sequence length */
1334         0x00,                           /* reset sequence length */
1335         0x00, 0x78,                     /* media capabilities */
1336         0xE0, 0x01,                     /* Nway advertisment */
1337         0x00, 0x50,                     /* FDX bitmap */
1338         0x00, 0x18,                     /* TTM bitmap */
1339 };
1340
1341 static int
1342 srom(Ctlr* ctlr)
1343 {
1344         int i, k, oui, phy, x;
1345         uchar *p;
1346
1347         /*
1348          * This is a partial decoding of the SROM format described in
1349          * 'Digital Semiconductor 21X4 Serial ROM Format, Version 4.05,
1350          * 2-Mar-98'. Only the 2114[03] are handled, support for other
1351          * controllers can be added as needed.
1352          * Do a dummy read first to get the size and allocate ctlr->srom.
1353          */
1354         sromr(ctlr, 0);
1355         if(ctlr->srom == nil)
1356                 ctlr->srom = malloc((1<<ctlr->sromsz)*sizeof(ushort));
1357         for(i = 0; i < (1<<ctlr->sromsz); i++){
1358                 x = sromr(ctlr, i);
1359                 ctlr->srom[2*i] = x;
1360                 ctlr->srom[2*i+1] = x>>8;
1361         }
1362
1363         /*
1364          * There are 2 SROM layouts:
1365          *      e.g. Digital EtherWORKS station address at offset 20;
1366          *                              this complies with the 21140A SROM
1367          *                              application note from Digital;
1368          *      e.g. SMC9332            station address at offset 0 followed by
1369          *                              2 additional bytes, repeated at offset
1370          *                              6; the 8 bytes are also repeated in
1371          *                              reverse order at offset 8.
1372          * To check which it is, read the SROM and check for the repeating
1373          * patterns of the non-compliant cards; if that fails use the one at
1374          * offset 20.
1375          */
1376         ctlr->sromea = ctlr->srom;
1377         for(i = 0; i < 8; i++){
1378                 x = ctlr->srom[i];
1379                 if(x != ctlr->srom[15-i] || x != ctlr->srom[16+i]){
1380                         ctlr->sromea = &ctlr->srom[20];
1381                         break;
1382                 }
1383         }
1384
1385         /*
1386          * Fake up the SROM for the PNIC.
1387          * It looks like a 21140 with a PHY.
1388          * The MAC address is byte-swapped in the orginal SROM data.
1389          */
1390         if(ctlr->id == Pnic){
1391                 memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
1392                 for(i = 0; i < Eaddrlen; i += 2){
1393                         ctlr->srom[20+i] = ctlr->srom[i+1];
1394                         ctlr->srom[20+i+1] = ctlr->srom[i];
1395                 }
1396         }
1397
1398         /*
1399          * Next, try to find the info leaf in the SROM for media detection.
1400          * If it's a non-conforming card try to match the vendor ethernet code
1401          * and point p at a fake info leaf with compact 21140 entries.
1402          */
1403         if(ctlr->sromea == ctlr->srom){
1404                 p = nil;
1405                 for(i = 0; leaf21140[i] != nil; i++){
1406                         if(memcmp(leaf21140[i], ctlr->sromea, 3) == 0){
1407                                 p = &leaf21140[i][4];
1408                                 break;
1409                         }
1410                 }
1411                 if(p == nil)
1412                         return -1;
1413         }
1414         else
1415                 p = &ctlr->srom[(ctlr->srom[28]<<8)|ctlr->srom[27]];
1416
1417         /*
1418          * Set up the info needed for later media detection.
1419          * For the 21140, set the general-purpose mask in CSR12.
1420          * The info block entries are stored in order of increasing
1421          * precedence, so detection will work backwards through the
1422          * stored indexes into ctlr->srom.
1423          * If an entry is found which matches the selected connection
1424          * type, save the index. Otherwise, start at the last entry.
1425          * If any MII entries are found (type 1 and 3 blocks), scan
1426          * for PHYs.
1427          */
1428         ctlr->leaf = p;
1429         ctlr->sct = *p++;
1430         ctlr->sct |= *p++<<8;
1431         if(ctlr->id != Tulip3){
1432                 csr32w(ctlr, 12, Gpc|*p++);
1433                 delay(200);
1434         }
1435         ctlr->k = *p++;
1436         if(ctlr->k >= nelem(ctlr->infoblock))
1437                 ctlr->k = nelem(ctlr->infoblock)-1;
1438         ctlr->sctk = ctlr->k-1;
1439         phy = 0;
1440         for(k = 0; k < ctlr->k; k++){
1441                 ctlr->infoblock[k] = p;
1442                 /*
1443                  * The RAMIX PMC665 has a badly-coded SROM,
1444                  * hence the test for 21143 and type 3.
1445                  */
1446                 if((*p & 0x80) || (ctlr->id == Tulip3 && *(p+1) == 3)){
1447                         *p |= 0x80;
1448                         if(*(p+1) == 1 || *(p+1) == 3)
1449                                 phy = 1;
1450                         if(*(p+1) == 5)
1451                                 ctlr->type5block = p;
1452                         p += (*p & ~0x80)+1;
1453                 }
1454                 else{
1455                         debug("type0: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
1456                                 p[0], p[1], p[2], p[3]); 
1457                         if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF))
1458                                 ctlr->sctk = k;
1459                         p += 4;
1460                 }
1461         }
1462         ctlr->curk = ctlr->sctk;
1463         debug("sct 0x%uX medium 0x%uX k %d curk %d phy %d\n",
1464                 ctlr->sct, ctlr->medium, ctlr->k, ctlr->curk, phy);
1465
1466         if(phy){
1467                 x = 0;
1468                 for(k = 0; k < nelem(ctlr->phy); k++){
1469                         if((oui = miir(ctlr, k, 2)) == -1 || oui == 0)
1470                                 continue;
1471                         if(DEBUG){
1472                                 oui = (oui & 0x3FF)<<6;
1473                                 oui |= miir(ctlr, k, 3)>>10;
1474                                 miir(ctlr, k, 1);
1475                                 debug("phy%d: index %d oui %uX reg1 %uX\n",
1476                                         x, k, oui, miir(ctlr, k, 1));
1477                                 USED(oui);
1478                         }
1479                         ctlr->phy[x] = k;
1480                 }
1481         }
1482
1483         ctlr->fd = 0;
1484         ctlr->medium = -1;
1485
1486         return 0;
1487 }
1488
1489 static void
1490 dec2114xpci(void)
1491 {
1492         Ctlr *ctlr;
1493         Pcidev *p;
1494         int x;
1495
1496         p = nil;
1497         while(p = pcimatch(p, 0, 0)){
1498                 if(p->ccrb != 0x02 || p->ccru != 0)
1499                         continue;
1500                 switch((p->did<<16)|p->vid){
1501                 default:
1502                         continue;
1503
1504                 case Tulip3:                    /* 21143 */
1505                         /*
1506                          * Exit sleep mode.
1507                          */
1508                         x = pcicfgr32(p, 0x40);
1509                         x &= ~0xc0000000;
1510                         pcicfgw32(p, 0x40, x);
1511                         /*FALLTHROUGH*/
1512
1513                 case Pnic:                      /* PNIC */
1514                 case Pnic2:                     /* PNIC-II */
1515                 case Tulip0:                    /* 21140 */
1516                         break;
1517                 }
1518
1519                 /*
1520                  * bar[0] is the I/O port register address and
1521                  * bar[1] is the memory-mapped register address.
1522                  */
1523                 ctlr = malloc(sizeof(Ctlr));
1524                 ctlr->port = p->mem[0].bar & ~0x01;
1525                 ctlr->pcidev = p;
1526                 ctlr->id = (p->did<<16)|p->vid;
1527
1528                 if(ioalloc(ctlr->port, p->mem[0].size, 0, "dec2114x") < 0){
1529                         print("dec2114x: port 0x%uX in use\n", ctlr->port);
1530                         free(ctlr);
1531                         continue;
1532                 }
1533
1534                 /*
1535                  * Some cards (e.g. ANA-6910FX) seem to need the Ps bit
1536                  * set or they don't always work right after a hardware
1537                  * reset.
1538                  */
1539                 csr32w(ctlr, 6, Mbo|Ps);
1540                 softreset(ctlr);
1541
1542                 if(srom(ctlr)){
1543                         iofree(ctlr->port);
1544                         free(ctlr);
1545                         continue;
1546                 }
1547
1548                 switch(ctlr->id){
1549                 default:
1550                         break;
1551
1552                 case Pnic:                      /* PNIC */
1553                         /*
1554                          * Turn off the jabber timer.
1555                          */
1556                         csr32w(ctlr, 15, 0x00000001);
1557                         break;
1558                 }
1559
1560                 if(ctlrhead != nil)
1561                         ctlrtail->next = ctlr;
1562                 else
1563                         ctlrhead = ctlr;
1564                 ctlrtail = ctlr;
1565         }
1566 }
1567
1568 static int
1569 reset(Ether* ether)
1570 {
1571         Ctlr *ctlr;
1572         int i, x;
1573         uchar ea[Eaddrlen];
1574         static int scandone;
1575
1576         if(scandone == 0){
1577                 dec2114xpci();
1578                 scandone = 1;
1579         }
1580
1581         /*
1582          * Any adapter matches if no ether->port is supplied,
1583          * otherwise the ports must match.
1584          */
1585         for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
1586                 if(ctlr->active)
1587                         continue;
1588                 if(ether->port == 0 || ether->port == ctlr->port){
1589                         ctlr->active = 1;
1590                         break;
1591                 }
1592         }
1593         if(ctlr == nil)
1594                 return -1;
1595
1596         ether->ctlr = ctlr;
1597         ether->port = ctlr->port;
1598 //      ether->irq = ctlr->pcidev->intl;
1599 ether->irq = 2;         /* arrrrrgh */
1600         ether->tbdf = ctlr->pcidev->tbdf;
1601
1602         /*
1603          * Check if the adapter's station address is to be overridden.
1604          * If not, read it from the EEPROM and set in ether->ea prior to
1605          * loading the station address in the hardware.
1606          */
1607         memset(ea, 0, Eaddrlen);
1608         if(memcmp(ea, ether->ea, Eaddrlen) == 0)
1609                 memmove(ether->ea, ctlr->sromea, Eaddrlen);
1610
1611         /*
1612          * Look for a medium override in case there's no autonegotiation
1613          * (no MII) or the autonegotiation fails.
1614          */
1615         for(i = 0; i < ether->nopt; i++){
1616                 if(cistrcmp(ether->opt[i], "FD") == 0){
1617                         ctlr->fd = 1;
1618                         continue;
1619                 }
1620                 for(x = 0; x < nelem(mediatable); x++){
1621                         debug("compare <%s> <%s>\n", mediatable[x],
1622                                 ether->opt[i]);
1623                         if(cistrcmp(mediatable[x], ether->opt[i]))
1624                                 continue;
1625                         ctlr->medium = x;
1626         
1627                         switch(ctlr->medium){
1628                         default:
1629                                 ctlr->fd = 0;
1630                                 break;
1631         
1632                         case 0x04:              /* 10BASE-TFD */
1633                         case 0x05:              /* 100BASE-TXFD */
1634                         case 0x08:              /* 100BASE-FXFD */
1635                                 ctlr->fd = 1;
1636                                 break;
1637                         }
1638                         break;
1639                 }
1640         }
1641
1642         ether->mbps = media(ether, 1);
1643
1644         /*
1645          * Initialise descriptor rings, ethernet address.
1646          */
1647         ctlr->nrdr = Nrde;
1648         ctlr->ntdr = Ntde;
1649         pcisetbme(ctlr->pcidev);
1650         ctlrinit(ether);
1651
1652         /*
1653          * Linkage to the generic ethernet driver.
1654          */
1655         ether->attach = attach;
1656         ether->transmit = transmit;
1657         ether->interrupt = interrupt;
1658         ether->ifstat = ifstat;
1659
1660         ether->arg = ether;
1661         ether->promiscuous = promiscuous;
1662
1663         return 0;
1664 }
1665
1666 void
1667 ether2114xlink(void)
1668 {
1669         addethercard("21140",  reset);
1670         addethercard("2114x",  reset);
1671 }