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