The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mtx/ether2114x.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6cd660335a930a63bc9d72712878cb47


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.