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/pc/etherec2t.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  * Supposed NE2000 PCMCIA clones, see the comments in ether2000.c
    3  */
    4 #include "u.h"
    5 #include "../port/lib.h"
    6 #include "mem.h"
    7 #include "dat.h"
    8 #include "fns.h"
    9 #include "io.h"
   10 #include "../port/error.h"
   11 #include "../port/netif.h"
   12 
   13 #include "etherif.h"
   14 #include "ether8390.h"
   15 
   16 enum {
   17         Data            = 0x10,         /* offset from I/O base of data port */
   18         Reset           = 0x1F,         /* offset from I/O base of reset port */
   19 };
   20 
   21 typedef struct Ec2t {
   22         char*   name;
   23         int     iochecksum;
   24 } Ec2t;
   25 
   26 static Ec2t ec2tpcmcia[] = {
   27         { "EC2T", 0, },                 /* Linksys Combo PCMCIA EthernetCard */
   28         { "PCMPC100", 1, },             /* EtherFast 10/100 PC Card */
   29         { "PCM100", 1, },               /* EtherFast PCM100 Card */
   30         { "EN2216", 0, },               /* Accton EtherPair-PCMCIA */
   31         { "FA410TX", 1, },              /* Netgear FA410TX */
   32         { "Network Everywhere", 0, },   /* Linksys NP10T 10BaseT Card */
   33         { "10/100 Port Attached", 1, }, /* SMC 8040TX */
   34         { "8041TX-10/100-PC-Card-V2", 0 }, /* SMC 8041TX */
   35         { "FA411", 0 },                 /* Netgear FA411 PCMCIA */
   36         { nil, 0, },
   37 };
   38 
   39 static int
   40 reset(Ether* ether)
   41 {
   42         ushort buf[16];
   43         ulong port;
   44         Dp8390 *ctlr;
   45         int i, slot;
   46         uchar ea[Eaddrlen], sum, x;
   47         Ec2t *ec2t, tmpec2t;
   48 
   49         /*
   50          * Set up the software configuration.
   51          * Use defaults for port, irq, mem and size
   52          * if not specified.
   53          * The manual says 16KB memory, the box
   54          * says 32KB. The manual seems to be correct.
   55          */
   56         if(ether->port == 0)
   57                 ether->port = 0x300;
   58         if(ether->irq == 0)
   59                 ether->irq = 9;
   60         if(ether->mem == 0)
   61                 ether->mem = 0x4000;
   62         if(ether->size == 0)
   63                 ether->size = 16*1024;
   64         port = ether->port;
   65 
   66         if(ioalloc(ether->port, 0x20, 0, "ec2t") < 0)
   67                 return -1;
   68         slot = -1;
   69         for(ec2t = ec2tpcmcia; ec2t->name != nil; ec2t++){
   70                 if((slot = pcmspecial(ec2t->name, ether)) >= 0)
   71                         break;
   72         }
   73         if(ec2t->name == nil){
   74                 ec2t = &tmpec2t;
   75                 ec2t->name = nil;
   76                 ec2t->iochecksum = 0;
   77                 for(i = 0; i < ether->nopt; i++){
   78                         if(cistrncmp(ether->opt[i], "id=", 3) == 0){
   79                                 ec2t->name = &ether->opt[i][3];
   80                                 slot = pcmspecial(ec2t->name, ether);
   81                         }
   82                         else if(cistrncmp(ether->opt[i], "iochecksum", 10) == 0)
   83                                 ec2t->iochecksum = 1;
   84                 }
   85         }
   86         if(slot < 0){
   87                 iofree(port);
   88                 return -1;
   89         }
   90 
   91         ether->ctlr = malloc(sizeof(Dp8390));
   92         ctlr = ether->ctlr;
   93         ctlr->width = 2;
   94         ctlr->ram = 0;
   95 
   96         ctlr->port = port;
   97         ctlr->data = port+Data;
   98 
   99         ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz);
  100         ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
  101         ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz);
  102 
  103         ctlr->dummyrr = 0;
  104         for(i = 0; i < ether->nopt; i++){
  105                 if(cistrcmp(ether->opt[i], "nodummyrr") == 0)
  106                         ctlr->dummyrr = 0;
  107                 else if(cistrncmp(ether->opt[i], "dummyrr=", 8) == 0)
  108                         ctlr->dummyrr = strtol(&ether->opt[i][8], nil, 0);
  109         }
  110 
  111         /*
  112          * Reset the board. This is done by doing a read
  113          * followed by a write to the Reset address.
  114          */
  115         buf[0] = inb(port+Reset);
  116         delay(2);
  117         outb(port+Reset, buf[0]);
  118         delay(2);
  119 
  120         /*
  121          * Init the (possible) chip, then use the (possible)
  122          * chip to read the (possible) PROM for ethernet address
  123          * and a marker byte.
  124          * Could just look at the DP8390 command register after
  125          * initialisation has been tried, but that wouldn't be
  126          * enough, there are other ethernet boards which could
  127          * match.
  128          */
  129         dp8390reset(ether);
  130         sum = 0;
  131         if(ec2t->iochecksum){
  132                 /*
  133                  * These cards have the ethernet address in I/O space.
  134                  * There's a checksum over 8 bytes which sums to 0xFF.
  135                  */
  136                 for(i = 0; i < 8; i++){
  137                         x = inb(port+0x14+i);
  138                         sum += x;
  139                         buf[i] = (x<<8)|x;
  140                 }
  141         }
  142         else{
  143                 memset(buf, 0, sizeof(buf));
  144                 dp8390read(ctlr, buf, 0, sizeof(buf));
  145                 if((buf[0x0E] & 0xFF) == 0x57 && (buf[0x0F] & 0xFF) == 0x57)
  146                         sum = 0xFF;
  147         }
  148         if(sum != 0xFF){
  149                 pcmspecialclose(slot);
  150                 iofree(ether->port);
  151                 free(ether->ctlr);
  152                 return -1;
  153         }
  154 
  155         /*
  156          * Stupid machine. Shorts were asked for,
  157          * shorts were delivered, although the PROM is a byte array.
  158          * Set the ethernet address.
  159          */
  160         memset(ea, 0, Eaddrlen);
  161         if(memcmp(ea, ether->ea, Eaddrlen) == 0){
  162                 for(i = 0; i < sizeof(ether->ea); i++)
  163                         ether->ea[i] = buf[i];
  164         }
  165         dp8390setea(ether);
  166 
  167         return 0;
  168 }
  169 
  170 void
  171 etherec2tlink(void)
  172 {
  173         addethercard("EC2T", reset);
  174 }

Cache object: 24c285b40fb1059672be92e30a013215


[ 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.