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/drivers/dpeth/wd.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 **  File:       wd.c
    3 **
    4 **  Driver for the Ethercard (WD80x3) and derivates
    5 **  This file contains only the wd80x3 specific code,
    6 **  the rest is in 8390.c
    7 **
    8 **  Created:    March 14, 1994 by Philip Homburg
    9 **  PchId:
   10 **
   11 **  Modified: Jun. 08, 2000 by Giovanni Falzoni <gfalzoni@inwind.it>
   12 **      Adaptation to interfacing new main network task.
   13 **
   14 **  $Id: wd.c,v 1.4 2005/08/22 15:17:40 beng Exp $
   15 */
   16 
   17 #include "drivers.h"
   18 #include <net/gen/ether.h>
   19 #include <net/gen/eth_io.h>
   20 #include "dp.h"
   21 
   22 #if (ENABLE_WDETH == 1)
   23 
   24 #include "8390.h"
   25 #include "wd.h"
   26 
   27 #define WET_ETHERNET    0x01    /* Ethernet transceiver */
   28 #define WET_STARLAN     0x02    /* Starlan transceiver */
   29 #define WET_INTERF_CHIP 0x04    /* has a WD83C583 interface chip */
   30 #define WET_BRD_16BIT   0x08    /* 16 bit board */
   31 #define WET_SLT_16BIT   0x10    /* 16 bit slot */
   32 #define WET_790         0x20    /* '790 chip */
   33 
   34 static const int we_int_table[8] = {9, 3, 5, 7, 10, 11, 15, 4};
   35 static const int we_790int_table[8] = {0, 9, 3, 5, 7, 10, 11, 15};
   36 
   37 _PROTOTYPE(static void we_init, (dpeth_t * dep));
   38 _PROTOTYPE(static void we_stop, (dpeth_t * dep));
   39 _PROTOTYPE(static int we_aliasing, (dpeth_t * dep));
   40 _PROTOTYPE(static int we_interface_chip, (dpeth_t * dep));
   41 _PROTOTYPE(static int we_16bitboard, (dpeth_t * dep));
   42 _PROTOTYPE(static int we_16bitslot, (dpeth_t * dep));
   43 _PROTOTYPE(static int we_ultra, (dpeth_t * dep));
   44 
   45 /*===========================================================================*
   46  *                              wdeth_probe                                  *
   47  *===========================================================================*/
   48 int wdeth_probe(dep)
   49 dpeth_t *dep;
   50 {
   51   int sum;
   52 
   53   if (dep->de_linmem == 0)
   54         return FALSE;           /* No shared memory, so no WD board */
   55 
   56   sum = inb_we(dep, EPL_EA0) + inb_we(dep, EPL_EA1) +
   57         inb_we(dep, EPL_EA2) + inb_we(dep, EPL_EA3) +
   58         inb_we(dep, EPL_EA4) + inb_we(dep, EPL_EA5) +
   59         inb_we(dep, EPL_TLB) + inb_we(dep, EPL_CHKSUM);
   60   if ((sum & 0xFF) != 0xFF)
   61         return FALSE;           /* No ethernet board at this address */
   62 
   63   dep->de_initf = we_init;
   64   dep->de_stopf = we_stop;
   65   dep->de_prog_IO = 0;
   66   return TRUE;
   67 }
   68 
   69 /*===========================================================================*
   70  *                              we_init                                      *
   71  *===========================================================================*/
   72 static void we_init(dep)
   73 dpeth_t *dep;
   74 {
   75   int i, int_indx, int_nr;
   76   int tlb, rambit, revision;
   77   int icr, irr, hwr, b, gcr;
   78   int we_type;
   79   int sendq_nr;
   80 
   81   for (i = 0; i < 6; i += 1) {
   82         dep->de_address.ea_addr[i] = inb_we(dep, EPL_EA0 + i);
   83   }
   84 
   85   dep->de_dp8390_port = dep->de_base_port + EPL_DP8390;
   86 
   87   dep->de_16bit = 0;
   88 
   89   we_type = 0;
   90   we_type |= WET_ETHERNET;      /* assume ethernet */
   91   if (we_ultra(dep)) we_type |= WET_790;
   92   if (!we_aliasing(dep)) {
   93         if (we_interface_chip(dep)) we_type |= WET_INTERF_CHIP;
   94         if (we_16bitboard(dep)) {
   95                 we_type |= WET_BRD_16BIT;
   96                 if (we_16bitslot(dep)) we_type |= WET_SLT_16BIT;
   97         }
   98   }
   99   if (we_type & WET_SLT_16BIT) dep->de_16bit = 1;
  100 
  101   /* Look at the on board ram size. */
  102   tlb = inb_we(dep, EPL_TLB);
  103   revision = tlb & E_TLB_REV;
  104   rambit = tlb & E_TLB_RAM;
  105 
  106   if (dep->de_ramsize != 0) {
  107         /* Size set from boot environment. */
  108   } else if (revision < 2) {
  109         dep->de_ramsize = 0x2000;       /* 8K */
  110         if (we_type & WET_BRD_16BIT)
  111                 dep->de_ramsize = 0x4000;       /* 16K */
  112         else if ((we_type & WET_INTERF_CHIP) &&
  113                  inb_we(dep, EPL_ICR) & E_ICR_MEMBIT) {
  114                 dep->de_ramsize = 0x8000;       /* 32K */
  115         }
  116   } else {
  117         if (we_type & WET_BRD_16BIT) {
  118                 /* 32K or 16K */
  119                 dep->de_ramsize = rambit ? 0x8000 : 0x4000;
  120         } else {
  121                 /* 32K or 8K */
  122                 dep->de_ramsize = rambit ? 0x8000 : 0x2000;
  123         }
  124   }
  125 
  126   if (we_type & WET_790) {
  127         outb_we(dep, EPL_MSR, E_MSR_RESET);
  128         if ((we_type & (WET_BRD_16BIT | WET_SLT_16BIT)) ==
  129             (WET_BRD_16BIT | WET_SLT_16BIT)) {
  130                 outb_we(dep, EPL_LAAR, E_LAAR_LAN16E | E_LAAR_MEM16E);
  131         }
  132   } else if (we_type & WET_BRD_16BIT) {
  133         if (we_type & WET_SLT_16BIT) {
  134                 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
  135                         E_LAAR_LAN16E | E_LAAR_MEM16E);
  136         } else {
  137                 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
  138                         E_LAAR_LAN16E);
  139         }
  140   }
  141   if (we_type & WET_790) {
  142         outb_we(dep, EPL_MSR, E_MSR_MENABLE);
  143         hwr = inb_we(dep, EPL_790_HWR);
  144         outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
  145         b = inb_we(dep, EPL_790_B);
  146         outb_we(dep, EPL_790_B, ((dep->de_linmem >> 13) & 0x0f) |
  147                 ((dep->de_linmem >> 11) & 0x40) | (b & 0xb0));
  148         outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
  149   } else {
  150         outb_we(dep, EPL_MSR, E_MSR_RESET);
  151         outb_we(dep, EPL_MSR, E_MSR_MENABLE |
  152                 ((dep->de_linmem >> 13) & E_MSR_MEMADDR));
  153   }
  154 
  155   if ((we_type & WET_INTERF_CHIP) && !(we_type & WET_790)) {
  156         icr = inb_we(dep, EPL_ICR);
  157         irr = inb_we(dep, EPL_IRR);
  158         int_indx = (icr & E_ICR_IR2) | ((irr & (E_IRR_IR0 | E_IRR_IR1)) >> 5);
  159         int_nr = we_int_table[int_indx];
  160         DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr));
  161         if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr;
  162         outb_we(dep, EPL_IRR, irr | E_IRR_IEN);
  163   }
  164   if (we_type & WET_790) {
  165         hwr = inb_we(dep, EPL_790_HWR);
  166         outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
  167 
  168         gcr = inb_we(dep, EPL_790_GCR);
  169 
  170         outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
  171 
  172         int_indx = ((gcr & E_790_GCR_IR2) >> 4) |
  173                 ((gcr & (E_790_GCR_IR1 | E_790_GCR_IR0)) >> 2);
  174         int_nr = we_790int_table[int_indx];
  175         DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr));
  176         if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr;
  177         icr = inb_we(dep, EPL_790_ICR);
  178         outb_we(dep, EPL_790_ICR, icr | E_790_ICR_EIL);
  179   }
  180 
  181   /* Strip the "default flag." */
  182   dep->de_irq &= ~DEI_DEFAULT;
  183 
  184   dep->de_offset_page = 0;      /* Shared memory starts at 0 */
  185   /* Allocate one send buffer (1.5KB) per 8KB of on board memory.
  186   sendq_nr = dep->de_ramsize / 0x2000;
  187   if (sendq_nr < 1)
  188         sendq_nr = 1;
  189   else if (sendq_nr > SENDQ_NR) */
  190         sendq_nr = SENDQ_NR;
  191   dep->de_sendq_nr = sendq_nr;
  192   for (i = 0; i < sendq_nr; i++) {
  193         dep->de_sendq[i].sq_sendpage = i * SENDQ_PAGES;
  194   }
  195   dep->de_startpage = i * SENDQ_PAGES;
  196   dep->de_stoppage = dep->de_ramsize / DP_PAGESIZE;
  197 
  198   ns_init(dep);                 /* Initialize DP controller */
  199 
  200   printf("%s: WD80%d3 (%dkB RAM) at %X:%d:%lX - ",
  201          dep->de_name,
  202          we_type & WET_BRD_16BIT ? 1 : 0,
  203          dep->de_ramsize / 1024,
  204          dep->de_base_port,
  205          dep->de_irq,
  206          dep->de_linmem);
  207   for (i = 0; i < SA_ADDR_LEN; i += 1)
  208         printf("%02X%c", dep->de_address.ea_addr[i],
  209                i < SA_ADDR_LEN - 1 ? ':' : '\n');
  210 
  211   return;
  212 }
  213 
  214 /*===========================================================================*
  215  *                              we_stop                                      *
  216  *===========================================================================*/
  217 static void we_stop(dep)
  218 dpeth_t *dep;
  219 {
  220 
  221   if (dep->de_16bit) outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_LAN16E);
  222   outb_we(dep, EPL_MSR, E_MSR_RESET);
  223   outb_we(dep, EPL_MSR, 0);
  224   sys_irqdisable(&dep->de_hook);
  225   return;
  226 }
  227 
  228 /*===========================================================================*
  229  *                              we_aliasing                                  *
  230  *===========================================================================*/
  231 static int we_aliasing(dep)
  232 dpeth_t *dep;
  233 {
  234 /* Determine whether wd8003 hardware performs register aliasing. This implies
  235  * an old WD8003E board. */
  236 
  237   if (inb_we(dep, EPL_REG1) != inb_we(dep, EPL_EA1)) return 0;
  238   if (inb_we(dep, EPL_REG2) != inb_we(dep, EPL_EA2)) return 0;
  239   if (inb_we(dep, EPL_REG3) != inb_we(dep, EPL_EA3)) return 0;
  240   if (inb_we(dep, EPL_REG4) != inb_we(dep, EPL_EA4)) return 0;
  241   if (inb_we(dep, EPL_REG7) != inb_we(dep, EPL_CHKSUM)) return 0;
  242   return 1;
  243 }
  244 
  245 /*===========================================================================*
  246  *                              we_interface_chip                            *
  247  *===========================================================================*/
  248 static int we_interface_chip(dep)
  249 dpeth_t *dep;
  250 {
  251 /* Determine if the board has an interface chip. */
  252 
  253   outb_we(dep, EPL_GP2, 0x35);
  254   if (inb_we(dep, EPL_GP2) != 0x35) return 0;
  255   outb_we(dep, EPL_GP2, 0x3A);
  256   if (inb_we(dep, EPL_GP2) != 0x3A) return 0;
  257   return 1;
  258 }
  259 
  260 /*===========================================================================*
  261  *                              we_16bitboard                                *
  262  *===========================================================================*/
  263 static int we_16bitboard(dep)
  264 dpeth_t *dep;
  265 {
  266 /* Determine whether the board is capable of doing 16 bit memory moves.
  267  * If the 16 bit enable bit is unchangable by software we'll assume an
  268  * 8 bit board.
  269  */
  270   int icr;
  271   u8_t tlb;
  272 
  273   icr = inb_we(dep, EPL_ICR);
  274 
  275   outb_we(dep, EPL_ICR, icr ^ E_ICR_16BIT);
  276   if (inb_we(dep, EPL_ICR) == icr) {
  277         tlb = inb_we(dep, EPL_TLB);
  278 
  279         DEBUG(printf("%s: tlb= 0x%x\n", dep->de_name, tlb));
  280 
  281         return tlb == E_TLB_EB || tlb == E_TLB_E ||
  282                 tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216C;
  283   }
  284   outb_we(dep, EPL_ICR, icr);
  285   return 1;
  286 }
  287 
  288 /*===========================================================================*
  289  *                              we_16bitslot                                 *
  290  *===========================================================================*/
  291 static int we_16bitslot(dep)
  292 dpeth_t *dep;
  293 {
  294 /* Determine if the 16 bit board in plugged into a 16 bit slot.  */
  295 
  296   return !!(inb_we(dep, EPL_ICR) & E_ICR_16BIT);
  297 }
  298 
  299 /*===========================================================================*
  300  *                              we_ultra                                     *
  301  *===========================================================================*/
  302 static int we_ultra(dep)
  303 dpeth_t *dep;
  304 {
  305 /* Determine if we has an '790 chip.  */
  306   u8_t tlb;
  307 
  308   tlb = inb_we(dep, EPL_TLB);
  309   return tlb == E_TLB_SMC8216C;
  310 }
  311 
  312 #endif                          /* ENABLE_WDETH */
  313 
  314 /** wd.c **/

Cache object: 8e1117b465c61c028e2907c29e85f445


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