Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/eth16i.c, revision 1.1

1.1     ! root        1: /* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
        !             2: 
        !             3:    Written 1994-95 by Mika Kuoppala
        !             4: 
        !             5:    Copyright (C) 1994, 1995 by Mika Kuoppala
        !             6:    Based on skeleton.c and at1700.c by Donald Becker
        !             7: 
        !             8:    This software may be used and distributed according to the terms
        !             9:    of the GNU Public Licence, incorporated herein by reference.
        !            10: 
        !            11:    The author may be reached as [email protected]
        !            12: 
        !            13:    This driver supports following cards :
        !            14:        - ICL EtherTeam 16i
        !            15:        - ICL EtherTeam 32 EISA
        !            16: 
        !            17:    Sources:
        !            18:      - skeleton.c  a sample network driver core for linux,
        !            19:        written by Donald Becker <[email protected]>
        !            20:      - at1700.c a driver for Allied Telesis AT1700, written 
        !            21:        by Donald Becker.
        !            22:      - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
        !            23:        written by Markku Viima
        !            24:      - The Fujitsu MB86965 databook.
        !            25:    
        !            26:    Valuable assistance from:
        !            27:        Markku Viima (ICL) 
        !            28:        Ari Valve (ICL)
        !            29:    
        !            30:    Revision history:
        !            31: 
        !            32:    Version     Date            Description
        !            33:    
        !            34:    0.01                15.12-94        Initial version (card detection)
        !            35:    0.02         23.01-95        Interrupt is now hooked correctly
        !            36:    0.03         01.02-95        Rewrote initialization part
        !            37:    0.04         07.02-95        Base skeleton done...
        !            38:                                Made a few changes to signature checking
        !            39:                                to make it a bit reliable.
        !            40:                                - fixed bug in tx_buf mapping
        !            41:                                - fixed bug in initialization (DLC_EN
        !            42:                                  wasn't enabled when initialization
        !            43:                                  was done.)
        !            44:    0.05                08.02-95        If there were more than one packet to send,
        !            45:                                transmit was jammed due to invalid
        !            46:                                register write...now fixed
        !            47:    0.06         19.02-95        Rewrote interrupt handling        
        !            48:    0.07         13.04-95        Wrote EEPROM read routines
        !            49:                                 Card configuration now set according to
        !            50:                                data read from EEPROM
        !            51:    0.08         23.06-95        Wrote part that tries to probe used interface
        !            52:                                 port if AUTO is selected
        !            53: 
        !            54:    0.09         01.09-95       Added module support
        !            55:    
        !            56:    0.10         04.09-95       Fixed receive packet allocation to work         
        !            57:                                with kernels > 1.3.x
        !            58:    
        !            59:    0.20                20.09-95        Added support for EtherTeam32 EISA      
        !            60: 
        !            61:    0.21         17.10-95        Removed the unnecessary extern 
        !            62:                                init_etherdev() declaration. Some
        !            63:                                other cleanups.
        !            64:    Bugs:
        !            65:        In some cases the interface autoprobing code doesn't find 
        !            66:        the correct interface type. In this case you can 
        !            67:        manually choose the interface type in DOS with E16IC.EXE which is 
        !            68:        configuration software for EtherTeam16i and EtherTeam32 cards.
        !            69:        
        !            70:    To do:
        !            71:        - Real multicast support
        !            72: */
        !            73: 
        !            74: static char *version = 
        !            75:        "eth16i.c: v0.21 17-10-95 Mika Kuoppala ([email protected])\n";
        !            76: 
        !            77: #include <linux/module.h>
        !            78: 
        !            79: #include <linux/kernel.h>
        !            80: #include <linux/sched.h>
        !            81: #include <linux/types.h>                 
        !            82: #include <linux/fcntl.h>                 
        !            83: #include <linux/interrupt.h>             
        !            84: #include <linux/ptrace.h>                
        !            85: #include <linux/ioport.h>                
        !            86: #include <linux/in.h>            
        !            87: #include <linux/malloc.h>                
        !            88: #include <linux/string.h>                
        !            89: #include <linux/errno.h>
        !            90: 
        !            91: #include <linux/netdevice.h>
        !            92: #include <linux/etherdevice.h>
        !            93: #include <linux/skbuff.h>
        !            94: 
        !            95: #include <asm/system.h>                  
        !            96: #include <asm/bitops.h>                  
        !            97: #include <asm/io.h>              
        !            98: #include <asm/dma.h>
        !            99: 
        !           100: /* Few macros */
        !           101: #define BIT(a)                 ( (1 << (a)) )  
        !           102: #define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) 
        !           103: #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
        !           104: 
        !           105: /* This is the I/O address space for Etherteam 16i adapter. */
        !           106: #define ETH16I_IO_EXTENT 32
        !           107: 
        !           108: /* Ticks before deciding that transmit has timed out */
        !           109: #define TIMEOUT_TICKS          30
        !           110: 
        !           111: /* Maximum loop count when receiving packets */
        !           112: #define MAX_RX_LOOP            40
        !           113: 
        !           114: /* Some interrupt masks */
        !           115: #define ETH16I_INTR_ON        0x8f82
        !           116: #define ETH16I_INTR_OFF               0x0000
        !           117:         
        !           118: /* Buffers header status byte meanings */
        !           119: #define PKT_GOOD               BIT(5)
        !           120: #define PKT_GOOD_RMT           BIT(4)
        !           121: #define PKT_SHORT              BIT(3)
        !           122: #define PKT_ALIGN_ERR          BIT(2)
        !           123: #define PKT_CRC_ERR            BIT(1)
        !           124: #define PKT_RX_BUF_OVERFLOW    BIT(0)
        !           125: 
        !           126: /* Transmit status register (DLCR0) */
        !           127: #define TX_STATUS_REG          0
        !           128: #define TX_DONE                BIT(7)
        !           129: #define NET_BUSY               BIT(6)
        !           130: #define TX_PKT_RCD             BIT(5)
        !           131: #define CR_LOST                BIT(4)
        !           132: #define COLLISION              BIT(2)
        !           133: #define COLLISIONS_16          BIT(1)
        !           134: 
        !           135: /* Receive status register (DLCR1) */
        !           136: #define RX_STATUS_REG          1
        !           137: #define RX_PKT                 BIT(7)  /* Packet received */
        !           138: #define BUS_RD_ERR             BIT(6)
        !           139: #define SHORT_PKT_ERR          BIT(3)
        !           140: #define ALIGN_ERR              BIT(2)
        !           141: #define CRC_ERR                BIT(1)
        !           142: #define RX_BUF_OVERFLOW        BIT(0)
        !           143:               
        !           144: /* Transmit Interrupt Enable Register (DLCR2) */
        !           145: #define TX_INTR_REG            2
        !           146: #define TX_INTR_DONE           BIT(7)
        !           147: #define TX_INTR_COL            BIT(2)
        !           148: #define TX_INTR_16_COL         BIT(1)
        !           149: 
        !           150: /* Receive Interrupt Enable Register (DLCR3) */
        !           151: #define RX_INTR_REG            3
        !           152: #define RX_INTR_RECEIVE        BIT(7)
        !           153: #define RX_INTR_SHORT_PKT      BIT(3)
        !           154: #define RX_INTR_CRC_ERR        BIT(1)
        !           155: #define RX_INTR_BUF_OVERFLOW   BIT(0)
        !           156: 
        !           157: /* Transmit Mode Register (DLCR4) */
        !           158: #define TRANSMIT_MODE_REG      4
        !           159: #define LOOPBACK_CONTROL       BIT(1)
        !           160: #define CONTROL_OUTPUT         BIT(2)
        !           161: 
        !           162: /* Receive Mode Register (DLCR5) */
        !           163: #define RECEIVE_MODE_REG       5
        !           164: #define RX_BUFFER_EMPTY        BIT(6)
        !           165: #define ACCEPT_BAD_PACKETS     BIT(5)
        !           166: #define RECEIVE_SHORT_ADDR     BIT(4)
        !           167: #define ACCEPT_SHORT_PACKETS   BIT(3)
        !           168: #define REMOTE_RESET           BIT(2)
        !           169: 
        !           170: #define ADDRESS_FILTER_MODE    BIT(1) | BIT(0)
        !           171: #define REJECT_ALL             0
        !           172: #define ACCEPT_ALL             3
        !           173: #define MODE_1                 1            /* NODE ID, BC, MC, 2-24th bit */
        !           174: #define MODE_2                 2            /* NODE ID, BC, MC, Hash Table */
        !           175: 
        !           176: /* Configuration Register 0 (DLCR6) */
        !           177: #define CONFIG_REG_0           6
        !           178: #define DLC_EN                 BIT(7)
        !           179: #define SRAM_CYCLE_TIME_100NS  BIT(6)
        !           180: #define SYSTEM_BUS_WIDTH_8     BIT(5)       /* 1 = 8bit, 0 = 16bit */
        !           181: #define BUFFER_WIDTH_8         BIT(4)       /* 1 = 8bit, 0 = 16bit */
        !           182: #define TBS1                   BIT(3)       
        !           183: #define TBS0                   BIT(2)
        !           184: #define BS1                    BIT(1)       /* 00=8kb,  01=16kb  */
        !           185: #define BS0                    BIT(0)       /* 10=32kb, 11=64kb  */
        !           186: 
        !           187: #ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */ 
        !           188: #define ETH16I_TX_BUF_SIZE     2             /* 2 = 8kb, 3 = 16kb */
        !           189: #endif                                      
        !           190: #define TX_BUF_1x2048            0
        !           191: #define TX_BUF_2x2048            1
        !           192: #define TX_BUF_2x4098            2
        !           193: #define TX_BUF_2x8192            3
        !           194: 
        !           195: /* Configuration Register 1 (DLCR7) */
        !           196: #define CONFIG_REG_1           7
        !           197: #define POWERUP                BIT(5)
        !           198: 
        !           199: /* Transmit start register */
        !           200: #define TRANSMIT_START_REG     10
        !           201: #define TRANSMIT_START_RB      2
        !           202: #define TX_START               BIT(7)       /* Rest of register bit indicate*/
        !           203:                                             /* number of packets in tx buffer*/
        !           204: /* Node ID registers (DLCR8-13) */
        !           205: #define NODE_ID_0              8
        !           206: #define NODE_ID_RB             0
        !           207: 
        !           208: /* Hash Table registers (HT8-15) */
        !           209: #define HASH_TABLE_0           8
        !           210: #define HASH_TABLE_RB          1
        !           211: 
        !           212: /* Buffer memory ports */
        !           213: #define BUFFER_MEM_PORT_LB    8
        !           214: #define DATAPORT              BUFFER_MEM_PORT_LB
        !           215: #define BUFFER_MEM_PORT_HB    9
        !           216: 
        !           217: /* 16 Collision control register (BMPR11) */
        !           218: #define COL_16_REG             11
        !           219: #define HALT_ON_16             0x00
        !           220: #define RETRANS_AND_HALT_ON_16 0x02
        !           221: 
        !           222: /* DMA Burst and Transceiver Mode Register (BMPR13) */
        !           223: #define TRANSCEIVER_MODE_REG   13
        !           224: #define TRANSCEIVER_MODE_RB    2         
        !           225: #define IO_BASE_UNLOCK        BIT(7)
        !           226: #define LOWER_SQUELCH_TRESH    BIT(6)
        !           227: #define LINK_TEST_DISABLE      BIT(5)
        !           228: #define AUI_SELECT             BIT(4)
        !           229: #define DIS_AUTO_PORT_SEL      BIT(3)
        !           230: 
        !           231: /* Filter Self Receive Register (BMPR14)  */
        !           232: #define FILTER_SELF_RX_REG     14
        !           233: #define SKIP_RECEIVE_PACKET    BIT(2)
        !           234: #define FILTER_SELF_RECEIVE    BIT(0)
        !           235: #define RX_BUF_SKIP_PACKET     SKIP_RECEIVE_PACKET | FILTER_SELF_RECEIVE
        !           236: 
        !           237: /* EEPROM Control Register (BMPR 16) */
        !           238: #define EEPROM_CTRL_REG        16
        !           239: 
        !           240: /* EEPROM Data Register (BMPR 17) */
        !           241: #define EEPROM_DATA_REG        17
        !           242: 
        !           243: /* NMC93CSx6 EEPROM Control Bits */
        !           244: #define CS_0                   0x00
        !           245: #define CS_1                   0x20
        !           246: #define SK_0                   0x00
        !           247: #define SK_1                   0x40
        !           248: #define DI_0                   0x00
        !           249: #define DI_1                   0x80
        !           250: 
        !           251: /* NMC93CSx6 EEPROM Instructions */
        !           252: #define EEPROM_READ            0x80
        !           253: 
        !           254: /* NMC93CSx6 EEPROM Addresses */
        !           255: #define E_NODEID_0                     0x02
        !           256: #define E_NODEID_1                     0x03
        !           257: #define E_NODEID_2                     0x04
        !           258: #define E_PORT_SELECT                  0x14
        !           259:   #define E_PORT_BNC                   0
        !           260:   #define E_PORT_DIX                   1
        !           261:   #define E_PORT_TP                    2
        !           262:   #define E_PORT_AUTO                  3
        !           263: #define E_PRODUCT_CFG                  0x30
        !           264:  
        !           265: 
        !           266: /* Macro to slow down io between EEPROM clock transitions */
        !           267: #define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { __SLOW_DOWN_IO; }}while(0)
        !           268: 
        !           269: /* Jumperless Configuration Register (BMPR19) */
        !           270: #define JUMPERLESS_CONFIG      19
        !           271: 
        !           272: /* ID ROM registers, writing to them also resets some parts of chip */
        !           273: #define ID_ROM_0               24
        !           274: #define ID_ROM_7               31
        !           275: #define RESET                  ID_ROM_0
        !           276: 
        !           277: /* This is the I/O address list to be probed when seeking the card */
        !           278: static unsigned int eth16i_portlist[] =
        !           279:    { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 };
        !           280: 
        !           281: static unsigned int eth32i_portlist[] =
        !           282:    { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
        !           283:      0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 };
        !           284: 
        !           285: /* This is the Interrupt lookup table for Eth16i card */
        !           286: static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15 };
        !           287: 
        !           288: /* This is the Interrupt lookup table for Eth32i card */
        !           289: static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };  
        !           290: #define EISA_IRQ_REG   0xc89
        !           291: 
        !           292: static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
        !           293: unsigned int boot = 1;
        !           294: 
        !           295: /* Use 0 for production, 1 for verification, >2 for debug */
        !           296: #ifndef ETH16I_DEBUG
        !           297: #define ETH16I_DEBUG 0
        !           298: #endif
        !           299: static unsigned int eth16i_debug = ETH16I_DEBUG;
        !           300: 
        !           301: /* Information for each board */
        !           302: struct eth16i_local {
        !           303:   struct enet_statistics stats;
        !           304:   unsigned int tx_started:1;
        !           305:   unsigned char tx_queue;         /* Number of packets in transmit buffer */
        !           306:   unsigned short tx_queue_len;         
        !           307:   unsigned int tx_buf_size;
        !           308:   unsigned long open_time;
        !           309: };
        !           310: 
        !           311: /* Function prototypes */
        !           312: 
        !           313: extern int eth16i_probe(struct device *dev);
        !           314: 
        !           315: static int eth16i_probe1(struct device *dev, short ioaddr);
        !           316: static int eth16i_check_signature(short ioaddr);
        !           317: static int eth16i_probe_port(short ioaddr);
        !           318: static void eth16i_set_port(short ioaddr, int porttype);
        !           319: static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l);
        !           320: static int eth16i_receive_probe_packet(short ioaddr);
        !           321: static int eth16i_get_irq(short ioaddr);
        !           322: static int eth16i_read_eeprom(int ioaddr, int offset);
        !           323: static int eth16i_read_eeprom_word(int ioaddr);
        !           324: static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
        !           325: static int eth16i_open(struct device *dev);
        !           326: static int eth16i_close(struct device *dev);
        !           327: static int eth16i_tx(struct sk_buff *skb, struct device *dev);
        !           328: static void eth16i_rx(struct device *dev);
        !           329: static void eth16i_interrupt(int irq, struct pt_regs *regs);
        !           330: static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs); 
        !           331: static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
        !           332: static void eth16i_initialize(struct device *dev);
        !           333: static struct enet_statistics *eth16i_get_stats(struct device *dev);
        !           334: 
        !           335: static char *cardname = "ICL EtherTeam 16i/32";
        !           336: 
        !           337: #ifdef HAVE_DEVLIST 
        !           338: /* Support for alternate probe manager */
        !           339: /struct netdev_entry eth16i_drv = 
        !           340:    {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; 
        !           341: 
        !           342: #else  /* Not HAVE_DEVLIST */
        !           343: int eth16i_probe(struct device *dev)
        !           344: {
        !           345:   int i;
        !           346:   int ioaddr;
        !           347:   int base_addr = dev ? dev->base_addr : 0;
        !           348: 
        !           349:   if(eth16i_debug > 4) 
        !           350:     printk("Probing started for %s\n", cardname);
        !           351: 
        !           352:   if(base_addr > 0x1ff)           /* Check only single location */
        !           353:     return eth16i_probe1(dev, base_addr);
        !           354:   else if(base_addr != 0)         /* Don't probe at all */
        !           355:     return ENXIO;
        !           356: 
        !           357:   /* Seek card from the ISA io address space */
        !           358:   for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) {
        !           359:     if(check_region(ioaddr, ETH16I_IO_EXTENT))
        !           360:       continue;
        !           361:     if(eth16i_probe1(dev, ioaddr) == 0)
        !           362:       return 0;
        !           363:   }
        !           364: 
        !           365:   /* Seek card from the EISA io address space */
        !           366:   for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) {
        !           367:     if(check_region(ioaddr, ETH16I_IO_EXTENT))
        !           368:        continue;
        !           369:     if(eth16i_probe1(dev, ioaddr) == 0)
        !           370:        return 0;
        !           371:    }
        !           372: 
        !           373:   return ENODEV;
        !           374: }
        !           375: #endif  /* Not HAVE_DEVLIST */
        !           376: 
        !           377: static int eth16i_probe1(struct device *dev, short ioaddr)
        !           378: {
        !           379:   static unsigned version_printed = 0;
        !           380:   unsigned int irq = 0;
        !           381:   boot = 1;          /* To inform initilization that we are in boot probe */
        !           382: 
        !           383:   /*
        !           384:      The MB86985 chip has on register which holds information in which 
        !           385:      io address the chip lies. First read this register and compare
        !           386:      it to our current io address and if match then this could
        !           387:      be our chip.
        !           388:   */
        !           389:   
        !           390:   if(ioaddr < 0x1000) {
        !           391:     if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
        !           392:       return -ENODEV;
        !           393:   }
        !           394: 
        !           395:   /* Now we will go a bit deeper and try to find the chip's signature */
        !           396: 
        !           397:   if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
        !           398:     return -ENODEV;
        !           399:   
        !           400:   /* 
        !           401:      Now it seems that we have found a ethernet chip in this particular
        !           402:      ioaddr. The MB86985 chip has this feature, that when you read a 
        !           403:      certain register it will increase it's io base address to next
        !           404:      configurable slot. Now when we have found the chip, first thing is
        !           405:      to make sure that the chip's ioaddr will hold still here.
        !           406:   */
        !           407:   
        !           408:   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           409:   outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
        !           410:   
        !           411:   outb(0x00, ioaddr + RESET);             /* Will reset some parts of chip */
        !           412:   BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* This will disable the data link */
        !           413:   
        !           414:   if(dev == NULL)
        !           415:     dev = init_etherdev(0, sizeof(struct eth16i_local));
        !           416: 
        !           417:   if( (eth16i_debug & version_printed++) == 0)
        !           418:     printk(version);
        !           419: 
        !           420:   dev->base_addr = ioaddr;
        !           421:  
        !           422:   irq = eth16i_get_irq(ioaddr);
        !           423:   dev->irq = irq;
        !           424: 
        !           425:   /* Try to obtain interrupt vector */
        !           426:   if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i")) {
        !           427:     printk("%s: %s at %#3x, but is unusable due 
        !           428:            conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
        !           429:     return EAGAIN;
        !           430:   }
        !           431: 
        !           432:   printk("%s: %s at %#3x, IRQ %d, ", 
        !           433:         dev->name, cardname, ioaddr, dev->irq);
        !           434: 
        !           435:   /* Let's grab the region */
        !           436:   request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i");
        !           437: 
        !           438:   /* Now we will have to lock the chip's io address */
        !           439:   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           440:   outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
        !           441: 
        !           442:   eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
        !           443:   
        !           444:   /* Now let's same some energy by shutting down the chip ;) */
        !           445:   BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
        !           446:    
        !           447:   /* Initialize the device structure */
        !           448:   if(dev->priv == NULL)
        !           449:     dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
        !           450:   memset(dev->priv, 0, sizeof(struct eth16i_local));
        !           451: 
        !           452:   dev->open               = eth16i_open;
        !           453:   dev->stop               = eth16i_close;
        !           454:   dev->hard_start_xmit    = eth16i_tx;
        !           455:   dev->get_stats          = eth16i_get_stats;
        !           456:   dev->set_multicast_list = &eth16i_multicast;
        !           457: 
        !           458:   /* Fill in the fields of the device structure with ethernet values. */
        !           459:   ether_setup(dev);
        !           460: 
        !           461:   boot = 0;
        !           462: 
        !           463:   return 0;
        !           464: }
        !           465: 
        !           466: 
        !           467: static void eth16i_initialize(struct device *dev)
        !           468: {
        !           469:   short ioaddr = dev->base_addr;
        !           470:   int i, node_w = 0;
        !           471:   unsigned char node_byte = 0;
        !           472: 
        !           473:   /* Setup station address */
        !           474:   eth16i_select_regbank(NODE_ID_RB, ioaddr);
        !           475:   for(i = 0 ; i < 3 ; i++) {
        !           476:     unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i);
        !           477:     ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
        !           478:   }
        !           479: 
        !           480:   for(i = 0; i < 6; i++) { 
        !           481:     outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
        !           482:     if(boot) {
        !           483:       printk("%02x", inb(ioaddr + NODE_ID_0 + i));
        !           484:       if(i != 5)
        !           485:        printk(":");
        !           486:     }
        !           487:   }
        !           488: 
        !           489:   /* Now we will set multicast addresses to accept none */
        !           490:   eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
        !           491:   for(i = 0; i < 8; i++) 
        !           492:     outb(0x00, ioaddr + HASH_TABLE_0 + i);
        !           493: 
        !           494:   /*
        !           495:      Now let's disable the transmitter and receiver, set the buffer ram 
        !           496:      cycle time, bus width and buffer data path width. Also we shall
        !           497:      set transmit buffer size and total buffer size.
        !           498:   */
        !           499: 
        !           500:   eth16i_select_regbank(2, ioaddr);
        !           501: 
        !           502:   node_byte = 0;
        !           503:   node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG);
        !           504: 
        !           505:   if( (node_w & 0xFF00) == 0x0800)
        !           506:     node_byte |= BUFFER_WIDTH_8;
        !           507: 
        !           508:   node_byte |= BS1;
        !           509: 
        !           510:   if( (node_w & 0x00FF) == 64)
        !           511:     node_byte |= BS0;
        !           512:   
        !           513:   node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
        !           514: 
        !           515:   outb(node_byte, ioaddr + CONFIG_REG_0);
        !           516: 
        !           517:   /* We shall halt the transmitting, if 16 collisions are detected */
        !           518:   outb(RETRANS_AND_HALT_ON_16, ioaddr + COL_16_REG);
        !           519: 
        !           520:   if(boot) /* Now set port type */
        !           521:   {
        !           522:     char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
        !           523:     
        !           524:     ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
        !           525:     dev->if_port = (ptype & 0x00FF);
        !           526:     
        !           527:     printk(" %s interface.\n", porttype[dev->if_port]);
        !           528: 
        !           529:     if(ptype == E_PORT_AUTO)
        !           530:       ptype = eth16i_probe_port(ioaddr);
        !           531:     
        !           532:     eth16i_set_port(ioaddr, ptype);
        !           533:   }
        !           534: 
        !           535:   /* Set Receive Mode to normal operation */
        !           536:   outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
        !           537: }
        !           538: 
        !           539: static int eth16i_probe_port(short ioaddr)
        !           540: {
        !           541:   int i;
        !           542:   int retcode;
        !           543:   unsigned char dummy_packet[64] = { 0 };
        !           544: 
        !           545:   /* Powerup the chip */
        !           546:   outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
        !           547: 
        !           548:   BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           549: 
        !           550:   eth16i_select_regbank(NODE_ID_RB, ioaddr);
        !           551: 
        !           552:   for(i = 0; i < 6; i++) {
        !           553:     dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i);
        !           554:     dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i);
        !           555:   }
        !           556: 
        !           557:   dummy_packet[12] = 0x00;
        !           558:   dummy_packet[13] = 0x04;
        !           559: 
        !           560:   eth16i_select_regbank(2, ioaddr);
        !           561: 
        !           562:   for(i = 0; i < 3; i++) {
        !           563:     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           564:     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !           565:     eth16i_set_port(ioaddr, i);
        !           566:    
        !           567:     if(eth16i_debug > 1)
        !           568:        printk("Set port number %d\n", i);
        !           569: 
        !           570:     retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
        !           571:     if(retcode == 0) {
        !           572:       retcode = eth16i_receive_probe_packet(ioaddr);
        !           573:       if(retcode != -1) {
        !           574:        if(eth16i_debug > 1)
        !           575:                printk("Eth16i interface port found at %d\n", i);
        !           576:        return i;
        !           577:       }
        !           578:     }
        !           579:     else {
        !           580:       if(eth16i_debug > 1)
        !           581:        printk("TRANSMIT_DONE timeout\n");
        !           582:     }
        !           583:   }
        !           584:   
        !           585:   if( eth16i_debug > 1)
        !           586:        printk("Using default port\n");
        !           587:  
        !           588:  return E_PORT_BNC;
        !           589: }
        !           590: 
        !           591: static void eth16i_set_port(short ioaddr, int porttype)
        !           592: { 
        !           593:     unsigned short temp = 0;
        !           594: 
        !           595:     eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           596:     outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
        !           597: 
        !           598:     temp |= DIS_AUTO_PORT_SEL;
        !           599: 
        !           600:     switch(porttype) {
        !           601: 
        !           602:     case E_PORT_BNC :
        !           603:       temp |= AUI_SELECT;
        !           604:       break;
        !           605: 
        !           606:     case E_PORT_TP :
        !           607:       break;
        !           608:       
        !           609:     case E_PORT_DIX :
        !           610:       temp |= AUI_SELECT;
        !           611:       BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
        !           612:       break;
        !           613:     }  
        !           614:     outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
        !           615: 
        !           616:     if(eth16i_debug > 1) {
        !           617:        printk("TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
        !           618:        printk("TRANSCEIVER_MODE_REG = %x\n", inb(ioaddr+TRANSCEIVER_MODE_REG));
        !           619:     }
        !           620: }
        !           621: 
        !           622: static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l)
        !           623: {
        !           624:   int starttime;
        !           625: 
        !           626:   outb(0xff, ioaddr + TX_STATUS_REG);
        !           627: 
        !           628:   outw(l, ioaddr + DATAPORT);
        !           629:   outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);  
        !           630:   
        !           631:   starttime = jiffies;
        !           632:   outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); 
        !           633: 
        !           634:   while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
        !           635:     if( (jiffies - starttime) > TIMEOUT_TICKS) {
        !           636:       break;
        !           637:     }
        !           638:   }
        !           639:   
        !           640:   return(0);
        !           641: }
        !           642: 
        !           643: static int eth16i_receive_probe_packet(short ioaddr)
        !           644: {
        !           645:   int starttime;
        !           646:   
        !           647:   starttime = jiffies;
        !           648:   
        !           649:   while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
        !           650:     if( (jiffies - starttime) > TIMEOUT_TICKS) {
        !           651:       
        !           652:       if(eth16i_debug > 1)
        !           653:        printk("Timeout occured waiting transmit packet received\n");
        !           654:       starttime = jiffies;
        !           655:       while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
        !           656:        if( (jiffies - starttime) > TIMEOUT_TICKS) {
        !           657:        if(eth16i_debug > 1)
        !           658:          printk("Timeout occured waiting receive packet\n");
        !           659:         return -1;
        !           660:         }
        !           661:       }
        !           662:       
        !           663:       if(eth16i_debug > 1)
        !           664:        printk("RECEIVE_PACKET\n");
        !           665:       return(0); /* Found receive packet */
        !           666:     }
        !           667:   }
        !           668: 
        !           669:   if(eth16i_debug > 1) {
        !           670:        printk("TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
        !           671:        printk("RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
        !           672:   }
        !           673: 
        !           674:   return(0); /* Return success */
        !           675: }
        !           676: 
        !           677: static int eth16i_get_irq(short ioaddr)
        !           678: {
        !           679:   unsigned char cbyte;
        !           680:   
        !           681:   if( ioaddr < 0x1000) {
        !           682:        cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
        !           683:        return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
        !           684:   } else {  /* Oh..the card is EISA so method getting IRQ different */
        !           685:        unsigned short index = 0;
        !           686:        cbyte = inb(ioaddr + EISA_IRQ_REG);
        !           687:        while( (cbyte & 0x01) == 0) {
        !           688:                cbyte = cbyte >> 1;
        !           689:                index++;
        !           690:         }
        !           691:        return( eth32i_irqmap[ index ] );
        !           692:   }
        !           693: }
        !           694: 
        !           695: static int eth16i_check_signature(short ioaddr)
        !           696: {
        !           697:   int i;
        !           698:   unsigned char creg[4] = { 0 };
        !           699:   
        !           700:   for(i = 0; i < 4 ; i++) {
        !           701: 
        !           702:     creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
        !           703:   
        !           704:     if(eth16i_debug > 1)
        !           705:        printk("eth16i: read signature byte %x at %x\n", creg[i],
        !           706:               ioaddr + TRANSMIT_MODE_REG + i);
        !           707:   }
        !           708: 
        !           709:   creg[0] &= 0x0F;      /* Mask collision cnr */
        !           710:   creg[2] &= 0x7F;      /* Mask DCLEN bit */
        !           711: 
        !           712: #ifdef 0
        !           713: /* 
        !           714:        This was removed because the card was sometimes left to state
        !           715:        from which it couldn't be find anymore. If there is need
        !           716:        to more strict chech still this have to be fixed.
        !           717: */
        !           718:   if( !( (creg[0] == 0x06) && (creg[1] == 0x41)) ) {
        !           719:     if(creg[1] != 0x42)
        !           720:       return -1;
        !           721:   }
        !           722: #endif
        !           723: 
        !           724:   if( !( (creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
        !           725:       creg[2] &= 0x42;
        !           726:       creg[3] &= 0x03;
        !           727: 
        !           728:       if( !( (creg[2] == 0x42) && (creg[3] == 0x00)) )
        !           729:        return -1;
        !           730:   }
        !           731: 
        !           732:   if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
        !           733:     return -1;
        !           734:   if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
        !           735:     return -1;
        !           736: 
        !           737:   return 0;
        !           738: }
        !           739: 
        !           740: static int eth16i_read_eeprom(int ioaddr, int offset)
        !           741: {
        !           742:   int data = 0;
        !           743: 
        !           744:   eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset);
        !           745:   outb(CS_1, ioaddr + EEPROM_CTRL_REG);
        !           746:   data = eth16i_read_eeprom_word(ioaddr);
        !           747:   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           748: 
        !           749:   return(data);  
        !           750: }
        !           751: 
        !           752: static int eth16i_read_eeprom_word(int ioaddr)
        !           753: {
        !           754:   int i;
        !           755:   int data = 0;
        !           756: 
        !           757:   for(i = 16; i > 0; i--) {
        !           758:     outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           759:     eeprom_slow_io();
        !           760:     outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           761:     eeprom_slow_io();
        !           762:     data = (data << 1) | ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
        !           763:     eeprom_slow_io();
        !           764:   }
        !           765: 
        !           766:   return(data);
        !           767: }
        !           768: 
        !           769: static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
        !           770: {
        !           771:   int i;
        !           772:   
        !           773:   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           774:   outb(DI_0, ioaddr + EEPROM_DATA_REG);
        !           775:   outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           776:   outb(DI_1, ioaddr + EEPROM_DATA_REG);
        !           777:   outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           778: 
        !           779:   for(i = 7; i >= 0; i--) {
        !           780:     short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 );
        !           781:     outb(cmd, ioaddr + EEPROM_DATA_REG);
        !           782:     outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           783:     eeprom_slow_io();
        !           784:     outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           785:     eeprom_slow_io();
        !           786:   } 
        !           787: }
        !           788: 
        !           789: static int eth16i_open(struct device *dev)
        !           790: {
        !           791:   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !           792:   int ioaddr = dev->base_addr;
        !           793:   
        !           794:   irq2dev_map[dev->irq] = dev;
        !           795: 
        !           796:   /* Powerup the chip */
        !           797:   outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
        !           798:   
        !           799:   /* Initialize the chip */
        !           800:   eth16i_initialize(dev);  
        !           801:   
        !           802:   /* Set the transmit buffer size */
        !           803:   lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
        !           804:   
        !           805:   if(eth16i_debug > 3)
        !           806:     printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
        !           807: 
        !           808:   /* Now enable Transmitter and Receiver sections */
        !           809:   BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !           810:  
        !           811:   /* Now switch to register bank 2, for run time operation */
        !           812:   eth16i_select_regbank(2, ioaddr);
        !           813: 
        !           814:   lp->open_time = jiffies;
        !           815:   lp->tx_started = 0;
        !           816:   lp->tx_queue = 0;
        !           817:   lp->tx_queue_len = 0;
        !           818: 
        !           819:   /* Turn on interrupts*/
        !           820:   outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);  
        !           821: 
        !           822:   dev->tbusy = 0;
        !           823:   dev->interrupt = 0;
        !           824:   dev->start = 1;
        !           825: 
        !           826: #ifdef MODULE
        !           827:   MOD_INC_USE_COUNT;
        !           828: #endif
        !           829: 
        !           830:   return 0;
        !           831: }
        !           832: 
        !           833: static int eth16i_close(struct device *dev)
        !           834: {
        !           835:   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !           836:   int ioaddr = dev->base_addr;
        !           837: 
        !           838:   lp->open_time = 0;
        !           839: 
        !           840:   dev->tbusy = 1;
        !           841:   dev->start = 0;
        !           842: 
        !           843:   /* Disable transmit and receive */
        !           844:   BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           845: 
        !           846:   /* Reset the chip */
        !           847:   outb(0xff, ioaddr + RESET);
        !           848: 
        !           849:   /* Save some energy by switching off power */
        !           850:   BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
        !           851: 
        !           852: #ifdef MODULE
        !           853:   MOD_DEC_USE_COUNT;
        !           854: #endif
        !           855: 
        !           856:   return 0;
        !           857: }
        !           858: 
        !           859: static int eth16i_tx(struct sk_buff *skb, struct device *dev)
        !           860: {
        !           861:   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !           862:   int ioaddr = dev->base_addr;
        !           863: 
        !           864:   if(dev->tbusy) {
        !           865:     /* 
        !           866:        If we get here, some higher level has decided that we are broken. 
        !           867:        There should really be a "kick me" function call instead. 
        !           868:     */
        !           869:     
        !           870:     int tickssofar = jiffies - dev->trans_start;
        !           871:     if(tickssofar < TIMEOUT_TICKS)  /* Let's not rush with our timeout, */  
        !           872:       return 1;                     /* wait a couple of ticks first     */
        !           873: 
        !           874:     printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
        !           875:           inw(ioaddr + TX_STATUS_REG), 
        !           876:           (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? 
        !           877:           "IRQ conflict" : "network cable problem");
        !           878: 
        !           879:     /* Let's dump all registers */
        !           880:     if(eth16i_debug > 0) { 
        !           881:       printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
        !           882:             dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2), 
        !           883:             inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
        !           884:             inb(ioaddr + 6), inb(ioaddr + 7));
        !           885: 
        !           886: 
        !           887:       printk("lp->tx_queue = %d\n", lp->tx_queue);
        !           888:       printk("lp->tx_queue_len = %d\n", lp->tx_queue_len);
        !           889:       printk("lp->tx_started = %d\n", lp->tx_started);
        !           890: 
        !           891:     }
        !           892: 
        !           893:     lp->stats.tx_errors++;
        !           894: 
        !           895:     /* Now let's try to restart the adaptor */
        !           896:     
        !           897:     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           898:     outw(0xffff, ioaddr + RESET);
        !           899:     eth16i_initialize(dev);
        !           900:     outw(0xffff, ioaddr + TX_STATUS_REG);
        !           901:     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !           902:             
        !           903:     lp->tx_started = 0;
        !           904:     lp->tx_queue = 0;
        !           905:     lp->tx_queue_len = 0;
        !           906:     
        !           907:     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !           908:     
        !           909:     dev->tbusy = 0;
        !           910:     dev->trans_start = jiffies;
        !           911:   }
        !           912: 
        !           913:   /* 
        !           914:      If some higher layer thinks we've missed an tx-done interrupt
        !           915:      we are passed NULL. Caution: dev_tint() handles the cli()/sti()
        !           916:      itself 
        !           917:   */
        !           918:   if(skb == NULL) {
        !           919:     dev_tint(dev);
        !           920:     return 0;
        !           921:   }
        !           922: 
        !           923:   /* Block a timer based transmitter from overlapping. This could better be
        !           924:      done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
        !           925: 
        !           926:   /* Turn off TX interrupts */
        !           927:   outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
        !           928: 
        !           929:   if(set_bit(0, (void *)&dev->tbusy) != 0)
        !           930:     printk("%s: Transmitter access conflict.\n", dev->name);
        !           931:   else {
        !           932:     short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        !           933:     unsigned char *buf = skb->data;
        !           934:   
        !           935:     outw(length, ioaddr + DATAPORT);
        !           936:     
        !           937:     if( ioaddr < 0x1000 ) 
        !           938:        outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
        !           939:     else {
        !           940:        unsigned char frag = length % 4;
        !           941: 
        !           942:        outsl(ioaddr + DATAPORT, buf, length >> 2);
        !           943:        
        !           944:        if( frag != 0 ) {
        !           945:          outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
        !           946:          if( frag == 3 ) 
        !           947:            outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
        !           948:        }
        !           949:     }
        !           950: 
        !           951:     lp->tx_queue++;
        !           952:     lp->tx_queue_len += length + 2;
        !           953: 
        !           954:     if(lp->tx_started == 0) {
        !           955:       /* If the transmitter is idle..always trigger a transmit */
        !           956:       outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
        !           957:       lp->tx_queue = 0;
        !           958:       lp->tx_queue_len = 0;
        !           959:       dev->trans_start = jiffies;
        !           960:       lp->tx_started = 1;
        !           961:       dev->tbusy = 0;
        !           962:     }
        !           963:     else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
        !           964:       /* There is still more room for one more packet in tx buffer */
        !           965:       dev->tbusy = 0;
        !           966:     }
        !           967:         
        !           968:     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !           969: 
        !           970:     /* Turn TX interrupts back on */
        !           971:     /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
        !           972:   } 
        !           973:   dev_kfree_skb(skb, FREE_WRITE);
        !           974: 
        !           975:   return 0;
        !           976: }
        !           977: 
        !           978: static void eth16i_rx(struct device *dev)
        !           979: {
        !           980:   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !           981:   int ioaddr = dev->base_addr;
        !           982:   int boguscount = MAX_RX_LOOP;
        !           983: 
        !           984:   /* Loop until all packets have been read */
        !           985:   while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
        !           986:     
        !           987:     /* Read status byte from receive buffer */ 
        !           988:     ushort status = inw(ioaddr + DATAPORT);
        !           989: 
        !           990:     if(eth16i_debug > 4)
        !           991:       printk("%s: Receiving packet mode %02x status %04x.\n", 
        !           992:             dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
        !           993:   
        !           994:       if( !(status & PKT_GOOD) ) {
        !           995:        /* Hmm..something went wrong. Let's check what error occured */
        !           996:        lp->stats.rx_errors++;
        !           997:        if( status & PKT_SHORT     ) lp->stats.rx_length_errors++;
        !           998:        if( status & PKT_ALIGN_ERR ) lp->stats.rx_frame_errors++;
        !           999:        if( status & PKT_CRC_ERR   ) lp->stats.rx_crc_errors++;
        !          1000:        if( status & PKT_RX_BUF_OVERFLOW) lp->stats.rx_over_errors++;
        !          1001:       }
        !          1002:       else {   /* Ok so now we should have a good packet */
        !          1003:        struct sk_buff *skb;
        !          1004: 
        !          1005:        /* Get the size of the packet from receive buffer */
        !          1006:        ushort pkt_len = inw(ioaddr + DATAPORT);
        !          1007: 
        !          1008:        if(pkt_len > ETH_FRAME_LEN) {
        !          1009:          printk("%s: %s claimed a very large packet, size of %d bytes.\n", 
        !          1010:                 dev->name, cardname, pkt_len);
        !          1011:          outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
        !          1012:          lp->stats.rx_dropped++;
        !          1013:          break;
        !          1014:        }
        !          1015: 
        !          1016:        skb = dev_alloc_skb(pkt_len + 3);
        !          1017:        if( skb == NULL ) {
        !          1018:          printk("%s: Could'n allocate memory for packet (len %d)\n", 
        !          1019:                 dev->name, pkt_len);
        !          1020:          outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
        !          1021:          lp->stats.rx_dropped++;
        !          1022:          break;
        !          1023:        }
        !          1024:        
        !          1025:        skb->dev = dev;
        !          1026:        skb_reserve(skb,2);
        !          1027:        /* 
        !          1028:           Now let's get the packet out of buffer.
        !          1029:           size is (pkt_len + 1) >> 1, cause we are now reading words
        !          1030:           and it have to be even aligned.
        !          1031:        */ 
        !          1032: 
        !          1033:        if( ioaddr < 0x1000) 
        !          1034:          insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
        !          1035:        else {  
        !          1036:          unsigned char *buf = skb_put(skb, pkt_len);
        !          1037:          unsigned char frag = pkt_len % 4;
        !          1038: 
        !          1039:          insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
        !          1040:        
        !          1041:          if(frag != 0) {
        !          1042:                unsigned short rest[2];
        !          1043:                rest[0] = inw( ioaddr + DATAPORT );
        !          1044:                if(frag == 3)
        !          1045:                        rest[1] = inw( ioaddr + DATAPORT );
        !          1046: 
        !          1047:                memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
        !          1048:          }
        !          1049:        }
        !          1050:        
        !          1051:         skb->protocol=eth_type_trans(skb, dev);
        !          1052:        netif_rx(skb);
        !          1053:        lp->stats.rx_packets++;
        !          1054:          
        !          1055:        if( eth16i_debug > 5 ) {
        !          1056:          int i;
        !          1057:          printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
        !          1058:          for(i = 0; i < 14; i++) 
        !          1059:            printk(" %02x", skb->data[i]);
        !          1060:          printk(".\n");
        !          1061:        }
        !          1062:        
        !          1063:       } /* else */
        !          1064: 
        !          1065:     if(--boguscount <= 0)
        !          1066:       break;
        !          1067: 
        !          1068:   } /* while */
        !          1069: 
        !          1070: #if 0
        !          1071:   {
        !          1072:     int i;
        !          1073: 
        !          1074:     for(i = 0; i < 20; i++) {
        !          1075:       if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == RX_BUFFER_EMPTY)
        !          1076:        break;
        !          1077:       inw(ioaddr + DATAPORT);
        !          1078:       outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
        !          1079:     }
        !          1080: 
        !          1081:     if(eth16i_debug > 1)
        !          1082:       printk("%s: Flushed receive buffer.\n", dev->name);
        !          1083:   }
        !          1084: #endif
        !          1085: 
        !          1086:   return;
        !          1087: }
        !          1088: 
        !          1089: static void eth16i_interrupt(int irq, struct pt_regs *regs)
        !          1090: {
        !          1091:   struct device *dev = (struct device *)(irq2dev_map[irq]);
        !          1092:   struct eth16i_local *lp;
        !          1093:   int ioaddr = 0,
        !          1094:       status;
        !          1095: 
        !          1096:   if(dev == NULL) {
        !          1097:     printk("eth16i_interrupt(): irq %d for unknown device. \n", irq);
        !          1098:     return;
        !          1099:   }
        !          1100: 
        !          1101:   /* Turn off all interrupts from adapter */
        !          1102:   outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); 
        !          1103: 
        !          1104:   dev->interrupt = 1;
        !          1105: 
        !          1106:   ioaddr = dev->base_addr;
        !          1107:   lp = (struct eth16i_local *)dev->priv;
        !          1108:   status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
        !          1109:   outw(status, ioaddr + TX_STATUS_REG);      /* Clear status bits */
        !          1110:   
        !          1111:   if(eth16i_debug > 3)
        !          1112:     printk("%s: Interrupt with status %04x.\n", dev->name, status);
        !          1113: 
        !          1114:   if( status & 0x00ff ) {          /* Let's check the transmit status reg */
        !          1115:     
        !          1116:     if(status & TX_DONE) {         /* The transmit has been done */
        !          1117:       lp->stats.tx_packets++;
        !          1118: 
        !          1119:       if(lp->tx_queue) {           /* Is there still packets ? */
        !          1120:          /* There was packet(s) so start transmitting and write also
        !          1121:           how many packets there is to be sended */
        !          1122:        outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
        !          1123:        lp->tx_queue = 0;
        !          1124:        lp->tx_queue_len = 0;
        !          1125:        dev->trans_start = jiffies;
        !          1126:        dev->tbusy = 0;
        !          1127:        mark_bh(NET_BH);
        !          1128:       }
        !          1129:       else {
        !          1130:        lp->tx_started = 0;
        !          1131:        dev->tbusy = 0;
        !          1132:        mark_bh(NET_BH);
        !          1133:       }
        !          1134:     }
        !          1135:   }
        !          1136:     
        !          1137:   if( ( status & 0xff00 ) || 
        !          1138:      ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
        !          1139:     eth16i_rx(dev);  /* We have packet in receive buffer */
        !          1140:   }
        !          1141: 
        !          1142:   dev->interrupt = 0;
        !          1143:   
        !          1144:   /* Turn interrupts back on */
        !          1145:   outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !          1146: 
        !          1147:   return;
        !          1148: }
        !          1149: 
        !          1150: static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs)
        !          1151: {
        !          1152:   short ioaddr = dev->base_addr;
        !          1153:   
        !          1154:   if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
        !          1155:   {
        !          1156:     dev->flags|=IFF_PROMISC;   /* Must do this */
        !          1157:     outb(3, ioaddr + RECEIVE_MODE_REG);    
        !          1158:   } else {
        !          1159:     outb(2, ioaddr + RECEIVE_MODE_REG);
        !          1160:   }
        !          1161: }
        !          1162: 
        !          1163: static struct enet_statistics *eth16i_get_stats(struct device *dev)
        !          1164: {
        !          1165:   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1166: 
        !          1167:   return &lp->stats;
        !          1168: }
        !          1169: 
        !          1170: static void eth16i_select_regbank(unsigned char banknbr, short ioaddr)
        !          1171: {
        !          1172:   unsigned char data;
        !          1173: 
        !          1174:   data = inb(ioaddr + CONFIG_REG_1);
        !          1175:   outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); 
        !          1176: }
        !          1177: 
        !          1178: #ifdef MODULE
        !          1179: static char devicename[9] = { 0, };
        !          1180: static struct device dev_eth16i = {
        !          1181:        devicename,
        !          1182:        0, 0, 0, 0,
        !          1183:        0, 0,
        !          1184:        0, 0, 0, NULL, eth16i_probe };
        !          1185: 
        !          1186: int io = 0x2a0;
        !          1187: int irq = 0;
        !          1188: 
        !          1189: int init_module(void)
        !          1190: {
        !          1191:        if(io == 0)
        !          1192:                printk("eth16i: You should not use auto-probing with insmod!\n");
        !          1193:        
        !          1194:        dev_eth16i.base_addr = io;
        !          1195:        dev_eth16i.irq = irq;
        !          1196:        if( register_netdev( &dev_eth16i ) != 0 ) {
        !          1197:                printk("eth16i: register_netdev() returned non-zero.\n");
        !          1198:                return -EIO;
        !          1199:        }
        !          1200: 
        !          1201:        return 0;
        !          1202: }
        !          1203: 
        !          1204: void cleanup_module(void)
        !          1205: {
        !          1206:        unregister_netdev( &dev_eth16i );
        !          1207:        free_irq( dev_eth16i.irq );
        !          1208:        irq2dev_map[ dev_eth16i.irq ] = NULL;
        !          1209:        release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT );
        !          1210: }
        !          1211: 
        !          1212: #endif /* MODULE */
        !          1213: 
        !          1214: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.