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/etherwavelan.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 /* Pci/pcmcia code for wavelan.c */
    2 
    3 #include "u.h"
    4 #include "../port/lib.h"
    5 #include "mem.h"
    6 #include "dat.h"
    7 #include "fns.h"
    8 #include "io.h"
    9 #include "../port/error.h"
   10 #include "../port/netif.h"
   11 #include "etherif.h"
   12 
   13 #include "wavelan.h"
   14 
   15 static int
   16 wavelanpcmciareset(Ether *ether)
   17 {
   18         int i;
   19         char *p;
   20         Ctlr *ctlr;
   21 
   22         if((ctlr = malloc(sizeof(Ctlr))) == nil)
   23                 return -1;
   24 
   25         ilock(ctlr);
   26         ctlr->ctlrno = ether->ctlrno;
   27 
   28         if (ether->port==0)
   29                 ether->port=WDfltIOB;
   30         ctlr->iob = ether->port;
   31 
   32         if (ether->irq==0)
   33                 ether->irq=WDfltIRQ;
   34 
   35         if (ioalloc(ether->port,WIOLen,0,"wavelan")<0){
   36         //      print("#l%d: port 0x%lx in use\n",
   37         //                      ether->ctlrno, ether->port);
   38                 goto abort1;
   39         }
   40 
   41         /*
   42          * If id= is specified, card must match.  Otherwise try generic.
   43          */
   44         ctlr->slot = -1;
   45         for(i=0; i<ether->nopt; i++){
   46                 if(cistrncmp(ether->opt[i], "id=", 3) == 0){
   47                         if((ctlr->slot = pcmspecial(&ether->opt[i][3], ether)) < 0)
   48                                 goto abort;
   49                         break;
   50                 }
   51         }
   52         if(ctlr->slot == -1){
   53                 for (i=0; wavenames[i]; i++)
   54                         if((ctlr->slot = pcmspecial(wavenames[i], ether))>=0)
   55                                 break;
   56                 if(!wavenames[i]){
   57                         DEBUG("no wavelan found\n");
   58                         goto abort;
   59                 }
   60         }
   61 
   62         // DEBUG("#l%d: port=0x%lx irq=%ld\n",
   63         //              ether->ctlrno, ether->port, ether->irq);
   64 
   65         if(wavelanreset(ether, ctlr) < 0){
   66         abort:
   67                 iofree(ether->port);
   68         abort1:
   69                 iunlock(ctlr);
   70                 free(ctlr);
   71                 ether->ctlr = nil;
   72                 return -1;
   73         }
   74 
   75         for(i = 0; i < ether->nopt; i++){
   76                 if(p = strchr(ether->opt[i], '='))
   77                         *p = ' ';
   78                 w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
   79         }
   80 
   81         iunlock(ctlr);
   82         return 0;
   83 }
   84 
   85 static struct {
   86         int vid;
   87         int did;
   88 } wavelanpci[] = {
   89         0x1260, 0x3873, /* Intersil Prism2.5 */
   90         0x1737, 0x0019, /* Linksys WPC-11 untested */
   91 };
   92 
   93 static Ctlr *ctlrhead, *ctlrtail;
   94 
   95 static void
   96 wavelanpciscan(void)
   97 {
   98         int i;
   99         void *mem;
  100         Pcidev *p;
  101         Ctlr *ctlr;
  102 
  103         p = nil;
  104         while(p = pcimatch(p, 0, 0)){
  105                 for(i=0; i<nelem(wavelanpci); i++)
  106                         if(p->vid == wavelanpci[i].vid && p->did == wavelanpci[i].did)
  107                                 break;
  108                 if(i==nelem(wavelanpci))
  109                         continue;
  110 
  111                 /*
  112                  * On the Prism, bar[0] is the memory-mapped register address (4KB),
  113                  */
  114                 if(p->mem[0].size != 4096){
  115                         print("wavelanpci: %.4ux %.4ux: unlikely mmio size\n", p->vid, p->did);
  116                         continue;
  117                 }
  118 
  119                 ctlr = malloc(sizeof(Ctlr));
  120                 ctlr->pcidev = p;
  121                 mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
  122                 if(mem == nil){
  123                         print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
  124                         free(ctlr);
  125                         continue;
  126                 }
  127                 ctlr->mmb = mem;
  128                 if(ctlrhead != nil)
  129                         ctlrtail->next = ctlr;
  130                 else
  131                         ctlrhead = ctlr;
  132                 ctlrtail = ctlr;
  133                 pcisetbme(p);
  134         }
  135 }
  136 
  137 static int
  138 wavelanpcireset(Ether *ether)
  139 {
  140         int i;
  141         char *p;
  142         Ctlr *ctlr;
  143 
  144         if(ctlrhead == nil)
  145                 wavelanpciscan();
  146 
  147         /*
  148          * Allow plan9.ini to set vid, did?
  149          */
  150         for(ctlr=ctlrhead; ctlr!=nil; ctlr=ctlr->next)
  151                 if(ctlr->active == 0)
  152                         break;
  153         if(ctlr == nil)
  154                 return -1;
  155 
  156         ctlr->active = 1;
  157         ilock(ctlr);
  158         ether->irq = ctlr->pcidev->intl;
  159         ether->tbdf = ctlr->pcidev->tbdf;
  160 
  161         /*
  162          * Really hard reset.
  163          */
  164         csr_outs(ctlr, WR_PciCor, 0x0080);
  165         delay(250);
  166         csr_outs(ctlr, WR_PciCor, 0x0000);
  167         delay(500);
  168         for(i=0; i<2*10; i++){
  169                 if(!(csr_ins(ctlr, WR_Cmd)&WCmdBusy))
  170                         break;
  171                 delay(100);
  172         }
  173         if(i >= 2*10)
  174                 print("wavelan pci %.4ux %.4ux: reset timeout %.4ux\n",
  175                         ctlr->pcidev->vid, ctlr->pcidev->did, csr_ins(ctlr, WR_Cmd));
  176 
  177         if(wavelanreset(ether, ctlr) < 0){
  178                 iunlock(ctlr);
  179                 ether->ctlr = nil;
  180                 return -1;
  181         }
  182 
  183         for(i = 0; i < ether->nopt; i++){
  184                 if(p = strchr(ether->opt[i], '='))
  185                         *p = ' ';
  186                 w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
  187         }
  188         iunlock(ctlr);
  189         return 0;
  190 }
  191         
  192 void
  193 etherwavelanlink(void)
  194 {
  195         addethercard("wavelan", wavelanpcmciareset);
  196         addethercard("wavelanpci", wavelanpcireset);
  197 }

Cache object: ed7be3037e18cadb1a637723baa9d72f


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