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/lance/lance.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  * lance.c
    3  *
    4  * This file contains a ethernet device driver for AMD LANCE based ethernet
    5  * cards.
    6  *
    7  * The valid messages and their parameters are:
    8  *
    9  *   m_type       DL_PORT    DL_PROC   DL_COUNT   DL_MODE   DL_ADDR
   10  * |------------+----------+---------+----------+---------+---------|
   11  * | HARDINT    |          |         |          |         |         |
   12  * |------------|----------|---------|----------|---------|---------|
   13  * | DL_WRITE   | port nr  | proc nr | count    | mode    | address |
   14  * |------------|----------|---------|----------|---------|---------|
   15  * | DL_WRITEV  | port nr  | proc nr | count    | mode    | address |
   16  * |------------|----------|---------|----------|---------|---------|
   17  * | DL_READ    | port nr  | proc nr | count    |         | address |
   18  * |------------|----------|---------|----------|---------|---------|
   19  * | DL_READV   | port nr  | proc nr | count    |         | address |
   20  * |------------|----------|---------|----------|---------|---------|
   21  * | DL_INIT    | port nr  | proc nr | mode     |         | address |
   22  * |------------|----------|---------|----------|---------|---------|
   23  * | DL_GETSTAT | port nr  | proc nr |          |         | address |
   24  * |------------|----------|---------|----------|---------|---------|
   25  * | DL_STOP    | port_nr  |         |          |         |         |
   26  * |------------|----------|---------|----------|---------|---------|
   27  *
   28  * The messages sent are:
   29  *
   30  *   m-type       DL_POR T   DL_PROC   DL_COUNT   DL_STAT   DL_CLCK
   31  * |------------|----------|---------|----------|---------|---------|
   32  * |DL_TASK_REPL| port nr  | proc nr | rd-count | err|stat| clock   |
   33  * |------------|----------|---------|----------|---------|---------|
   34  *
   35  *   m_type       m3_i1     m3_i2       m3_ca1
   36  * |------------+---------+-----------+---------------|
   37  * |DL_INIT_REPL| port nr | last port | ethernet addr |
   38  * |------------|---------|-----------|---------------|
   39  *
   40  * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
   41  * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
   42  */
   43 
   44 #define VERBOSE 0
   45 
   46 #include "../drivers.h"
   47 
   48 #include <minix/keymap.h>
   49 #include <net/hton.h>
   50 #include <net/gen/ether.h>
   51 #include <net/gen/eth_io.h>
   52 #include <assert.h>
   53 
   54 #include <minix/syslib.h>
   55 
   56 #include "lance.h"
   57 #include "../libpci/pci.h"
   58 /*#include "proc.h"*/
   59 
   60 #include <sys/ioc_memory.h>
   61 
   62 /* new I/O functions in Minix 3 */
   63 #define out_byte( x, y ) sys_outb( x, y )
   64 #define out_word( x, y ) sys_outw( x, y )
   65 
   66 static U8_t in_byte(U16_t port)
   67 {
   68         U8_t value;
   69         int s;
   70         if ((s=sys_inb(port, &value)) != OK)
   71                 printf( "lance: warning, sys_inb failed: %d\n", s );
   72         return value;
   73 }
   74 
   75 static U16_t in_word( U16_t port)
   76 {
   77         U16_t value;
   78         int s;
   79         if ((s=sys_inw(port, &value)) != OK)
   80                 printf( "lance: warning, sys_inw failed: %d\n", s );
   81         return value;
   82 }
   83 /*
   84 #define in_byte( x ) inb( x )
   85 #define in_word( x ) inw( x )
   86 */
   87 
   88 static ether_card_t ec_table[EC_PORT_NR_MAX];
   89 static int eth_tasknr= ANY;
   90 static u16_t eth_ign_proto;
   91 
   92 /* Configuration */
   93 typedef struct ec_conf
   94 {
   95   port_t ec_port;
   96   int ec_irq;
   97   phys_bytes ec_mem;
   98   char *ec_envvar;
   99 } ec_conf_t;
  100 
  101 /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */
  102 ec_conf_t ec_conf[]=    /* Card addresses */
  103 {
  104         /* I/O port, IRQ,  Buffer address,  Env. var,   Buf selector. */
  105         {  0x1000,     9,    0x00000,        "LANCE0" },
  106         {  0xD000,    15,    0x00000,        "LANCE1" },
  107 };
  108 
  109 /* Actually, we use PCI-BIOS info. */
  110 PRIVATE struct pcitab
  111 {
  112         u16_t vid;
  113         u16_t did;
  114         int checkclass;
  115 } pcitab[]=
  116 {
  117         { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0 },              /* AMD LANCE */
  118 
  119         { 0x0000, 0x0000, 0 }
  120 };
  121 /*
  122 struct pci_device pci_dev_list[] = {
  123   { PCI_VENDOR_ID_AMD,          PCI_DEVICE_ID_AMD_LANCE,
  124     "AMD Lance/PCI",            0, 0, 0, 0, 0, 0}, 
  125   { PCI_VENDOR_ID_AMD,          PCI_DEVICE_ID_AMD_LANCE,
  126     "AMD Lance/PCI",            0, 0, 0, 0, 0, 0}, 
  127   {0, 0, NULL, 0, 0, 0, 0, 0, 0}
  128 };
  129 */
  130 
  131 /* General */
  132 _PROTOTYPE( static void do_init, (message *mp)                          );
  133 _PROTOTYPE( static void ec_init, (ether_card_t *ec)                     );
  134 _PROTOTYPE( static void ec_confaddr, (ether_card_t *ec)                 );
  135 _PROTOTYPE( static void ec_reinit, (ether_card_t *ec)                   );
  136 _PROTOTYPE( static void ec_check_ints, (ether_card_t *ec)               );
  137 _PROTOTYPE( static void conf_hw, (ether_card_t *ec)                     );
  138 /*_PROTOTYPE( static int ec_handler, (irq_hook_t *hook)                   );*/
  139 _PROTOTYPE( static void update_conf, (ether_card_t *ec, ec_conf_t *ecp) );
  140 _PROTOTYPE( static void mess_reply, (message *req, message *reply)      );
  141 _PROTOTYPE( static void do_int, (ether_card_t *ec)                      );
  142 _PROTOTYPE( static void reply, 
  143             (ether_card_t *ec, int err, int may_block)                  );
  144 _PROTOTYPE( static void ec_reset, (ether_card_t *ec)                    );
  145 _PROTOTYPE( static void ec_send, (ether_card_t *ec)                     );
  146 _PROTOTYPE( static void ec_recv, (ether_card_t *ec)                     );
  147 _PROTOTYPE( static void do_vwrite, 
  148             (message *mp, int from_int, int vectored)                   );
  149 _PROTOTYPE( static void do_vread, (message *mp, int vectored)           );
  150 _PROTOTYPE( static void get_userdata, 
  151             (int user_proc, vir_bytes user_addr, 
  152              vir_bytes count, void *loc_addr)                           );
  153 _PROTOTYPE( static void ec_user2nic, 
  154             (ether_card_t *dep, iovec_dat_t *iovp, 
  155              vir_bytes offset, int nic_addr, 
  156              vir_bytes count)                                           );
  157 _PROTOTYPE( static void ec_nic2user, 
  158             (ether_card_t *ec, int nic_addr, 
  159              iovec_dat_t *iovp, vir_bytes offset, 
  160              vir_bytes count)                                           );
  161 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp)             );
  162 _PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp)              );
  163 _PROTOTYPE( static void do_getstat, (message *mp)                       );
  164 _PROTOTYPE( static void put_userdata, 
  165             (int user_proc,
  166              vir_bytes user_addr, vir_bytes count, 
  167              void *loc_addr)                                            );
  168 _PROTOTYPE( static void do_stop, (message *mp)                          );
  169 _PROTOTYPE( static void do_getname, (message *mp)                       );
  170 
  171 _PROTOTYPE( static void lance_dump, (void)                              );
  172 _PROTOTYPE( static void lance_stop, (void)                              );
  173 _PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec)   );
  174 
  175 /* probe+init LANCE cards */
  176 _PROTOTYPE( static int lance_probe, (ether_card_t *ec)                  );
  177 _PROTOTYPE( static void lance_init_card, (ether_card_t *ec)             );
  178 
  179 /* --- LANCE --- */
  180 /* General */
  181 #define Address                 unsigned long
  182 
  183 
  184 /* Minix 3 */
  185 #define virt_to_bus(x)          (vir2phys((unsigned long)x))
  186 unsigned long vir2phys( unsigned long x )
  187 {
  188         int r;
  189         unsigned long value;
  190         
  191         if ( (r=sys_umap( SELF, D, x, 4, &value )) != OK )
  192                 panic( "lance", "sys_umap failed", r );
  193         
  194         return value;
  195 }
  196 
  197 /* DMA limitations */
  198 #define DMA_ADDR_MASK  0xFFFFFF /* mask to verify DMA address is 24-bit */
  199 
  200 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance + sizeof(lance)) & ~DMA_ADDR_MASK) == 0 )
  201 
  202 #define ETH_FRAME_LEN           1518
  203 
  204 #define LANCE_MUST_PAD          0x00000001
  205 #define LANCE_ENABLE_AUTOSELECT 0x00000002
  206 #define LANCE_SELECT_PHONELINE  0x00000004
  207 #define LANCE_MUST_UNRESET      0x00000008
  208 
  209 static const struct lance_chip_type
  210 {
  211   int        id_number;
  212   const char *name;
  213   int        flags;
  214 } chip_table[] = {
  215   {0x0000, "LANCE 7990",           /* Ancient lance chip.  */
  216    LANCE_MUST_PAD + LANCE_MUST_UNRESET},
  217   {0x0003, "PCnet/ISA 79C960",     /* 79C960 PCnet/ISA.  */
  218    LANCE_ENABLE_AUTOSELECT},
  219   {0x2260, "PCnet/ISA+ 79C961",    /* 79C961 PCnet/ISA+, Plug-n-Play.  */
  220    LANCE_ENABLE_AUTOSELECT},
  221   {0x2420, "PCnet/PCI 79C970",     /* 79C970 or 79C974 PCnet-SCSI, PCI. */
  222    LANCE_ENABLE_AUTOSELECT},
  223   {0x2430, "PCnet32",              /* 79C965 PCnet for VL bus. */
  224    LANCE_ENABLE_AUTOSELECT},
  225   {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
  226    LANCE_ENABLE_AUTOSELECT},
  227   {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
  228    LANCE_ENABLE_AUTOSELECT},
  229   {0x2626, "PCnet/HomePNA 79C978",        
  230    LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
  231   {0x0, "PCnet (unknown)",
  232    LANCE_ENABLE_AUTOSELECT},
  233 };
  234 
  235 /* ############## for LANCE device ############## */
  236 #define LANCE_ETH_ADDR          0x0
  237 #define LANCE_DATA              0x10
  238 #define LANCE_ADDR              0x12
  239 #define LANCE_RESET             0x14
  240 #define LANCE_BUS_IF            0x16
  241 #define LANCE_TOTAL_SIZE        0x18
  242 
  243 /* Use 2^4=16 {Rx,Tx} buffers */
  244 #define LANCE_LOG_RX_BUFFERS    4
  245 #define RX_RING_SIZE            (1 << (LANCE_LOG_RX_BUFFERS))
  246 #define RX_RING_MOD_MASK        (RX_RING_SIZE - 1)
  247 #define RX_RING_LEN_BITS        ((LANCE_LOG_RX_BUFFERS) << 29)
  248 
  249 #define LANCE_LOG_TX_BUFFERS    4
  250 #define TX_RING_SIZE            (1 << (LANCE_LOG_TX_BUFFERS))
  251 #define TX_RING_MOD_MASK        (TX_RING_SIZE - 1)
  252 #define TX_RING_LEN_BITS        ((LANCE_LOG_TX_BUFFERS) << 29)
  253 
  254 /* for lance_interface */
  255 struct lance_init_block
  256 {
  257   unsigned short  mode;
  258   unsigned char   phys_addr[6];
  259   unsigned long   filter[2];
  260   Address         rx_ring;
  261   Address         tx_ring;
  262 };
  263 
  264 struct lance_rx_head
  265 {
  266   union {
  267     Address         base;
  268     unsigned char   addr[4];
  269   } u;
  270   short           buf_length;     /* 2s complement */
  271   short           msg_length;
  272 };
  273 
  274 struct lance_tx_head
  275 {
  276   union {
  277     Address         base;
  278     unsigned char   addr[4];
  279   } u;
  280   short           buf_length;     /* 2s complement */
  281   short           misc;
  282 };
  283 
  284 struct lance_interface
  285 {
  286   struct lance_init_block init_block;
  287   struct lance_rx_head    rx_ring[RX_RING_SIZE];
  288   struct lance_tx_head    tx_ring[TX_RING_SIZE];
  289   unsigned char           rbuf[RX_RING_SIZE][ETH_FRAME_LEN];
  290   unsigned char           tbuf[TX_RING_SIZE][ETH_FRAME_LEN];
  291 };
  292 
  293 /* =============== global variables =============== */
  294 static struct lance_interface  *lp;
  295 static char lance[sizeof(struct lance_interface)+8];
  296 static int rx_slot_nr = 0;          /* Rx-slot number */
  297 static int tx_slot_nr = 0;          /* Tx-slot number */
  298 static int cur_tx_slot_nr = 0;      /* Tx-slot number */
  299 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
  300 static char *progname;
  301 
  302 
  303 /*===========================================================================*
  304  *                            lance_task                                     *
  305  *===========================================================================*/
  306 void main( int argc, char **argv )
  307 {
  308   message m;
  309   int i,irq,r, tasknr;
  310   ether_card_t *ec;
  311   long v;
  312         int fkeys, sfkeys;
  313         (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
  314 
  315         env_setargs( argc, argv );
  316         
  317         fkeys = sfkeys = 0; bit_set( sfkeys, 7 );
  318  
  319         if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
  320                 printf( "Error registering key\n" );
  321         
  322         if((eth_tasknr=getprocnr()) < 0)
  323                 panic("lance","couldn't get own proc nr", i);
  324 
  325   v= 0;
  326   (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
  327   eth_ign_proto= htons((u16_t) v);
  328 
  329   /* Try to notify inet that we are present (again) */
  330   r = findproc("inet", &tasknr);
  331   if (r == OK)
  332         notify(tasknr);
  333 
  334   while (TRUE)
  335     {
  336       for (i=0;i<EC_PORT_NR_MAX;++i)
  337         {
  338           ec= &ec_table[i];
  339           if (ec->ec_irq != 0)
  340             sys_irqenable(&ec->ec_hook);
  341         }
  342         
  343       if ((r= receive(ANY, &m)) != OK)
  344         panic( "lance", "receive failed", r);
  345         
  346       for (i=0;i<EC_PORT_NR_MAX;++i)
  347         {
  348           ec= &ec_table[i];
  349           if (ec->ec_irq != 0)
  350             sys_irqdisable(&ec->ec_hook);
  351         }
  352 
  353 /*printf( "." );*/
  354 
  355       switch (m.m_type){
  356       case DEV_PING:   notify(m.m_source);              continue;
  357       case DL_WRITE:   do_vwrite(&m, FALSE, FALSE);    break;
  358       case DL_WRITEV:  do_vwrite(&m, FALSE, TRUE);     break;
  359       case DL_READ:    do_vread(&m, FALSE);            break;
  360       case DL_READV:   do_vread(&m, TRUE);             break;
  361       case DL_INIT:    do_init(&m);                    break;
  362       case DL_GETSTAT: do_getstat(&m);                 break;
  363       case DL_STOP:    do_stop(&m);                    break;
  364       case DL_GETNAME: do_getname(&m);                  break;
  365       case FKEY_PRESSED: lance_dump();                 break;
  366       /*case HARD_STOP:  lance_stop();                   break;*/
  367       case SYS_SIG:
  368       {
  369         sigset_t set = m.NOTIFY_ARG;
  370         if ( sigismember( &set, SIGKSTOP ) )
  371                 lance_stop();
  372       }
  373         break;
  374       case HARD_INT:
  375         for (i=0;i<EC_PORT_NR_MAX;++i)
  376           {
  377             ec= &ec_table[i];
  378             if (ec->mode != EC_ENABLED)
  379               continue;
  380             
  381             /*
  382             printf( "#.\n" );
  383             */
  384             
  385             irq=ec->ec_irq;
  386             /*if (ec->ec_int_pending)*/
  387               {
  388                 ec->ec_int_pending = 0;
  389                 ec_check_ints(ec);
  390                 do_int(ec);
  391               }
  392           }
  393         break;
  394       default:
  395         panic( "lance", "illegal message", m.m_type);
  396       }
  397     }
  398 }
  399 
  400 /*===========================================================================*
  401  *                            lance_dump                                     *
  402  *===========================================================================*/
  403 static void lance_dump()
  404 {
  405   ether_card_t *ec;
  406   int i, isr;
  407   unsigned short ioaddr;
  408   
  409   printf("\n");
  410   for (i= 0, ec = &ec_table[0]; i<EC_PORT_NR_MAX; i++, ec++)
  411     {
  412       if (ec->mode == EC_DISABLED)
  413         printf("lance port %d is disabled\n", i);
  414       else if (ec->mode == EC_SINK)
  415         printf("lance port %d is in sink mode\n", i);
  416       
  417       if (ec->mode != EC_ENABLED)
  418         continue;
  419       
  420       printf("lance statistics of port %d:\n", i);
  421       
  422       printf("recvErr    :%8ld\t", ec->eth_stat.ets_recvErr);
  423       printf("sendErr    :%8ld\t", ec->eth_stat.ets_sendErr);
  424       printf("OVW        :%8ld\n", ec->eth_stat.ets_OVW);
  425       
  426       printf("CRCerr     :%8ld\t", ec->eth_stat.ets_CRCerr);
  427       printf("frameAll   :%8ld\t", ec->eth_stat.ets_frameAll);
  428       printf("missedP    :%8ld\n", ec->eth_stat.ets_missedP);
  429       
  430       printf("packetR    :%8ld\t", ec->eth_stat.ets_packetR);
  431       printf("packetT    :%8ld\t", ec->eth_stat.ets_packetT);
  432       printf("transDef   :%8ld\n", ec->eth_stat.ets_transDef);
  433       
  434       printf("collision  :%8ld\t", ec->eth_stat.ets_collision);
  435       printf("transAb    :%8ld\t", ec->eth_stat.ets_transAb);
  436       printf("carrSense  :%8ld\n", ec->eth_stat.ets_carrSense);
  437       
  438       printf("fifoUnder  :%8ld\t", ec->eth_stat.ets_fifoUnder);
  439       printf("fifoOver   :%8ld\t", ec->eth_stat.ets_fifoOver);
  440       printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
  441       
  442       printf("OWC        :%8ld\t", ec->eth_stat.ets_OWC);
  443       
  444       ioaddr = ec->ec_port;
  445       out_word(ioaddr+LANCE_ADDR, 0x00);
  446       isr=in_word(ioaddr+LANCE_DATA);
  447       printf("isr = 0x%x + 0x%x, flags = 0x%x\n", isr,
  448              in_word(ioaddr+LANCE_DATA), ec->flags);
  449       
  450       printf("irq = %d\tioadr = %d\n", ec->ec_irq, ec->ec_port);
  451     }
  452 }
  453 
  454 /*===========================================================================*
  455  *                               lance_stop                                  *
  456  *===========================================================================*/
  457 static void lance_stop()
  458 {
  459   message mess;
  460   int i;
  461 
  462   for (i= 0; i<EC_PORT_NR_MAX; i++)
  463     {
  464       if (ec_table[i].mode != EC_ENABLED)
  465         continue;
  466       mess.m_type= DL_STOP;
  467       mess.DL_PORT= i;
  468       do_stop(&mess);
  469     }
  470     
  471         /*printf("LANCE driver stopped.\n");*/
  472         
  473         sys_exit( 0 );
  474 }
  475 
  476 
  477 /*===========================================================================*
  478  *                              do_init                                      *
  479  *===========================================================================*/
  480 static void do_init(mp)
  481 message *mp;
  482 {
  483   int port;
  484   ether_card_t *ec;
  485   message reply_mess;
  486 
  487 pci_init();
  488 
  489   port = mp->DL_PORT;
  490   if (port < 0 || port >= EC_PORT_NR_MAX)
  491     {
  492       reply_mess.m_type= DL_INIT_REPLY;
  493       reply_mess.m3_i1= ENXIO;
  494       mess_reply(mp, &reply_mess);
  495       return;
  496     }
  497   ec= &ec_table[port];
  498   strcpy(ec->port_name, "eth_card#0");
  499   ec->port_name[9] += port;
  500   if (ec->mode == EC_DISABLED)
  501     {
  502       /* This is the default, try to (re)locate the device. */
  503       /* only try to enable if memory is correct for DMA */
  504           if ( CORRECT_DMA_MEM() )
  505           {
  506                 conf_hw(ec);
  507           }
  508           else
  509           {
  510                 report( "LANCE", "DMA denied because address out of range", NO_NUM );
  511           }
  512           
  513       if (ec->mode == EC_DISABLED)
  514         {
  515           /* Probe failed, or the device is configured off. */
  516           reply_mess.m_type= DL_INIT_REPLY;
  517           reply_mess.m3_i1= ENXIO;
  518           mess_reply(mp, &reply_mess);
  519           return;
  520         }
  521       if (ec->mode == EC_ENABLED)
  522         ec_init(ec);
  523     }
  524 
  525   if (ec->mode == EC_SINK)
  526     {
  527       ec->mac_address.ea_addr[0] = 
  528         ec->mac_address.ea_addr[1] = 
  529         ec->mac_address.ea_addr[2] = 
  530         ec->mac_address.ea_addr[3] = 
  531         ec->mac_address.ea_addr[4] = 
  532         ec->mac_address.ea_addr[5] = 0;
  533       ec_confaddr(ec);
  534       reply_mess.m_type = DL_INIT_REPLY;
  535       reply_mess.m3_i1 = mp->DL_PORT;
  536       reply_mess.m3_i2 = EC_PORT_NR_MAX;
  537       *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
  538       mess_reply(mp, &reply_mess);
  539       return;
  540     }
  541   assert(ec->mode == EC_ENABLED);
  542   assert(ec->flags & ECF_ENABLED);
  543 
  544   ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD);
  545 
  546   if (mp->DL_MODE & DL_PROMISC_REQ)
  547     ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD;
  548   if (mp->DL_MODE & DL_MULTI_REQ)
  549     ec->flags |= ECF_MULTI;
  550   if (mp->DL_MODE & DL_BROAD_REQ)
  551     ec->flags |= ECF_BROAD;
  552 
  553   ec->client = mp->m_source;
  554   ec_reinit(ec);
  555 
  556   reply_mess.m_type = DL_INIT_REPLY;
  557   reply_mess.m3_i1 = mp->DL_PORT;
  558   reply_mess.m3_i2 = EC_PORT_NR_MAX;
  559   *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
  560 
  561   mess_reply(mp, &reply_mess);
  562 }
  563 
  564 
  565 /*===========================================================================*
  566  *                              do_int                                       *
  567  *===========================================================================*/
  568 static void do_int(ec)
  569 ether_card_t *ec;
  570 {
  571   if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV))
  572     reply(ec, OK, TRUE);
  573 }
  574 
  575 #if 0
  576 /*===========================================================================*
  577  *                              ec_handler                                   *
  578  *===========================================================================*/
  579 static int ec_handler(hook)
  580 irq_hook_t *hook;
  581 {
  582   /* LANCE interrupt, send message and reenable interrupts. */
  583 #if 0
  584   printf(">> ec_handler(): \n");
  585 #endif
  586 
  587   structof(ether_card_t, ec_hook, hook)->ec_int_pending= 1;
  588 
  589   notify(eth_tasknr);
  590 
  591   return 0;
  592 }
  593 #endif
  594 
  595 /*===========================================================================*
  596  *                              conf_hw                                      *
  597  *===========================================================================*/
  598 static void conf_hw(ec)
  599 ether_card_t *ec;
  600 {
  601   static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */ };
  602 
  603   int ifnr;
  604   ec_conf_t *ecp;
  605 
  606   ec->mode= EC_DISABLED;     /* Superfluous */
  607   ifnr= ec-ec_table;
  608 
  609   ecp= &ec_conf[ifnr];
  610   update_conf(ec, ecp);
  611   if (ec->mode != EC_ENABLED)
  612     return;
  613 
  614   if (!lance_probe(ec))
  615     {
  616       printf("%s: No ethernet card found on PCI-BIOS info.\n", 
  617              ec->port_name);
  618       ec->mode= EC_DISABLED;
  619       return;
  620     }
  621 
  622   /* Allocate a memory segment, programmed I/O should set the
  623    * memory segment (linmem) to zero.
  624    */
  625   if (ec->ec_linmem != 0)
  626     {
  627         assert( 0 );
  628         /*phys2seg(&ec->ec_memseg, &ec->ec_memoff, ec->ec_linmem);*/
  629     }
  630 
  631 /* XXX */ if (ec->ec_linmem == 0) ec->ec_linmem= 0xFFFF0000;
  632 
  633   ec->flags = ECF_EMPTY;
  634   ec->eth_stat = empty_stat;
  635 }
  636 
  637 
  638 /*===========================================================================*
  639  *                              update_conf                                  *
  640  *===========================================================================*/
  641 static void update_conf(ec, ecp)
  642 ether_card_t *ec;
  643 ec_conf_t *ecp;
  644 {
  645   long v;
  646   static char ec_fmt[] = "x:d:x:x";
  647 
  648   /* Get the default settings and modify them from the environment. */
  649   ec->mode= EC_SINK;
  650   v= ecp->ec_port;
  651   switch (env_parse(ecp->ec_envvar, ec_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
  652   case EP_OFF:
  653     ec->mode= EC_DISABLED;
  654     break;
  655   case EP_ON:
  656   case EP_SET:
  657     ec->mode= EC_ENABLED;      /* Might become disabled if 
  658                                 * all probes fail */
  659     break;
  660   }
  661   
  662   ec->ec_port= v;
  663 
  664   v= ecp->ec_irq | DEI_DEFAULT;
  665   (void) env_parse(ecp->ec_envvar, ec_fmt, 1, &v, 0L,
  666                    (long) NR_IRQ_VECTORS - 1);
  667   ec->ec_irq= v;
  668   
  669   v= ecp->ec_mem;
  670   (void) env_parse(ecp->ec_envvar, ec_fmt, 2, &v, 0L, 0xFFFFFL);
  671   ec->ec_linmem= v;
  672   
  673   v= 0;
  674   (void) env_parse(ecp->ec_envvar, ec_fmt, 3, &v, 0x2000L, 0x8000L);
  675   ec->ec_ramsize= v;
  676 }
  677 
  678 
  679 /*===========================================================================*
  680  *                              ec_init                                      *
  681  *===========================================================================*/
  682 static void ec_init(ec)
  683 ether_card_t *ec;
  684 {
  685   int i, r;
  686 
  687   /* General initialization */
  688   ec->flags = ECF_EMPTY;
  689   /*disable_irq(ec->ec_irq);*/
  690   lance_init_card(ec); /* Get mac_address, etc ...*/
  691 
  692   ec_confaddr(ec);
  693 
  694 #if VERBOSE
  695   printf("%s: Ethernet address ", ec->port_name);
  696   for (i= 0; i < 6; i++)
  697     printf("%x%c", ec->mac_address.ea_addr[i],
  698            i < 5 ? ':' : '\n');
  699 #endif
  700 
  701   /* Finish the initialization */
  702   ec->flags |= ECF_ENABLED;
  703 
  704   /* Set the interrupt handler */
  705   /*put_irq_handler(&ec->ec_hook, ec->ec_irq, ec_handler);*/
  706   ec->ec_hook = ec->ec_irq;
  707         if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK)
  708                 printf("lance: error, couldn't set IRQ policy: %d\n", r);
  709 
  710 /*  enable_irq(ec->ec_irq); */
  711 
  712 /*  enter_kdebug(">> ec_init():"); */
  713 
  714   return;
  715 }
  716 
  717 
  718 /*===========================================================================*
  719  *                              reply                                        *
  720  *===========================================================================*/
  721 static void reply(ec, err, may_block)
  722 ether_card_t *ec;
  723 int err;
  724 int may_block;
  725 {
  726   message reply;
  727   int status,r;
  728   clock_t now;
  729 
  730   status = 0;
  731   if (ec->flags & ECF_PACK_SEND)
  732     status |= DL_PACK_SEND;
  733   if (ec->flags & ECF_PACK_RECV)
  734     status |= DL_PACK_RECV;
  735 
  736   reply.m_type   = DL_TASK_REPLY;
  737   reply.DL_PORT  = ec - ec_table;
  738   reply.DL_PROC  = ec->client;
  739   reply.DL_STAT  = status | ((u32_t) err << 16);
  740   reply.DL_COUNT = ec->read_s;
  741 #if 1
  742   if ((r=getuptime(&now)) != OK)
  743         panic("lance", "getuptime() failed:", r);
  744   reply.DL_CLCK = now; 
  745 #else
  746   reply.DL_CLCK = 0;
  747 #endif
  748 
  749   r = send(ec->client, &reply);
  750 #if 1
  751   if (r == ELOCKED && may_block)
  752     {
  753 /*     enter_kdebug(">> lance_task: ELOCKED!"); */
  754       return;
  755     }
  756 #endif
  757   if (r < 0)
  758     panic( "lance", "send failed:", r);
  759 
  760   ec->read_s = 0;
  761   ec->flags &= ~(ECF_PACK_SEND | ECF_PACK_RECV);
  762 }
  763 
  764 
  765 /*===========================================================================*
  766  *                              mess_reply                                   *
  767  *===========================================================================*/
  768 static void mess_reply(req, reply_mess)
  769 message *req;
  770 message *reply_mess;
  771 {
  772   if (send(req->m_source, reply_mess) != OK)
  773     panic( "lance", "unable to mess_reply", NO_NUM);
  774 }
  775 
  776 
  777 /*===========================================================================*
  778  *                              ec_confaddr                                  *
  779  *===========================================================================*/
  780 static void ec_confaddr(ec)
  781 ether_card_t *ec;
  782 {
  783   int i;
  784   char eakey[16];
  785   static char eafmt[]= "x:x:x:x:x:x";
  786   long v;
  787 
  788   /* User defined ethernet address? */
  789   strcpy(eakey, ec_conf[ec-ec_table].ec_envvar);
  790   strcat(eakey, "_EA");
  791 
  792   for (i= 0; i < 6; i++)
  793     {
  794       v= ec->mac_address.ea_addr[i];
  795       if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
  796         break;
  797       ec->mac_address.ea_addr[i]= v;
  798     }
  799   
  800   if (i != 0 && i != 6)
  801     {
  802       /* It's all or nothing; force a panic. */
  803       (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
  804     }
  805 }
  806 
  807 
  808 /*===========================================================================*
  809  *                              ec_reinit                                    *
  810  *===========================================================================*/
  811 static void ec_reinit(ec)
  812 ether_card_t *ec;
  813 {
  814   int i;
  815   unsigned short ioaddr = ec->ec_port;
  816 
  817   out_word(ioaddr+LANCE_ADDR, 0x0);
  818   (void)in_word(ioaddr+LANCE_ADDR);
  819   out_word(ioaddr+LANCE_DATA, 0x4);           /* stop */
  820 
  821   /* purge Tx-ring */
  822   tx_slot_nr = cur_tx_slot_nr = 0;
  823   for (i=0; i<TX_RING_SIZE; i++) {
  824     lp->tx_ring[i].u.base = 0;
  825     isstored[i]=0;
  826   }
  827 
  828   /* re-init Rx-ring */
  829   rx_slot_nr = 0;
  830   for (i=0; i<RX_RING_SIZE; i++) 
  831     {
  832       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
  833       lp->rx_ring[i].u.addr[3] |= 0x80;
  834     }
  835 
  836   /* Set 'Receive Mode' */
  837   if (ec->flags & ECF_PROMISC)
  838     {
  839       out_word(ioaddr+LANCE_ADDR, 0xf);
  840       out_word(ioaddr+LANCE_DATA, 0x8000);
  841     }
  842   else
  843     {
  844       if (ec->flags & (ECF_BROAD | ECF_MULTI))
  845         {
  846           out_word(ioaddr+LANCE_ADDR, 0xf);
  847           out_word(ioaddr+LANCE_DATA, 0x0000);
  848         }
  849       else
  850         {
  851           out_word(ioaddr+LANCE_ADDR, 0xf);
  852           out_word(ioaddr+LANCE_DATA, 0x4000);
  853         }
  854     }
  855 
  856   out_word(ioaddr+LANCE_ADDR, 0x0);
  857   (void)in_word(ioaddr+LANCE_ADDR);
  858   out_word(ioaddr+LANCE_DATA, 0x142);   /* start && enable interrupt */
  859 
  860   return;
  861 }
  862 
  863 /*===========================================================================*
  864  *                              ec_check_ints                                *
  865  *===========================================================================*/
  866 static void ec_check_ints(ec)
  867 ether_card_t *ec;
  868 {
  869   int must_restart=0;
  870   int check,status;
  871   int isr=0x0000;
  872   unsigned short ioaddr = ec->ec_port;
  873 
  874   if (!(ec->flags & ECF_ENABLED))
  875     panic( "lance", "got premature interrupt", NO_NUM);
  876 
  877     for (;;)
  878       {
  879 #if 0
  880         printf("ETH: Reading ISR...");
  881 #endif
  882         out_word(ioaddr+LANCE_ADDR, 0x00);
  883         isr=in_word(ioaddr+LANCE_DATA);
  884         if (isr & 0x8600)
  885           out_word( ioaddr+LANCE_DATA, isr & ~0x004f);
  886         out_word(ioaddr+LANCE_DATA, 0x7940);
  887 #if 0
  888         printf("ISR=0x%x...",in_word(ioaddr+LANCE_DATA));
  889 #endif
  890 #define ISR_WINT 0x0200
  891 #define ISR_RINT 0x0400
  892 #define ISR_RERR 0x1000
  893 #define ISR_WERR 0x4000
  894 #define ISR_ERR  0x8000
  895 #define ISR_RST  0x0000
  896 
  897         if ((isr & (ISR_WINT|ISR_RINT|ISR_RERR|ISR_WERR|ISR_ERR)) == 0x0000)
  898           {
  899 #if 0
  900             printf("OK\n");
  901 #endif
  902             break;
  903           }
  904 
  905         if (isr & ISR_RERR)
  906           {
  907 #if 0
  908             printf("RERR\n");
  909 #endif
  910             ec->eth_stat.ets_recvErr++;
  911           }
  912         if ((isr & ISR_WERR) || (isr & ISR_WINT))
  913           {
  914             if (isr & ISR_WERR)
  915               {
  916 #if 0
  917                 printf("WERR\n");
  918 #endif
  919                 ec->eth_stat.ets_sendErr++;
  920               }
  921             if (isr & ISR_WINT)
  922               {
  923 #if 0
  924                 printf("WINT\n");
  925 #endif
  926                 /* status check: restart if needed. */
  927                 status = lp->tx_ring[cur_tx_slot_nr].u.base;
  928 
  929                 /* ??? */
  930                 if (status & 0x40000000)
  931                   {
  932                     status = lp->tx_ring[cur_tx_slot_nr].misc;
  933                     ec->eth_stat.ets_sendErr++;
  934                     if (status & 0x0400)
  935                       ec->eth_stat.ets_transAb++;
  936                     if (status & 0x0800)
  937                       ec->eth_stat.ets_carrSense++;
  938                     if (status & 0x1000)
  939                       ec->eth_stat.ets_OWC++;
  940                     if (status & 0x4000)
  941                       {
  942                         ec->eth_stat.ets_fifoUnder++;
  943                         must_restart=1;
  944                       }
  945                   }
  946                 else
  947                   {
  948                     if (status & 0x18000000)
  949                       ec->eth_stat.ets_collision++;
  950                     ec->eth_stat.ets_packetT++;
  951                   }
  952               }
  953             /* transmit a packet on the next slot if it exists. */
  954             check = 0;
  955             if (isstored[cur_tx_slot_nr]==1)
  956               {
  957                 /* free the tx-slot just transmitted */
  958                 isstored[cur_tx_slot_nr]=0;
  959                 cur_tx_slot_nr = (++cur_tx_slot_nr) & TX_RING_MOD_MASK;
  960                 
  961                 /* next tx-slot is ready? */
  962                 if (isstored[cur_tx_slot_nr]==1)
  963                   check=1;
  964                 else
  965                   check=0;
  966               }
  967             else
  968               {
  969                 panic( "lance", "got premature WINT...", NO_NUM);
  970               }
  971             if (check==1)
  972               {
  973                 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
  974                 out_word(ioaddr+LANCE_ADDR, 0x0000);
  975                 out_word(ioaddr+LANCE_DATA, 0x0048);
  976               }
  977             else
  978               if (check==-1)
  979                 continue;
  980             /* we set a buffered message in the slot if it exists. */
  981             /* and transmit it, if needed. */
  982             if (ec->flags & ECF_SEND_AVAIL)
  983               ec_send(ec);
  984           }
  985         if (isr & ISR_RINT)
  986           {
  987 #if 0
  988             printf("RINT\n");
  989 #endif
  990             ec_recv(ec);
  991           }
  992 
  993         if (isr & ISR_RST)
  994           {
  995             ec->flags = ECF_STOPPED;
  996             break;
  997           }
  998 
  999         /* ??? cf. lance driver on linux */
 1000         if (must_restart == 1)
 1001           {
 1002 #if 0
 1003             printf("ETH: restarting...\n");
 1004 #endif
 1005             out_word(ioaddr+LANCE_ADDR, 0x0);
 1006             (void)in_word(ioaddr+LANCE_ADDR);
 1007             out_word(ioaddr+LANCE_DATA, 0x4);  /* stop */
 1008             out_word(ioaddr+LANCE_DATA, 0x2);  /* start */
 1009           }
 1010       }
 1011     
 1012     if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
 1013       {
 1014 #if 0
 1015         printf("ETH: resetting...\n");
 1016 #endif
 1017         ec_reset(ec);
 1018       }
 1019 }
 1020 
 1021 /*===========================================================================*
 1022  *                              ec_reset                                     *
 1023  *===========================================================================*/
 1024 static void ec_reset(ec)
 1025 ether_card_t *ec;
 1026 {
 1027   /* Stop/start the chip, and clear all RX,TX-slots */
 1028   unsigned short ioaddr = ec->ec_port;
 1029   int i;
 1030   
 1031   out_word(ioaddr+LANCE_ADDR, 0x0);
 1032   (void)in_word(ioaddr+LANCE_ADDR);
 1033   out_word(ioaddr+LANCE_DATA, 0x4);                      /* stop */
 1034   out_word(ioaddr+LANCE_DATA, 0x2);                      /* start */
 1035   
 1036   /* purge Tx-ring */
 1037   tx_slot_nr = cur_tx_slot_nr = 0;
 1038   for (i=0; i<TX_RING_SIZE; i++) {
 1039     lp->tx_ring[i].u.base = 0;
 1040     isstored[i]=0;
 1041   }
 1042 
 1043   /* re-init Rx-ring */
 1044   rx_slot_nr = 0;
 1045   for (i=0; i<RX_RING_SIZE; i++) 
 1046     {
 1047       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
 1048       lp->rx_ring[i].u.addr[3] |= 0x80;
 1049     }
 1050 
 1051   /* store a buffered message on the slot if exists */
 1052   ec_send(ec);
 1053   ec->flags &= ~ECF_STOPPED;
 1054 }
 1055 
 1056 /*===========================================================================*
 1057  *                              ec_send                                      *
 1058  *===========================================================================*/
 1059 static void ec_send(ec)
 1060 ether_card_t *ec;
 1061 {
 1062   /* from ec_check_ints() or ec_reset(). */
 1063   /* this function proccesses the buffered message. (slot/transmit) */
 1064   if (!(ec->flags & ECF_SEND_AVAIL))
 1065     return;
 1066   
 1067   ec->flags &= ~ECF_SEND_AVAIL;
 1068   switch(ec->sendmsg.m_type)
 1069     {
 1070     case DL_WRITE:  do_vwrite(&ec->sendmsg, TRUE, FALSE);       break;
 1071     case DL_WRITEV: do_vwrite(&ec->sendmsg, TRUE, TRUE);        break;
 1072     default:
 1073       panic( "lance", "wrong type:", ec->sendmsg.m_type);
 1074       break;
 1075     }
 1076 }
 1077 
 1078 /*===========================================================================*
 1079  *                              do_vread                                     *
 1080  *===========================================================================*/
 1081 static void do_vread(mp, vectored)
 1082 message *mp;
 1083 int vectored;
 1084 {
 1085   int port, count, size;
 1086   ether_card_t *ec;
 1087 
 1088   port = mp->DL_PORT;
 1089   count = mp->DL_COUNT;
 1090   ec= &ec_table[port];
 1091   ec->client= mp->DL_PROC;
 1092 
 1093   if (vectored)
 1094     {
 1095       get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
 1096                    (count > IOVEC_NR ? IOVEC_NR : count) *
 1097                    sizeof(iovec_t), ec->read_iovec.iod_iovec);
 1098       ec->read_iovec.iod_iovec_s    = count;
 1099       ec->read_iovec.iod_proc_nr    = mp->DL_PROC;
 1100       ec->read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
 1101       
 1102       ec->tmp_iovec = ec->read_iovec;
 1103       size= calc_iovec_size(&ec->tmp_iovec);
 1104     }
 1105   else
 1106     {
 1107       ec->read_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
 1108       ec->read_iovec.iod_iovec[0].iov_size = mp->DL_COUNT;
 1109       ec->read_iovec.iod_iovec_s           = 1;
 1110       ec->read_iovec.iod_proc_nr           = mp->DL_PROC;
 1111       ec->read_iovec.iod_iovec_addr        = 0;
 1112 
 1113       size= count;
 1114     }
 1115   ec->flags |= ECF_READING;
 1116 
 1117   ec_recv(ec);
 1118 
 1119   if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
 1120     ec_reset(ec);
 1121   reply(ec, OK, FALSE);
 1122 }
 1123 
 1124 /*===========================================================================*
 1125  *                              ec_recv                                      *
 1126  *===========================================================================*/
 1127 static void ec_recv(ec)
 1128 ether_card_t *ec;
 1129 {
 1130   vir_bytes length;
 1131   int packet_processed;
 1132   int status;
 1133   unsigned short ioaddr = ec->ec_port;
 1134 
 1135   if ((ec->flags & ECF_READING)==0)
 1136     return;
 1137   if (!(ec->flags & ECF_ENABLED))
 1138     return;
 1139 
 1140   /* we check all the received slots until find a properly received packet */
 1141   packet_processed = FALSE;
 1142   while (!packet_processed)
 1143     {
 1144       status = lp->rx_ring[rx_slot_nr].u.base >> 24;
 1145       if ( (status & 0x80) == 0x00 )
 1146         {
 1147           status = lp->rx_ring[rx_slot_nr].u.base >> 24;
 1148 
 1149           /* ??? */
 1150           if (status != 0x03)
 1151             {
 1152               if (status & 0x01)
 1153                 ec->eth_stat.ets_recvErr++;
 1154               if (status & 0x04)
 1155                 ec->eth_stat.ets_fifoOver++;
 1156               if (status & 0x08)
 1157                 ec->eth_stat.ets_CRCerr++;
 1158               if (status & 0x10)
 1159                 ec->eth_stat.ets_OVW++;
 1160               if (status & 0x20)
 1161                 ec->eth_stat.ets_frameAll++;
 1162               length = 0;
 1163             }
 1164           else
 1165             {
 1166               ec->eth_stat.ets_packetR++;
 1167               length = lp->rx_ring[rx_slot_nr].msg_length;
 1168             }
 1169           if (length > 0)
 1170             {
 1171               ec_nic2user(ec, (int)(lp->rbuf[rx_slot_nr]),
 1172                           &ec->read_iovec, 0, length);
 1173               
 1174               ec->read_s = length;
 1175               ec->flags |= ECF_PACK_RECV;
 1176               ec->flags &= ~ECF_READING;
 1177               packet_processed = TRUE;
 1178             }
 1179           /* set up this slot again, and we move to the next slot */
 1180           lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN;
 1181           lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80;
 1182 
 1183           out_word(ioaddr+LANCE_ADDR, 0x00);
 1184           out_word(ioaddr+LANCE_DATA, 0x7940);
 1185 
 1186           rx_slot_nr = (++rx_slot_nr) & RX_RING_MOD_MASK;
 1187         }
 1188       else
 1189         break;
 1190     }
 1191 }
 1192 
 1193 /*===========================================================================*
 1194  *                              do_vwrite                                    *
 1195  *===========================================================================*/
 1196 static void do_vwrite(mp, from_int, vectored)
 1197 message *mp;
 1198 int from_int;
 1199 int vectored;
 1200 {
 1201   int port, count, check;
 1202   ether_card_t *ec;
 1203   unsigned short ioaddr;
 1204 
 1205   port = mp->DL_PORT;
 1206   count = mp->DL_COUNT;
 1207   ec = &ec_table[port];
 1208   ec->client= mp->DL_PROC;
 1209 
 1210   if (isstored[tx_slot_nr]==1)
 1211     {
 1212       /* all slots are used, so this message is buffered */
 1213       ec->sendmsg= *mp;
 1214       ec->flags |= ECF_SEND_AVAIL;
 1215       reply(ec, OK, FALSE);
 1216       return;
 1217     }
 1218 
 1219   /* convert the message to write_iovec */
 1220   if (vectored)
 1221     {
 1222       get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
 1223                    (count > IOVEC_NR ? IOVEC_NR : count) *
 1224                    sizeof(iovec_t), ec->write_iovec.iod_iovec);
 1225 
 1226       ec->write_iovec.iod_iovec_s    = count;
 1227       ec->write_iovec.iod_proc_nr    = mp->DL_PROC;
 1228       ec->write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
 1229 
 1230       ec->tmp_iovec = ec->write_iovec;
 1231       ec->write_s = calc_iovec_size(&ec->tmp_iovec);
 1232     }
 1233   else
 1234     {  
 1235       ec->write_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
 1236       ec->write_iovec.iod_iovec[0].iov_size = mp->DL_COUNT;
 1237 
 1238       ec->write_iovec.iod_iovec_s    = 1;
 1239       ec->write_iovec.iod_proc_nr    = mp->DL_PROC;
 1240       ec->write_iovec.iod_iovec_addr = 0;
 1241 
 1242       ec->write_s = mp->DL_COUNT;
 1243     }
 1244 
 1245   /* copy write_iovec to the slot on DMA address */
 1246   ec_user2nic(ec, &ec->write_iovec, 0,
 1247               (int)(lp->tbuf[tx_slot_nr]), ec->write_s);
 1248   /* set-up for transmitting, and transmit it if needed. */
 1249   lp->tx_ring[tx_slot_nr].buf_length = -ec->write_s;
 1250   lp->tx_ring[tx_slot_nr].misc = 0x0;
 1251   lp->tx_ring[tx_slot_nr].u.base 
 1252     = virt_to_bus(lp->tbuf[tx_slot_nr]) & 0xffffff;
 1253   isstored[tx_slot_nr]=1;
 1254   if (cur_tx_slot_nr == tx_slot_nr)
 1255     check=1;
 1256   else
 1257     check=0;
 1258   tx_slot_nr = (++tx_slot_nr) & TX_RING_MOD_MASK;
 1259 
 1260   if (check == 1)
 1261     {
 1262       ioaddr = ec->ec_port;
 1263       lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
 1264       out_word(ioaddr+LANCE_ADDR, 0x0000);
 1265       out_word(ioaddr+LANCE_DATA, 0x0048);
 1266     }
 1267         
 1268   ec->flags |= ECF_PACK_SEND;
 1269 
 1270   /* reply by calling do_int() if this function is called from interrupt. */
 1271   if (from_int)
 1272     return;
 1273   reply(ec, OK, FALSE);
 1274 }
 1275 
 1276 
 1277 /*===========================================================================*
 1278  *                              get_userdata                                 *
 1279  *===========================================================================*/
 1280 static void get_userdata(user_proc, user_addr, count, loc_addr)
 1281 int user_proc;
 1282 vir_bytes user_addr;
 1283 vir_bytes count;
 1284 void *loc_addr;
 1285 {
 1286         /*
 1287   phys_bytes src;
 1288 
 1289   src = numap_local(user_proc, user_addr, count);
 1290   if (!src)
 1291     panic( "lance", "umap failed", NO_NUM);
 1292 
 1293   phys_copy(src, vir2phys(loc_addr), (phys_bytes) count);
 1294   */
 1295         int cps;
 1296         cps = sys_datacopy(user_proc, user_addr, SELF, (vir_bytes) loc_addr, count);
 1297         if (cps != OK) printf("lance: warning, scopy failed: %d\n", cps);
 1298 }
 1299 
 1300 /*===========================================================================*
 1301  *                              ec_user2nic                                  *
 1302  *===========================================================================*/
 1303 static void ec_user2nic(ec, iovp, offset, nic_addr, count)
 1304 ether_card_t *ec;
 1305 iovec_dat_t *iovp;
 1306 vir_bytes offset;
 1307 int nic_addr;
 1308 vir_bytes count;
 1309 {
 1310   /*phys_bytes phys_hw, phys_user;*/
 1311   int bytes, i, r;
 1312 
 1313   /*
 1314   phys_hw = vir2phys(nic_addr);
 1315   */
 1316   i= 0;
 1317   while (count > 0)
 1318     {
 1319       if (i >= IOVEC_NR)
 1320         {
 1321           ec_next_iovec(iovp);
 1322           i= 0;
 1323           continue;
 1324         }
 1325       if (offset >= iovp->iod_iovec[i].iov_size)
 1326         {
 1327           offset -= iovp->iod_iovec[i].iov_size;
 1328           i++;
 1329           continue;
 1330         }
 1331       bytes = iovp->iod_iovec[i].iov_size - offset;
 1332       if (bytes > count)
 1333         bytes = count;
 1334       
 1335       /*
 1336       phys_user = numap_local(iovp->iod_proc_nr,
 1337                         iovp->iod_iovec[i].iov_addr + offset, bytes);
 1338       
 1339       phys_copy(phys_user, phys_hw, (phys_bytes) bytes);
 1340       */
 1341       if ( (r=sys_datacopy(iovp->iod_proc_nr, iovp->iod_iovec[i].iov_addr + offset,
 1342         SELF, nic_addr, count )) != OK )
 1343         panic( "lance", "sys_datacopy failed", r );
 1344         
 1345       count -= bytes;
 1346       nic_addr += bytes;
 1347       offset += bytes;
 1348     }
 1349 }
 1350 
 1351 /*===========================================================================*
 1352  *                              ec_nic2user                                  *
 1353  *===========================================================================*/
 1354 static void ec_nic2user(ec, nic_addr, iovp, offset, count)
 1355 ether_card_t *ec;
 1356 int nic_addr;
 1357 iovec_dat_t *iovp;
 1358 vir_bytes offset;
 1359 vir_bytes count;
 1360 {
 1361   /*phys_bytes phys_hw, phys_user;*/
 1362   int bytes, i, r;
 1363 
 1364   /*phys_hw = vir2phys(nic_addr);*/
 1365 
 1366   i= 0;
 1367   while (count > 0)
 1368     {
 1369       if (i >= IOVEC_NR)
 1370         {
 1371           ec_next_iovec(iovp);
 1372           i= 0;
 1373           continue;
 1374         }
 1375       if (offset >= iovp->iod_iovec[i].iov_size)
 1376         {
 1377           offset -= iovp->iod_iovec[i].iov_size;
 1378           i++;
 1379           continue;
 1380         }
 1381       bytes = iovp->iod_iovec[i].iov_size - offset;
 1382       if (bytes > count)
 1383         bytes = count;
 1384       /*
 1385       phys_user = numap_local(iovp->iod_proc_nr,
 1386                         iovp->iod_iovec[i].iov_addr + offset, bytes);
 1387 
 1388       phys_copy(phys_hw, phys_user, (phys_bytes) bytes);
 1389       */
 1390       if ( (r=sys_datacopy( SELF, nic_addr, iovp->iod_proc_nr, iovp->iod_iovec[i].iov_addr + offset, bytes )) != OK )
 1391         panic( "lance", "sys_datacopy failed: ", r );
 1392       
 1393       count -= bytes;
 1394       nic_addr += bytes;
 1395       offset += bytes;
 1396     }
 1397 }
 1398 
 1399 
 1400 /*===========================================================================*
 1401  *                              calc_iovec_size                              *
 1402  *===========================================================================*/
 1403 static int calc_iovec_size(iovp)
 1404 iovec_dat_t *iovp;
 1405 {
 1406   int size,i;
 1407 
 1408   size = i = 0;
 1409         
 1410   while (i < iovp->iod_iovec_s)
 1411     {
 1412       if (i >= IOVEC_NR)
 1413         {
 1414           ec_next_iovec(iovp);
 1415           i= 0;
 1416           continue;
 1417         }
 1418       size += iovp->iod_iovec[i].iov_size;
 1419       i++;
 1420     }
 1421 
 1422   return size;
 1423 }
 1424 
 1425 /*===========================================================================*
 1426  *                           ec_next_iovec                                   *
 1427  *===========================================================================*/
 1428 static void ec_next_iovec(iovp)
 1429 iovec_dat_t *iovp;
 1430 {
 1431   iovp->iod_iovec_s -= IOVEC_NR;
 1432   iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
 1433 
 1434   get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr, 
 1435                (iovp->iod_iovec_s > IOVEC_NR ? 
 1436                 IOVEC_NR : iovp->iod_iovec_s) * sizeof(iovec_t), 
 1437                iovp->iod_iovec); 
 1438 }
 1439 
 1440 
 1441 /*===========================================================================*
 1442  *                              do_getstat                                   *
 1443  *===========================================================================*/
 1444 static void do_getstat(mp)
 1445 message *mp;
 1446 {
 1447   int port;
 1448   ether_card_t *ec;
 1449 
 1450   port = mp->DL_PORT;
 1451   if (port < 0 || port >= EC_PORT_NR_MAX)
 1452     panic( "lance", "illegal port", port);
 1453 
 1454   ec= &ec_table[port];
 1455   ec->client= mp->DL_PROC;
 1456 
 1457   put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
 1458                (vir_bytes) sizeof(ec->eth_stat), &ec->eth_stat);
 1459   reply(ec, OK, FALSE);
 1460 }
 1461 
 1462 /*===========================================================================*
 1463  *                              put_userdata                                 *
 1464  *===========================================================================*/
 1465 static void put_userdata(user_proc, user_addr, count, loc_addr)
 1466 int user_proc;
 1467 vir_bytes user_addr;
 1468 vir_bytes count;
 1469 void *loc_addr;
 1470 {
 1471   /*phys_bytes dst;
 1472 
 1473   dst = numap_local(user_proc, user_addr, count);
 1474   if (!dst)
 1475     panic( "lance", "umap failed", NO_NUM);
 1476 
 1477   phys_copy(vir2phys(loc_addr), dst, (phys_bytes) count);
 1478   */
 1479         int cps;
 1480         cps = sys_datacopy(SELF, (vir_bytes) loc_addr, user_proc, user_addr, count);
 1481         if (cps != OK) printf("lance: warning, scopy failed: %d\n", cps);
 1482 }
 1483 
 1484 /*===========================================================================*
 1485  *                              do_stop                                      *
 1486  *===========================================================================*/
 1487 static void do_stop(mp)
 1488 message *mp;
 1489 {
 1490   int port;
 1491   ether_card_t *ec;
 1492   unsigned short ioaddr;
 1493 
 1494   port = mp->DL_PORT;
 1495   if (port < 0 || port >= EC_PORT_NR_MAX)
 1496     panic( "lance", "illegal port", port);
 1497   ec = &ec_table[port];
 1498 
 1499   if (!(ec->flags & ECF_ENABLED))
 1500     return;
 1501 
 1502   ioaddr = ec->ec_port;
 1503   
 1504   out_word(ioaddr+LANCE_ADDR, 0x0);
 1505   (void)in_word(ioaddr+LANCE_ADDR);
 1506   out_word(ioaddr+LANCE_DATA, 0x4);                          /* stop */
 1507   out_word(ioaddr+LANCE_RESET, in_word(ioaddr+LANCE_RESET)); /* reset */
 1508 
 1509   ec->flags = ECF_EMPTY;
 1510 }
 1511 
 1512 static void getAddressing(devind, ec)
 1513 int devind;
 1514 ether_card_t *ec;
 1515 {
 1516         unsigned int      membase, ioaddr;
 1517         int reg, irq;
 1518 
 1519         for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4)
 1520         {
 1521           ioaddr = pci_attr_r32(devind, reg);
 1522 
 1523           if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 
 1524               || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
 1525             continue;
 1526           /* Strip the I/O address out of the returned value */
 1527           ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
 1528           /* Get the memory base address */
 1529           membase = pci_attr_r32(devind, PCI_BASE_ADDRESS_1);
 1530           /* KK: Get the IRQ number */
 1531           irq = pci_attr_r8(devind, PCI_INTERRUPT_PIN);
 1532           if (irq)
 1533             irq = pci_attr_r8(devind, PCI_INTERRUPT_LINE);
 1534           /* Get the ROM base address */
 1535           /*pci_attr_r32(devind, PCI_ROM_ADDRESS, &romaddr);
 1536           romaddr >>= 10;*/
 1537           /* Take the first one or the one that matches in boot ROM address */
 1538           /*if (pci_ioaddr == 0 
 1539               || romaddr == ((unsigned long) rom.rom_segment << 4)) {*/
 1540             ec->ec_linmem = membase;
 1541             ec->ec_port = ioaddr;
 1542             ec->ec_irq = irq;
 1543           /*}*/
 1544         }
 1545 }
 1546 
 1547 /*===========================================================================*
 1548  *                            lance_probe                                    *
 1549  *===========================================================================*/
 1550 static int lance_probe(ec)
 1551 ether_card_t *ec;
 1552 {
 1553   unsigned short    pci_cmd, attached = 0;
 1554   unsigned short    ioaddr;
 1555   int               lance_version, chip_version;
 1556         int devind, just_one, i, r;
 1557         
 1558         u16_t vid, did;
 1559         u32_t bar;
 1560         u8_t ilr;
 1561         char *dname;
 1562 
 1563         if ((ec->ec_pcibus | ec->ec_pcidev | ec->ec_pcifunc) != 0)
 1564         {
 1565                 /* Look for specific PCI device */
 1566                 r= pci_find_dev(ec->ec_pcibus, ec->ec_pcidev,
 1567                         ec->ec_pcifunc, &devind);
 1568                 if (r == 0)
 1569                 {
 1570                         printf("%s: no PCI found at %d.%d.%d\n",
 1571                                 ec->port_name, ec->ec_pcibus,
 1572                                 ec->ec_pcidev, ec->ec_pcifunc);
 1573                         return 0;
 1574                 }
 1575                 pci_ids(devind, &vid, &did);
 1576                 just_one= TRUE;
 1577         }
 1578         else
 1579         {
 1580                 r= pci_first_dev(&devind, &vid, &did);
 1581                 if (r == 0)
 1582                         return 0;
 1583                 just_one= FALSE;
 1584         }
 1585 
 1586         for(;;)
 1587         {
 1588                 for (i= 0; pcitab[i].vid != 0; i++)
 1589                 {
 1590                         if (pcitab[i].vid != vid)
 1591                                 continue;
 1592                         if (pcitab[i].did != did)
 1593                                 continue;
 1594                         if (pcitab[i].checkclass)
 1595                         {
 1596                           panic("lance",
 1597                             "class check not implemented", NO_NUM);
 1598                         }
 1599                         break;
 1600                 }
 1601                 if (pcitab[i].vid != 0)
 1602                         break;
 1603 
 1604                 if (just_one)
 1605                 {
 1606                         printf(
 1607                 "%s: wrong PCI device (%04x/%04x) found at %d.%d.%d\n",
 1608                                 ec->port_name, vid, did,
 1609                                 ec->ec_pcibus,
 1610                                 ec->ec_pcidev, ec->ec_pcifunc);
 1611                         return 0;
 1612                 }
 1613 
 1614                 r= pci_next_dev(&devind, &vid, &did);
 1615                 if (!r)
 1616                         return 0;
 1617         }
 1618 
 1619         dname= pci_dev_name(vid, did);
 1620         if (!dname)
 1621                 dname= "unknown device";
 1622         
 1623         /*
 1624         printf("%s: ", ec->port_name);
 1625         printf("%s ", dname);
 1626         printf("(%x/", vid);
 1627         printf("%x) ", did);
 1628         printf("at %s\n", pci_slot_name(devind));
 1629         */
 1630         pci_reserve(devind);    
 1631         
 1632 /*  for (i = 0; pci_dev_list[i].vendor != 0; i++) {
 1633     if (pci_dev_list[i].suffix == 1)
 1634       {
 1635         ec->ec_port   = pci_dev_list[i].ioaddr;
 1636         ec->ec_irq    = pci_dev_list[i].irq;
 1637         ec->ec_linmem = pci_dev_list[i].membase;
 1638         ec->ec_bus    = pci_dev_list[i].bus;
 1639         ec->ec_dev    = pci_dev_list[i].devfn;
 1640         ec->ec_fnc    =
 1641         pci_dev_list[i].suffix = -1;
 1642         attached = 1;
 1643         break;
 1644       }
 1645   }
 1646   if (attached == 0)
 1647     return 0; 
 1648 */
 1649         getAddressing(devind, ec);
 1650 
 1651   /* ===== Bus Master ? ===== */
 1652   /*pcibios_read_config_word(ec->ec_bus, ec->ec_devfn, PCI_COMMAND, &pci_cmd);*/
 1653   pci_cmd = pci_attr_r32(devind, PCI_CR);
 1654   if (!(pci_cmd & PCI_COMMAND_MASTER)) {
 1655     pci_cmd |= PCI_COMMAND_MASTER;
 1656     /*pcibios_write_config_word(ec->ec_bus, ec->ec_devfn, PCI_COMMAND, pci_cmd);*/
 1657     pci_attr_w32(devind, PCI_CR, pci_cmd);
 1658   }
 1659 
 1660   /* ===== Probe Details ===== */
 1661   ioaddr = ec->ec_port;
 1662 
 1663   out_word(ioaddr+LANCE_RESET, in_word(ioaddr+LANCE_RESET)); /* Reset */
 1664   out_word(ioaddr+LANCE_ADDR, 0x0);                          /* Sw to win 0 */
 1665   if (in_word(ioaddr+LANCE_DATA) != 0x4)
 1666     {
 1667       ec->mode=EC_DISABLED;
 1668     }
 1669   /* Probe Chip Version */
 1670   out_word(ioaddr+LANCE_ADDR, 88);     /* Get the version of the chip */
 1671   if (in_word(ioaddr+LANCE_ADDR) != 88)
 1672     lance_version = 0;
 1673   else
 1674     {
 1675       chip_version = in_word(ioaddr+LANCE_DATA);
 1676       out_word(ioaddr+LANCE_ADDR, 89);
 1677       chip_version |= in_word(ioaddr+LANCE_DATA) << 16;
 1678       if ((chip_version & 0xfff) != 0x3)
 1679         {
 1680           ec->mode=EC_DISABLED;
 1681         }
 1682       chip_version = (chip_version >> 12) & 0xffff;
 1683       for (lance_version = 1; chip_table[lance_version].id_number != 0;
 1684            ++lance_version)
 1685         if (chip_table[lance_version].id_number == chip_version)
 1686           break;
 1687     }
 1688 
 1689 #if 0
 1690   printf("%s: %s at %X:%d\n",
 1691          ec->port_name, chip_table[lance_version].name,
 1692          ec->ec_port, ec->ec_irq);
 1693 #endif
 1694 
 1695   return lance_version;
 1696 }
 1697 
 1698 /*===========================================================================*
 1699  *                              do_getname                                   *
 1700  *===========================================================================*/
 1701 static void do_getname(mp)
 1702 message *mp;
 1703 {
 1704         int r;
 1705 
 1706         strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
 1707         mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
 1708         mp->m_type= DL_NAME_REPLY;
 1709         r= send(mp->m_source, mp);
 1710         if (r != OK)
 1711                 panic("LANCE", "do_getname: send failed", r);
 1712 }
 1713 
 1714 /*===========================================================================*
 1715  *                            lance_init_card                                *
 1716  *===========================================================================*/
 1717 static void lance_init_card(ec)
 1718 ether_card_t *ec;
 1719 {
 1720   int i;
 1721   Address l;
 1722   unsigned short ioaddr = ec->ec_port;
 1723 
 1724   /* ============= setup init_block(cf. lance_probe1) ================ */
 1725   /* make sure data structure is 8-byte aligned */
 1726   l = ((Address)lance + 7) & ~7;
 1727   lp = (struct lance_interface *)l;
 1728   lp->init_block.mode = 0x3;      /* disable Rx and Tx */
 1729   lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
 1730   /* using multiple Rx/Tx buffer */
 1731   lp->init_block.rx_ring 
 1732     = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
 1733   lp->init_block.tx_ring 
 1734     = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
 1735 
 1736   l = virt_to_bus(&lp->init_block);
 1737   out_word(ioaddr+LANCE_ADDR, 0x1); 
 1738   (void)in_word(ioaddr+LANCE_ADDR);
 1739   out_word(ioaddr+LANCE_DATA, (unsigned short)l);
 1740   out_word(ioaddr+LANCE_ADDR, 0x2);
 1741   (void)in_word(ioaddr+LANCE_ADDR);
 1742   out_word(ioaddr+LANCE_DATA, (unsigned short)(l >> 16));
 1743   out_word(ioaddr+LANCE_ADDR, 0x4);
 1744   (void)in_word(ioaddr+LANCE_ADDR);
 1745   out_word(ioaddr+LANCE_DATA, 0x915);
 1746   out_word(ioaddr+LANCE_ADDR, 0x0);
 1747   (void)in_word(ioaddr+LANCE_ADDR);
 1748 
 1749   /* ============= Get MAC address (cf. lance_probe1) ================ */
 1750   for (i = 0; i < 6; ++i)
 1751     ec->mac_address.ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i);
 1752 
 1753   /* ============ (re)start init_block(cf. lance_reset) =============== */
 1754   /* Reset the LANCE */
 1755   (void)in_word(ioaddr+LANCE_RESET);
 1756 
 1757   /* ----- Re-initialize the LANCE ----- */
 1758   /* Set station address */
 1759   for (i = 0; i < 6; ++i)
 1760     lp->init_block.phys_addr[i] = ec->mac_address.ea_addr[i];
 1761   /* Preset the receive ring headers */
 1762   for (i=0; i<RX_RING_SIZE; i++) {
 1763     lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
 1764     /* OWN */
 1765     lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
 1766     /* we set the top byte as the very last thing */
 1767     lp->rx_ring[i].u.addr[3] = 0x80;
 1768   }
 1769   /* Preset the transmitting ring headers */
 1770   for (i=0; i<TX_RING_SIZE; i++) {
 1771     lp->tx_ring[i].u.base = 0;
 1772     isstored[i] = 0;
 1773   }
 1774   lp->init_block.mode = 0x0;      /* enable Rx and Tx */
 1775 
 1776   l = (Address)virt_to_bus(&lp->init_block);
 1777   out_word(ioaddr+LANCE_ADDR, 0x1);
 1778   (void)in_word(ioaddr+LANCE_ADDR);
 1779   out_word(ioaddr+LANCE_DATA, (short)l);
 1780   out_word(ioaddr+LANCE_ADDR, 0x2);
 1781   (void)in_word(ioaddr+LANCE_ADDR);
 1782   out_word(ioaddr+LANCE_DATA, (short)(l >> 16));
 1783   out_word(ioaddr+LANCE_ADDR, 0x4);
 1784   (void)in_word(ioaddr+LANCE_ADDR);
 1785   out_word(ioaddr+LANCE_DATA, 0x915);
 1786   out_word(ioaddr+LANCE_ADDR, 0x0);
 1787   (void)in_word(ioaddr+LANCE_ADDR);
 1788 
 1789   /* ----- start when init done. ----- */
 1790   out_word(ioaddr+LANCE_DATA, 0x4);           /* stop */
 1791   out_word(ioaddr+LANCE_DATA, 0x1);           /* init */
 1792   for (i = 10000; i > 0; --i)
 1793     if (in_word(ioaddr+LANCE_DATA) & 0x100)
 1794       break;
 1795 
 1796   /* Set 'Multicast Table' */
 1797   for (i=0;i<4;++i)
 1798     {
 1799       out_word(ioaddr+LANCE_ADDR, 0x8 + i);
 1800       out_word(ioaddr+LANCE_DATA, 0xffff);
 1801     }
 1802 
 1803   /* Set 'Receive Mode' */
 1804   if (ec->flags & ECF_PROMISC)
 1805     {
 1806       out_word(ioaddr+LANCE_ADDR, 0xf);
 1807       out_word(ioaddr+LANCE_DATA, 0x8000);
 1808     }
 1809   else
 1810     {
 1811       if (ec->flags & (ECF_BROAD | ECF_MULTI))
 1812         {
 1813           out_word(ioaddr+LANCE_ADDR, 0xf);
 1814           out_word(ioaddr+LANCE_DATA, 0x0000);
 1815         }
 1816       else
 1817         {
 1818           out_word(ioaddr+LANCE_ADDR, 0xf);
 1819           out_word(ioaddr+LANCE_DATA, 0x4000);
 1820         }
 1821     }
 1822   
 1823   out_word(ioaddr+LANCE_ADDR, 0x0);
 1824   (void)in_word(ioaddr+LANCE_ADDR);
 1825   out_word(ioaddr+LANCE_DATA, 0x142);   /* start && enable interrupt */
 1826 
 1827   return;
 1828 }

Cache object: e756577cf1d7b849be81465697e72df2


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