Annotation of Gnu-Mach/linux/src/drivers/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-1998 by Mika Kuoppala
        !             4:    
        !             5:    Copyright (C) 1994-1998 by Mika Kuoppala
        !             6:    Based on skeleton.c and heavily on 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:          (Uses true 32 bit transfers rather than 16i compability mode)
        !            17: 
        !            18:    Example Module usage:
        !            19:         insmod eth16i.o ioaddr=0x2a0 mediatype=bnc
        !            20: 
        !            21:        mediatype can be one of the following: bnc,tp,dix,auto,eprom
        !            22: 
        !            23:        'auto' will try to autoprobe mediatype.
        !            24:        'eprom' will use whatever type defined in eprom.
        !            25: 
        !            26:    I have benchmarked driver with PII/300Mhz as a ftp client
        !            27:    and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
        !            28:    
        !            29:    Sources:
        !            30:      - skeleton.c  a sample network driver core for linux,
        !            31:        written by Donald Becker <[email protected]>
        !            32:      - at1700.c a driver for Allied Telesis AT1700, written 
        !            33:        by Donald Becker.
        !            34:      - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
        !            35:        written by Markku Viima
        !            36:      - The Fujitsu MB86965 databook.
        !            37:    
        !            38:    Author thanks following persons due to their valueble assistance:    
        !            39:         Markku Viima (ICL)
        !            40:        Ari Valve (ICL)      
        !            41:        Donald Becker
        !            42:        Kurt Huwig <[email protected]>
        !            43: 
        !            44:    Revision history:
        !            45: 
        !            46:    Version     Date            Description
        !            47:    
        !            48:    0.01         15.12-94        Initial version (card detection)
        !            49:    0.02         23.01-95        Interrupt is now hooked correctly
        !            50:    0.03         01.02-95        Rewrote initialization part
        !            51:    0.04         07.02-95        Base skeleton done...
        !            52:                                 Made a few changes to signature checking
        !            53:                                 to make it a bit reliable.
        !            54:                                 - fixed bug in tx_buf mapping
        !            55:                                 - fixed bug in initialization (DLC_EN
        !            56:                                   wasn't enabled when initialization
        !            57:                                   was done.)
        !            58:    0.05         08.02-95        If there were more than one packet to send,
        !            59:                                 transmit was jammed due to invalid
        !            60:                                 register write...now fixed
        !            61:    0.06         19.02-95        Rewrote interrupt handling        
        !            62:    0.07         13.04-95        Wrote EEPROM read routines
        !            63:                                 Card configuration now set according to
        !            64:                                 data read from EEPROM
        !            65:    0.08         23.06-95        Wrote part that tries to probe used interface
        !            66:                                 port if AUTO is selected
        !            67: 
        !            68:    0.09         01.09-95        Added module support
        !            69:    
        !            70:    0.10         04.09-95        Fixed receive packet allocation to work
        !            71:                                 with kernels > 1.3.x
        !            72:       
        !            73:    0.20                20.09-95        Added support for EtherTeam32 EISA      
        !            74: 
        !            75:    0.21         17.10-95        Removed the unnecessary extern 
        !            76:                                init_etherdev() declaration. Some
        !            77:                                other cleanups.
        !            78:                                
        !            79:    0.22                22.02-96        Receive buffer was not flushed
        !            80:                                correctly when faulty packet was
        !            81:                                received. Now fixed.
        !            82: 
        !            83:    0.23                26.02-96        Made resetting the adapter      
        !            84:                                more reliable.
        !            85:    
        !            86:    0.24                27.02-96        Rewrote faulty packet handling in eth16i_rx
        !            87: 
        !            88:    0.25                22.05-96        kfree() was missing from cleanup_module.
        !            89: 
        !            90:    0.26                11.06-96        Sometimes card was not found by 
        !            91:                                check_signature(). Now made more reliable.
        !            92:    
        !            93:    0.27                23.06-96        Oops. 16 consecutive collisions halted 
        !            94:                                adapter. Now will try to retransmit 
        !            95:                                MAX_COL_16 times before finally giving up.
        !            96:    
        !            97:    0.28                28.10-97        Added dev_id parameter (NULL) for free_irq
        !            98: 
        !            99:    0.29         29.10-97        Multiple card support for module users
        !           100: 
        !           101:    0.30         30.10-97        Fixed irq allocation bug.
        !           102:                                 (request_irq moved from probe to open)
        !           103: 
        !           104:    0.30a        21.08-98        Card detection made more relaxed. Driver
        !           105:                                 had problems with some TCP/IP-PROM boots
        !           106:                                to find the card. Suggested by 
        !           107:                                Kurt Huwig <[email protected]>
        !           108: 
        !           109:    0.31         28.08-98        Media interface port can now be selected
        !           110:                                 with module parameters or kernel
        !           111:                                boot parameters. 
        !           112: 
        !           113:    0.32         31.08-98        IRQ was never freed if open/close 
        !           114:                                 pair wasn't called. Now fixed.
        !           115:    
        !           116:    0.33         10.09-98        When eth16i_open() was called after
        !           117:                                 eth16i_close() chip never recovered.
        !           118:                                Now more shallow reset is made on
        !           119:                                close.
        !           120: 
        !           121:    Bugs:
        !           122:        In some cases the media interface autoprobing code doesn't find 
        !           123:        the correct interface type. In this case you can 
        !           124:        manually choose the interface type in DOS with E16IC.EXE which is 
        !           125:        configuration software for EtherTeam16i and EtherTeam32 cards.
        !           126:        This is also true for IRQ setting. You cannot use module
        !           127:        parameter to configure IRQ of the card (yet). 
        !           128: 
        !           129:    To do:
        !           130:        - Real multicast support
        !           131:        - Rewrite the media interface autoprobing code. Its _horrible_ !
        !           132:        - Possibly merge all the MB86965 specific code to external
        !           133:          module for use by eth16.c and Donald's at1700.c
        !           134:        - IRQ configuration with module parameter. I will do
        !           135:          this when i will get enough info about setting
        !           136:          irq without configuration utility.
        !           137: */
        !           138: 
        !           139: static char *version = 
        !           140:     "eth16i.c: v0.33 10-09-98 Mika Kuoppala ([email protected])\n";
        !           141: 
        !           142: #include <linux/module.h>
        !           143: 
        !           144: #include <linux/kernel.h>
        !           145: #include <linux/sched.h>
        !           146: #include <linux/types.h>                 
        !           147: #include <linux/fcntl.h>                 
        !           148: #include <linux/interrupt.h>             
        !           149: #include <linux/ptrace.h>                
        !           150: #include <linux/ioport.h>                
        !           151: #include <linux/in.h>            
        !           152: #include <linux/malloc.h>                
        !           153: #include <linux/string.h>                
        !           154: #include <linux/errno.h>
        !           155: 
        !           156: #include <linux/netdevice.h>
        !           157: #include <linux/etherdevice.h>
        !           158: #include <linux/skbuff.h>
        !           159: 
        !           160: #include <asm/system.h>                  
        !           161: #include <asm/bitops.h>                  
        !           162: #include <asm/io.h>              
        !           163: #include <asm/dma.h>
        !           164: 
        !           165: #ifndef LINUX_VERSION_CODE
        !           166: #include <linux/version.h>
        !           167: #endif
        !           168: 
        !           169: #if LINUX_VERSION_CODE >= 0x20123
        !           170: #include <linux/init.h>
        !           171: #else
        !           172: #define __init
        !           173: #define __initdata
        !           174: #define __initfunc(x) x
        !           175: #endif
        !           176: 
        !           177: #if LINUX_VERSION_CODE < 0x20138
        !           178: #define test_and_set_bit(val,addr) set_bit(val,addr)
        !           179: #endif
        !           180: 
        !           181: #if LINUX_VERSION_CODE < 0x020100
        !           182: typedef struct enet_statistics eth16i_stats_type;
        !           183: #else
        !           184: typedef struct net_device_stats eth16i_stats_type;
        !           185: #endif
        !           186: 
        !           187: /* Few macros */
        !           188: #define BIT(a)                ( (1 << (a)) )  
        !           189: #define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) 
        !           190: #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
        !           191: 
        !           192: /* This is the I/O address space for Etherteam 16i adapter. */
        !           193: #define ETH16I_IO_EXTENT       32
        !           194: 
        !           195: /* Ticks before deciding that transmit has timed out */
        !           196: #define TX_TIMEOUT             (400*HZ/1000)
        !           197: 
        !           198: /* Maximum loop count when receiving packets */
        !           199: #define MAX_RX_LOOP            20
        !           200: 
        !           201: /* Some interrupt masks */
        !           202: #define ETH16I_INTR_ON        0xef8a       /* Higher is receive mask */
        !           203: #define ETH16I_INTR_OFF               0x0000
        !           204:         
        !           205: /* Buffers header status byte meanings */
        !           206: #define PKT_GOOD               BIT(5)
        !           207: #define PKT_GOOD_RMT           BIT(4)
        !           208: #define PKT_SHORT              BIT(3)
        !           209: #define PKT_ALIGN_ERR          BIT(2)
        !           210: #define PKT_CRC_ERR            BIT(1)
        !           211: #define PKT_RX_BUF_OVERFLOW    BIT(0)
        !           212: 
        !           213: /* Transmit status register (DLCR0) */
        !           214: #define TX_STATUS_REG          0
        !           215: #define TX_DONE                BIT(7)
        !           216: #define NET_BUSY               BIT(6)
        !           217: #define TX_PKT_RCD             BIT(5)
        !           218: #define CR_LOST                BIT(4)
        !           219: #define TX_JABBER_ERR         BIT(3)
        !           220: #define COLLISION              BIT(2)
        !           221: #define COLLISIONS_16          BIT(1)
        !           222: 
        !           223: /* Receive status register (DLCR1) */
        !           224: #define RX_STATUS_REG          1
        !           225: #define RX_PKT                 BIT(7)  /* Packet received */
        !           226: #define BUS_RD_ERR             BIT(6)
        !           227: #define SHORT_PKT_ERR          BIT(3)
        !           228: #define ALIGN_ERR              BIT(2)
        !           229: #define CRC_ERR                BIT(1)
        !           230: #define RX_BUF_OVERFLOW        BIT(0)
        !           231:               
        !           232: /* Transmit Interrupt Enable Register (DLCR2) */
        !           233: #define TX_INTR_REG            2
        !           234: #define TX_INTR_DONE           BIT(7)
        !           235: #define TX_INTR_COL            BIT(2)
        !           236: #define TX_INTR_16_COL         BIT(1)
        !           237: 
        !           238: /* Receive Interrupt Enable Register (DLCR3) */
        !           239: #define RX_INTR_REG            3
        !           240: #define RX_INTR_RECEIVE        BIT(7)
        !           241: #define RX_INTR_SHORT_PKT      BIT(3)
        !           242: #define RX_INTR_CRC_ERR        BIT(1)
        !           243: #define RX_INTR_BUF_OVERFLOW   BIT(0)
        !           244: 
        !           245: /* Transmit Mode Register (DLCR4) */
        !           246: #define TRANSMIT_MODE_REG      4
        !           247: #define LOOPBACK_CONTROL       BIT(1)
        !           248: #define CONTROL_OUTPUT         BIT(2)
        !           249: 
        !           250: /* Receive Mode Register (DLCR5) */
        !           251: #define RECEIVE_MODE_REG       5
        !           252: #define RX_BUFFER_EMPTY        BIT(6)
        !           253: #define ACCEPT_BAD_PACKETS     BIT(5)
        !           254: #define RECEIVE_SHORT_ADDR     BIT(4)
        !           255: #define ACCEPT_SHORT_PACKETS   BIT(3)
        !           256: #define REMOTE_RESET           BIT(2)
        !           257: 
        !           258: #define ADDRESS_FILTER_MODE    BIT(1) | BIT(0)
        !           259: #define REJECT_ALL             0
        !           260: #define ACCEPT_ALL             3
        !           261: #define MODE_1                 1            /* NODE ID, BC, MC, 2-24th bit */
        !           262: #define MODE_2                 2            /* NODE ID, BC, MC, Hash Table */
        !           263: 
        !           264: /* Configuration Register 0 (DLCR6) */
        !           265: #define CONFIG_REG_0           6
        !           266: #define DLC_EN                 BIT(7)
        !           267: #define SRAM_CYCLE_TIME_100NS  BIT(6)
        !           268: #define SYSTEM_BUS_WIDTH_8     BIT(5)       /* 1 = 8bit, 0 = 16bit */
        !           269: #define BUFFER_WIDTH_8         BIT(4)       /* 1 = 8bit, 0 = 16bit */
        !           270: #define TBS1                   BIT(3)       
        !           271: #define TBS0                   BIT(2)
        !           272: #define SRAM_BS1               BIT(1)       /* 00=8kb,  01=16kb  */
        !           273: #define SRAM_BS0               BIT(0)       /* 10=32kb, 11=64kb  */
        !           274: 
        !           275: #ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */ 
        !           276: #define ETH16I_TX_BUF_SIZE     3             /* 2 = 8kb, 3 = 16kb */
        !           277: #endif                                      
        !           278: #define TX_BUF_1x2048          0
        !           279: #define TX_BUF_2x2048          1
        !           280: #define TX_BUF_2x4098          2
        !           281: #define TX_BUF_2x8192          3
        !           282: 
        !           283: /* Configuration Register 1 (DLCR7) */
        !           284: #define CONFIG_REG_1           7
        !           285: #define POWERUP                BIT(5)
        !           286: 
        !           287: /* Transmit start register */
        !           288: #define TRANSMIT_START_REG     10
        !           289: #define TRANSMIT_START_RB      2
        !           290: #define TX_START               BIT(7)       /* Rest of register bit indicate*/
        !           291:                                             /* number of packets in tx buffer*/
        !           292: /* Node ID registers (DLCR8-13) */
        !           293: #define NODE_ID_0              8
        !           294: #define NODE_ID_RB             0
        !           295: 
        !           296: /* Hash Table registers (HT8-15) */
        !           297: #define HASH_TABLE_0           8
        !           298: #define HASH_TABLE_RB          1
        !           299: 
        !           300: /* Buffer memory ports */
        !           301: #define BUFFER_MEM_PORT_LB     8
        !           302: #define DATAPORT               BUFFER_MEM_PORT_LB
        !           303: #define BUFFER_MEM_PORT_HB     9
        !           304: 
        !           305: /* 16 Collision control register (BMPR11) */
        !           306: #define COL_16_REG             11
        !           307: #define HALT_ON_16             0x00
        !           308: #define RETRANS_AND_HALT_ON_16 0x02
        !           309: 
        !           310: /* Maximum number of attempts to send after 16 concecutive collisions */
        !           311: #define MAX_COL_16            10
        !           312: 
        !           313: /* DMA Burst and Transceiver Mode Register (BMPR13) */
        !           314: #define TRANSCEIVER_MODE_REG   13
        !           315: #define TRANSCEIVER_MODE_RB    2         
        !           316: #define IO_BASE_UNLOCK        BIT(7)
        !           317: #define LOWER_SQUELCH_TRESH    BIT(6)
        !           318: #define LINK_TEST_DISABLE      BIT(5)
        !           319: #define AUI_SELECT             BIT(4)
        !           320: #define DIS_AUTO_PORT_SEL      BIT(3)
        !           321: 
        !           322: /* Filter Self Receive Register (BMPR14)  */
        !           323: #define FILTER_SELF_RX_REG     14
        !           324: #define SKIP_RX_PACKET         BIT(2)
        !           325: #define FILTER_SELF_RECEIVE    BIT(0)
        !           326: 
        !           327: /* EEPROM Control Register (BMPR 16) */
        !           328: #define EEPROM_CTRL_REG        16
        !           329: 
        !           330: /* EEPROM Data Register (BMPR 17) */
        !           331: #define EEPROM_DATA_REG        17
        !           332: 
        !           333: /* NMC93CSx6 EEPROM Control Bits */
        !           334: #define CS_0                   0x00
        !           335: #define CS_1                   0x20
        !           336: #define SK_0                   0x00
        !           337: #define SK_1                   0x40
        !           338: #define DI_0                   0x00
        !           339: #define DI_1                   0x80
        !           340: 
        !           341: /* NMC93CSx6 EEPROM Instructions */
        !           342: #define EEPROM_READ            0x80
        !           343: 
        !           344: /* NMC93CSx6 EEPROM Addresses */
        !           345: #define E_NODEID_0             0x02
        !           346: #define E_NODEID_1             0x03
        !           347: #define E_NODEID_2             0x04
        !           348: #define E_PORT_SELECT          0x14
        !           349:   #define E_PORT_BNC           0x00
        !           350:   #define E_PORT_DIX           0x01
        !           351:   #define E_PORT_TP            0x02
        !           352:   #define E_PORT_AUTO          0x03
        !           353:   #define E_PORT_FROM_EPROM    0x04
        !           354: #define E_PRODUCT_CFG          0x30
        !           355:  
        !           356: 
        !           357: /* Macro to slow down io between EEPROM clock transitions */
        !           358: #define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
        !           359: 
        !           360: /* Jumperless Configuration Register (BMPR19) */
        !           361: #define JUMPERLESS_CONFIG      19
        !           362: 
        !           363: /* ID ROM registers, writing to them also resets some parts of chip */
        !           364: #define ID_ROM_0               24
        !           365: #define ID_ROM_7               31
        !           366: #define RESET                  ID_ROM_0
        !           367: 
        !           368: /* This is the I/O address list to be probed when seeking the card */
        !           369: static unsigned int eth16i_portlist[] =
        !           370:    { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 };
        !           371: 
        !           372: static unsigned int eth32i_portlist[] =
        !           373:    { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
        !           374:      0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 };
        !           375: 
        !           376: /* This is the Interrupt lookup table for Eth16i card */
        !           377: static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15, 0 };
        !           378: #define NUM_OF_ISA_IRQS    4
        !           379: 
        !           380: /* This is the Interrupt lookup table for Eth32i card */
        !           381: static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };  
        !           382: #define EISA_IRQ_REG   0xc89
        !           383: #define NUM_OF_EISA_IRQS   8
        !           384: 
        !           385: static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
        !           386: static unsigned int boot = 1;
        !           387: 
        !           388: /* Use 0 for production, 1 for verification, >2 for debug */
        !           389: #ifndef ETH16I_DEBUG
        !           390: #define ETH16I_DEBUG 0
        !           391: #endif
        !           392: static unsigned int eth16i_debug = ETH16I_DEBUG;
        !           393: 
        !           394: /* Information for each board */
        !           395: 
        !           396: struct eth16i_local {
        !           397:        eth16i_stats_type stats;
        !           398:        unsigned char     tx_started;
        !           399:        unsigned char     tx_buf_busy;
        !           400:        unsigned short    tx_queue;  /* Number of packets in transmit buffer */
        !           401:        unsigned short    tx_queue_len;         
        !           402:        unsigned int      tx_buf_size;
        !           403:        unsigned long     open_time;
        !           404:        unsigned long     tx_buffered_packets;  
        !           405:        unsigned long     col_16;
        !           406: };
        !           407: 
        !           408: /* Function prototypes */
        !           409: 
        !           410: extern int     eth16i_probe(struct device *dev);
        !           411: 
        !           412: static int     eth16i_probe1(struct device *dev, int ioaddr);
        !           413: static int     eth16i_check_signature(int ioaddr);
        !           414: static int     eth16i_probe_port(int ioaddr);
        !           415: static void    eth16i_set_port(int ioaddr, int porttype);
        !           416: static int     eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l);
        !           417: static int     eth16i_receive_probe_packet(int ioaddr);
        !           418: static int     eth16i_get_irq(int ioaddr);
        !           419: static int     eth16i_read_eeprom(int ioaddr, int offset);
        !           420: static int     eth16i_read_eeprom_word(int ioaddr);
        !           421: static void    eth16i_eeprom_cmd(int ioaddr, unsigned char command);
        !           422: static int     eth16i_open(struct device *dev);
        !           423: static int     eth16i_close(struct device *dev);
        !           424: static int     eth16i_tx(struct sk_buff *skb, struct device *dev);
        !           425: static void    eth16i_rx(struct device *dev);
        !           426: static void    eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
        !           427: static void    eth16i_reset(struct device *dev);
        !           428: static void    eth16i_skip_packet(struct device *dev);
        !           429: static void    eth16i_multicast(struct device *dev); 
        !           430: static void    eth16i_select_regbank(unsigned char regbank, int ioaddr);
        !           431: static void    eth16i_initialize(struct device *dev);
        !           432: 
        !           433: #if 0
        !           434: static int     eth16i_set_irq(struct device *dev);
        !           435: #endif
        !           436: 
        !           437: #ifdef MODULE
        !           438: static ushort  eth16i_parse_mediatype(const char* s);
        !           439: #endif
        !           440: 
        !           441: static struct enet_statistics *eth16i_get_stats(struct device *dev);
        !           442: 
        !           443: static char *cardname = "ICL EtherTeam 16i/32";
        !           444: 
        !           445: #ifdef HAVE_DEVLIST 
        !           446: 
        !           447: /* Support for alternate probe manager */
        !           448: /struct netdev_entry eth16i_drv = 
        !           449:  {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; 
        !           450: 
        !           451: #else  /* Not HAVE_DEVLIST */
        !           452: 
        !           453: __initfunc(int eth16i_probe(struct device *dev))
        !           454: {
        !           455:        int i;
        !           456:        int ioaddr;
        !           457:        int base_addr = dev ? dev->base_addr : 0;
        !           458:     
        !           459:        if(eth16i_debug > 4) 
        !           460:                printk(KERN_DEBUG "Probing started for %s\n", cardname);
        !           461: 
        !           462:        if(base_addr > 0x1ff)           /* Check only single location */
        !           463:                return eth16i_probe1(dev, base_addr);
        !           464:        else if(base_addr != 0)         /* Don't probe at all */
        !           465:                return ENXIO;
        !           466: 
        !           467:        /* Seek card from the ISA io address space */
        !           468:        for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) {
        !           469:                if(check_region(ioaddr, ETH16I_IO_EXTENT))
        !           470:                        continue;
        !           471:                if(eth16i_probe1(dev, ioaddr) == 0)
        !           472:                        return 0;
        !           473:        }
        !           474: 
        !           475:        /* Seek card from the EISA io address space */
        !           476:        for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) {
        !           477:                if(check_region(ioaddr, ETH16I_IO_EXTENT))
        !           478:                        continue;
        !           479:                if(eth16i_probe1(dev, ioaddr) == 0)
        !           480:                        return 0;
        !           481:        }
        !           482: 
        !           483:        return ENODEV;
        !           484: }
        !           485: #endif  /* Not HAVE_DEVLIST */
        !           486: 
        !           487: __initfunc(static int eth16i_probe1(struct device *dev, int ioaddr))
        !           488: {
        !           489:        static unsigned version_printed = 0;
        !           490:        boot = 1;  /* To inform initilization that we are in boot probe */
        !           491: 
        !           492:        /*
        !           493:          The MB86985 chip has on register which holds information in which 
        !           494:          io address the chip lies. First read this register and compare
        !           495:          it to our current io address and if match then this could
        !           496:          be our chip.
        !           497:          */
        !           498: 
        !           499:        if(ioaddr < 0x1000) {
        !           500:        
        !           501:                if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] 
        !           502:                   != ioaddr)
        !           503:                        return -ENODEV;
        !           504:        }
        !           505: 
        !           506:        /* Now we will go a bit deeper and try to find the chip's signature */
        !           507: 
        !           508:        if(eth16i_check_signature(ioaddr) != 0) 
        !           509:                return -ENODEV;
        !           510: 
        !           511:        /* 
        !           512:           Now it seems that we have found a ethernet chip in this particular
        !           513:           ioaddr. The MB86985 chip has this feature, that when you read a 
        !           514:           certain register it will increase it's io base address to next
        !           515:           configurable slot. Now when we have found the chip, first thing is
        !           516:           to make sure that the chip's ioaddr will hold still here.
        !           517:           */
        !           518: 
        !           519:        eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           520:        outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
        !           521: 
        !           522:        outb(0x00, ioaddr + RESET);             /* Reset some parts of chip */
        !           523:        BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* Disable the data link */
        !           524: 
        !           525:        if(dev == NULL)
        !           526:                dev = init_etherdev(0, 0);
        !           527: 
        !           528:        if( (eth16i_debug & version_printed++) == 0)
        !           529:                printk(KERN_INFO "%s", version);
        !           530: 
        !           531:        dev->base_addr = ioaddr;
        !           532:        
        !           533: #if 0
        !           534:        if(dev->irq) {
        !           535:                if(eth16i_set_irq(dev)) {
        !           536:                        dev->irq = eth16i_get_irq(ioaddr);
        !           537:                }
        !           538: 
        !           539:        }
        !           540:        else {
        !           541: #endif
        !           542: 
        !           543:        dev->irq = eth16i_get_irq(ioaddr);
        !           544: 
        !           545:        /* Try to obtain interrupt vector */
        !           546: 
        !           547:        if (request_irq(dev->irq, (void *)&eth16i_interrupt, 0, "eth16i", dev)) {       
        !           548:                printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", 
        !           549:                       dev->name, cardname, ioaddr, dev->irq);
        !           550:                return -EAGAIN;
        !           551:        }
        !           552: 
        !           553: #if 0
        !           554:        irq2dev_map[dev->irq] = dev;
        !           555: #endif
        !           556: 
        !           557:        printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ",
        !           558:               dev->name, cardname, ioaddr, dev->irq);
        !           559: 
        !           560:        /* Let's grab the region */
        !           561:        request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i");
        !           562: 
        !           563:        /* Now we will have to lock the chip's io address */
        !           564:        eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           565:        outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
        !           566: 
        !           567:        eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
        !           568: 
        !           569:        /* Now let's same some energy by shutting down the chip ;) */
        !           570:        BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
        !           571: 
        !           572:        /* Initialize the device structure */
        !           573:        if(dev->priv == NULL) {
        !           574:                dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
        !           575:                if(dev->priv == NULL)
        !           576:                        return -ENOMEM;
        !           577:        }
        !           578: 
        !           579:        memset(dev->priv, 0, sizeof(struct eth16i_local));
        !           580: 
        !           581:        dev->open               = eth16i_open;
        !           582:        dev->stop               = eth16i_close;
        !           583:        dev->hard_start_xmit    = eth16i_tx;
        !           584:        dev->get_stats          = eth16i_get_stats;
        !           585:        dev->set_multicast_list = &eth16i_multicast;
        !           586: 
        !           587:        /* Fill in the fields of the device structure with ethernet values. */
        !           588:        ether_setup(dev);
        !           589: 
        !           590:        boot = 0;
        !           591: 
        !           592:        return 0;
        !           593: }
        !           594: 
        !           595: 
        !           596: static void eth16i_initialize(struct device *dev)
        !           597: {
        !           598:        int ioaddr = dev->base_addr;
        !           599:        int i, node_w = 0;
        !           600:        unsigned char node_byte = 0;
        !           601: 
        !           602:        /* Setup station address */
        !           603:        eth16i_select_regbank(NODE_ID_RB, ioaddr);
        !           604:        for(i = 0 ; i < 3 ; i++) {
        !           605:                unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i);
        !           606:                ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
        !           607:        }
        !           608: 
        !           609:        for(i = 0; i < 6; i++) { 
        !           610:                outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
        !           611:                if(boot) {
        !           612:                        printk("%02x", inb(ioaddr + NODE_ID_0 + i));
        !           613:                        if(i != 5)
        !           614:                                printk(":");
        !           615:                }
        !           616:        }
        !           617: 
        !           618:        /* Now we will set multicast addresses to accept none */
        !           619:        eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
        !           620:        for(i = 0; i < 8; i++) 
        !           621:                outb(0x00, ioaddr + HASH_TABLE_0 + i);
        !           622: 
        !           623:        /*
        !           624:          Now let's disable the transmitter and receiver, set the buffer ram 
        !           625:          cycle time, bus width and buffer data path width. Also we shall
        !           626:          set transmit buffer size and total buffer size.
        !           627:          */
        !           628: 
        !           629:        eth16i_select_regbank(2, ioaddr);
        !           630: 
        !           631:        node_byte = 0;
        !           632:        node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG);
        !           633: 
        !           634:        if( (node_w & 0xFF00) == 0x0800)
        !           635:                node_byte |= BUFFER_WIDTH_8;
        !           636: 
        !           637:        node_byte |= SRAM_BS1;
        !           638: 
        !           639:        if( (node_w & 0x00FF) == 64)
        !           640:                node_byte |= SRAM_BS0;
        !           641: 
        !           642:        node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
        !           643: 
        !           644:        outb(node_byte, ioaddr + CONFIG_REG_0);
        !           645: 
        !           646:        /* We shall halt the transmitting, if 16 collisions are detected */
        !           647:        outb(HALT_ON_16, ioaddr + COL_16_REG);
        !           648: 
        !           649: #ifdef MODULE
        !           650:        /* if_port already set by init_module() */
        !           651: #else
        !           652:        dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ? 
        !           653:                dev->mem_start : E_PORT_FROM_EPROM;
        !           654: #endif
        !           655: 
        !           656:        /* Set interface port type */
        !           657:        if(boot) {
        !           658:                char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" };
        !           659: 
        !           660:                switch(dev->if_port)
        !           661:                {
        !           662: 
        !           663:                case E_PORT_FROM_EPROM:
        !           664:                        dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
        !           665:                        break;
        !           666: 
        !           667:                case E_PORT_AUTO:
        !           668:                        dev->if_port = eth16i_probe_port(ioaddr);
        !           669:                        break;
        !           670:                        
        !           671:                case E_PORT_BNC:
        !           672:                case E_PORT_TP:
        !           673:                case E_PORT_DIX:
        !           674:                        break;
        !           675:                }
        !           676: 
        !           677:                printk(" %s interface.\n", porttype[dev->if_port]);
        !           678: 
        !           679:                eth16i_set_port(ioaddr, dev->if_port);
        !           680:        }
        !           681: 
        !           682:        /* Set Receive Mode to normal operation */
        !           683:        outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
        !           684: }
        !           685: 
        !           686: static int eth16i_probe_port(int ioaddr)
        !           687: {
        !           688:        int i;
        !           689:        int retcode;
        !           690:        unsigned char dummy_packet[64] = { 0 };
        !           691: 
        !           692:        /* Powerup the chip */
        !           693:        outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
        !           694: 
        !           695:        BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           696: 
        !           697:        eth16i_select_regbank(NODE_ID_RB, ioaddr);
        !           698: 
        !           699:        for(i = 0; i < 6; i++) {
        !           700:                dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i);
        !           701:                dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i);
        !           702:        }
        !           703: 
        !           704:        dummy_packet[12] = 0x00;
        !           705:        dummy_packet[13] = 0x04;
        !           706: 
        !           707:        eth16i_select_regbank(2, ioaddr);
        !           708: 
        !           709:        for(i = 0; i < 3; i++) {
        !           710:                BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !           711:                BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !           712:                eth16i_set_port(ioaddr, i);
        !           713: 
        !           714:                if(eth16i_debug > 1)
        !           715:                        printk(KERN_DEBUG "Set port number %d\n", i);
        !           716: 
        !           717:                retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
        !           718:                if(retcode == 0) {
        !           719:                        retcode = eth16i_receive_probe_packet(ioaddr);
        !           720:                        if(retcode != -1) {
        !           721:                                if(eth16i_debug > 1)
        !           722:                                        printk(KERN_DEBUG "Eth16i interface port found at %d\n", i);
        !           723:                                return i;
        !           724:                        }
        !           725:                }
        !           726:                else {
        !           727:                        if(eth16i_debug > 1)
        !           728:                                printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n");
        !           729:                }
        !           730:        }
        !           731: 
        !           732:        if( eth16i_debug > 1)
        !           733:                printk(KERN_DEBUG "Using default port\n");
        !           734: 
        !           735:        return E_PORT_BNC;
        !           736: }
        !           737: 
        !           738: static void eth16i_set_port(int ioaddr, int porttype)
        !           739: { 
        !           740:        unsigned short temp = 0;
        !           741: 
        !           742:        eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        !           743:        outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
        !           744: 
        !           745:        temp |= DIS_AUTO_PORT_SEL;
        !           746: 
        !           747:        switch(porttype) {
        !           748: 
        !           749:        case E_PORT_BNC :
        !           750:                temp |= AUI_SELECT;
        !           751:                break;
        !           752: 
        !           753:        case E_PORT_TP :
        !           754:                break;
        !           755: 
        !           756:        case E_PORT_DIX :
        !           757:                temp |= AUI_SELECT;
        !           758:                BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
        !           759:                break;
        !           760:        }  
        !           761: 
        !           762:        outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
        !           763: 
        !           764:        if(eth16i_debug > 1) {
        !           765:                printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
        !           766:                printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n", 
        !           767:                       inb(ioaddr+TRANSCEIVER_MODE_REG));
        !           768:        }
        !           769: }
        !           770: 
        !           771: static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
        !           772: {
        !           773:        int starttime;
        !           774: 
        !           775:        outb(0xff, ioaddr + TX_STATUS_REG);
        !           776: 
        !           777:        outw(l, ioaddr + DATAPORT);
        !           778:        outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);  
        !           779: 
        !           780:        starttime = jiffies;
        !           781:        outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); 
        !           782: 
        !           783:        while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
        !           784:                if( (jiffies - starttime) > TX_TIMEOUT) {
        !           785:                        return -1;
        !           786:                }
        !           787:        }
        !           788: 
        !           789:        return 0;
        !           790: }
        !           791: 
        !           792: static int eth16i_receive_probe_packet(int ioaddr)
        !           793: {
        !           794:        int starttime;
        !           795: 
        !           796:        starttime = jiffies;
        !           797: 
        !           798:        while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
        !           799:                if( (jiffies - starttime) > TX_TIMEOUT) {
        !           800: 
        !           801:                        if(eth16i_debug > 1)
        !           802:                                printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n");
        !           803:                        starttime = jiffies;
        !           804:                        while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
        !           805:                                if( (jiffies - starttime) > TX_TIMEOUT) {
        !           806:                                        if(eth16i_debug > 1)
        !           807:                                                printk(KERN_DEBUG "Timeout occured waiting receive packet\n");
        !           808:                                        return -1;
        !           809:                                }
        !           810:                        }
        !           811: 
        !           812:                        if(eth16i_debug > 1)
        !           813:                                printk(KERN_DEBUG "RECEIVE_PACKET\n");
        !           814:                        return(0); /* Found receive packet */
        !           815:                }
        !           816:        }
        !           817: 
        !           818:        if(eth16i_debug > 1) {
        !           819:                printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
        !           820:                printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
        !           821:        }
        !           822: 
        !           823:        return(0); /* Return success */
        !           824: }
        !           825: 
        !           826: #if 0
        !           827: static int eth16i_set_irq(struct device* dev)
        !           828: {
        !           829:        const int ioaddr = dev->base_addr;
        !           830:        const int irq = dev->irq;
        !           831:        int i = 0;
        !           832: 
        !           833:        if(ioaddr < 0x1000) {           
        !           834:                while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
        !           835:                        i++;
        !           836:        
        !           837:                if(i < NUM_OF_ISA_IRQS) {
        !           838:                        u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
        !           839:                        cbyte = (cbyte & 0x3F) | (i << 6);
        !           840:                        outb(cbyte, ioaddr + JUMPERLESS_CONFIG);
        !           841:                        return 0;
        !           842:                }
        !           843:        }
        !           844:        else {
        !           845:                printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
        !           846:        }
        !           847:        
        !           848:        return -1;
        !           849: 
        !           850: }
        !           851: #endif
        !           852: 
        !           853: static int eth16i_get_irq(int ioaddr)
        !           854: {
        !           855:        unsigned char cbyte;
        !           856: 
        !           857:        if( ioaddr < 0x1000) {
        !           858:                cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
        !           859:                return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
        !           860:        } else {  /* Oh..the card is EISA so method getting IRQ different */
        !           861:                unsigned short index = 0;
        !           862:                cbyte = inb(ioaddr + EISA_IRQ_REG);
        !           863:                while( (cbyte & 0x01) == 0) {
        !           864:                        cbyte = cbyte >> 1;
        !           865:                        index++;
        !           866:                }
        !           867:                return( eth32i_irqmap[ index ] );
        !           868:        }
        !           869: }
        !           870: 
        !           871: static int eth16i_check_signature(int ioaddr)
        !           872: {
        !           873:        int i;
        !           874:        unsigned char creg[4] = { 0 };
        !           875: 
        !           876:        for(i = 0; i < 4 ; i++) {
        !           877: 
        !           878:                creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
        !           879: 
        !           880:                if(eth16i_debug > 1)
        !           881:                        printk("eth16i: read signature byte %x at %x\n", 
        !           882:                               creg[i],
        !           883:                               ioaddr + TRANSMIT_MODE_REG + i);
        !           884:        }
        !           885: 
        !           886:        creg[0] &= 0x0F;      /* Mask collision cnr */
        !           887:        creg[2] &= 0x7F;      /* Mask DCLEN bit */
        !           888: 
        !           889: #ifdef 0
        !           890:        /* 
        !           891:           This was removed because the card was sometimes left to state
        !           892:           from which it couldn't be find anymore. If there is need
        !           893:           to more strict check still this have to be fixed.
        !           894:           */
        !           895:        if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) {
        !           896:                if(creg[1] != 0x42)
        !           897:                        return -1;
        !           898:        }
        !           899: #endif
        !           900: 
        !           901:        if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
        !           902:                creg[2] &= 0x40;
        !           903:                creg[3] &= 0x03;
        !           904:                
        !           905:                if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
        !           906:                        return -1;
        !           907:        }
        !           908:        
        !           909:        if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
        !           910:                return -1;
        !           911:        
        !           912:        if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
        !           913:                return -1;
        !           914: 
        !           915:        return 0;
        !           916: }
        !           917: 
        !           918: static int eth16i_read_eeprom(int ioaddr, int offset)
        !           919: {
        !           920:        int data = 0;
        !           921: 
        !           922:        eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset);
        !           923:        outb(CS_1, ioaddr + EEPROM_CTRL_REG);
        !           924:        data = eth16i_read_eeprom_word(ioaddr);
        !           925:        outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           926: 
        !           927:        return(data);  
        !           928: }
        !           929: 
        !           930: static int eth16i_read_eeprom_word(int ioaddr)
        !           931: {
        !           932:        int i;
        !           933:        int data = 0;
        !           934:      
        !           935:        for(i = 16; i > 0; i--) {
        !           936:                outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           937:                eeprom_slow_io();
        !           938:                outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           939:                eeprom_slow_io();
        !           940:                data = (data << 1) | 
        !           941:                        ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
        !           942:                
        !           943:                eeprom_slow_io();
        !           944:        }
        !           945: 
        !           946:        return(data);
        !           947: }
        !           948: 
        !           949: static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
        !           950: {
        !           951:        int i;
        !           952: 
        !           953:        outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           954:        outb(DI_0, ioaddr + EEPROM_DATA_REG);
        !           955:        outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           956:        outb(DI_1, ioaddr + EEPROM_DATA_REG);
        !           957:        outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           958: 
        !           959:        for(i = 7; i >= 0; i--) {
        !           960:                short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 );
        !           961:                outb(cmd, ioaddr + EEPROM_DATA_REG);
        !           962:                outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
        !           963:                eeprom_slow_io();
        !           964:                outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
        !           965:                eeprom_slow_io();
        !           966:        } 
        !           967: }
        !           968: 
        !           969: static int eth16i_open(struct device *dev)
        !           970: {
        !           971:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !           972:        int ioaddr = dev->base_addr;
        !           973:        
        !           974:        /* Powerup the chip */
        !           975:        outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
        !           976: 
        !           977:        /* Initialize the chip */
        !           978:        eth16i_initialize(dev);  
        !           979: 
        !           980:        /* Set the transmit buffer size */
        !           981:        lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
        !           982: 
        !           983:        if(eth16i_debug > 0)
        !           984:                printk(KERN_DEBUG "%s: transmit buffer size %d\n", 
        !           985:                       dev->name, lp->tx_buf_size);
        !           986: 
        !           987:        /* Now enable Transmitter and Receiver sections */
        !           988:        BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !           989: 
        !           990:        /* Now switch to register bank 2, for run time operation */
        !           991:        eth16i_select_regbank(2, ioaddr);
        !           992: 
        !           993:        lp->open_time = jiffies;
        !           994:        lp->tx_started = 0;
        !           995:        lp->tx_queue = 0;
        !           996:        lp->tx_queue_len = 0;
        !           997: 
        !           998:        /* Turn on interrupts*/
        !           999:        outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);  
        !          1000: 
        !          1001:        dev->tbusy = 0;
        !          1002:        dev->interrupt = 0;
        !          1003:        dev->start = 1;
        !          1004: 
        !          1005:        MOD_INC_USE_COUNT;
        !          1006: 
        !          1007:        return 0;
        !          1008: }
        !          1009: 
        !          1010: static int eth16i_close(struct device *dev)
        !          1011: {
        !          1012:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1013:        int ioaddr = dev->base_addr;
        !          1014: 
        !          1015:        eth16i_reset(dev);
        !          1016: 
        !          1017:        /* Turn off interrupts*/
        !          1018:        outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);  
        !          1019: 
        !          1020:        dev->start = 0;
        !          1021:        dev->tbusy = 1;
        !          1022: 
        !          1023:        lp->open_time = 0;
        !          1024: 
        !          1025:        /* Disable transmit and receive */
        !          1026:        BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !          1027: 
        !          1028:        /* Reset the chip */
        !          1029:        /* outb(0xff, ioaddr + RESET); */
        !          1030:        /* outw(0xffff, ioaddr + TX_STATUS_REG);    */
        !          1031:        
        !          1032:        outb(0x00, ioaddr + CONFIG_REG_1);
        !          1033: 
        !          1034:        MOD_DEC_USE_COUNT;
        !          1035: 
        !          1036:        return 0;
        !          1037: }
        !          1038: 
        !          1039: static int eth16i_tx(struct sk_buff *skb, struct device *dev)
        !          1040: {
        !          1041:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1042:        int ioaddr = dev->base_addr;
        !          1043:        int status = 0;
        !          1044: 
        !          1045:        if(dev->tbusy) {
        !          1046:                
        !          1047:                /* 
        !          1048:                   If we get here, some higher level has decided that 
        !          1049:                   we are broken. There should really be a "kick me" 
        !          1050:                   function call instead. 
        !          1051:                   */
        !          1052: 
        !          1053:                int tickssofar = jiffies - dev->trans_start;
        !          1054:                if(tickssofar < TX_TIMEOUT)  
        !          1055:                        return 1;                     
        !          1056: 
        !          1057:                outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
        !          1058: 
        !          1059:                printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n", 
        !          1060:                       dev->name,
        !          1061:                       inw(ioaddr + TX_STATUS_REG), 
        !          1062:                       (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? 
        !          1063:                       "IRQ conflict" : "network cable problem");
        !          1064: 
        !          1065:                dev->trans_start = jiffies;
        !          1066: 
        !          1067:                /* Let's dump all registers */
        !          1068:                if(eth16i_debug > 0) { 
        !          1069:                        printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
        !          1070:                               dev->name, inb(ioaddr + 0), 
        !          1071:                               inb(ioaddr + 1), inb(ioaddr + 2), 
        !          1072:                               inb(ioaddr + 3), inb(ioaddr + 4), 
        !          1073:                               inb(ioaddr + 5),
        !          1074:                               inb(ioaddr + 6), inb(ioaddr + 7));
        !          1075: 
        !          1076:                        printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n",
        !          1077:                               dev->name, inb(ioaddr + TRANSMIT_START_REG),
        !          1078:                               inb(ioaddr + COL_16_REG));
        !          1079: 
        !          1080:                        printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue);
        !          1081:                        printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len);
        !          1082:                        printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started);
        !          1083: 
        !          1084:                }
        !          1085: 
        !          1086:                lp->stats.tx_errors++;
        !          1087: 
        !          1088:                eth16i_reset(dev);
        !          1089: 
        !          1090:                dev->trans_start = jiffies;
        !          1091: 
        !          1092:                outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !          1093: 
        !          1094:        }
        !          1095: 
        !          1096:        /* 
        !          1097:           If some higher layer thinks we've missed an tx-done interrupt
        !          1098:           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
        !          1099:           itself 
        !          1100:           */
        !          1101:        
        !          1102:        if(skb == NULL) {
        !          1103: #if LINUX_VERSION_CODE < 0x020100
        !          1104:                dev_tint(dev);
        !          1105: #endif
        !          1106:                if(eth16i_debug > 0) 
        !          1107:                        printk(KERN_WARNING "%s: Missed tx-done interrupt.\n", dev->name);
        !          1108:                return 0;
        !          1109:        }
        !          1110: 
        !          1111:        /* Block a timer based transmitter from overlapping. 
        !          1112:           This could better be done with atomic_swap(1, dev->tbusy), 
        !          1113:           but set_bit() works as well. */
        !          1114: 
        !          1115:        set_bit(0, (void *)&lp->tx_buf_busy);
        !          1116:        
        !          1117:        /* Turn off TX interrupts */
        !          1118:        outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
        !          1119: 
        !          1120:        if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) {
        !          1121:                printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
        !          1122:                status = -1;
        !          1123:        }
        !          1124:        else {
        !          1125:                ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        !          1126:                unsigned char *buf = skb->data;
        !          1127: 
        !          1128:                if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
        !          1129:                        if(eth16i_debug > 0) 
        !          1130:                                printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);  
        !          1131:                } 
        !          1132:                else {
        !          1133:                        outw(length, ioaddr + DATAPORT);
        !          1134: 
        !          1135:                        if( ioaddr < 0x1000 ) 
        !          1136:                                outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
        !          1137:                        else {
        !          1138:                                unsigned char frag = length % 4;
        !          1139: 
        !          1140:                                outsl(ioaddr + DATAPORT, buf, length >> 2);
        !          1141: 
        !          1142:                                if( frag != 0 ) {
        !          1143:                                        outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
        !          1144:                                        if( frag == 3 ) 
        !          1145:                                                outsw(ioaddr + DATAPORT, 
        !          1146:                                                      (buf + (length & 0xFFFC) + 2), 1);
        !          1147:                                }
        !          1148:                        }
        !          1149: 
        !          1150:                        lp->tx_buffered_packets++;
        !          1151:                        lp->tx_queue++;
        !          1152:                        lp->tx_queue_len += length + 2;
        !          1153:                        
        !          1154:                }
        !          1155:                
        !          1156:                lp->tx_buf_busy = 0;
        !          1157: 
        !          1158:                if(lp->tx_started == 0) {
        !          1159:                        /* If the transmitter is idle..always trigger a transmit */
        !          1160:                        outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
        !          1161:                        lp->tx_queue = 0;
        !          1162:                        lp->tx_queue_len = 0;
        !          1163:                        dev->trans_start = jiffies;
        !          1164:                        lp->tx_started = 1;
        !          1165:                        dev->tbusy = 0;
        !          1166:                }
        !          1167:                else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
        !          1168:                        /* There is still more room for one more packet in tx buffer */
        !          1169:                        dev->tbusy = 0;
        !          1170:                }
        !          1171:                
        !          1172:                outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !          1173:                
        !          1174:                /* Turn TX interrupts back on */
        !          1175:                /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
        !          1176:                status = 0;
        !          1177:        } 
        !          1178: 
        !          1179: #if LINUX_VERSION_CODE >= 0x020100
        !          1180:        dev_kfree_skb(skb);
        !          1181: #else
        !          1182:        dev_kfree_skb(skb, FREE_WRITE);
        !          1183: #endif
        !          1184: 
        !          1185:        return status;
        !          1186: }
        !          1187: 
        !          1188: static void eth16i_rx(struct device *dev)
        !          1189: {
        !          1190:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1191:        int ioaddr = dev->base_addr;
        !          1192:        int boguscount = MAX_RX_LOOP;
        !          1193: 
        !          1194:        /* Loop until all packets have been read */
        !          1195:        while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
        !          1196: 
        !          1197:                /* Read status byte from receive buffer */ 
        !          1198:                ushort status = inw(ioaddr + DATAPORT);
        !          1199: 
        !          1200:                /* Get the size of the packet from receive buffer */
        !          1201:                ushort pkt_len = inw(ioaddr + DATAPORT);
        !          1202: 
        !          1203:                if(eth16i_debug > 4)
        !          1204:                        printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n", 
        !          1205:                               dev->name, 
        !          1206:                               inb(ioaddr + RECEIVE_MODE_REG), status);
        !          1207:                
        !          1208:                if( !(status & PKT_GOOD) ) {
        !          1209:                        lp->stats.rx_errors++;
        !          1210: 
        !          1211:                        if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
        !          1212:                                lp->stats.rx_length_errors++;
        !          1213:                                eth16i_reset(dev);
        !          1214:                                return;         
        !          1215:                        }
        !          1216:                        else { 
        !          1217:                                eth16i_skip_packet(dev);
        !          1218:                                lp->stats.rx_dropped++;
        !          1219:                        }       
        !          1220:                }
        !          1221:                else {   /* Ok so now we should have a good packet */
        !          1222:                        struct sk_buff *skb;
        !          1223: 
        !          1224:                        skb = dev_alloc_skb(pkt_len + 3);
        !          1225:                        if( skb == NULL ) {
        !          1226:                                printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", 
        !          1227:                                       dev->name, pkt_len);
        !          1228:                                eth16i_skip_packet(dev);
        !          1229:                                lp->stats.rx_dropped++;
        !          1230:                                break;
        !          1231:                        }
        !          1232: 
        !          1233:                        skb->dev = dev;
        !          1234:                        skb_reserve(skb,2);
        !          1235:                        
        !          1236:                        /* 
        !          1237:                           Now let's get the packet out of buffer.
        !          1238:                           size is (pkt_len + 1) >> 1, cause we are now reading words
        !          1239:                           and it have to be even aligned.
        !          1240:                           */ 
        !          1241:                        
        !          1242:                        if(ioaddr < 0x1000) 
        !          1243:                                insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), 
        !          1244:                                     (pkt_len + 1) >> 1);
        !          1245:                        else {  
        !          1246:                                unsigned char *buf = skb_put(skb, pkt_len);
        !          1247:                                unsigned char frag = pkt_len % 4;
        !          1248: 
        !          1249:                                insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
        !          1250: 
        !          1251:                                if(frag != 0) {
        !          1252:                                        unsigned short rest[2];
        !          1253:                                        rest[0] = inw( ioaddr + DATAPORT );
        !          1254:                                        if(frag == 3)
        !          1255:                                                rest[1] = inw( ioaddr + DATAPORT );
        !          1256: 
        !          1257:                                        memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
        !          1258:                                }
        !          1259:                        }
        !          1260: 
        !          1261:                        skb->protocol=eth_type_trans(skb, dev);
        !          1262:                        netif_rx(skb);
        !          1263:                        lp->stats.rx_packets++;
        !          1264: 
        !          1265:                        if( eth16i_debug > 5 ) {
        !          1266:                                int i;
        !          1267:                                printk(KERN_DEBUG "%s: Received packet of length %d.\n", 
        !          1268:                                       dev->name, pkt_len);
        !          1269:                                for(i = 0; i < 14; i++) 
        !          1270:                                        printk(KERN_DEBUG " %02x", skb->data[i]);
        !          1271:                                printk(KERN_DEBUG ".\n");
        !          1272:                        }
        !          1273: 
        !          1274:                } /* else */
        !          1275: 
        !          1276:                if(--boguscount <= 0)
        !          1277:                        break;
        !          1278: 
        !          1279:        } /* while */
        !          1280: 
        !          1281: #if 0
        !          1282:        {
        !          1283:                int i;
        !          1284: 
        !          1285:                for(i = 0; i < 20; i++) {
        !          1286:                        if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 
        !          1287:                            RX_BUFFER_EMPTY)
        !          1288:                                break;
        !          1289:                        inw(ioaddr + DATAPORT);
        !          1290:                        outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
        !          1291:                }
        !          1292: 
        !          1293:                if(eth16i_debug > 1)
        !          1294:                        printk(KERN_DEBUG "%s: Flushed receive buffer.\n", dev->name);
        !          1295:        }
        !          1296: #endif
        !          1297: 
        !          1298:        return;
        !          1299: }
        !          1300: 
        !          1301: static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        !          1302: {
        !          1303:        struct device *dev = dev_id;
        !          1304:        struct eth16i_local *lp;
        !          1305:        int ioaddr = 0,
        !          1306:                status;
        !          1307: 
        !          1308:        if(dev == NULL) {
        !          1309:                printk(KERN_WARNING "eth16i_interrupt(): irq %d for unknown device. \n", irq);
        !          1310:                return;
        !          1311:        }
        !          1312: 
        !          1313:        /* Turn off all interrupts from adapter */
        !          1314:        outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
        !          1315: 
        !          1316:        set_bit(0, (void *)&dev->tbusy);        /* Set the device busy so that */
        !          1317:        /* eth16i_tx wont be called */
        !          1318: 
        !          1319:        if(dev->interrupt)
        !          1320:                printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n", dev->name);
        !          1321:        dev->interrupt = 1;
        !          1322: 
        !          1323:        ioaddr = dev->base_addr;
        !          1324:        lp = (struct eth16i_local *)dev->priv;
        !          1325:        status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
        !          1326:        outw(status, ioaddr + TX_STATUS_REG);      /* Clear status bits */
        !          1327: 
        !          1328:        if(eth16i_debug > 3)
        !          1329:                printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status);
        !          1330: 
        !          1331:        if( status & 0x7f00 ) {
        !          1332: 
        !          1333:                lp->stats.rx_errors++;
        !          1334: 
        !          1335:                if(status & (BUS_RD_ERR << 8) ) 
        !          1336:                        printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
        !          1337:                if(status & (SHORT_PKT_ERR << 8) )   lp->stats.rx_length_errors++;
        !          1338:                if(status & (ALIGN_ERR << 8) )       lp->stats.rx_frame_errors++;
        !          1339:                if(status & (CRC_ERR << 8) )        lp->stats.rx_crc_errors++;
        !          1340:                if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++;
        !          1341:        }
        !          1342:        if( status & 0x001a) {
        !          1343: 
        !          1344:                lp->stats.tx_errors++;
        !          1345: 
        !          1346:                if(status & CR_LOST) lp->stats.tx_carrier_errors++;
        !          1347:                if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++;
        !          1348: 
        !          1349: #if 0         
        !          1350:                if(status & COLLISION) {
        !          1351:                        lp->stats.collisions += 
        !          1352:                                ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
        !          1353:                }
        !          1354: #endif
        !          1355:                if(status & COLLISIONS_16) {
        !          1356:                        if(lp->col_16 < MAX_COL_16) { 
        !          1357:                                lp->col_16++;
        !          1358:                                lp->stats.collisions++;
        !          1359:                                /* Resume transmitting, skip failed packet */
        !          1360:                                outb(0x02, ioaddr + COL_16_REG);
        !          1361:                        }
        !          1362:                        else {
        !          1363:                                printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name);
        !          1364:                        }
        !          1365:                }
        !          1366:        }
        !          1367: 
        !          1368:        if( status & 0x00ff ) {          /* Let's check the transmit status reg */
        !          1369: 
        !          1370:                if(status & TX_DONE) {         /* The transmit has been done */
        !          1371:                        lp->stats.tx_packets = lp->tx_buffered_packets;
        !          1372:                        lp->col_16 = 0;            
        !          1373: 
        !          1374:                        if(lp->tx_queue) {           /* Is there still packets ? */
        !          1375:                                /* There was packet(s) so start transmitting and write also
        !          1376:                                   how many packets there is to be sended */
        !          1377:                                outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
        !          1378:                                lp->tx_queue = 0;
        !          1379:                                lp->tx_queue_len = 0;
        !          1380:                                lp->tx_started = 1;
        !          1381:                                dev->trans_start = jiffies;
        !          1382:                                mark_bh(NET_BH); 
        !          1383:                        }
        !          1384:                        else {
        !          1385:                                lp->tx_started = 0;
        !          1386:                                mark_bh(NET_BH);
        !          1387:                        }
        !          1388:                }
        !          1389:        }
        !          1390: 
        !          1391:        if( ( status & 0x8000 ) || 
        !          1392:            ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
        !          1393:                eth16i_rx(dev);  /* We have packet in receive buffer */
        !          1394:        }  
        !          1395:        
        !          1396:        dev->interrupt = 0;
        !          1397:        
        !          1398:        /* Turn interrupts back on */
        !          1399:        outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
        !          1400:        
        !          1401:        if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
        !          1402:                /* There is still more room for one more packet in tx buffer */
        !          1403:                dev->tbusy = 0;
        !          1404:        }
        !          1405:        
        !          1406:        return;
        !          1407: }
        !          1408: 
        !          1409: static void eth16i_skip_packet(struct device *dev)
        !          1410: {       
        !          1411:        int ioaddr = dev->base_addr;
        !          1412: 
        !          1413:        inw(ioaddr + DATAPORT);
        !          1414:        inw(ioaddr + DATAPORT);
        !          1415:        inw(ioaddr + DATAPORT);
        !          1416: 
        !          1417:        outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
        !          1418:        while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0);
        !          1419: }
        !          1420: 
        !          1421: static void eth16i_reset(struct device *dev)
        !          1422: {
        !          1423:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1424:        int ioaddr = dev->base_addr;
        !          1425: 
        !          1426:        if(eth16i_debug > 1) 
        !          1427:                printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
        !          1428: 
        !          1429:        BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
        !          1430:        outw(0xffff, ioaddr + TX_STATUS_REG);    
        !          1431:        eth16i_select_regbank(2, ioaddr);
        !          1432: 
        !          1433:        lp->tx_started = 0;
        !          1434:        lp->tx_buf_busy = 0;
        !          1435:        lp->tx_queue = 0;
        !          1436:        lp->tx_queue_len = 0;    
        !          1437: 
        !          1438:        dev->interrupt = 0;
        !          1439:        dev->start = 1;
        !          1440:        dev->tbusy = 0;
        !          1441:        BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
        !          1442: }
        !          1443: 
        !          1444: static void eth16i_multicast(struct device *dev)
        !          1445: {
        !          1446:        int ioaddr = dev->base_addr;
        !          1447:   
        !          1448:        if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
        !          1449:        {
        !          1450:                dev->flags|=IFF_PROMISC;        /* Must do this */
        !          1451:                outb(3, ioaddr + RECEIVE_MODE_REG);    
        !          1452:        } else {
        !          1453:                outb(2, ioaddr + RECEIVE_MODE_REG);
        !          1454:        }
        !          1455: }
        !          1456: 
        !          1457: static struct enet_statistics *eth16i_get_stats(struct device *dev)
        !          1458: {
        !          1459:        struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
        !          1460: 
        !          1461:        return &lp->stats;
        !          1462: }
        !          1463: 
        !          1464: static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
        !          1465: {
        !          1466:        unsigned char data;
        !          1467: 
        !          1468:        data = inb(ioaddr + CONFIG_REG_1);
        !          1469:        outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); 
        !          1470: }
        !          1471: 
        !          1472: #ifdef MODULE
        !          1473: 
        !          1474: static ushort eth16i_parse_mediatype(const char* s)
        !          1475: {
        !          1476:        if(!s)
        !          1477:                return E_PORT_FROM_EPROM;
        !          1478:        
        !          1479:         if (!strncmp(s, "bnc", 3))
        !          1480:                return E_PORT_BNC;
        !          1481:         else if (!strncmp(s, "tp", 2))
        !          1482:                 return E_PORT_TP;
        !          1483:         else if (!strncmp(s, "dix", 3))
        !          1484:                 return E_PORT_DIX;
        !          1485:         else if (!strncmp(s, "auto", 4))
        !          1486:                return E_PORT_AUTO;
        !          1487:        else
        !          1488:                return E_PORT_FROM_EPROM;
        !          1489: }
        !          1490: 
        !          1491: #define MAX_ETH16I_CARDS 4  /* Max number of Eth16i cards per module */
        !          1492: #define NAMELEN          8  /* number of chars for storing dev->name */
        !          1493: 
        !          1494: static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, };
        !          1495: static struct device dev_eth16i[MAX_ETH16I_CARDS] = {
        !          1496:        {
        !          1497:                NULL,
        !          1498:                0, 0, 0, 0,
        !          1499:                0, 0,
        !          1500:                0, 0, 0, NULL, NULL
        !          1501:        },
        !          1502: };
        !          1503: 
        !          1504: static int ioaddr[MAX_ETH16I_CARDS] = { 0, };
        !          1505: #if 0
        !          1506: static int irq[MAX_ETH16I_CARDS] = { 0, };
        !          1507: #endif
        !          1508: static char* mediatype[MAX_ETH16I_CARDS] = { 0, };
        !          1509: static int debug = -1;
        !          1510: 
        !          1511: #if (LINUX_VERSION_CODE >= 0x20115) 
        !          1512: MODULE_AUTHOR("Mika Kuoppala <[email protected]>");
        !          1513: MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
        !          1514: 
        !          1515: MODULE_PARM(ioaddr, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
        !          1516: MODULE_PARM_DESC(ioaddr, "eth16i io base address");
        !          1517: 
        !          1518: #if 0
        !          1519: MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
        !          1520: MODULE_PARM_DESC(irq, "eth16i interrupt request number");
        !          1521: #endif
        !          1522: 
        !          1523: MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s");
        !          1524: MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype");
        !          1525: 
        !          1526: MODULE_PARM(debug, "i");
        !          1527: MODULE_PARM_DESC(debug, "eth16i debug level (0-4)");
        !          1528: #endif
        !          1529: 
        !          1530: int init_module(void)
        !          1531: {
        !          1532:        int this_dev, found = 0;
        !          1533: 
        !          1534:        for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
        !          1535:        {
        !          1536:                struct device *dev = &dev_eth16i[this_dev];
        !          1537:        
        !          1538:                dev->name = namelist + (NAMELEN*this_dev);
        !          1539:                dev->irq = 0; /* irq[this_dev]; */
        !          1540:                dev->base_addr = ioaddr[this_dev];
        !          1541:                dev->init = eth16i_probe;
        !          1542: 
        !          1543:                if(debug != -1)
        !          1544:                        eth16i_debug = debug;
        !          1545: 
        !          1546:                if(eth16i_debug > 1)
        !          1547:                        printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" );
        !          1548: 
        !          1549:                dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
        !          1550: 
        !          1551:                if(ioaddr[this_dev] == 0)
        !          1552:                {
        !          1553:                        if(this_dev != 0) break; /* Only autoprobe 1st one */
        !          1554: 
        !          1555:                        printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
        !          1556:                }
        !          1557: 
        !          1558:                if(register_netdev(dev) != 0)
        !          1559:                {
        !          1560:                        printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
        !          1561:                               ioaddr[this_dev]);
        !          1562:            
        !          1563:                        if(found != 0) return 0;
        !          1564:                        return -ENXIO;
        !          1565:                }
        !          1566: 
        !          1567:                found++;
        !          1568:        }
        !          1569:        return 0;
        !          1570: }
        !          1571:        
        !          1572: void cleanup_module(void)
        !          1573: {
        !          1574:        int this_dev;
        !          1575: 
        !          1576:        for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
        !          1577:        {
        !          1578:                struct device* dev = &dev_eth16i[this_dev];
        !          1579:                
        !          1580:                if(dev->priv != NULL)
        !          1581:                {
        !          1582:                        unregister_netdev(dev);
        !          1583:                        kfree(dev->priv);
        !          1584:                        dev->priv = NULL;
        !          1585:                        
        !          1586:                        free_irq(dev->irq, dev);
        !          1587:                        release_region(dev->base_addr, ETH16I_IO_EXTENT);
        !          1588:                        
        !          1589:                }
        !          1590:        }
        !          1591: }
        !          1592: #endif /* MODULE */
        !          1593: 
        !          1594: /*
        !          1595:  * Local variables:
        !          1596:  *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c"
        !          1597:  *  alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c"
        !          1598:  *  tab-width: 8
        !          1599:  *  c-basic-offset: 8
        !          1600:  *  c-indent-level: 8
        !          1601:  * End:
        !          1602:  */
        !          1603: 
        !          1604: /* End of file eth16i.c */

unix.superglobalmegacorp.com

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