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