diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /drivers/net | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'drivers/net')
224 files changed, 36837 insertions, 14155 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 029571460..47ad2e076 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -95,10 +95,10 @@ static const char *version = #include <linux/string.h> #include <linux/errno.h> #include <linux/config.h> /* for CONFIG_IP_MULTICAST */ +#include <linux/spinlock.h> #include <asm/bitops.h> #include <asm/io.h> -#include <asm/spinlock.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> @@ -116,16 +116,16 @@ static unsigned int netcard_portlist[] __initdata = { * Index to functions. */ -int el1_probe(struct device *dev); -static int el1_probe1(struct device *dev, int ioaddr); -static int el_open(struct device *dev); -static int el_start_xmit(struct sk_buff *skb, struct device *dev); +int el1_probe(struct net_device *dev); +static int el1_probe1(struct net_device *dev, int ioaddr); +static int el_open(struct net_device *dev); +static int el_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void el_receive(struct device *dev); -static void el_reset(struct device *dev); -static int el1_close(struct device *dev); -static struct net_device_stats *el1_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void el_receive(struct net_device *dev); +static void el_reset(struct net_device *dev); +static int el1_close(struct net_device *dev); +static struct net_device_stats *el1_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #define EL1_IO_EXTENT 16 @@ -210,7 +210,7 @@ struct net_local struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; #else -int __init el1_probe(struct device *dev) +int __init el1_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -237,7 +237,7 @@ int __init el1_probe(struct device *dev) * The actual probe. */ -static int __init el1_probe1(struct device *dev, int ioaddr) +static int __init el1_probe1(struct net_device *dev, int ioaddr) { struct net_local *lp; const char *mname; /* Vendor name */ @@ -355,7 +355,7 @@ static int __init el1_probe1(struct device *dev, int ioaddr) * Open/initialize the board. */ -static int el_open(struct device *dev) +static int el_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -374,7 +374,7 @@ static int el_open(struct device *dev) return 0; } -static int el_start_xmit(struct sk_buff *skb, struct device *dev) +static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -480,7 +480,7 @@ load_it_again_sam: static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr; int axsr; /* Aux. status reg. */ @@ -661,7 +661,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs) * We must check everything to see if it is good. */ -static void el_receive(struct device *dev) +static void el_receive(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -717,7 +717,7 @@ static void el_receive(struct device *dev) return; } -static void el_reset(struct device *dev) +static void el_reset(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -742,7 +742,7 @@ static void el_reset(struct device *dev) sti(); } -static int el1_close(struct device *dev) +static int el1_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -763,7 +763,7 @@ static int el1_close(struct device *dev) return 0; } -static struct net_device_stats *el1_get_stats(struct device *dev) +static struct net_device_stats *el1_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -774,7 +774,7 @@ static struct net_device_stats *el1_get_stats(struct device *dev) * best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -799,7 +799,7 @@ static void set_multicast_list(struct device *dev) static char devicename[9] = { 0, }; -static struct device dev_3c501 = +static struct net_device dev_3c501 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index 3c0ada25e..56769686b 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -52,9 +52,9 @@ static const char *version = #include "3c503.h" #define WRD_COUNT 4 -int el2_probe(struct device *dev); -int el2_pio_probe(struct device *dev); -int el2_probe1(struct device *dev, int ioaddr); +int el2_probe(struct net_device *dev); +int el2_pio_probe(struct net_device *dev); +int el2_probe1(struct net_device *dev, int ioaddr); /* A zero-terminated list of I/O addresses to be probed in PIO mode. */ static unsigned int netcard_portlist[] __initdata = @@ -71,15 +71,15 @@ struct netdev_entry el2pio_drv = {"3c503pio", el2_pioprobe1, EL1_IO_EXTENT, netcard_portlist}; #endif -static int el2_open(struct device *dev); -static int el2_close(struct device *dev); -static void el2_reset_8390(struct device *dev); -static void el2_init_card(struct device *dev); -static void el2_block_output(struct device *dev, int count, +static int el2_open(struct net_device *dev); +static int el2_close(struct net_device *dev); +static void el2_reset_8390(struct net_device *dev); +static void el2_init_card(struct net_device *dev); +static void el2_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void el2_block_input(struct device *dev, int count, struct sk_buff *skb, +static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -91,7 +91,7 @@ static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, ethercard jumpered to programmed-I/O mode. */ int __init -el2_probe(struct device *dev) +el2_probe(struct net_device *dev) { int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0}; int base_addr = dev->base_addr; @@ -126,7 +126,7 @@ el2_probe(struct device *dev) /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ int __init -el2_pio_probe(struct device *dev) +el2_pio_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -152,7 +152,7 @@ el2_pio_probe(struct device *dev) returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ int __init -el2_probe1(struct device *dev, int ioaddr) +el2_probe1(struct net_device *dev, int ioaddr) { int i, iobase_reg, membase_reg, saved_406, wordlength; static unsigned version_printed = 0; @@ -334,7 +334,7 @@ el2_probe1(struct device *dev, int ioaddr) } static int -el2_open(struct device *dev) +el2_open(struct net_device *dev) { if (dev->irq < 2) { @@ -370,7 +370,7 @@ el2_open(struct device *dev) } static int -el2_close(struct device *dev) +el2_close(struct net_device *dev) { free_irq(dev->irq, dev); dev->irq = ei_status.saved_irq; @@ -386,7 +386,7 @@ el2_close(struct device *dev) Bad ring buffer packet header */ static void -el2_reset_8390(struct device *dev) +el2_reset_8390(struct net_device *dev) { if (ei_debug > 1) { printk("%s: Resetting the 3c503 board...", dev->name); @@ -402,7 +402,7 @@ el2_reset_8390(struct device *dev) /* Initialize the 3c503 GA registers after a reset. */ static void -el2_init_card(struct device *dev) +el2_init_card(struct net_device *dev) { /* Unmap the station PROM and select the DIX or BNC connector. */ outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); @@ -434,7 +434,7 @@ el2_init_card(struct device *dev) * out through the ASIC FIFO. */ static void -el2_block_output(struct device *dev, int count, +el2_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned short int *wrd; @@ -507,7 +507,7 @@ el2_block_output(struct device *dev, int count, /* Read the 4 byte, page aligned 8390 specific header. */ static void -el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int boguscount; unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8); @@ -546,7 +546,7 @@ el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) static void -el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; unsigned short int *buf; @@ -625,7 +625,7 @@ el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off #define NAMELEN 8 /* #of chars for storing dev->name */ static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, }; -static struct device dev_el2[MAX_EL2_CARDS] = { +static struct net_device dev_el2[MAX_EL2_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -649,7 +649,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { - struct device *dev = &dev_el2[this_dev]; + struct net_device *dev = &dev_el2[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -679,7 +679,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { - struct device *dev = &dev_el2[this_dev]; + struct net_device *dev = &dev_el2[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* NB: el2_close() handles free_irq */ diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 5f5875953..1bd65d54f 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -221,7 +221,7 @@ static inline int inb_command(unsigned int base_addr) return inb(base_addr + PORT_COMMAND); } -static inline void outb_control(unsigned char val, struct device *dev) +static inline void outb_control(unsigned char val, struct net_device *dev) { outb(val, dev->base_addr + PORT_CONTROL); ((elp_device *)(dev->priv))->hcr_val = val; @@ -276,16 +276,16 @@ static inline int get_status(unsigned int base_addr) return stat1; } -static inline void set_hsf(struct device *dev, int hsf) +static inline void set_hsf(struct net_device *dev, int hsf) { cli(); outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev); sti(); } -static int start_receive(struct device *, pcb_struct *); +static int start_receive(struct net_device *, pcb_struct *); -inline static void adapter_reset(struct device *dev) +inline static void adapter_reset(struct net_device *dev) { int timeout; elp_device *adapter = dev->priv; @@ -323,7 +323,7 @@ inline static void adapter_reset(struct device *dev) * never happen in theory, but seems to occur occasionally if the card gets * prodded at the wrong time. */ -static inline void check_3c505_dma(struct device *dev) +static inline void check_3c505_dma(struct net_device *dev) { elp_device *adapter = dev->priv; if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) { @@ -371,7 +371,7 @@ static inline unsigned int send_pcb_fast(unsigned int base_addr, unsigned char b } /* Check to see if the receiver needs restarting, and kick it if so */ -static inline void prime_rx(struct device *dev) +static inline void prime_rx(struct net_device *dev) { elp_device *adapter = dev->priv; while (adapter->rx_active < ELP_RX_PCBS && dev->start) { @@ -404,7 +404,7 @@ static inline void prime_rx(struct device *dev) * timeout is reduced to 500us). */ -static int send_pcb(struct device *dev, pcb_struct * pcb) +static int send_pcb(struct net_device *dev, pcb_struct * pcb) { int i; int timeout; @@ -487,7 +487,7 @@ static int send_pcb(struct device *dev, pcb_struct * pcb) * *****************************************************************/ -static int receive_pcb(struct device *dev, pcb_struct * pcb) +static int receive_pcb(struct net_device *dev, pcb_struct * pcb) { int i, j; int total_length; @@ -571,7 +571,7 @@ static int receive_pcb(struct device *dev, pcb_struct * pcb) * ******************************************************/ -static int start_receive(struct device *dev, pcb_struct * tx_pcb) +static int start_receive(struct net_device *dev, pcb_struct * tx_pcb) { int status; elp_device *adapter = dev->priv; @@ -599,7 +599,7 @@ static int start_receive(struct device *dev, pcb_struct * tx_pcb) * ******************************************************/ -static void receive_packet(struct device *dev, int len) +static void receive_packet(struct net_device *dev, int len) { int rlen; elp_device *adapter = dev->priv; @@ -668,7 +668,7 @@ static void elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) int len; int dlen; int icount = 0; - struct device *dev; + struct net_device *dev; elp_device *adapter; int timeout; @@ -885,7 +885,7 @@ static void elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) * ******************************************************/ -static int elp_open(struct device *dev) +static int elp_open(struct net_device *dev) { elp_device *adapter; @@ -1022,7 +1022,7 @@ static int elp_open(struct device *dev) * ******************************************************/ -static int send_packet(struct device *dev, struct sk_buff *skb) +static int send_packet(struct net_device *dev, struct sk_buff *skb) { elp_device *adapter = dev->priv; unsigned long target; @@ -1092,7 +1092,7 @@ static int send_packet(struct device *dev, struct sk_buff *skb) * ******************************************************/ -static int elp_start_xmit(struct sk_buff *skb, struct device *dev) +static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev) { if (dev->interrupt) { printk("%s: start_xmit aborted (in irq)\n", dev->name); @@ -1157,7 +1157,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct device *dev) * ******************************************************/ -static struct net_device_stats *elp_get_stats(struct device *dev) +static struct net_device_stats *elp_get_stats(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; @@ -1194,7 +1194,7 @@ static struct net_device_stats *elp_get_stats(struct device *dev) * ******************************************************/ -static int elp_close(struct device *dev) +static int elp_close(struct net_device *dev) { elp_device *adapter; @@ -1247,7 +1247,7 @@ static int elp_close(struct device *dev) * ************************************************************/ -static void elp_set_mc_list(struct device *dev) +static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; @@ -1306,7 +1306,7 @@ static void elp_set_mc_list(struct device *dev) * ******************************************************/ -static inline void elp_init(struct device *dev) +static inline void elp_init(struct net_device *dev) { elp_device *adapter = dev->priv; @@ -1339,7 +1339,7 @@ static inline void elp_init(struct device *dev) * Called only by elp_autodetect ************************************************************/ -static int __init elp_sense(struct device *dev) +static int __init elp_sense(struct net_device *dev) { int timeout; int addr = dev->base_addr; @@ -1406,7 +1406,7 @@ static int __init elp_sense(struct device *dev) * Called only by eplus_probe *************************************************************/ -static int __init elp_autodetect(struct device *dev) +static int __init elp_autodetect(struct net_device *dev) { int idx = 0; @@ -1450,7 +1450,7 @@ static int __init elp_autodetect(struct device *dev) * work at all if it was in a weird state). */ -int __init elplus_probe(struct device *dev) +int __init elplus_probe(struct net_device *dev) { elp_device *adapter; int i, tries, tries1, timeout, okay; @@ -1654,7 +1654,7 @@ int __init elplus_probe(struct device *dev) #ifdef MODULE #define NAMELEN 9 static char devicename[ELP_MAX_CARDS][NAMELEN] = {{0,}}; -static struct device dev_3c505[ELP_MAX_CARDS] = +static struct net_device dev_3c505[ELP_MAX_CARDS] = { { NULL, /* device name is inserted by net_init.c */ 0, 0, 0, 0, @@ -1674,7 +1674,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_3c505[this_dev]; + struct net_device *dev = &dev_3c505[this_dev]; dev->name = devicename[this_dev]; dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -1703,7 +1703,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_3c505[this_dev]; + struct net_device *dev = &dev_3c505[this_dev]; if (dev->priv != NULL) { unregister_netdev(dev); kfree(dev->priv); diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index f53a17be8..3ad87d4ec 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -50,11 +50,11 @@ static const char *version = #include <linux/ioport.h> #include <linux/in.h> #include <linux/string.h> +#include <linux/spinlock.h> #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/dma.h> -#include <asm/spinlock.h> #include <linux/errno.h> #include <linux/netdevice.h> @@ -279,18 +279,18 @@ static unsigned short init_words[] = { /* Index to functions, as function prototypes. */ -extern int el16_probe(struct device *dev); /* Called from Space.c */ +extern int el16_probe(struct net_device *dev); /* Called from Space.c */ -static int el16_probe1(struct device *dev, int ioaddr); -static int el16_open(struct device *dev); -static int el16_send_packet(struct sk_buff *skb, struct device *dev); +static int el16_probe1(struct net_device *dev, int ioaddr); +static int el16_open(struct net_device *dev); +static int el16_send_packet(struct sk_buff *skb, struct net_device *dev); static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void el16_rx(struct device *dev); -static int el16_close(struct device *dev); -static struct net_device_stats *el16_get_stats(struct device *dev); +static void el16_rx(struct net_device *dev); +static int el16_close(struct net_device *dev); +static struct net_device_stats *el16_get_stats(struct net_device *dev); -static void hardware_send_packet(struct device *dev, void *buf, short length); -static void init_82586_mem(struct device *dev); +static void hardware_send_packet(struct net_device *dev, void *buf, short length); +static void init_82586_mem(struct net_device *dev); #ifdef HAVE_DEVLIST @@ -305,7 +305,7 @@ struct netdev_entry netcard_drv = device and return success. */ -int __init el16_probe(struct device *dev) +int __init el16_probe(struct net_device *dev) { int base_addr = dev ? dev->base_addr : 0; int i; @@ -326,7 +326,7 @@ int __init el16_probe(struct device *dev) return ENODEV; } -int __init el16_probe1(struct device *dev, int ioaddr) +int __init el16_probe1(struct net_device *dev, int ioaddr) { static unsigned char init_ID_done = 0, version_printed = 0; int i, irq, irqval; @@ -432,7 +432,7 @@ int __init el16_probe1(struct device *dev, int ioaddr) return 0; } -static int el16_open(struct device *dev) +static int el16_open(struct net_device *dev) { /* Initialize the 82586 memory and start it. */ init_82586_mem(dev); @@ -446,7 +446,7 @@ static int el16_open(struct device *dev) return 0; } -static int el16_send_packet(struct sk_buff *skb, struct device *dev) +static int el16_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -514,7 +514,7 @@ static int el16_send_packet(struct sk_buff *skb, struct device *dev) Handle the network interface interrupts. */ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; ushort ack_cmd = 0; @@ -592,7 +592,7 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((status & 0x0070) != 0x0040 && dev->start) { - static void init_rx_bufs(struct device *); + static void init_rx_bufs(struct net_device *); /* The Rx unit is not ready, it must be hung. Restart the receiver by initializing the rx buffers, and issuing an Rx start command. */ if (net_debug) @@ -616,7 +616,7 @@ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -static int el16_close(struct device *dev) +static int el16_close(struct net_device *dev) { int ioaddr = dev->base_addr; unsigned long shmem = dev->mem_start; @@ -642,7 +642,7 @@ static int el16_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *el16_get_stats(struct device *dev) +static struct net_device_stats *el16_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -652,7 +652,7 @@ static struct net_device_stats *el16_get_stats(struct device *dev) } /* Initialize the Rx-block list. */ -static void init_rx_bufs(struct device *dev) +static void init_rx_bufs(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long write_ptr; @@ -695,7 +695,7 @@ static void init_rx_bufs(struct device *dev) writew(lp->rx_head,write_ptr+2); /* Link */ } -static void init_82586_mem(struct device *dev) +static void init_82586_mem(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -753,7 +753,7 @@ static void init_82586_mem(struct device *dev) return; } -static void hardware_send_packet(struct device *dev, void *buf, short length) +static void hardware_send_packet(struct net_device *dev, void *buf, short length) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -798,7 +798,7 @@ static void hardware_send_packet(struct device *dev, void *buf, short length) dev->tbusy = 0; } -static void el16_rx(struct device *dev) +static void el16_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long shmem = dev->mem_start; @@ -869,7 +869,7 @@ static void el16_rx(struct device *dev) } #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_3c507 = { +static struct net_device dev_3c507 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 4a14d326b..a6bbd842f 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -64,8 +64,8 @@ static int max_interrupt_work = 10; #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> /* for udelay() */ +#include <linux/spinlock.h> -#include <asm/spinlock.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/irq.h> @@ -129,7 +129,7 @@ enum RxFilter { struct el3_private { struct enet_statistics stats; - struct device *next_dev; + struct net_device *next_dev; spinlock_t lock; /* skb send-queue */ int head, size; @@ -137,18 +137,18 @@ struct el3_private { char mca_slot; }; static int id_port = 0x110; /* Start with 0x110 to avoid new sound cards.*/ -static struct device *el3_root_dev = NULL; +static struct net_device *el3_root_dev = NULL; static ushort id_read_eeprom(int index); static ushort read_eeprom(int ioaddr, int index); -static int el3_open(struct device *dev); -static int el3_start_xmit(struct sk_buff *skb, struct device *dev); +static int el3_open(struct net_device *dev); +static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void update_stats(struct device *dev); -static struct enet_statistics *el3_get_stats(struct device *dev); -static int el3_rx(struct device *dev); -static int el3_close(struct device *dev); -static void set_multicast_list(struct device *dev); +static void update_stats(struct net_device *dev); +static struct enet_statistics *el3_get_stats(struct net_device *dev); +static int el3_rx(struct net_device *dev); +static int el3_close(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #ifdef CONFIG_MCA struct el3_mca_adapters_struct { @@ -166,7 +166,7 @@ struct el3_mca_adapters_struct el3_mca_adapters[] = { }; #endif -int el3_probe(struct device *dev) +int el3_probe(struct net_device *dev) { short lrs_state = 0xff, i; int ioaddr, irq, if_port; @@ -226,9 +226,6 @@ int el3_probe(struct device *dev) * detected and is enabled */ - printk("3c509: found %s at slot %d\n", - el3_mca_adapters[j].name, slot + 1 ); - pos4 = mca_read_stored_pos( slot, 4 ); pos5 = mca_read_stored_pos( slot, 5 ); @@ -242,6 +239,9 @@ int el3_probe(struct device *dev) continue; } + printk("3c509: found %s at slot %d\n", + el3_mca_adapters[j].name, slot + 1 ); + /* claim the slot */ mca_set_adapter_name(slot, el3_mca_adapters[j].name); mca_set_adapter_procfn(slot, NULL, NULL); @@ -425,7 +425,7 @@ static ushort id_read_eeprom(int index) static int -el3_open(struct device *dev) +el3_open(struct net_device *dev) { int ioaddr = dev->base_addr; int i; @@ -505,7 +505,7 @@ el3_open(struct device *dev) } static int -el3_start_xmit(struct sk_buff *skb, struct device *dev) +el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -615,7 +615,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev) static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct el3_private *lp; int ioaddr, status; int i = max_interrupt_work; @@ -708,7 +708,7 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct enet_statistics * -el3_get_stats(struct device *dev) +el3_get_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; unsigned long flags; @@ -729,7 +729,7 @@ el3_get_stats(struct device *dev) operation, and it's simpler for the rest of the driver to assume that window 1 is always valid rather than use a special window-state variable. */ -static void update_stats(struct device *dev) +static void update_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -759,7 +759,7 @@ static void update_stats(struct device *dev) } static int -el3_rx(struct device *dev) +el3_rx(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -829,7 +829,7 @@ el3_rx(struct device *dev) * Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { unsigned long flags; struct el3_private *lp = (struct el3_private *)dev->priv; @@ -856,7 +856,7 @@ set_multicast_list(struct device *dev) } static int -el3_close(struct device *dev) +el3_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -926,7 +926,7 @@ init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (el3_root_dev) { diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 26c82991c..43019acd3 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -293,7 +293,7 @@ struct boom_tx_desc { struct vortex_private { char devname[8]; /* "ethN" string, also for kernel debug. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; /* The Rx and Tx rings are here to keep them quad-word-aligned. */ struct boom_rx_desc rx_ring[RX_RING_SIZE]; struct boom_tx_desc tx_ring[TX_RING_SIZE]; @@ -343,21 +343,21 @@ static struct media_table { { "Default", 0, 0xFF, XCVR_10baseT, 10000}, }; -static int vortex_scan(struct device *dev); -static struct device *vortex_found_device(struct device *dev, int ioaddr, +static int vortex_scan(struct net_device *dev); +static struct net_device *vortex_found_device(struct net_device *dev, int ioaddr, int irq, int product_index, int options); -static int vortex_probe1(struct device *dev); -static int vortex_open(struct device *dev); +static int vortex_probe1(struct net_device *dev); +static int vortex_open(struct net_device *dev); static void vortex_timer(unsigned long arg); -static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); -static int vortex_rx(struct device *dev); -static int boomerang_rx(struct device *dev); +static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int vortex_rx(struct net_device *dev); +static int boomerang_rx(struct net_device *dev); static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs); -static int vortex_close(struct device *dev); -static void update_stats(int addr, struct device *dev); -static struct enet_statistics *vortex_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int vortex_close(struct net_device *dev); +static void update_stats(int addr, struct net_device *dev); +static struct enet_statistics *vortex_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* Unlike the other PCI cards the 59x cards don't need a large contiguous @@ -381,7 +381,7 @@ static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,}; #ifdef MODULE static int debug = -1; /* A list of all installed Vortex devices, for removing the driver module. */ -static struct device *root_vortex_dev = NULL; +static struct net_device *root_vortex_dev = NULL; int init_module(void) @@ -399,7 +399,7 @@ init_module(void) } #else -int tc515_probe(struct device *dev) +int tc515_probe(struct net_device *dev) { int cards_found = 0; @@ -412,7 +412,7 @@ int tc515_probe(struct device *dev) } #endif /* not MODULE */ -static int vortex_scan(struct device *dev) +static int vortex_scan(struct net_device *dev) { int cards_found = 0; static int ioaddr = 0x100; @@ -452,7 +452,7 @@ static int vortex_scan(struct device *dev) return cards_found; } -static struct device *vortex_found_device(struct device *dev, int ioaddr, +static struct net_device *vortex_found_device(struct net_device *dev, int ioaddr, int irq, int product_index, int options) { @@ -460,13 +460,13 @@ static struct device *vortex_found_device(struct device *dev, int ioaddr, #ifdef MODULE /* Allocate and fill new device structure. */ - int dev_size = sizeof(struct device) + + int dev_size = sizeof(struct net_device) + sizeof(struct vortex_private) + 15; /* Pad for alignment */ - dev = (struct device *) kmalloc(dev_size, GFP_KERNEL); + dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); memset(dev, 0, dev_size); /* Align the Rx and Tx ring entries. */ - dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15); + dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15); vp = (struct vortex_private *)dev->priv; dev->name = vp->devname; /* An empty string. */ dev->base_addr = ioaddr; @@ -517,7 +517,7 @@ static struct device *vortex_found_device(struct device *dev, int ioaddr, return dev; } -static int vortex_probe1(struct device *dev) +static int vortex_probe1(struct net_device *dev) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -607,7 +607,7 @@ static int vortex_probe1(struct device *dev) static int -vortex_open(struct device *dev) +vortex_open(struct net_device *dev) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -778,7 +778,7 @@ vortex_open(struct device *dev) static void vortex_timer(unsigned long data) { #ifdef AUTOMEDIA - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; unsigned long flags; @@ -850,7 +850,7 @@ static void vortex_timer(unsigned long data) } static int -vortex_start_xmit(struct sk_buff *skb, struct device *dev) +vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1018,7 +1018,7 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs) { /* Use the now-standard shared IRQ implementation. */ - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct vortex_private *lp; int ioaddr, status; int latency; @@ -1162,7 +1162,7 @@ static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs) } static int -vortex_rx(struct device *dev) +vortex_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1232,7 +1232,7 @@ vortex_rx(struct device *dev) } static int -boomerang_rx(struct device *dev) +boomerang_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int entry = vp->cur_rx % RX_RING_SIZE; @@ -1322,7 +1322,7 @@ boomerang_rx(struct device *dev) } static int -vortex_close(struct device *dev) +vortex_close(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1388,7 +1388,7 @@ vortex_close(struct device *dev) } static struct enet_statistics * -vortex_get_stats(struct device *dev) +vortex_get_stats(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; unsigned long flags; @@ -1409,7 +1409,7 @@ vortex_get_stats(struct device *dev) table. This is done by checking that the ASM (!) code generated uses atomic updates with '+='. */ -static void update_stats(int ioaddr, struct device *dev) +static void update_stats(int ioaddr, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1445,7 +1445,7 @@ static void update_stats(int ioaddr, struct device *dev) multicast setting is to receive all multicast frames. At least the chip has a very clean way to set the mode, unlike many others. */ static void -set_rx_mode(struct device *dev) +set_rx_mode(struct net_device *dev) { int ioaddr = dev->base_addr; short new_mode; @@ -1466,7 +1466,7 @@ set_rx_mode(struct device *dev) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_vortex_dev) { diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index 958100d66..b18ce126e 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -182,23 +182,23 @@ sizeof(nop_cmd) = 8; elmc_id_reset586(); } } } static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr); -static int elmc_open(struct device *dev); -static int elmc_close(struct device *dev); -static int elmc_send_packet(struct sk_buff *, struct device *); -static struct net_device_stats *elmc_get_stats(struct device *dev); +static int elmc_open(struct net_device *dev); +static int elmc_close(struct net_device *dev); +static int elmc_send_packet(struct sk_buff *, struct net_device *); +static struct net_device_stats *elmc_get_stats(struct net_device *dev); #ifdef ELMC_MULTICAST -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif /* helper-functions */ -static int init586(struct device *dev); -static int check586(struct device *dev, unsigned long where, unsigned size); -static void alloc586(struct device *dev); -static void startrecv586(struct device *dev); -static void *alloc_rfa(struct device *dev, void *ptr); -static void elmc_rcv_int(struct device *dev); -static void elmc_xmt_int(struct device *dev); -static void elmc_rnr_int(struct device *dev); +static int init586(struct net_device *dev); +static int check586(struct net_device *dev, unsigned long where, unsigned size); +static void alloc586(struct net_device *dev); +static void startrecv586(struct net_device *dev); +static void *alloc_rfa(struct net_device *dev, void *ptr); +static void elmc_rcv_int(struct net_device *dev); +static void elmc_xmt_int(struct net_device *dev); +static void elmc_rnr_int(struct net_device *dev); struct priv { struct net_device_stats stats; @@ -268,7 +268,7 @@ static void elmc_do_reset586(int ioaddr, int ints) * close device */ -static int elmc_close(struct device *dev) +static int elmc_close(struct net_device *dev) { elmc_id_reset586(); /* the hard way to stop the receiver */ @@ -288,7 +288,7 @@ static int elmc_close(struct device *dev) * open device */ -static int elmc_open(struct device *dev) +static int elmc_open(struct net_device *dev) { elmc_id_attn586(); /* disable interrupts */ @@ -319,7 +319,7 @@ static int elmc_open(struct device *dev) * Check to see if there's an 82586 out there. */ -static int __init check586(struct device *dev, unsigned long where, unsigned size) +static int __init check586(struct net_device *dev, unsigned long where, unsigned size) { struct priv *p = (struct priv *) dev->priv; char *iscp_addrs[2]; @@ -359,7 +359,7 @@ static int __init check586(struct device *dev, unsigned long where, unsigned siz * set iscp at the right place, called by elmc_probe and open586. */ -void alloc586(struct device *dev) +void alloc586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -394,7 +394,7 @@ void alloc586(struct device *dev) static int elmc_getinfo(char *buf, int slot, void *d) { int len = 0; - struct device *dev = (struct device *) d; + struct net_device *dev = (struct net_device *) d; int i; if (dev == NULL) @@ -422,7 +422,7 @@ static int elmc_getinfo(char *buf, int slot, void *d) /*****************************************************************/ -int __init elmc_probe(struct device *dev) +int __init elmc_probe(struct net_device *dev) { static int slot = 0; int base_addr = dev ? dev->base_addr : 0; @@ -593,7 +593,7 @@ int __init elmc_probe(struct device *dev) * needs a correct 'allocated' memory */ -static int init586(struct device *dev) +static int init586(struct net_device *dev) { void *ptr; unsigned long s; @@ -831,7 +831,7 @@ static int init586(struct device *dev) * It sets up the Receive Frame Area (RFA). */ -static void *alloc_rfa(struct device *dev, void *ptr) +static void *alloc_rfa(struct net_device *dev, void *ptr) { volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr; volatile struct rbd_struct *rbd; @@ -877,7 +877,7 @@ static void *alloc_rfa(struct device *dev, void *ptr) static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; unsigned short stat; struct priv *p; @@ -952,7 +952,7 @@ static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) * receive-interrupt */ -static void elmc_rcv_int(struct device *dev) +static void elmc_rcv_int(struct net_device *dev) { int status; unsigned short totlen; @@ -999,7 +999,7 @@ static void elmc_rcv_int(struct device *dev) * handle 'Receiver went not ready'. */ -static void elmc_rnr_int(struct device *dev) +static void elmc_rnr_int(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1021,7 +1021,7 @@ static void elmc_rnr_int(struct device *dev) * handle xmit - interrupt */ -static void elmc_xmt_int(struct device *dev) +static void elmc_xmt_int(struct net_device *dev) { int status; struct priv *p = (struct priv *) dev->priv; @@ -1066,7 +1066,7 @@ static void elmc_xmt_int(struct device *dev) * (re)start the receiver */ -static void startrecv586(struct device *dev) +static void startrecv586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1080,7 +1080,7 @@ static void startrecv586(struct device *dev) * send frame */ -static int elmc_send_packet(struct sk_buff *skb, struct device *dev) +static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev) { int len; #ifndef NO_NOPCOMMANDS @@ -1192,7 +1192,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct device *dev) * Someone wanna have the statistics */ -static struct net_device_stats *elmc_get_stats(struct device *dev) +static struct net_device_stats *elmc_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; unsigned short crc, aln, rsc, ovrn; @@ -1219,7 +1219,7 @@ static struct net_device_stats *elmc_get_stats(struct device *dev) */ #ifdef ELMC_MULTICAST -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if (!dev->start) { /* without a running interface, promiscuous doesn't work */ @@ -1244,7 +1244,7 @@ static void set_multicast_list(struct device *dev) static char devicenames[NAMELEN * MAX_3C523_CARDS] = {0,}; -static struct device dev_elmc[MAX_3C523_CARDS] = +static struct net_device dev_elmc[MAX_3C523_CARDS] = { { NULL /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL @@ -1263,7 +1263,7 @@ int init_module(void) /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */ for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) { - struct device *dev = &dev_elmc[this_dev]; + struct net_device *dev = &dev_elmc[this_dev]; dev->name=devicenames+(NAMELEN*this_dev); dev->irq=irq[this_dev]; dev->base_addr=io[this_dev]; @@ -1285,7 +1285,7 @@ void cleanup_module(void) int this_dev; for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) { - struct device *dev = &dev_elmc[this_dev]; + struct net_device *dev = &dev_elmc[this_dev]; if(dev->priv) { /* shutdown interrupts on the card */ elmc_id_reset586(); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 33297b0e1..ddb6d8bf8 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -1,3 +1,4 @@ + /* 3c527.c: 3Com Etherlink/MC32 driver for Linux * * (c) Copyright 1998 Red Hat Software Inc @@ -15,7 +16,7 @@ */ static const char *version = - "3c527.c:v0.04 1999/03/16 Alan Cox (alan@redhat.com)\n"; + "3c527.c:v0.05 1999/09/06 Alan Cox (alan@redhat.com)\n"; /* * Things you need @@ -108,6 +109,7 @@ struct mc32_local u16 tx_skb_end; struct sk_buff *rx_skb[RX_RING_MAX]; /* Receive ring */ void *rx_ptr[RX_RING_MAX]; /* Data pointers */ + u32 mc_list_valid; /* True when the mclist is set */ }; /* The station (ethernet) address prefix, used for a sanity check. */ @@ -129,15 +131,17 @@ const struct mca_adapters_t mc32_adapters[] = { /* Index to functions, as function prototypes. */ -extern int mc32_probe(struct device *dev); +extern int mc32_probe(struct net_device *dev); -static int mc32_probe1(struct device *dev, int ioaddr); -static int mc32_open(struct device *dev); -static int mc32_send_packet(struct sk_buff *skb, struct device *dev); +static int mc32_probe1(struct net_device *dev, int ioaddr); +static int mc32_open(struct net_device *dev); +static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev); static void mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int mc32_close(struct device *dev); -static struct net_device_stats *mc32_get_stats(struct device *dev); -static void mc32_set_multicast_list(struct device *dev); +static int mc32_close(struct net_device *dev); +static struct net_device_stats *mc32_get_stats(struct net_device *dev); +static void mc32_set_multicast_list(struct net_device *dev); +static void mc32_reset_multicast_list(struct net_device *dev); + /* * Check for a network adaptor of this type, and return '0' iff one exists. @@ -147,7 +151,7 @@ static void mc32_set_multicast_list(struct device *dev); * (detachable devices only). */ -int __init mc32_probe(struct device *dev) +int __init mc32_probe(struct net_device *dev) { static int current_mca_slot = -1; int i; @@ -183,7 +187,7 @@ int __init mc32_probe(struct device *dev) * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -static int __init mc32_probe1(struct device *dev, int slot) +static int __init mc32_probe1(struct net_device *dev, int slot) { static unsigned version_printed = 0; int i; @@ -435,7 +439,7 @@ static int __init mc32_probe1(struct device *dev, int slot) * Polled command stuff */ -static void mc32_ring_poll(struct device *dev) +static void mc32_ring_poll(struct net_device *dev) { int ioaddr = dev->base_addr; while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR)); @@ -445,16 +449,56 @@ static void mc32_ring_poll(struct device *dev) /* * Send exec commands */ - -static int mc32_command(struct device *dev, u16 cmd, void *data, int len) + + +/* + * Send command from interrupt state + */ + +static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len) +{ + struct mc32_local *lp = (struct mc32_local *)dev->priv; + int ioaddr = dev->base_addr; + + if(lp->exec_pending) + return -1; + + lp->exec_pending=1; + lp->exec_box->mbox=0; + lp->exec_box->mbox=cmd; + memcpy((void *)lp->exec_box->data, data, len); + barrier(); /* the memcpy forgot the volatile so be sure */ + + /* Send the command */ + while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR)); + outb(1<<6, ioaddr+HOST_CMD); + return 0; +} + + +/* + * Send command and block for results. On completion spot and reissue + * multicasts + */ + +static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; unsigned long flags; + int ret = 0; + /* + * Wait for a command + */ + while(lp->exec_pending) sleep_on(&lp->event); + /* + * Issue mine + */ + lp->exec_pending=1; lp->exec_box->mbox=0; lp->exec_box->mbox=cmd; @@ -472,23 +516,25 @@ static int mc32_command(struct device *dev, u16 cmd, void *data, int len) lp->exec_pending=0; restore_flags(flags); + + if(lp->exec_box->data[0]&(1<<13)) + ret = -1; /* * A multicast set got blocked - do it now */ - + if(lp->mc_reload_wait) - mc32_set_multicast_list(dev); + mc32_reset_multicast_list(dev); - if(lp->exec_box->data[0]&(1<<13)) - return -1; - return 0; + return ret; } + /* * RX abort */ -static void mc32_rx_abort(struct device *dev) +static void mc32_rx_abort(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -504,7 +550,7 @@ static void mc32_rx_abort(struct device *dev) * RX enable */ -static void mc32_rx_begin(struct device *dev) +static void mc32_rx_begin(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -518,7 +564,7 @@ static void mc32_rx_begin(struct device *dev) lp->rx_halted=0; } -static void mc32_tx_abort(struct device *dev) +static void mc32_tx_abort(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -565,7 +611,7 @@ static void mc32_tx_abort(struct device *dev) * TX enable */ -static void mc32_tx_begin(struct device *dev) +static void mc32_tx_begin(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -588,7 +634,7 @@ static void mc32_tx_begin(struct device *dev) * Load the rx ring */ -static int mc32_load_rx_ring(struct device *dev) +static int mc32_load_rx_ring(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int i; @@ -652,7 +698,7 @@ static void mc32_flush_tx_ring(struct mc32_local *lp) * sometime after booting when the 'ifconfig' program is run. */ -static int mc32_open(struct device *dev) +static int mc32_open(struct net_device *dev) { int ioaddr = dev->base_addr; u16 zero_word=0; @@ -717,7 +763,7 @@ static int mc32_open(struct device *dev) return 0; } -static int mc32_send_packet(struct sk_buff *skb, struct device *dev) +static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; @@ -796,12 +842,12 @@ static int mc32_send_packet(struct sk_buff *skb, struct device *dev) return 0; } -static void mc32_update_stats(struct device *dev) +static void mc32_update_stats(struct net_device *dev) { } -static void mc32_rx_ring(struct device *dev) +static void mc32_rx_ring(struct net_device *dev) { struct mc32_local *lp=dev->priv; int ioaddr = dev->base_addr; @@ -879,7 +925,7 @@ static void mc32_rx_ring(struct device *dev) */ static void mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct mc32_local *lp; int ioaddr, status, boguscount = 0; int rx_event = 0; @@ -1002,7 +1048,7 @@ static void mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* The inverse routine to mc32_open(). */ -static int mc32_close(struct device *dev) +static int mc32_close(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1050,7 +1096,7 @@ static int mc32_close(struct device *dev) * This may be called with the card open or closed. */ -static struct net_device_stats *mc32_get_stats(struct device *dev) +static struct net_device_stats *mc32_get_stats(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; return &lp->net_stats; @@ -1063,20 +1109,18 @@ static struct net_device_stats *mc32_get_stats(struct device *dev) * num_addrs > 0 Multicast mode, receive normal and MC packets, * and do best-effort filtering. */ -static void mc32_set_multicast_list(struct device *dev) +static void do_mc32_set_multicast_list(struct net_device *dev, int retry) { + struct mc32_local *lp = (struct mc32_local *)dev->priv; u16 filt; + if (dev->flags&IFF_PROMISC) - { /* Enable promiscuous mode */ filt = 1; - mc32_command(dev, 0, &filt, 2); - } else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10) { dev->flags|=IFF_PROMISC; filt = 1; - mc32_command(dev, 0, &filt, 2); } else if(dev->mc_count) { @@ -1087,30 +1131,53 @@ static void mc32_set_multicast_list(struct device *dev) int i; filt = 0; - block[1]=0; - block[0]=dev->mc_count; - bp=block+2; - for(i=0;i<dev->mc_count;i++) + if(retry==0) + lp->mc_list_valid = 0; + if(!lp->mc_list_valid) { - memcpy(bp, dmc->dmi_addr, 6); - bp+=6; - dmc=dmc->next; + block[1]=0; + block[0]=dev->mc_count; + bp=block+2; + + for(i=0;i<dev->mc_count;i++) + { + memcpy(bp, dmc->dmi_addr, 6); + bp+=6; + dmc=dmc->next; + } + if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1) + { + lp->mc_reload_wait = 1; + return; + } + lp->mc_list_valid=1; } - mc32_command(dev, 2, block, 2+6*dev->mc_count); - mc32_command(dev, 0, &filt, 2); } else { filt = 0; - mc32_command(dev, 0, &filt, 2); } + if(mc32_command_nowait(dev, 0, &filt, 2)==-1) + { + lp->mc_reload_wait = 1; + } +} + +static void mc32_set_multicast_list(struct net_device *dev) +{ + do_mc32_set_multicast_list(dev,0); +} + +static void mc32_reset_multicast_list(struct net_device *dev) +{ + do_mc32_set_multicast_list(dev,1); } #ifdef MODULE static char devicename[9] = { 0, }; -static struct device this_device = { +static struct net_device this_device = { devicename, /* will be inserted by linux/drivers/net/mc32_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff --git a/drivers/net/3c527.h b/drivers/net/3c527.h index e4060000b..dfe2738cb 100644 --- a/drivers/net/3c527.h +++ b/drivers/net/3c527.h @@ -37,4 +37,4 @@ struct skb_header #define CONTROL_EL 0x40 /* End of List */ -#define MCA_MC32_ID 0x0041 /* Our MCA ident */ +#define MCA_MC32_ID 0x0041 /* Our MCA ident */
\ No newline at end of file diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 62f73cd71..4ab2add71 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -229,14 +229,14 @@ struct pci_id_info { const char *name; u16 vendor_id, device_id, device_id_mask, flags; int drv_flags, io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, HAS_PWR_CTRL=0x10, HAS_MII=0x20, HAS_NWAY=0x40, HAS_CB_FNS=0x80, }; -static struct device *vortex_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int dev_id, int card_idx); static struct pci_id_info pci_tbl[] = { {"3c590 Vortex 10Mbps", 0x10B7, 0x5900, 0xffff, @@ -263,15 +263,26 @@ static struct pci_id_info pci_tbl[] = { PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, {"3c905B Cyclone 100baseTx", 0x10B7, 0x9055, 0xffff, PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY, 128, vortex_probe1}, + {"3c905B Cyclone 10/100/BNC", 0x10B7, 0x9058, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY, 128, vortex_probe1}, {"3c905B-FX Cyclone 100baseFx", 0x10B7, 0x905A, 0xffff, PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c905C Tornado", 0x10B7, 0x9200, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, {"3c980 Cyclone", 0x10B7, 0x9800, 0xfff0, PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3cSOHO100-TX Hurricane", 0x10B7, 0x7646, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c555 Laptop Hurricane", 0x10B7, 0x5055, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, {"3c575 Boomerang CardBus", 0x10B7, 0x5057, 0xffff, PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, {"3CCFE575 Cyclone CardBus", 0x10B7, 0x5157, 0xffff, PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, 128, vortex_probe1}, + {"3CCFE656 Cyclone CardBus", 0x10B7, 0x6560, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, + 128, vortex_probe1}, {"3c575 series CardBus (unknown version)", 0x10B7, 0x5057, 0xf0ff, PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, {"3Com Boomerang (unknown version)", 0x10B7, 0x9000, 0xff00, @@ -422,7 +433,7 @@ struct vortex_private { /* The addresses of transmit- and receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; - struct device *next_module; + struct net_device *next_module; void *priv_addr; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ @@ -482,23 +493,23 @@ static struct media_table { }; #ifndef CARDBUS -static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]); +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]); #endif -static int vortex_open(struct device *dev); +static int vortex_open(struct net_device *dev); static void mdio_sync(long ioaddr, int bits); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); static void vortex_timer(unsigned long arg); -static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); -static int boomerang_start_xmit(struct sk_buff *skb, struct device *dev); -static int vortex_rx(struct device *dev); -static int boomerang_rx(struct device *dev); +static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int vortex_rx(struct net_device *dev); +static int boomerang_rx(struct net_device *dev); static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int vortex_close(struct device *dev); -static void update_stats(long ioaddr, struct device *dev); -static struct net_device_stats *vortex_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); -static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int vortex_close(struct net_device *dev); +static void update_stats(long ioaddr, struct net_device *dev); +static struct net_device_stats *vortex_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ @@ -507,7 +518,7 @@ static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd); static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,}; static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* A list of all installed Vortex devices, for removing the driver module. */ -static struct device *root_vortex_dev = NULL; +static struct net_device *root_vortex_dev = NULL; #ifdef MODULE #ifndef CARDBUS @@ -524,7 +535,7 @@ static dev_node_t *vortex_attach(dev_locator_t *loc) u16 dev_id, vendor_id; u32 io; u8 bus, devfn, irq; - struct device *dev; + struct net_device *dev; int chip_idx; if (loc->bus != LOC_PCI) return NULL; @@ -566,14 +577,14 @@ static dev_node_t *vortex_attach(dev_locator_t *loc) static void vortex_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "vortex_detach(%s)\n", node->dev_name); for (devp = &root_vortex_dev; *devp; devp = next) { next = &((struct vortex_private *)(*devp)->priv)->next_module; if (strcmp((*devp)->name, node->dev_name) == 0) break; } if (*devp) { - struct device *dev = *devp; + struct net_device *dev = *devp; struct vortex_private *vp = dev->priv; if (dev->flags & IFF_UP) vortex_close(dev); @@ -608,7 +619,7 @@ int init_module(void) } #else -int tc59x_probe(struct device *dev) +int tc59x_probe(struct net_device *dev) { static int scanned=0; if(scanned++) @@ -619,7 +630,7 @@ int tc59x_probe(struct device *dev) #endif /* not MODULE */ #ifndef CARDBUS -static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]) +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]) { int cards_found = 0; @@ -655,20 +666,9 @@ static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]) continue; { -#if LINUX_VERSION_CODE >= 0x20155 struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[0] & ~3; + ioaddr = pdev->resource[0].start; irq = pdev->irq; -#else - u32 pci_ioaddr; - u8 pci_irq_line; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - ioaddr = pci_ioaddr & ~3;; - irq = pci_irq_line; -#endif } /* Power-up the card. */ @@ -773,8 +773,8 @@ static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]) } #endif /* ! Cardbus */ -static struct device *vortex_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int card_idx) { struct vortex_private *vp; @@ -975,7 +975,7 @@ static struct device *vortex_probe1(int pci_bus, int pci_devfn, static int -vortex_open(struct device *dev) +vortex_open(struct net_device *dev) { long ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1170,7 +1170,7 @@ vortex_open(struct device *dev) static void vortex_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -1272,7 +1272,7 @@ static void vortex_timer(unsigned long data) return; } -static void vortex_tx_timeout(struct device *dev) +static void vortex_tx_timeout(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1343,7 +1343,7 @@ static void vortex_tx_timeout(struct device *dev) * the cache impact. */ static void -vortex_error(struct device *dev, int status) +vortex_error(struct net_device *dev, int status) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1432,7 +1432,7 @@ vortex_error(struct device *dev, int status) static int -vortex_start_xmit(struct sk_buff *skb, struct device *dev) +vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1494,7 +1494,7 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) } static int -boomerang_start_xmit(struct sk_buff *skb, struct device *dev) +boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1558,7 +1558,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr; int latency, status; @@ -1683,7 +1683,7 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -static int vortex_rx(struct device *dev) +static int vortex_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1756,7 +1756,7 @@ static int vortex_rx(struct device *dev) } static int -boomerang_rx(struct device *dev) +boomerang_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int entry = vp->cur_rx % RX_RING_SIZE; @@ -1852,7 +1852,7 @@ boomerang_rx(struct device *dev) } static int -vortex_close(struct device *dev) +vortex_close(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1912,7 +1912,7 @@ vortex_close(struct device *dev) return 0; } -static struct net_device_stats *vortex_get_stats(struct device *dev) +static struct net_device_stats *vortex_get_stats(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; unsigned long flags; @@ -1933,7 +1933,7 @@ static struct net_device_stats *vortex_get_stats(struct device *dev) table. This is done by checking that the ASM (!) code generated uses atomic updates with '+='. */ -static void update_stats(long ioaddr, struct device *dev) +static void update_stats(long ioaddr, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1964,7 +1964,7 @@ static void update_stats(long ioaddr, struct device *dev) return; } -static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1992,7 +1992,7 @@ static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd) /* Pre-Cyclone chips have no documented multicast filter, so the only multicast setting is to receive all multicast frames. At least the chip has a very clean way to set the mode, unlike many others. */ -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; int new_mode; @@ -2107,7 +2107,7 @@ static void mdio_write(long ioaddr, int phy_id, int location, int value) #ifdef MODULE void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&vortex_ops); diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 1991659f0..118f92af3 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -101,7 +101,7 @@ static void load_csrs (struct lance_private *lp) #define DEBUG_IRING 0 /* Set up the Lance Rx and Tx rings and the init block */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -219,7 +219,7 @@ static int init_restart_lance (struct lance_private *lp) return 0; } -static int lance_reset (struct device *dev) +static int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int status; @@ -242,7 +242,7 @@ static int lance_reset (struct device *dev) return status; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -320,7 +320,7 @@ static int lance_rx (struct device *dev) return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -405,7 +405,7 @@ static int lance_tx (struct device *dev) static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = (struct lance_private *)dev->priv; int csr0; DECLARE_LL; @@ -460,7 +460,7 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) dev->interrupt = 0; } -int lance_open (struct device *dev) +int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; DECLARE_LL; @@ -472,7 +472,7 @@ int lance_open (struct device *dev) return lance_reset(dev); } -int lance_close (struct device *dev) +int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; DECLARE_LL; @@ -489,7 +489,7 @@ int lance_close (struct device *dev) return 0; } -int lance_start_xmit (struct sk_buff *skb, struct device *dev) +int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -560,7 +560,7 @@ int lance_start_xmit (struct sk_buff *skb, struct device *dev) return status; } -struct net_device_stats *lance_get_stats (struct device *dev) +struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -568,7 +568,7 @@ struct net_device_stats *lance_get_stats (struct device *dev) } /* taken from the depca driver via a2065.c */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -619,7 +619,7 @@ static void lance_load_multicast (struct device *dev) } -void lance_set_multicast (struct device *dev) +void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; diff --git a/drivers/net/7990.h b/drivers/net/7990.h index 4a8f07207..18fb26d92 100644 --- a/drivers/net/7990.h +++ b/drivers/net/7990.h @@ -247,10 +247,10 @@ struct lance_private #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) /* Now the prototypes we export */ -extern int lance_open(struct device *dev); -extern int lance_close (struct device *dev); -extern int lance_start_xmit (struct sk_buff *skb, struct device *dev); -extern struct net_device_stats *lance_get_stats (struct device *dev); -extern void lance_set_multicast (struct device *dev); +extern int lance_open(struct net_device *dev); +extern int lance_close (struct net_device *dev); +extern int lance_start_xmit (struct sk_buff *skb, struct net_device *dev); +extern struct net_device_stats *lance_get_stats (struct net_device *dev); +extern void lance_set_multicast (struct net_device *dev); #endif /* ndef _7990_H */ diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 1dcbd9f40..f3e183904 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -103,11 +103,6 @@ static const char *version = "82596.c:v1.0 15/07/98\n"; #define PORT_ALTSCP 0x02 /* alternate SCB address */ #define PORT_ALTDUMP 0x03 /* Alternate DUMP address */ -#ifndef HAVE_PORTRESERVE -#define check_region(addr, size) 0 -#define request_region(addr, size,name) do ; while(0) -#endif - #ifndef HAVE_ALLOC_SKB #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority) #define kfree_skbmem(buff, size) kfree_s(buff,size) @@ -258,20 +253,20 @@ char init_setup[] = 0x00, 0x7f /* *multi IA */ }; -static int i596_open(struct device *dev); -static int i596_start_xmit(struct sk_buff *skb, struct device *dev); +static int i596_open(struct net_device *dev); +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int i596_close(struct device *dev); -static struct net_device_stats *i596_get_stats(struct device *dev); -static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd); +static int i596_close(struct net_device *dev); +static struct net_device_stats *i596_get_stats(struct net_device *dev); +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); static void print_eth(char *); -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); static int ticks_limit = 25; static int max_cmd_backlog = 16; -static inline void CA(struct device *dev) +static inline void CA(struct net_device *dev) { #ifdef CONFIG_MVME16x_NET if (MACH_IS_MVME16x) { @@ -291,7 +286,7 @@ static inline void CA(struct device *dev) } -static inline void MPU_PORT(struct device *dev, int c, volatile void *x) +static inline void MPU_PORT(struct net_device *dev, int c, volatile void *x) { #ifdef CONFIG_MVME16x_NET if (MACH_IS_MVME16x) { @@ -315,7 +310,7 @@ static inline void MPU_PORT(struct device *dev, int c, volatile void *x) #if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) static void i596_error(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct i596_cmd *cmd; struct i596_private *lp = (struct i596_private *) dev->priv; @@ -338,7 +333,7 @@ static void i596_error(int irq, void *dev_id, struct pt_regs *regs) } #endif -static inline int init_rx_bufs(struct device *dev, int num) +static inline int init_rx_bufs(struct net_device *dev, int num) { struct i596_private *lp = (struct i596_private *) dev->priv; int i; @@ -373,7 +368,7 @@ static inline int init_rx_bufs(struct device *dev, int num) return (i); } -static inline void remove_rx_bufs(struct device *dev) +static inline void remove_rx_bufs(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_rfd *rfd = WSWAPrfd(lp->scb.rfd); @@ -388,7 +383,7 @@ static inline void remove_rx_bufs(struct device *dev) while (rfd != lp->rx_tail); } -static inline void init_i596_mem(struct device *dev) +static inline void init_i596_mem(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; #if !defined(CONFIG_MVME16x_NET) && !defined(CONFIG_BVME6000_NET) @@ -528,7 +523,7 @@ static inline void init_i596_mem(struct device *dev) return; } -static inline int i596_rx(struct device *dev) +static inline int i596_rx(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_rfd *rfd; @@ -645,7 +640,7 @@ static inline void i596_cleanup_cmd(struct i596_private *lp) lp->scb.cmd = WSWAPcmd(lp->cmd_head); } -static inline void i596_reset(struct device *dev, struct i596_private *lp, int ioaddr) +static inline void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) { int boguscnt = 1000; unsigned long flags; @@ -688,7 +683,7 @@ static inline void i596_reset(struct device *dev, struct i596_private *lp, int i init_i596_mem(dev); } -static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd) +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) { struct i596_private *lp = (struct i596_private *) dev->priv; int ioaddr = dev->base_addr; @@ -746,7 +741,7 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd) } } -static int i596_open(struct device *dev) +static int i596_open(struct net_device *dev) { int i; @@ -779,7 +774,7 @@ static int i596_open(struct device *dev) return 0; /* Always succeed */ } -static int i596_start_xmit(struct sk_buff *skb, struct device *dev) +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; int ioaddr = dev->base_addr; @@ -878,7 +873,7 @@ static void print_eth(char *add) printk("type %2.2X%2.2X\n", (unsigned char) add[12], (unsigned char) add[13]); } -int __init i82596_probe(struct device *dev) +int __init i82596_probe(struct net_device *dev) { int i; struct i596_private *lp; @@ -983,7 +978,7 @@ int __init i82596_probe(struct device *dev) static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct i596_private *lp; short ioaddr; int boguscnt = 2000; @@ -1176,7 +1171,7 @@ static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -static int i596_close(struct device *dev) +static int i596_close(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; int boguscnt = 2000; @@ -1239,7 +1234,7 @@ static int i596_close(struct device *dev) } static struct net_device_stats * - i596_get_stats(struct device *dev) + i596_get_stats(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; @@ -1250,7 +1245,7 @@ static struct net_device_stats * * Set or clear the multicast filter for this adaptor. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_cmd *cmd; @@ -1317,7 +1312,7 @@ struct netdev_entry i596_drv = #ifdef MODULE static char devicename[9] = {0,}; -static struct device dev_apricot = +static struct net_device dev_apricot = { devicename, /* device name inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff --git a/drivers/net/8390.c b/drivers/net/8390.c index c6be83778..4b4cc6466 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -76,18 +76,18 @@ static const char *version = /* These are the operational function interfaces to board-specific routines. - void reset_8390(struct device *dev) + void reset_8390(struct net_device *dev) Resets the board associated with DEV, including a hardware reset of the 8390. This is only called when there is a transmit timeout, and it is always followed by 8390_init(). - void block_output(struct device *dev, int count, const unsigned char *buf, + void block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The "page" value uses the 8390's 256-byte pages. - void get_8390_hdr(struct device *dev, struct e8390_hdr *hdr, int ring_page) + void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) Read the 4 byte, page aligned 8390 header. *If* there is a subsequent read, it will be of the rest of the packet. - void block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) + void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) Read COUNT bytes from the packet buffer into the skb data area. Start reading from RING_OFFSET, the address as the 8390 sees it. This will always follow the read of the 8390 header. @@ -103,16 +103,16 @@ int ei_debug = 1; #endif /* Index to functions. */ -static void ei_tx_intr(struct device *dev); -static void ei_tx_err(struct device *dev); -static void ei_receive(struct device *dev); -static void ei_rx_overrun(struct device *dev); +static void ei_tx_intr(struct net_device *dev); +static void ei_tx_err(struct net_device *dev); +static void ei_receive(struct net_device *dev); +static void ei_rx_overrun(struct net_device *dev); /* Routines generic to NS8390-based boards. */ -static void NS8390_trigger_send(struct device *dev, unsigned int length, +static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page); -static void set_multicast_list(struct device *dev); -static void do_set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); +static void do_set_multicast_list(struct net_device *dev); /* * SMP and the 8390 setup. @@ -146,7 +146,7 @@ static void do_set_multicast_list(struct device *dev); up anew at each open, even though many of these registers should only need to be set once at boot. */ -int ei_open(struct device *dev) +int ei_open(struct net_device *dev) { unsigned long flags; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -174,7 +174,7 @@ int ei_open(struct device *dev) } /* Opposite of above. Only used when "ifconfig <devname> down" is done. */ -int ei_close(struct device *dev) +int ei_close(struct net_device *dev) { struct ei_device *ei_local = (struct ei_device *) dev->priv; unsigned long flags; @@ -190,9 +190,9 @@ int ei_close(struct device *dev) return 0; } -static int ei_start_xmit(struct sk_buff *skb, struct device *dev) +static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int length, send_length, output_page; unsigned long flags; @@ -404,8 +404,8 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; - int e8390_base; + struct net_device *dev = dev_id; + long e8390_base; int interrupts, nr_serviced = 0; struct ei_device *ei_local; @@ -516,9 +516,9 @@ void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) * Called with lock held */ -static void ei_tx_err(struct device *dev) +static void ei_tx_err(struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; unsigned char txsr = inb_p(e8390_base+EN0_TSR); unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); @@ -554,9 +554,9 @@ static void ei_tx_err(struct device *dev) /* We have finished a transmit: check for errors and then trigger the next packet to be sent. Called with lock held */ -static void ei_tx_intr(struct device *dev) +static void ei_tx_intr(struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int status = inb(e8390_base + EN0_TSR); @@ -644,9 +644,9 @@ static void ei_tx_intr(struct device *dev) /* We have a good packet(s), get it/them out of the buffers. Called with lock held */ -static void ei_receive(struct device *dev) +static void ei_receive(struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; unsigned char rxing_page, this_frame, next_frame; unsigned short current_offset; @@ -773,9 +773,9 @@ static void ei_receive(struct device *dev) * computer will hate you - it takes 10mS or so. */ -static void ei_rx_overrun(struct device *dev) +static void ei_rx_overrun(struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; unsigned char was_txing, must_resend = 0; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -842,9 +842,9 @@ static void ei_rx_overrun(struct device *dev) * Collect the stats. This is called unlocked and from several contexts. */ -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; unsigned long flags; @@ -888,7 +888,7 @@ static inline u32 update_crc(u8 byte, u32 current_crc) * associated with this dev structure. */ -static inline void make_mc_bits(u8 *bits, struct device *dev) +static inline void make_mc_bits(u8 *bits, struct net_device *dev) { struct dev_mc_list *dmi; @@ -917,9 +917,9 @@ static inline void make_mc_bits(u8 *bits, struct device *dev) * from a BH in 2.1.x. Must be called with lock held. */ -static void do_set_multicast_list(struct device *dev) +static void do_set_multicast_list(struct net_device *dev) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; int i; struct ei_device *ei_local = (struct ei_device*)dev->priv; @@ -972,7 +972,7 @@ static void do_set_multicast_list(struct device *dev) * not called too often. Must protect against both bh and irq users */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { unsigned long flags; struct ei_device *ei_local = (struct ei_device*)dev->priv; @@ -983,11 +983,11 @@ static void set_multicast_list(struct device *dev) } /* - * Initialize the rest of the 8390 device structure. Do NOT __initfunc + * Initialize the rest of the 8390 device structure. Do NOT __init * this, as it is used by 8390 based modular drivers too. */ -int ethdev_init(struct device *dev) +int ethdev_init(struct net_device *dev) { if (ei_debug > 1) printk(version); @@ -1022,9 +1022,9 @@ int ethdev_init(struct device *dev) * Must be called with lock held. */ -void NS8390_init(struct device *dev, int startp) +void NS8390_init(struct net_device *dev, int startp) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; @@ -1085,10 +1085,10 @@ void NS8390_init(struct device *dev, int startp) /* Trigger a transmit start, assuming the length is valid. Always called with the page lock held */ -static void NS8390_trigger_send(struct device *dev, unsigned int length, +static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { - int e8390_base = dev->base_addr; + long e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 4f280b013..068ead40d 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -53,10 +53,10 @@ extern unsigned long autoirq_report(int waittime); #if defined(LOAD_8390_BY_KMOD) && defined(MODULE) && !defined(NS8390_CORE) /* Function pointers to be mapped onto the 8390 core support */ -static int (*S_ethdev_init)(struct device *dev); -static void (*S_NS8390_init)(struct device *dev, int startp); -static int (*S_ei_open)(struct device *dev); -static int (*S_ei_close)(struct device *dev); +static int (*S_ethdev_init)(struct net_device *dev); +static void (*S_NS8390_init)(struct net_device *dev, int startp); +static int (*S_ei_open)(struct net_device *dev); +static int (*S_ei_close)(struct net_device *dev); static void (*S_ei_interrupt)(int irq, void *dev_id, struct pt_regs *regs); @@ -143,23 +143,23 @@ extern __inline__ void unlock_8390_module(void) #define load_8390_module(driver) 0 #define lock_8390_module() do { } while (0) #define unlock_8390_module() do { } while (0) -extern int ethdev_init(struct device *dev); -extern void NS8390_init(struct device *dev, int startp); -extern int ei_open(struct device *dev); -extern int ei_close(struct device *dev); +extern int ethdev_init(struct net_device *dev); +extern void NS8390_init(struct net_device *dev, int startp); +extern int ei_open(struct net_device *dev); +extern int ei_close(struct net_device *dev); extern void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); #endif -/* Most of these entries should be in 'struct device' (or most of the +/* Most of these entries should be in 'struct net_device' (or most of the things in there should be here!) */ /* You have one of these per-board */ struct ei_device { const char *name; - void (*reset_8390)(struct device *); - void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int); - void (*block_output)(struct device *, int, const unsigned char *, int); - void (*block_input)(struct device *, int, struct sk_buff *, int); + void (*reset_8390)(struct net_device *); + void (*get_8390_hdr)(struct net_device *, struct e8390_pkt_hdr *, int); + void (*block_output)(struct net_device *, int, const unsigned char *, int); + void (*block_input)(struct net_device *, int, struct sk_buff *, int); unsigned char mcfilter[8]; unsigned open:1; unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 79a89cb4b..1902e5070 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -24,6 +24,9 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Ethertap network tap' CONFIG_ETHERTAP fi fi + +tristate 'General Instruments Surfboard 1000' CONFIG_NET_SB1000 + # # Ethernet # @@ -90,7 +93,12 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139 + tristate 'SiS 900 PCI Fast Ethernet Adapter support' CONFIG_SIS900 tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN + tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC + if [ "$CONFIG_ACENIC" != "n" ]; then + bool 'Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I + fi fi bool 'Other ISA cards' CONFIG_NET_ISA if [ "$CONFIG_NET_ISA" = "y" ]; then @@ -121,7 +129,6 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then if [ "$CONFIG_NET_EISA" = "y" ]; then tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 fi @@ -143,6 +150,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then tristate 'SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100 bool 'Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET fi + tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE fi bool 'Pocket and portable adaptors' CONFIG_NET_POCKET if [ "$CONFIG_NET_POCKET" = "y" ]; then @@ -194,9 +202,11 @@ if [ ! "$CONFIG_PARPORT" = "n" ]; then dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT fi -tristate 'PPP (point-to-point) support' CONFIG_PPP +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then - comment 'CCP compressors for PPP are only built as modules.' + dep_tristate 'PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate 'PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate 'PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi tristate 'SLIP (serial line) support' CONFIG_SLIP @@ -227,6 +237,11 @@ fi endmenu +bool 'Fibre Channel driver support' CONFIG_NET_FC +if [ "$CONFIG_NET_FC" = "y" ]; then + tristate 'Interphase 5526 Tachyon chipset based adaptor support' CONFIG_IPHASE5526 +fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER @@ -284,6 +299,7 @@ fi endmenu + # # X.25 network drivers # @@ -293,3 +309,7 @@ if [ "$CONFIG_LAPB" != "n" ]; then dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB fi fi + +if [ "$CONFIG_PCMCIA" != "n" ]; then + source drivers/net/pcmcia/Config.in +fi diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 381ae5dfc..e1abc4c0e 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -5,7 +5,7 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) hamradio irda +ALL_SUB_DIRS := $(SUB_DIRS) hamradio irda fc pcmcia L_TARGET := net.a L_OBJS := auto_irq.o @@ -29,6 +29,15 @@ CONFIG_85230_MODULE := CONFIG_SYNCPPP_BUILTIN := CONFIG_SYNCPPP_MODULE := +ifeq ($(CONFIG_PCMCIA),y) + SUB_DIRS += pcmcia + MOD_SUB_DIRS += pcmcia +else + ifeq ($(CONFIG_PCMCIA),m) + MOD_SUB_DIRS += pcmcia + endif +endif + ifeq ($(CONFIG_ISDN),y) ifeq ($(CONFIG_ISDN_PPP),y) CONFIG_SLHC_BUILTIN = y @@ -91,6 +100,14 @@ else endif endif +ifeq ($(CONFIG_NET_SB1000),y) +L_OBJS += sb1000.o +else + ifeq ($(CONFIG_NET_SB1000),m) + M_OBJS += sb1000.o + endif +endif + ifeq ($(CONFIG_DAYNAPORT), y) L_OBJS += daynaport.o CONFIG_8390_BUILTIN = y @@ -302,16 +319,38 @@ endif # bsd_comp.o is *always* a module, for some documented reason # (licensing). ifeq ($(CONFIG_PPP),y) -LX_OBJS += ppp.o -M_OBJS += bsd_comp.o +LX_OBJS += ppp_generic.o CONFIG_SLHC_BUILTIN = y -CONFIG_PPPDEF_BUILTIN = y + ifeq ($(CONFIG_PPP_ASYNC),y) + LX_OBJS += ppp_async.o + else + ifeq ($(CONFIG_PPP_ASYNC),m) + MX_OBJS += ppp_async.o + endif + endif + ifeq ($(CONFIG_PPP_DEFLATE),y) + CONFIG_PPPDEF_BUILTIN = y + else + ifeq ($(CONFIG_PPP_DEFLATE),m) + CONFIG_PPPDEF_MODULE = y + endif + endif + ifeq ($(CONFIG_PPP_BSDCOMP),m) + M_OBJS += bsd_comp.o + endif else ifeq ($(CONFIG_PPP),m) + MX_OBJS += ppp_generic.o CONFIG_SLHC_MODULE = y - CONFIG_PPPDEF_MODULE = y - MX_OBJS += ppp.o - M_OBJS += bsd_comp.o + ifeq ($(CONFIG_PPP_ASYNC),m) + MX_OBJS += ppp_async.o + endif + ifeq ($(CONFIG_PPP_DEFLATE),m) + CONFIG_PPPDEF_MODULE = y + endif + ifeq ($(CONFIG_PPP_BSDCOMP),m) + M_OBJS += bsd_comp.o + endif endif endif @@ -382,6 +421,10 @@ else endif endif +ifeq ($(CONFIG_SUN3LANCE),y) +L_OBJS += sun3lance.o +endif + ifeq ($(CONFIG_PCNET32),y) L_OBJS += pcnet32.o else @@ -558,6 +601,14 @@ else endif endif +ifeq ($(CONFIG_SIS900),y) +L_OBJS += sis900.o +else + ifeq ($(CONFIG_SIS900),m) + M_OBJS += sis900.o + endif +endif + ifeq ($(CONFIG_YELLOWFIN),y) L_OBJS += yellowfin.o else @@ -845,13 +896,11 @@ endif # if anything built-in uses ppp_deflate, then build it into the kernel also. # If not, but a module uses it, build as a module. -# ... NO!!! ppp_deflate.o does not work as resident; -# it works only as a module! ifdef CONFIG_PPPDEF_BUILTIN -MX_OBJS += ppp_deflate.o +L_OBJS += ppp_deflate.o else ifdef CONFIG_PPPDEF_MODULE - MX_OBJS += ppp_deflate.o + M_OBJS += ppp_deflate.o endif endif @@ -884,6 +933,17 @@ else M_OBJS += hplance.o endif endif + +ifeq ($(CONFIG_MVME147_NET),y) +L_OBJS += mvme147.o +CONFIG_7990_BUILTIN = y +else + ifeq ($(CONFIG_MVME147_NET),m) + CONFIG_7990_MODULE = y + M_OBJS += mvme147.o + endif +endif + # If we need generic LANCE support, either in the kernel or as a module, # build it in the appropriate way. ifdef CONFIG_7990_BUILTIN @@ -1056,6 +1116,10 @@ else endif endif +ifeq ($(CONFIG_MACSONIC),y) +L_OBJS += macsonic.o +endif + ifeq ($(CONFIG_BMAC),y) L_OBJS += bmac.o else @@ -1064,6 +1128,14 @@ else endif endif +ifeq ($(CONFIG_ADAPTEC_STARFIRE),y) +L_OBJS += starfire.o +else + ifeq ($(CONFIG_ADAPTEC_STARFIRE),m) + M_OBJS += starfire.o + endif +endif + ifeq ($(CONFIG_VENDOR_SANGOMA),y) LX_OBJS += sdladrv.o L_OBJS += sdlamain.o @@ -1101,6 +1173,15 @@ ifeq ($(CONFIG_CYCLADES_SYNC),y) endif endif +ifeq ($(CONFIG_CYCLADES_SYNC),m) + MX_OBJS += cycx_drv.o + M_OBJS += cyclomx.o + CYCLOMX_OBJS = cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + CYCLOMX_OBJS += cycx_x25.o + endif +endif + ifeq ($(CONFIG_X25_ASY),y) L_OBJS += x25_asy.o else @@ -1130,6 +1211,15 @@ else endif endif +ifeq ($(CONFIG_NET_FC),y) +SUB_DIRS += fc +MOD_IN_SUB_DIRS += fc +else + ifeq ($(CONFIG_NET_FC),m) + MOD_IN_SUB_DIRS += fc + endif +endif + include $(TOPDIR)/Rules.make clean: diff --git a/drivers/net/Space.c b/drivers/net/Space.c index fd660f2ab..27c431e14 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -39,105 +39,113 @@ ethernet adaptor have the name "eth[0123...]". */ -extern int ne2_probe(struct device *dev); -extern int tulip_probe(struct device *dev); -extern int hp100_probe(struct device *dev); -extern int ultra_probe(struct device *dev); -extern int ultra32_probe(struct device *dev); -extern int ultramca_probe(struct device *dev); -extern int wd_probe(struct device *dev); -extern int el2_probe(struct device *dev); -extern int ne2k_pci_probe(struct device *dev); -extern int ne_probe(struct device *dev); -extern int hp_probe(struct device *dev); -extern int hp_plus_probe(struct device *dev); -extern int znet_probe(struct device *); -extern int express_probe(struct device *); -extern int eepro_probe(struct device *); -extern int eepro100_probe(struct device *); -extern int el3_probe(struct device *); -extern int at1500_probe(struct device *); -extern int pcnet32_probe(struct device *); -extern int at1700_probe(struct device *); -extern int fmv18x_probe(struct device *); -extern int eth16i_probe(struct device *); -extern int depca_probe(struct device *); -extern int i82596_probe(struct device *); -extern int ewrk3_probe(struct device *); -extern int de4x5_probe(struct device *); -extern int el1_probe(struct device *); -extern int wavelan_probe(struct device *); -extern int arlan_probe(struct device *); -extern int el16_probe(struct device *); -extern int elmc_probe(struct device *); -extern int skmca_probe(struct device *); -extern int elplus_probe(struct device *); -extern int ac3200_probe(struct device *); -extern int es_probe(struct device *); -extern int lne390_probe(struct device *); -extern int ne3210_probe(struct device *); -extern int e2100_probe(struct device *); -extern int ni5010_probe(struct device *); -extern int ni52_probe(struct device *); -extern int ni65_probe(struct device *); -extern int sonic_probe(struct device *); -extern int SK_init(struct device *); -extern int seeq8005_probe(struct device *); -extern int tc59x_probe(struct device *); -extern int dgrs_probe(struct device *); -extern int smc_init( struct device * ); -extern int sparc_lance_probe(struct device *); -extern int happy_meal_probe(struct device *); -extern int qec_probe(struct device *); -extern int bigmac_probe(struct device *); -extern int myri_sbus_probe(struct device *); -extern int sgiseeq_probe(struct device *); -extern int atarilance_probe(struct device *); -extern int a2065_probe(struct device *); -extern int ariadne_probe(struct device *); -extern int ariadne2_probe(struct device *); -extern int hydra_probe(struct device *); -extern int apne_probe(struct device *); -extern int bionet_probe(struct device *); -extern int pamsnet_probe(struct device *); -extern int tlan_probe(struct device *); -extern int mace_probe(struct device *); -extern int bmac_probe(struct device *); -extern int cs89x0_probe(struct device *dev); -extern int ethertap_probe(struct device *dev); -extern int ether1_probe (struct device *dev); -extern int ether3_probe (struct device *dev); -extern int etherh_probe (struct device *dev); -extern int am79c961_probe(struct device *dev); -extern int epic100_probe(struct device *dev); -extern int rtl8139_probe(struct device *dev); -extern int hplance_probe(struct device *dev); -extern int bagetlance_probe(struct device *); -extern int dec_lance_probe(struct device *); -extern int via_rhine_probe(struct device *dev); -extern int tc515_probe(struct device *dev); -extern int lance_probe(struct device *dev); -extern int rcpci_probe(struct device *); +extern int ne2_probe(struct net_device *dev); +extern int tulip_probe(struct net_device *dev); +extern int hp100_probe(struct net_device *dev); +extern int ultra_probe(struct net_device *dev); +extern int ultra32_probe(struct net_device *dev); +extern int ultramca_probe(struct net_device *dev); +extern int wd_probe(struct net_device *dev); +extern int el2_probe(struct net_device *dev); +extern int ne2k_pci_probe(struct net_device *dev); +extern int ne_probe(struct net_device *dev); +extern int hp_probe(struct net_device *dev); +extern int hp_plus_probe(struct net_device *dev); +extern int znet_probe(struct net_device *); +extern int express_probe(struct net_device *); +extern int eepro_probe(struct net_device *); +extern int eepro100_probe(struct net_device *); +extern int el3_probe(struct net_device *); +extern int at1500_probe(struct net_device *); +extern int pcnet32_probe(struct net_device *); +extern int at1700_probe(struct net_device *); +extern int fmv18x_probe(struct net_device *); +extern int eth16i_probe(struct net_device *); +extern int depca_probe(struct net_device *); +extern int i82596_probe(struct net_device *); +extern int ewrk3_probe(struct net_device *); +extern int de4x5_probe(struct net_device *); +extern int el1_probe(struct net_device *); +extern int wavelan_probe(struct net_device *); +extern int arlan_probe(struct net_device *); +extern int el16_probe(struct net_device *); +extern int elmc_probe(struct net_device *); +extern int skmca_probe(struct net_device *); +extern int elplus_probe(struct net_device *); +extern int ac3200_probe(struct net_device *); +extern int es_probe(struct net_device *); +extern int lne390_probe(struct net_device *); +extern int ne3210_probe(struct net_device *); +extern int e2100_probe(struct net_device *); +extern int ni5010_probe(struct net_device *); +extern int ni52_probe(struct net_device *); +extern int ni65_probe(struct net_device *); +extern int sonic_probe(struct net_device *); +extern int SK_init(struct net_device *); +extern int seeq8005_probe(struct net_device *); +extern int tc59x_probe(struct net_device *); +extern int dgrs_probe(struct net_device *); +extern int smc_init( struct net_device * ); +extern int sparc_lance_probe(struct net_device *); +extern int happy_meal_probe(struct net_device *); +extern int qec_probe(struct net_device *); +extern int bigmac_probe(struct net_device *); +extern int myri_sbus_probe(struct net_device *); +extern int sgiseeq_probe(struct net_device *); +extern int atarilance_probe(struct net_device *); +extern int sun3lance_probe(struct net_device *); +extern int a2065_probe(struct net_device *); +extern int ariadne_probe(struct net_device *); +extern int ariadne2_probe(struct net_device *); +extern int hydra_probe(struct net_device *); +extern int apne_probe(struct net_device *); +extern int bionet_probe(struct net_device *); +extern int pamsnet_probe(struct net_device *); +extern int tlan_probe(struct net_device *); +extern int mace_probe(struct net_device *); +extern int bmac_probe(struct net_device *); +extern int cs89x0_probe(struct net_device *dev); +extern int ethertap_probe(struct net_device *dev); +extern int ether1_probe (struct net_device *dev); +extern int ether3_probe (struct net_device *dev); +extern int etherh_probe (struct net_device *dev); +extern int am79c961_probe(struct net_device *dev); +extern int epic100_probe(struct net_device *dev); +extern int rtl8139_probe(struct net_device *dev); +extern int sis900_probe(struct net_device *dev); +extern int hplance_probe(struct net_device *dev); +extern int bagetlance_probe(struct net_device *); +extern int dec_lance_probe(struct net_device *); +extern int mvme147lance_probe(struct net_device *dev); +extern int via_rhine_probe(struct net_device *dev); +extern int starfire_probe(struct net_device *dev); +extern int tc515_probe(struct net_device *dev); +extern int lance_probe(struct net_device *dev); +extern int rcpci_probe(struct net_device *); +extern int mac_onboard_sonic_probe(struct net_device *dev); /* Gigabit Ethernet adapters */ -extern int yellowfin_probe(struct device *dev); -extern int acenic_probe(struct device *dev); +extern int yellowfin_probe(struct net_device *dev); +extern int acenic_probe(struct net_device *dev); /* Detachable devices ("pocket adaptors") */ -extern int atp_init(struct device *); -extern int de600_probe(struct device *); -extern int de620_probe(struct device *); +extern int atp_init(struct net_device *); +extern int de600_probe(struct net_device *); +extern int de620_probe(struct net_device *); /* FDDI adapters */ -extern int dfx_probe(struct device *dev); -extern int apfddi_init(struct device *dev); +extern int dfx_probe(struct net_device *dev); +extern int apfddi_init(struct net_device *dev); /* HIPPI boards */ -extern int rr_hippi_probe(struct device *); +extern int rr_hippi_probe(struct net_device *); + +/* Fibre Channel adapters */ +extern int iph5526_probe(struct net_device *dev); struct devprobe { - int (*probe)(struct device *dev); + int (*probe)(struct net_device *dev); int status; /* non-zero if autoprobe has failed */ }; @@ -148,7 +156,7 @@ struct devprobe * autoprobe (i.e. a probe that fails to find a card when autoprobing * will not be asked to autoprobe again). It exits when a card is found. */ -static int __init probe_list(struct device *dev, struct devprobe *plist) +static int __init probe_list(struct net_device *dev, struct devprobe *plist) { struct devprobe *p = plist; unsigned long base_addr = dev->base_addr; @@ -205,6 +213,9 @@ struct devprobe pci_probes[] __initdata = { #ifdef CONFIG_RTL8139 {rtl8139_probe, 0}, #endif +#ifdef CONFIG_SIS900 + {sis900_probe, 0}, +#endif #ifdef CONFIG_YELLOWFIN {yellowfin_probe, 0}, #endif @@ -214,6 +225,9 @@ struct devprobe pci_probes[] __initdata = { #ifdef CONFIG_VIA_RHINE {via_rhine_probe, 0}, #endif +#ifdef CONFIG_ADAPTEC_STARFIRE + {starfire_probe, 0}, +#endif {NULL, 0}, }; @@ -401,6 +415,9 @@ struct devprobe m68k_probes[] __initdata = { #ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */ {atarilance_probe, 0}, #endif +#ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */ + {sun3lance_probe, 0}, +#endif #ifdef CONFIG_A2065 /* Commodore/Ameristar A2065 Ethernet Board */ {a2065_probe, 0}, #endif @@ -425,6 +442,12 @@ struct devprobe m68k_probes[] __initdata = { #ifdef CONFIG_HPLANCE /* HP300 internal Ethernet */ {hplance_probe, 0}, #endif +#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */ + {mvme147lance_probe, 0}, +#endif +#ifdef CONFIG_MACSONIC /* Mac 68k Quadra builtin Ethernet */ + {mac_onboard_sonic_probe, 0}, +#endif {NULL, 0}, }; @@ -478,7 +501,7 @@ struct devprobe arm_probes[] __initdata = { * Unified ethernet device probe, segmented per architecture and * per bus interface. */ -static int __init ethif_probe(struct device *dev) +static int __init ethif_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; @@ -526,7 +549,7 @@ static int __init ethif_probe(struct device *dev) } #ifdef CONFIG_FDDI -static int __init fddiif_probe(struct device *dev) +static int __init fddiif_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; @@ -548,7 +571,7 @@ static int __init fddiif_probe(struct device *dev) #endif #ifdef CONFIG_HIPPI -static int hippi_probe(struct device *dev) +static int hippi_probe(struct net_device *dev) { /* * Damn this is ugly. @@ -570,24 +593,50 @@ static int hippi_probe(struct device *dev) } #endif +/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */ +#define __PAD6 "\0\0\0\0\0\0\0\0\0" +#define __PAD5 __PAD6 "\0" +#define __PAD4 __PAD5 "\0" +#define __PAD3 __PAD4 "\0" +#define __PAD2 __PAD3 "\0" + + +#ifdef CONFIG_NET_FC +static int fcif_probe(struct net_device *dev) +{ + if (dev->base_addr == -1) + return 1; + + if (1 +#ifdef CONFIG_IPHASE5526 + && iph5526_probe(dev) +#endif + && 1 ) { + return 1; /* -ENODEV or -EAGAIN would be more accurate. */ + } + return 0; +} +#endif /* CONFIG_NET_FC */ + + #ifdef CONFIG_ETHERTAP - static struct device tap0_dev = { "tap0", 0, 0, 0, 0, NETLINK_TAPBASE, 0, 0, 0, 0, NEXT_DEV, ethertap_probe, }; + static struct net_device tap0_dev = { "tap0" __PAD4, 0, 0, 0, 0, NETLINK_TAPBASE, 0, 0, 0, 0, NEXT_DEV, ethertap_probe, }; # undef NEXT_DEV # define NEXT_DEV (&tap0_dev) #endif #ifdef CONFIG_SDLA - extern int sdla_init(struct device *); - static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, }; + extern int sdla_init(struct net_device *); + static struct net_device sdla0_dev = { "sdla0" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, }; # undef NEXT_DEV # define NEXT_DEV (&sdla0_dev) #endif #if defined(CONFIG_LTPC) - extern int ltpc_probe(struct device *); - static struct device dev_ltpc = { - "lt0\0 ", + extern int ltpc_probe(struct net_device *); + static struct net_device dev_ltpc = { + "lt0" __PAD3, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, ltpc_probe }; @@ -596,18 +645,18 @@ static int hippi_probe(struct device *dev) #endif /* LTPC */ #if defined(CONFIG_COPS) - extern int cops_probe(struct device *); - static struct device cops2_dev = { "lt2", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, cops_probe }; - static struct device cops1_dev = { "lt1", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops2_dev, cops_probe }; - static struct device cops0_dev = { "lt0", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops1_dev, cops_probe }; + extern int cops_probe(struct net_device *); + static struct net_device cops2_dev = { "lt2" __PAD3, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, cops_probe }; + static struct net_device cops1_dev = { "lt1" __PAD3, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops2_dev, cops_probe }; + static struct net_device cops0_dev = { "lt0" __PAD3, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops1_dev, cops_probe }; # undef NEXT_DEV # define NEXT_DEV (&cops0_dev) #endif /* COPS */ #if defined(CONFIG_IPDDP) - extern int ipddp_init(struct device *dev); - static struct device dev_ipddp = { - "ipddp0\0 ", + extern int ipddp_init(struct net_device *dev); + static struct net_device dev_ipddp = { + "ipddp0" __PAD6, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, ipddp_init }; @@ -629,23 +678,23 @@ static int hippi_probe(struct device *dev) #define ETH_NOPROBE_ADDR 0xffe0 -static struct device eth7_dev = { - "eth7", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe }; -static struct device eth6_dev = { - "eth6", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð7_dev, ethif_probe }; -static struct device eth5_dev = { - "eth5", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð6_dev, ethif_probe }; -static struct device eth4_dev = { - "eth4", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð5_dev, ethif_probe }; -static struct device eth3_dev = { - "eth3", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð4_dev, ethif_probe }; -static struct device eth2_dev = { - "eth2", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð3_dev, ethif_probe }; -static struct device eth1_dev = { - "eth1", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð2_dev, ethif_probe }; - -static struct device eth0_dev = { - "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev, ethif_probe }; +static struct net_device eth7_dev = { + "eth7" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe }; +static struct net_device eth6_dev = { + "eth6" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð7_dev, ethif_probe }; +static struct net_device eth5_dev = { + "eth5" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð6_dev, ethif_probe }; +static struct net_device eth4_dev = { + "eth4" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð5_dev, ethif_probe }; +static struct net_device eth3_dev = { + "eth3" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð4_dev, ethif_probe }; +static struct net_device eth2_dev = { + "eth2" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð3_dev, ethif_probe }; +static struct net_device eth1_dev = { + "eth1" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð2_dev, ethif_probe }; + +static struct net_device eth0_dev = { + "eth0" __PAD4, 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev, ethif_probe }; # undef NEXT_DEV # define NEXT_DEV (ð0_dev) @@ -653,8 +702,8 @@ static struct device eth0_dev = { #if defined(SLIP) || defined(CONFIG_SLIP) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int slip_init_ctrl_dev(struct device *); -static struct device slip_bootstrap = { +extern int slip_init_ctrl_dev(struct net_device *); +static struct net_device slip_bootstrap = { "slip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, slip_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&slip_bootstrap) @@ -663,8 +712,8 @@ static struct device slip_bootstrap = { #if defined(X25_ASY) || defined(CONFIG_X25_ASY) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int x25_asy_init_ctrl_dev(struct device *); -static struct device x25_asy_bootstrap = { +extern int x25_asy_init_ctrl_dev(struct net_device *); +static struct net_device x25_asy_bootstrap = { "x25_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, x25_asy_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&x25_asy_bootstrap) @@ -673,41 +722,49 @@ static struct device x25_asy_bootstrap = { #if defined(CONFIG_MKISS) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int mkiss_init_ctrl_dev(struct device *); -static struct device mkiss_bootstrap = { +extern int mkiss_init_ctrl_dev(struct net_device *); +static struct net_device mkiss_bootstrap = { "mkiss_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, mkiss_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&mkiss_bootstrap) #endif /* MKISS */ +#if defined(CONFIG_YAM) +extern int yam_init(struct net_device *); +static struct net_device yam_bootstrap = { + "yam", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, yam_init, }; +#undef NEXT_DEV +#define NEXT_DEV (&yam_bootstrap) +#endif /* CONFIG_YAM */ + #if defined(CONFIG_STRIP) -extern int strip_init_ctrl_dev(struct device *); -static struct device strip_bootstrap = { +extern int strip_init_ctrl_dev(struct net_device *); +static struct net_device strip_bootstrap = { "strip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, strip_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&strip_bootstrap) #endif /* STRIP */ #if defined(CONFIG_PPP) -extern int ppp_init(struct device *); -static struct device ppp_bootstrap = { +extern int ppp_init(struct net_device *); +static struct net_device ppp_bootstrap = { "ppp_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, ppp_init, }; #undef NEXT_DEV #define NEXT_DEV (&ppp_bootstrap) #endif /* PPP */ #ifdef CONFIG_DUMMY - extern int dummy_init(struct device *dev); - static struct device dummy_dev = { - "dummy", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, }; + extern int dummy_init(struct net_device *dev); + static struct net_device dummy_dev = { + "dummy" __PAD5, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, }; # undef NEXT_DEV # define NEXT_DEV (&dummy_dev) #endif #ifdef CONFIG_EQUALIZER -extern int eql_init(struct device *dev); -struct device eql_dev = { - "eql", /* Master device for IP traffic load +extern int eql_init(struct net_device *dev); +struct net_device eql_dev = { + "eql" __PAD3, /* Master device for IP traffic load balancing */ 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */ 0, /* base I/O address */ @@ -722,11 +779,11 @@ struct device eql_dev = { #ifdef CONFIG_TR /* Token-ring device probe */ -extern int ibmtr_probe(struct device *); -extern int olympic_probe(struct device *); +extern int ibmtr_probe(struct net_device *); +extern int olympic_probe(struct net_device *); static int -trif_probe(struct device *dev) +trif_probe(struct net_device *dev) { if (1 #ifdef CONFIG_IBMTR @@ -746,73 +803,92 @@ trif_probe(struct device *dev) } return 0; } -static struct device tr7_dev = { - "tr7",0,0,0,0,0,0,0,0,0, NEXT_DEV, trif_probe }; -static struct device tr6_dev = { - "tr6",0,0,0,0,0,0,0,0,0, &tr7_dev, trif_probe }; -static struct device tr5_dev = { - "tr5",0,0,0,0,0,0,0,0,0, &tr6_dev, trif_probe }; -static struct device tr4_dev = { - "tr4",0,0,0,0,0,0,0,0,0, &tr5_dev, trif_probe }; -static struct device tr3_dev = { - "tr3",0,0,0,0,0,0,0,0,0, &tr4_dev, trif_probe }; -static struct device tr2_dev = { - "tr2",0,0,0,0,0,0,0,0,0, &tr3_dev, trif_probe }; -static struct device tr1_dev = { - "tr1",0,0,0,0,0,0,0,0,0, &tr2_dev, trif_probe }; -static struct device tr0_dev = { - "tr0",0,0,0,0,0,0,0,0,0, &tr1_dev, trif_probe }; +static struct net_device tr7_dev = { + "tr7" __PAD3,0,0,0,0,0,0,0,0,0, NEXT_DEV, trif_probe }; +static struct net_device tr6_dev = { + "tr6" __PAD3,0,0,0,0,0,0,0,0,0, &tr7_dev, trif_probe }; +static struct net_device tr5_dev = { + "tr5" __PAD3,0,0,0,0,0,0,0,0,0, &tr6_dev, trif_probe }; +static struct net_device tr4_dev = { + "tr4" __PAD3,0,0,0,0,0,0,0,0,0, &tr5_dev, trif_probe }; +static struct net_device tr3_dev = { + "tr3" __PAD3,0,0,0,0,0,0,0,0,0, &tr4_dev, trif_probe }; +static struct net_device tr2_dev = { + "tr2" __PAD3,0,0,0,0,0,0,0,0,0, &tr3_dev, trif_probe }; +static struct net_device tr1_dev = { + "tr1" __PAD3,0,0,0,0,0,0,0,0,0, &tr2_dev, trif_probe }; +static struct net_device tr0_dev = { + "tr0" __PAD3,0,0,0,0,0,0,0,0,0, &tr1_dev, trif_probe }; # undef NEXT_DEV # define NEXT_DEV (&tr0_dev) #endif #ifdef CONFIG_FDDI - static struct device fddi7_dev = - {"fddi7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, fddiif_probe}; - static struct device fddi6_dev = - {"fddi6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi7_dev, fddiif_probe}; - static struct device fddi5_dev = - {"fddi5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi6_dev, fddiif_probe}; - static struct device fddi4_dev = - {"fddi4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi5_dev, fddiif_probe}; - static struct device fddi3_dev = - {"fddi3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi4_dev, fddiif_probe}; - static struct device fddi2_dev = - {"fddi2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi3_dev, fddiif_probe}; - static struct device fddi1_dev = - {"fddi1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi2_dev, fddiif_probe}; - static struct device fddi0_dev = - {"fddi0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi1_dev, fddiif_probe}; + static struct net_device fddi7_dev = + {"fddi7" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, fddiif_probe}; + static struct net_device fddi6_dev = + {"fddi6" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi7_dev, fddiif_probe}; + static struct net_device fddi5_dev = + {"fddi5" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi6_dev, fddiif_probe}; + static struct net_device fddi4_dev = + {"fddi4" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi5_dev, fddiif_probe}; + static struct net_device fddi3_dev = + {"fddi3" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi4_dev, fddiif_probe}; + static struct net_device fddi2_dev = + {"fddi2" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi3_dev, fddiif_probe}; + static struct net_device fddi1_dev = + {"fddi1" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi2_dev, fddiif_probe}; + static struct net_device fddi0_dev = + {"fddi0" __PAD5, 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi1_dev, fddiif_probe}; #undef NEXT_DEV #define NEXT_DEV (&fddi0_dev) #endif #ifdef CONFIG_HIPPI - static struct device hip3_dev = - {"hip3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, hippi_probe}; - static struct device hip2_dev = - {"hip2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip3_dev, hippi_probe}; - static struct device hip1_dev = - {"hip1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip2_dev, hippi_probe}; - static struct device hip0_dev = - {"hip0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip1_dev, hippi_probe}; + static struct net_device hip3_dev = + {"hip3" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, hippi_probe}; + static struct net_device hip2_dev = + {"hip2" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip3_dev, hippi_probe}; + static struct net_device hip1_dev = + {"hip1" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip2_dev, hippi_probe}; + static struct net_device hip0_dev = + {"hip0" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip1_dev, hippi_probe}; #undef NEXT_DEV #define NEXT_DEV (&hip0_dev) #endif #ifdef CONFIG_APBIF - extern int bif_init(struct device *dev); - static struct device bif_dev = { - "bif", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, bif_init }; + extern int bif_init(struct net_device *dev); + static struct net_device bif_dev = { + "bif" __PAD3, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, bif_init }; # undef NEXT_DEV # define NEXT_DEV (&bif_dev) #endif + + +#ifdef CONFIG_NET_FC + static struct net_device fc1_dev = { + "fc1", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, fcif_probe}; + static struct net_device fc0_dev = { + "fc0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fc1_dev, fcif_probe}; +# undef NEXT_DEV +# define NEXT_DEV (&fc0_dev) +#endif + + +#ifdef CONFIG_NET_SB1000 + extern int sb1000_probe(struct net_device *dev); + static struct net_device sb1000_dev = { + "cm0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, sb1000_probe }; +# undef NEXT_DEV +# define NEXT_DEV (&sb1000_dev) +#endif -extern int loopback_init(struct device *dev); -struct device loopback_dev = { - "lo", /* Software Loopback interface */ +extern int loopback_init(struct net_device *dev); +struct net_device loopback_dev = { + "lo" __PAD2, /* Software Loopback interface */ 0x0, /* recv memory end */ 0x0, /* recv memory start */ 0x0, /* memory end */ @@ -824,5 +900,5 @@ struct device loopback_dev = { loopback_init /* loopback_init should set up the rest */ }; -struct device *dev_base = &loopback_dev; +struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 348b2e790..ead77eb9e 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -1,8 +1,7 @@ /* * Amiga Linux/68k A2065 Ethernet Driver * - * (C) Copyright 1995 by Geert Uytterhoeven - * (Geert.Uytterhoeven@cs.kuleuven.ac.be) + * (C) Copyright 1995 by Geert Uytterhoeven <geert@linux-m68k.org> * * Fixes and tips by: * - Janos Farkas (CHEXUM@sparta.banki.hu) @@ -169,7 +168,7 @@ static void load_csrs (struct lance_private *lp) /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -270,7 +269,7 @@ static int init_restart_lance (struct lance_private *lp) return 0; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -345,7 +344,7 @@ static int lance_rx (struct device *dev) return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -430,12 +429,12 @@ static int lance_tx (struct device *dev) static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev; + struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; int csr0; - dev = (struct device *) dev_id; + dev = (struct net_device *) dev_id; lp = (struct lance_private *) dev->priv; ll = lp->ll; @@ -488,9 +487,9 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open (struct device *dev) +static int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -499,7 +498,7 @@ static int lance_open (struct device *dev) last_dev = dev; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, lance_interrupt, 0, + if (request_irq(IRQ_AMIGA_PORTS, lance_interrupt, SA_SHIRQ, "a2065 Ethernet", dev)) return -EAGAIN; @@ -521,7 +520,7 @@ static int lance_open (struct device *dev) return status; } -static int lance_close (struct device *dev) +static int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -541,7 +540,7 @@ static int lance_close (struct device *dev) return 0; } -static inline int lance_reset (struct device *dev) +static inline int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -564,7 +563,7 @@ static inline int lance_reset (struct device *dev) return status; } -static int lance_start_xmit (struct sk_buff *skb, struct device *dev) +static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -644,7 +643,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev) return status; } -static struct net_device_stats *lance_get_stats (struct device *dev) +static struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -652,7 +651,7 @@ static struct net_device_stats *lance_get_stats (struct device *dev) } /* taken from the depca driver */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -702,7 +701,7 @@ static void lance_load_multicast (struct device *dev) return; } -static void lance_set_multicast (struct device *dev) +static void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -739,7 +738,7 @@ static void lance_set_multicast (struct device *dev) mark_bh(NET_BH); } -int __init a2065_probe(struct device *dev) +int __init a2065_probe(struct net_device *dev) { unsigned int key, is_cbm; const struct ConfigDev *cd; @@ -821,7 +820,7 @@ int __init a2065_probe(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device a2065_dev = +static struct net_device a2065_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/a2065.h b/drivers/net/a2065.h index 145bc694d..db6e9e65d 100644 --- a/drivers/net/a2065.h +++ b/drivers/net/a2065.h @@ -1,8 +1,7 @@ /* * Amiga Linux/68k A2065 Ethernet Driver * - * (C) Copyright 1995 by Geert Uytterhoeven - * (Geert.Uytterhoeven@cs.kuleuven.ac.be) + * (C) Copyright 1995 by Geert Uytterhoeven <geert@linux-m68k.org> * * --------------------------------------------------------------------------- * diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 8f1246d85..012dc2b8d 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -74,19 +74,19 @@ static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; #define AC_START_PG 0x00 /* First page of 8390 TX buffer */ #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */ -int ac3200_probe(struct device *dev); -static int ac_probe1(int ioaddr, struct device *dev); +int ac3200_probe(struct net_device *dev); +static int ac_probe1(int ioaddr, struct net_device *dev); -static int ac_open(struct device *dev); -static void ac_reset_8390(struct device *dev); -static void ac_block_input(struct device *dev, int count, +static int ac_open(struct net_device *dev); +static void ac_reset_8390(struct net_device *dev); +static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ac_block_output(struct device *dev, const int count, +static void ac_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int ac_close_card(struct device *dev); +static int ac_close_card(struct net_device *dev); /* Probe for the AC3200. @@ -95,7 +95,7 @@ static int ac_close_card(struct device *dev); or the unique value in the station address PROM. */ -int __init ac3200_probe(struct device *dev) +int __init ac3200_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -117,7 +117,7 @@ int __init ac3200_probe(struct device *dev) return ENODEV; } -static int __init ac_probe1(int ioaddr, struct device *dev) +static int __init ac_probe1(int ioaddr, struct net_device *dev) { int i; @@ -254,7 +254,7 @@ static int __init ac_probe1(int ioaddr, struct device *dev) return 0; } -static int ac_open(struct device *dev) +static int ac_open(struct net_device *dev) { #ifdef notyet /* Someday we may enable the IRQ and shared memory here. */ @@ -271,7 +271,7 @@ static int ac_open(struct device *dev) return 0; } -static void ac_reset_8390(struct device *dev) +static void ac_reset_8390(struct net_device *dev) { ushort ioaddr = dev->base_addr; @@ -290,7 +290,7 @@ static void ac_reset_8390(struct device *dev) the start of a page, so we optimize accordingly. */ static void -ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -299,7 +299,7 @@ ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) /* Block input and output are easy on shared memory ethercards, the only complication is when the ring buffer wraps. */ -static void ac_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8); @@ -316,7 +316,7 @@ static void ac_block_input(struct device *dev, int count, struct sk_buff *skb, } } -static void ac_block_output(struct device *dev, int count, +static void ac_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8); @@ -324,7 +324,7 @@ static void ac_block_output(struct device *dev, int count, memcpy_toio(shmem, buf, count); } -static int ac_close_card(struct device *dev) +static int ac_close_card(struct net_device *dev) { dev->start = 0; dev->tbusy = 1; @@ -349,7 +349,7 @@ static int ac_close_card(struct device *dev) #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, }; -static struct device dev_ac32[MAX_AC32_CARDS] = { +static struct net_device dev_ac32[MAX_AC32_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -371,7 +371,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { - struct device *dev = &dev_ac32[this_dev]; + struct net_device *dev = &dev_ac32[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -399,7 +399,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { - struct device *dev = &dev_ac32[this_dev]; + struct net_device *dev = &dev_ac32[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* Someday free_irq may be in ac_close_card() */ diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 38fa4b98f..72a8de88d 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -2,7 +2,7 @@ * acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card * and other Tigon based cards. * - * Copyright 1998 by Jes Sorensen, <Jes.Sorensen@cern.ch>. + * Copyright 1998, 1999 by Jes Sorensen, <Jes.Sorensen@cern.ch>. * * Thanks to Alteon and 3Com for providing hardware and documentation * enabling me to write this driver. @@ -18,13 +18,13 @@ * (at your option) any later version. * * Additional work by Pete Wyckoff <wyckoff@ca.sandia.gov> for initial - * Alpha and trace dump support. + * Alpha and trace dump support. The trace dump support has not been + * integrated yet however. */ -#define PKT_COPY_THRESHOLD 300 - +#include <linux/config.h> #include <linux/module.h> - +#include <linux/version.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/ioport.h> @@ -36,6 +36,9 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/mm.h> +#ifdef ETHTOOL +#include <linux/ethtool.h> +#endif #include <net/sock.h> #include <net/ip.h> @@ -45,16 +48,12 @@ #include <asm/byteorder.h> #include <asm/uaccess.h> -#include "acenic.h" - -/* - * These must be defined before the firmware is included. - */ -#define MAX_TEXT_LEN 96*1024 -#define MAX_RODATA_LEN 8*1024 -#define MAX_DATA_LEN 2*1024 -#include "acenic_firmware.h" +#ifdef CONFIG_ACENIC_OMIT_TIGON_I +#define ACE_IS_TIGON_I(ap) 0 +#else +#define ACE_IS_TIGON_I(ap) (ap->version == 1) +#endif #ifndef PCI_VENDOR_ID_ALTEON #define PCI_VENDOR_ID_ALTEON 0x12ae @@ -67,6 +66,37 @@ #define PCI_VENDOR_ID_NETGEAR 0x1385 #define PCI_DEVICE_ID_NETGEAR_GA620 0x620a #endif +/* + * They used the DEC vendor ID by mistake + */ +#ifndef PCI_DEVICE_ID_FARALLON_PN9000SX +#define PCI_DEVICE_ID_FARALLON_PN9000SX 0x1a +#endif +#ifndef PCI_VENDOR_ID_SGI +#define PCI_VENDOR_ID_SGI 0x10a9 +#endif +#ifndef PCI_DEVICE_ID_SGI_ACENIC +#define PCI_DEVICE_ID_SGI_ACENIC 0x0009 +#endif + +#ifndef wmb +#define wmb() mb() +#endif + +#if (LINUX_VERSION_CODE < 0x02030e) +#define net_device device +#endif + +#include "acenic.h" + +/* + * These must be defined before the firmware is included. + */ +#define MAX_TEXT_LEN 96*1024 +#define MAX_RODATA_LEN 8*1024 +#define MAX_DATA_LEN 2*1024 + +#include "acenic_firmware.h" /* * This driver currently supports Tigon I and Tigon II based cards @@ -137,6 +167,12 @@ * is available, on the 1/2MB NIC app. 300KB is available. * 68KB will always be available as a minimum for both * directions. The default value is a 50/50 split. + * dis_pci_mem_inval=<val> - disable PCI memory write and invalidate + * operations, default (1) is to always disable this as + * that is what Alteon does on NT. I have not been able + * to measure any real performance differences with + * this on my systems. Set <val>=0 if you want to + * enable these operations. * * If you use more than one NIC, specify the parameters for the * individual NICs with a comma, ie. trace=0,0x00001fff,0 you want to @@ -150,18 +186,98 @@ * * The mini ring is not used under Linux and I am not sure it makes sense * to actually use it. + * + * New interrupt handler strategy: + * + * The old interrupt handler worked using the traditional method of + * replacing an skbuff with a new one when a packet arrives. However + * the rx rings do not need to contain a static number of buffer + * descriptors, thus it makes sense to move the memory allocation out + * of the main interrupt handler and do it in a bottom half handler + * and only allocate new buffers when the number of buffers in the + * ring is below a certain threshold. In order to avoid starving the + * NIC under heavy load it is however necessary to force allocation + * when hitting a minimum threshold. The strategy for alloction is as + * follows: + * + * RX_LOW_BUF_THRES - allocate buffers in the bottom half + * RX_PANIC_LOW_THRES - we are very low on buffers, allocate + * the buffers in the interrupt handler + * RX_RING_THRES - maximum number of buffers in the rx ring + * RX_MINI_THRES - maximum number of buffers in the mini ring + * RX_JUMBO_THRES - maximum number of buffers in the jumbo ring + * + * One advantagous side effect of this allocation approach is that the + * entire rx processing can be done without holding any spin lock + * since the rx rings and registers are totally independant of the tx + * ring and its registers. This of course includes the kmalloc's of + * new skb's. Thus start_xmit can run in parallel with rx processing + * and the memory allocation on SMP systems. + * + * Note that running the skb reallocation in a bottom half opens up + * another can of races which needs to be handled properly. In + * particular it can happen that the interrupt handler tries to run + * the reallocation while the bottom half is either running on another + * CPU or was interrupted on the same CPU. To get around this the + * driver uses bitops to prevent the reallocation routines from being + * reentered. + * + * TX handling can also be done without holding any spin lock, wheee + * this is fun! since tx_ret_csm is only written to by the interrupt + * handler. The case to be aware of is when shutting down the device + * and cleaning up where it is necessary to make sure that + * start_xmit() is not running while this is happening. Well DaveM + * informs me that this case is already protected against ... bye bye + * Mr. Spin Lock, it was nice to know you. + * + * TX interrupts are now partly disabled so the NIC will only generate + * TX interrupts for the number of coal ticks, not for the number of + * TX packets in the queue. This should reduce the number of TX only, + * ie. when no RX processing is done, interrupts seen. */ /* - * Default values for tuning parameters + * Threshold values for RX buffer allocation - the low water marks for + * when to start refilling the rings are set to 75% of the ring + * sizes. It seems to make sense to refill the rings entirely from the + * intrrupt handler once it gets below the panic threshold, that way + * we don't risk that the refilling is moved to another CPU when the + * one running the interrupt handler just got the slab code hot in its + * cache. + */ +#define RX_RING_SIZE 72 +#define RX_MINI_SIZE 64 +#define RX_JUMBO_SIZE 48 + +#define RX_PANIC_STD_THRES 16 +#define RX_PANIC_STD_REFILL (3*RX_PANIC_STD_THRES)/2 +#define RX_LOW_STD_THRES (3*RX_RING_SIZE)/4 +#define RX_PANIC_MINI_THRES 12 +#define RX_PANIC_MINI_REFILL (3*RX_PANIC_MINI_THRES)/2 +#define RX_LOW_MINI_THRES (3*RX_MINI_SIZE)/4 +#define RX_PANIC_JUMBO_THRES 6 +#define RX_PANIC_JUMBO_REFILL (3*RX_PANIC_JUMBO_THRES)/2 +#define RX_LOW_JUMBO_THRES (3*RX_JUMBO_SIZE)/4 + + +/* + * Size of the mini ring entries, basically these just should be big + * enough to take TCP ACKs */ -#define DEF_TX_RATIO 31 -#define DEF_TX_COAL TICKS_PER_SEC / 500 -#define DEF_TX_MAX_DESC 7 -#define DEF_RX_COAL TICKS_PER_SEC / 10000 -#define DEF_RX_MAX_DESC 2 -#define DEF_TRACE 0 -#define DEF_STAT 2 * TICKS_PER_SEC +#define ACE_MINI_SIZE 100 + +#define ACE_MINI_BUFSIZE (ACE_MINI_SIZE + 2 + 16) +#define ACE_STD_BUFSIZE (ACE_STD_MTU + ETH_HLEN + 2+4+16) +#define ACE_JUMBO_BUFSIZE (ACE_JUMBO_MTU + ETH_HLEN + 2+4+16) + +#define DEF_TX_RATIO 24 +#define DEF_TX_COAL 1000 +#define DEF_TX_MAX_DESC 40 +#define DEF_RX_COAL 1000 +#define DEF_RX_MAX_DESC 20 +#define TX_COAL_INTS_ONLY 0 /* seems not worth it */ +#define DEF_TRACE 0 +#define DEF_STAT 2 * TICKS_PER_SEC static int link[8] = {0, }; static int trace[8] = {0, }; @@ -170,25 +286,20 @@ static int rx_coal_tick[8] = {0, }; static int max_tx_desc[8] = {0, }; static int max_rx_desc[8] = {0, }; static int tx_ratio[8] = {0, }; +static int dis_pci_mem_inval[8] = {1, 1, 1, 1, 1, 1, 1, 1}; -static const char __initdata *version = "acenic.c: v0.32 03/15/99 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; +static const char __initdata *version = "acenic.c: v0.34 09/03/99 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; -static struct device *root_dev = NULL; +static struct net_device *root_dev = NULL; static int probed __initdata = 0; -int __init acenic_probe (struct device *dev) + +int __init acenic_probe (struct net_device *dev) { int boards_found = 0; int version_disp; struct ace_private *ap; - u8 pci_latency; -#if 0 - u16 vendor, device; - u8 pci_bus; - u8 pci_dev_fun; - u8 irq; -#endif struct pci_dev *pdev = NULL; if (probed) @@ -208,7 +319,15 @@ int __init acenic_probe (struct device *dev) !((pdev->vendor == PCI_VENDOR_ID_3COM) && (pdev->device == PCI_DEVICE_ID_3COM_3C985)) && !((pdev->vendor == PCI_VENDOR_ID_NETGEAR) && - (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620))) + (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620)) && + /* + * Farallon used the DEC vendor ID on their cards by + * mistake for a while + */ + !((pdev->vendor == PCI_VENDOR_ID_DEC) && + (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) && + !((pdev->vendor == PCI_VENDOR_ID_SGI) && + (pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) continue; dev = init_etherdev(dev, sizeof(struct ace_private)); @@ -226,29 +345,18 @@ int __init acenic_probe (struct device *dev) ap = dev->priv; ap->pdev = pdev; - ap->vendor = pdev->vendor; dev->irq = pdev->irq; -#ifdef __SMP__ - spin_lock_init(&ap->lock); -#endif dev->open = &ace_open; dev->hard_start_xmit = &ace_start_xmit; dev->stop = &ace_close; dev->get_stats = &ace_get_stats; dev->set_multicast_list = &ace_set_multicast_list; -#if 0 dev->do_ioctl = &ace_ioctl; -#endif dev->set_mac_address = &ace_set_mac_addr; dev->change_mtu = &ace_change_mtu; - /* - * Dummy value. - */ - dev->base_addr = 42; - /* display version info if adapter is found */ if (!version_disp) { @@ -260,16 +368,36 @@ int __init acenic_probe (struct device *dev) pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command); - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency <= 0x40){ - pci_latency = 0x40; + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, + &ap->pci_latency); + if (ap->pci_latency <= 0x40){ + ap->pci_latency = 0x40; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, - pci_latency); + ap->pci_latency); } pci_set_master(pdev); - switch(ap->vendor){ + /* + * Remap the regs into kernel space - this is abuse of + * dev->base_addr since it was means for I/O port + * addresses but who gives a damn. + */ +#if (LINUX_VERSION_CODE < 0x02030d) + dev->base_addr = pdev->base_address[0]; +#else + dev->base_addr = pdev->resource[0].start; +#endif + + ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000); + if (!ap->regs){ + printk(KERN_ERR "%s: Unable to map I/O register, " + "AceNIC %i will be disabled.\n", + dev->name, boards_found); + break; + } + + switch(pdev->vendor){ case PCI_VENDOR_ID_ALTEON: sprintf(ap->name, "AceNIC Gigabit Ethernet"); printk(KERN_INFO "%s: Alteon AceNIC ", dev->name); @@ -282,26 +410,35 @@ int __init acenic_probe (struct device *dev) sprintf(ap->name, "NetGear GA620 Gigabit Ethernet"); printk(KERN_INFO "%s: NetGear GA620 ", dev->name); break; + case PCI_VENDOR_ID_DEC: + if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) { + sprintf(ap->name, "Farallon PN9000-SX " + "Gigabit Ethernet"); + printk(KERN_INFO "%s: Farallon PN9000-SX ", + dev->name); + break; + } + case PCI_VENDOR_ID_SGI: + sprintf(ap->name, "SGI AceNIC Gigabit Ethernet"); + printk(KERN_INFO "%s: SGI AceNIC ", dev->name); + break; default: sprintf(ap->name, "Unknown AceNIC based Gigabit Ethernet"); printk(KERN_INFO "%s: Unknown AceNIC ", dev->name); break; } - printk("Gigabit Ethernet at 0x%08lx, irq %i, PCI latency %i " - "clks\n", pdev->base_address[0], dev->irq, pci_latency); - - /* - * Remap the regs into kernel space. - */ - - ap->regs = (struct ace_regs *)ioremap(pdev->base_address[0], - 0x4000); - if (!ap->regs){ - printk(KERN_ERR "%s: Unable to map I/O register, " - "AceNIC %i will be disabled.\n", - dev->name, boards_found); - break; + printk("Gigabit Ethernet at 0x%08lx, irq %i\n", + dev->base_addr, dev->irq); + +#ifdef CONFIG_ACENIC_OMIT_TIGON_I + if ((readl(&ap->regs->HostCtrl) >> 28) == 4) { + printk(KERN_ERR "%s: Driver compiled without Tigon I" + " support - NIC disabled\n", dev->name); + iounmap(ap->regs); + unregister_netdev(dev); + continue; } +#endif #ifdef MODULE if (ace_init(dev, boards_found)) @@ -312,12 +449,6 @@ int __init acenic_probe (struct device *dev) #endif boards_found++; - - /* - * This is bollocks, but we need to tell the net-init - * code that it shall go for the next device. - */ - dev->base_addr = 0; } /* @@ -349,6 +480,7 @@ MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i"); MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i"); #endif + int init_module(void) { int cards; @@ -359,37 +491,54 @@ int init_module(void) return cards ? 0 : -ENODEV; } + void cleanup_module(void) { struct ace_private *ap; struct ace_regs *regs; - struct device *next; + struct net_device *next; short i; - unsigned long flags; while (root_dev){ next = ((struct ace_private *)root_dev->priv)->next; ap = (struct ace_private *)root_dev->priv; regs = ap->regs; - spin_lock_irqsave(&ap->lock, flags); writel(readl(®s->CpuCtrl) | CPU_HALT, ®s->CpuCtrl); - if (ap->version == 2) + if (ap->version >= 2) writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl); + /* + * This clears any pending interrupts + */ writel(0, ®s->Mb0Lo); - spin_unlock_irqrestore(&ap->lock, flags); - /* - * Release the RX buffers. + * Make sure no other CPUs are processing interrupts + * on the card before the buffers are being released. + * Otherwise one might experience some `interesting' + * effects. + * + * Then release the RX buffers - jumbo buffers were + * already released in ace_close(). */ + synchronize_irq(); + for (i = 0; i < RX_STD_RING_ENTRIES; i++) { - if (ap->rx_std_skbuff[i]) { + if (ap->skb->rx_std_skbuff[i]) { ap->rx_std_ring[i].size = 0; set_aceaddr_bus(&ap->rx_std_ring[i].addr, 0); - dev_kfree_skb(ap->rx_std_skbuff[i]); + dev_kfree_skb(ap->skb->rx_std_skbuff[i]); + } + } + if (ap->version >= 2) { + for (i = 0; i < RX_MINI_RING_ENTRIES; i++) { + if (ap->skb->rx_mini_skbuff[i]) { + ap->rx_mini_ring[i].size = 0; + set_aceaddr_bus(&ap->rx_mini_ring[i].addr, 0); + dev_kfree_skb(ap->skb->rx_mini_skbuff[i]); + } } } @@ -397,6 +546,7 @@ void cleanup_module(void) if(ap->trace_buf) kfree(ap->trace_buf); kfree(ap->info); + kfree(ap->skb); free_irq(root_dev->irq, root_dev); unregister_netdev(root_dev); kfree(root_dev); @@ -423,13 +573,13 @@ static inline void ace_issue_cmd(struct ace_regs *regs, struct cmd *cmd) } -static int __init ace_init(struct device *dev, int board_idx) +static int __init ace_init(struct net_device *dev, int board_idx) { struct ace_private *ap; struct ace_regs *regs; struct ace_info *info; - u32 tig_ver, mac1, mac2, tmp; unsigned long tmp_ptr, myjif; + u32 tig_ver, mac1, mac2, tmp, pci_state; short i; ap = dev->priv; @@ -457,6 +607,7 @@ static int __init ace_init(struct device *dev, int board_idx) tig_ver = readl(®s->HostCtrl) >> 28; switch(tig_ver){ +#ifndef CONFIG_ACENIC_OMIT_TIGON_I case 4: printk(KERN_INFO" Tigon I (Rev. 4), Firmware: %i.%i.%i, ", tigonFwReleaseMajor, tigonFwReleaseMinor, @@ -464,6 +615,7 @@ static int __init ace_init(struct device *dev, int board_idx) writel(0, ®s->LocalCtrl); ap->version = 1; break; +#endif case 6: printk(KERN_INFO" Tigon II (Rev. %i), Firmware: %i.%i.%i, ", tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor, @@ -518,24 +670,38 @@ static int __init ace_init(struct device *dev, int board_idx) dev->dev_addr[4] = (mac2 >> 8) & 0xff; dev->dev_addr[5] = mac2 & 0xff; + pci_state = readl(®s->PciState); + printk(KERN_INFO " PCI bus speed: %iMHz, latency: %i clks\n", + (pci_state & PCI_66MHZ) ? 66 : 33, ap->pci_latency); + /* * Set the max DMA transfer size. Seems that for most systems * the performance is better when no MAX parameter is * set. However for systems enabling PCI write and invalidate, * DMA writes must be set to the L1 cache line size to get * optimal performance. + * + * The default is now to turn the PCI write and invalidate off + * - that is what Alteon does for NT. */ tmp = READ_CMD_MEM | WRITE_CMD_MEM; - if (ap->version == 2){ -#if 0 + if (ap->version >= 2){ + tmp |= (MEM_READ_MULTIPLE | (pci_state & PCI_66MHZ)); /* - * According to the documentation this enables writes - * to all PCI regs - NOT good. + * Tuning parameters only supported for 8 cards */ - tmp |= DMA_WRITE_ALL_ALIGN; -#endif - tmp |= MEM_READ_MULTIPLE; - if (ap->pci_command & PCI_COMMAND_INVALIDATE){ + if (board_idx > 7 || dis_pci_mem_inval[board_idx]) { + if (ap->pci_command & PCI_COMMAND_INVALIDATE) { + ap->pci_command &= ~PCI_COMMAND_INVALIDATE; + pci_write_config_word(ap->pdev, PCI_COMMAND, + ap->pci_command); + printk(KERN_INFO "%s: disabling PCI memory " + "write and invalidate\n", dev->name); + } + } else if (ap->pci_command & PCI_COMMAND_INVALIDATE){ + printk(KERN_INFO "%s: PCI memory write & invalidate " + "enabled by BIOS, enabling counter " + "measures\n", dev->name); switch(L1_CACHE_BYTES){ case 16: tmp |= DMA_WRITE_MAX_16; @@ -558,19 +724,23 @@ static int __init ace_init(struct device *dev, int board_idx) } writel(tmp, ®s->PciState); - if (request_irq(dev->irq, ace_interrupt, SA_SHIRQ, ap->name, dev)) { - printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", - dev->name, dev->irq); - return -EAGAIN; - } - /* * Initialize the generic info block and the command+event rings * and the control blocks for the transmit and receive rings * as they need to be setup once and for all. */ - if (!(info = kmalloc(sizeof(struct ace_info), GFP_KERNEL | GFP_DMA))){ - free_irq(dev->irq, dev); + if (!(info = kmalloc(sizeof(struct ace_info), GFP_KERNEL))) + return -EAGAIN; + + /* + * Get the memory for the skb rings. + */ + if (!(ap->skb = kmalloc(sizeof(struct ace_skb), GFP_KERNEL))) + return -EAGAIN; + + if (request_irq(dev->irq, ace_interrupt, SA_SHIRQ, ap->name, dev)) { + printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", + dev->name, dev->irq); return -EAGAIN; } @@ -583,6 +753,7 @@ static int __init ace_init(struct device *dev, int board_idx) ap->info = info; memset(info, 0, sizeof(struct ace_info)); + memset(ap->skb, 0, sizeof(struct ace_skb)); ace_load_firmware(dev); ap->fw_running = 0; @@ -602,10 +773,11 @@ static int __init ace_init(struct device *dev, int board_idx) set_aceaddr(&info->evt_prd_ptr, &ap->evt_prd); ap->evt_prd = 0; + wmb(); writel(0, ®s->EvtCsm); - info->cmd_ctrl.flags = 0; set_aceaddr_bus(&info->cmd_ctrl.rngptr, (void *)0x100); + info->cmd_ctrl.flags = 0; info->cmd_ctrl.max_len = 0; for (i = 0; i < CMD_RING_ENTRIES; i++) @@ -616,32 +788,51 @@ static int __init ace_init(struct device *dev, int board_idx) set_aceaddr(&info->stats2_ptr, &info->s.stats); - info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4; set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_std_ring); - info->rx_std_ctrl.flags = FLG_RX_TCP_UDP_SUM; + info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4; + info->rx_std_ctrl.flags = RCB_FLG_TCP_UDP_SUM; memset(ap->rx_std_ring, 0, RX_STD_RING_ENTRIES * sizeof(struct rx_desc)); - info->rx_jumbo_ctrl.max_len = 0; + for (i = 0; i < RX_STD_RING_ENTRIES; i++) + ap->rx_std_ring[i].flags = BD_FLG_TCP_UDP_SUM; + + ap->rx_std_skbprd = 0; + atomic_set(&ap->cur_rx_bufs, 0); + set_aceaddr(&info->rx_jumbo_ctrl.rngptr, ap->rx_jumbo_ring); - info->rx_jumbo_ctrl.flags = FLG_RX_TCP_UDP_SUM; + info->rx_jumbo_ctrl.max_len = 0; + info->rx_jumbo_ctrl.flags = RCB_FLG_TCP_UDP_SUM; memset(ap->rx_jumbo_ring, 0, RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc)); - info->rx_mini_ctrl.max_len = 0; -#if 0 - set_aceaddr(&info->rx_mini_ctrl.rngptr, ap->rx_mini_ring); -#else - set_aceaddr_bus(&info->rx_mini_ctrl.rngptr, 0); -#endif - info->rx_mini_ctrl.flags = FLG_RNG_DISABLED; + for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) + ap->rx_jumbo_ring[i].flags = BD_FLG_TCP_UDP_SUM | BD_FLG_JUMBO; + + ap->rx_jumbo_skbprd = 0; + atomic_set(&ap->cur_jumbo_bufs, 0); -#if 0 memset(ap->rx_mini_ring, 0, RX_MINI_RING_ENTRIES * sizeof(struct rx_desc)); -#endif + + if (ap->version >= 2) { + set_aceaddr(&info->rx_mini_ctrl.rngptr, ap->rx_mini_ring); + info->rx_mini_ctrl.max_len = ACE_MINI_SIZE; + info->rx_mini_ctrl.flags = RCB_FLG_TCP_UDP_SUM; + + for (i = 0; i < RX_MINI_RING_ENTRIES; i++) + ap->rx_mini_ring[i].flags = + BD_FLG_TCP_UDP_SUM | BD_FLG_MINI; + } else { + set_aceaddr(&info->rx_mini_ctrl.rngptr, 0); + info->rx_mini_ctrl.flags = RCB_FLG_RNG_DISABLE; + info->rx_mini_ctrl.max_len = 0; + } + + ap->rx_mini_skbprd = 0; + atomic_set(&ap->cur_mini_bufs, 0); set_aceaddr(&info->rx_return_ctrl.rngptr, ap->rx_return_ring); info->rx_return_ctrl.flags = 0; @@ -658,9 +849,13 @@ static int __init ace_init(struct device *dev, int board_idx) writel(0, (unsigned long)ap->tx_ring + i * 4); } + set_aceaddr_bus(&info->tx_ctrl.rngptr, (void *)TX_RING_BASE); info->tx_ctrl.max_len = TX_RING_ENTRIES; +#if TX_COAL_INTS_ONLY + info->tx_ctrl.flags = RCB_FLG_COAL_INT_ONLY; +#else info->tx_ctrl.flags = 0; - set_aceaddr_bus(&info->tx_ctrl.rngptr, (void *)TX_RING_BASE); +#endif set_aceaddr(&info->tx_csm_ptr, &ap->tx_csm); @@ -714,7 +909,7 @@ static int __init ace_init(struct device *dev, int board_idx) */ tmp = LNK_ENABLE | LNK_FULL_DUPLEX | LNK_1000MB | LNK_100MB | LNK_10MB | LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL | LNK_NEGOTIATE; - if(ap->version == 2) + if(ap->version >= 2) tmp |= LNK_TX_FLOW_CTL_Y; /* @@ -751,28 +946,42 @@ static int __init ace_init(struct device *dev, int board_idx) "negotiation\n", dev->name); if (option & 0x200) tmp |= LNK_RX_FLOW_CTL_Y; - if ((option & 0x400) && (ap->version == 2)){ + if ((option & 0x400) && (ap->version >= 2)){ printk(KERN_INFO "%s: Enabling TX flow control\n", dev->name); tmp |= LNK_TX_FLOW_CTL_Y; } } + ap->link = tmp; writel(tmp, ®s->TuneLink); - if (ap->version == 2) + if (ap->version >= 2) writel(tmp, ®s->TuneFastLink); - if (ap->version == 1) + if (ACE_IS_TIGON_I(ap)) writel(tigonFwStartAddr, ®s->Pc); - else if (ap->version == 2) + if (ap->version == 2) writel(tigon2FwStartAddr, ®s->Pc); writel(0, ®s->Mb0Lo); /* - * Start the NIC CPU + * Set tx_csm before we start receiving interrupts, otherwise + * the interrupt handler might think it is supposed to process + * tx ints before we are up and running, which may cause a null + * pointer access in the int handler. */ + ap->tx_full = 0; + ap->cur_rx = 0; + ap->tx_prd = ap->tx_csm = ap->tx_ret_csm = 0; + + wmb(); + writel(0, ®s->TxPrd); + writel(0, ®s->RxRetCsm); + /* + * Start the NIC CPU + */ writel(readl(®s->CpuCtrl) & ~(CPU_HALT|CPU_TRACE), ®s->CpuCtrl); /* @@ -791,8 +1000,18 @@ static int __init ace_init(struct device *dev, int board_idx) * We load the ring here as there seem to be no way to tell the * firmware to wipe the ring without re-initializing it. */ - ace_load_std_rx_ring(dev); - + if (!test_and_set_bit(0, &ap->std_refill_busy)) + ace_load_std_rx_ring(ap, RX_RING_SIZE); + else + printk(KERN_ERR "%s: Someone is busy refilling the RX ring\n", + dev->name); + if (ap->version >= 2) { + if (!test_and_set_bit(0, &ap->mini_refill_busy)) + ace_load_mini_rx_ring(ap, RX_MINI_SIZE); + else + printk(KERN_ERR "%s: Someone is busy refilling " + "the RX mini ring\n", dev->name); + } return 0; } @@ -802,7 +1021,7 @@ static int __init ace_init(struct device *dev, int board_idx) */ static void ace_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct ace_private *ap = (struct ace_private *)dev->priv; struct ace_regs *regs = ap->regs; @@ -821,6 +1040,44 @@ static void ace_timer(unsigned long data) } +static void ace_bh(struct net_device *dev) +{ + struct ace_private *ap = dev->priv; + int cur_size; + + cur_size = atomic_read(&ap->cur_rx_bufs); + if ((cur_size < RX_LOW_STD_THRES) && + !test_and_set_bit(0, &ap->std_refill_busy)) { +#if DEBUG + printk("refilling buffers (current %i)\n", cur_size); +#endif + ace_load_std_rx_ring(ap, RX_RING_SIZE - cur_size); + } + + if (ap->version >= 2) { + cur_size = atomic_read(&ap->cur_mini_bufs); + if ((cur_size < RX_LOW_MINI_THRES) && + !test_and_set_bit(0, &ap->mini_refill_busy)) { +#if DEBUG + printk("refilling mini buffers (current %i)\n", + cur_size); +#endif + ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size); + } + } + + cur_size = atomic_read(&ap->cur_jumbo_bufs); + if (ap->jumbo && (cur_size < RX_LOW_JUMBO_THRES) && + !test_and_set_bit(0, &ap->jumbo_refill_busy)) { +#if DEBUG + printk("refilling jumbo buffers (current %i)\n", >cur_size); +#endif + ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size); + } + ap->bh_pending = 0; +} + + /* * Copy the contents of the NIC's trace buffer to kernel memory. */ @@ -836,69 +1093,92 @@ static void ace_dump_trace(struct ace_private *ap) /* * Load the standard rx ring. + * + * Loading rings is safe without holding the spin lock since this is + * done only before the device is enabled, thus no interrupts are + * generated and by the interrupt handler/bh handler. */ -static int ace_load_std_rx_ring(struct device *dev) +static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs) { - struct ace_private *ap; struct ace_regs *regs; - struct ace_info *info; - unsigned long flags; - struct cmd cmd; - short i; + short i, idx; - ap = (struct ace_private *)dev->priv; regs = ap->regs; - info = ap->info; - - spin_lock_irqsave(&ap->lock, flags); - /* - * Set tx_csm before we start receiving interrupts, otherwise - * the interrupt handler might think it is supposed to process - * tx ints before we are up and running, which may cause a null - * pointer access in the int handler. - */ - ap->tx_full = 0; - ap->cur_rx = ap->dirty_rx = 0; - ap->tx_prd = ap->tx_csm = ap->tx_ret_csm = 0; - writel(0, ®s->RxRetCsm); + idx = ap->rx_std_skbprd; - for (i = 0; i < RX_RING_THRESH; i++) { + for (i = 0; i < nr_bufs; i++) { struct sk_buff *skb; + struct rx_desc *rd; - ap->rx_std_ring[i].flags = 0; - skb = alloc_skb(ACE_STD_MTU + ETH_HLEN + 6, GFP_ATOMIC); - ap->rx_std_skbuff[i] = skb; - + skb = alloc_skb(ACE_STD_BUFSIZE, GFP_ATOMIC); /* - * Make sure the data contents end up on an aligned address + * Make sure IP header starts on a fresh cache line. */ - skb_reserve(skb, 2); - - set_aceaddr(&ap->rx_std_ring[i].addr, skb->data); - ap->rx_std_ring[i].size = ACE_STD_MTU + ETH_HLEN + 4; + skb_reserve(skb, 2 + 16); + ap->skb->rx_std_skbuff[idx] = skb; + + rd = &ap->rx_std_ring[idx]; + set_aceaddr(&rd->addr, skb->data); + rd->size = ACE_STD_MTU + ETH_HLEN + 4; + rd->idx = idx; + idx = (idx + 1) % RX_STD_RING_ENTRIES; + } - ap->rx_std_ring[i].flags = 0; - ap->rx_std_ring[i].type = DESC_RX; + atomic_add(nr_bufs, &ap->cur_rx_bufs); + ap->rx_std_skbprd = idx; - ap->rx_std_ring[i].idx = i; + if (ACE_IS_TIGON_I(ap)) { + struct cmd cmd; + cmd.evt = C_SET_RX_PRD_IDX; + cmd.code = 0; + cmd.idx = ap->rx_std_skbprd; + ace_issue_cmd(regs, &cmd); + } else { + writel(idx, ®s->RxStdPrd); + wmb(); } - ap->rx_std_skbprd = i; + clear_bit(0, &ap->std_refill_busy); + return; +} - /* - * The last descriptor needs to be marked as being special. - */ - ap->rx_std_ring[i-1].type = DESC_END; - cmd.evt = C_SET_RX_PRD_IDX; - cmd.code = 0; - cmd.idx = ap->rx_std_skbprd; - ace_issue_cmd(regs, &cmd); +static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs) +{ + struct ace_regs *regs; + short i, idx; + + regs = ap->regs; - spin_unlock_irqrestore(&ap->lock, flags); + idx = ap->rx_mini_skbprd; + for (i = 0; i < nr_bufs; i++) { + struct sk_buff *skb; + struct rx_desc *rd; - return 0; + skb = alloc_skb(ACE_MINI_BUFSIZE, GFP_ATOMIC); + /* + * Make sure the IP header ends up on a fresh cache line + */ + skb_reserve(skb, 2 + 16); + ap->skb->rx_mini_skbuff[idx] = skb; + + rd = &ap->rx_mini_ring[idx]; + set_aceaddr(&rd->addr, skb->data); + rd->size = ACE_MINI_SIZE; + rd->idx = idx; + idx = (idx + 1) % RX_MINI_RING_ENTRIES; + } + + atomic_add(nr_bufs, &ap->cur_mini_bufs); + + ap->rx_mini_skbprd = idx; + + writel(idx, ®s->RxMiniPrd); + wmb(); + + clear_bit(0, &ap->mini_refill_busy); + return; } @@ -906,63 +1186,56 @@ static int ace_load_std_rx_ring(struct device *dev) * Load the jumbo rx ring, this may happen at any time if the MTU * is changed to a value > 1500. */ -static int ace_load_jumbo_rx_ring(struct device *dev) +static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs) { - struct ace_private *ap; struct ace_regs *regs; - struct cmd cmd; - unsigned long flags; - short i; + short i, idx; - ap = (struct ace_private *)dev->priv; regs = ap->regs; - spin_lock_irqsave(&ap->lock, flags); + idx = ap->rx_jumbo_skbprd; - for (i = 0; i < RX_RING_JUMBO_THRESH; i++) { + for (i = 0; i < nr_bufs; i++) { struct sk_buff *skb; + struct rx_desc *rd; - ap->rx_jumbo_ring[i].flags = 0; - skb = alloc_skb(ACE_JUMBO_MTU + ETH_HLEN + 6, GFP_ATOMIC); - ap->rx_jumbo_skbuff[i] = skb; - + skb = alloc_skb(ACE_JUMBO_BUFSIZE, GFP_ATOMIC); /* - * Make sure the data contents end up on an aligned address + * Make sure the IP header ends up on a fresh cache line */ - skb_reserve(skb, 2); - - set_aceaddr(&ap->rx_jumbo_ring[i].addr, skb->data); - ap->rx_jumbo_ring[i].size = ACE_JUMBO_MTU + ETH_HLEN + 4; - - ap->rx_jumbo_ring[i].flags = DFLG_RX_JUMBO; - ap->rx_jumbo_ring[i].type = DESC_RX; - - ap->rx_jumbo_ring[i].idx = i; + skb_reserve(skb, 2 + 16); + ap->skb->rx_jumbo_skbuff[idx] = skb; + + rd = &ap->rx_jumbo_ring[idx]; + set_aceaddr(&rd->addr, skb->data); + rd->size = ACE_JUMBO_MTU + ETH_HLEN + 4; + rd->idx = idx; + idx = (idx + 1) % RX_JUMBO_RING_ENTRIES; } - ap->rx_jumbo_skbprd = i; - - /* - * The last descriptor needs to be marked as being special. - */ - ap->rx_jumbo_ring[i-1].type = DESC_END; - - cmd.evt = C_SET_RX_JUMBO_PRD_IDX; - cmd.code = 0; - cmd.idx = ap->rx_jumbo_skbprd; - ace_issue_cmd(regs, &cmd); + atomic_add(nr_bufs, &ap->cur_jumbo_bufs); + ap->rx_jumbo_skbprd = idx; - spin_unlock_irqrestore(&ap->lock, flags); + if (ACE_IS_TIGON_I(ap)) { + struct cmd cmd; + cmd.evt = C_SET_RX_JUMBO_PRD_IDX; + cmd.code = 0; + cmd.idx = ap->rx_jumbo_skbprd; + ace_issue_cmd(regs, &cmd); + } else { + writel(idx, ®s->RxJumboPrd); + wmb(); + } - return 0; + clear_bit(0, &ap->jumbo_refill_busy); + return; } /* * Tell the firmware not to accept jumbos and flush the jumbo ring. - * This function must be called with the spinlock held. */ -static int ace_flush_jumbo_rx_ring(struct device *dev) +static int ace_flush_jumbo_rx_ring(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -979,10 +1252,10 @@ static int ace_flush_jumbo_rx_ring(struct device *dev) ace_issue_cmd(regs, &cmd); for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) { - if (ap->rx_jumbo_skbuff[i]) { + if (ap->skb->rx_jumbo_skbuff[i]) { ap->rx_jumbo_ring[i].size = 0; set_aceaddr_bus(&ap->rx_jumbo_ring[i].addr, 0); - dev_kfree_skb(ap->rx_jumbo_skbuff[i]); + dev_kfree_skb(ap->skb->rx_jumbo_skbuff[i]); } } }else @@ -998,7 +1271,7 @@ static int ace_flush_jumbo_rx_ring(struct device *dev) * events) and are handled here, outside the main interrupt handler, * to reduce the size of the handler. */ -static u32 ace_handle_event(struct device *dev, u32 evtcsm, u32 evtprd) +static u32 ace_handle_event(struct net_device *dev, u32 evtcsm, u32 evtprd) { struct ace_private *ap; @@ -1017,13 +1290,14 @@ static u32 ace_handle_event(struct device *dev, u32 evtcsm, u32 evtprd) { u16 code = ap->evt_ring[evtcsm].code; if (code == E_C_LINK_UP){ - printk("%s: Optical link UP\n", dev->name); + printk(KERN_WARNING "%s: Optical link UP\n", + dev->name); } else if (code == E_C_LINK_DOWN) - printk(KERN_INFO "%s: Optical link DOWN\n", + printk(KERN_WARNING "%s: Optical link DOWN\n", dev->name); else - printk(KERN_INFO "%s: Unknown optical link " + printk(KERN_ERR "%s: Unknown optical link " "state %02x\n", dev->name, code); break; } @@ -1059,100 +1333,65 @@ static u32 ace_handle_event(struct device *dev, u32 evtcsm, u32 evtprd) } -static int ace_rx_int(struct device *dev, u32 rxretprd, u32 rxretcsm) +static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) { struct ace_private *ap = (struct ace_private *)dev->priv; - struct ace_regs *regs = ap->regs; - u32 idx, oldidx; + u32 idx; + int mini_count = 0, std_count = 0; idx = rxretcsm; while (idx != rxretprd){ - struct sk_buff *skb, *newskb, *oldskb; - struct rx_desc *newrxdesc, *oldrxdesc; - u32 prdidx, size; - void *addr; + struct sk_buff *skb, **oldskb_p; + struct rx_desc *rxdesc; + u32 skbidx; + int desc_type; u16 csum; - int jumbo; - - oldidx = ap->rx_return_ring[idx].idx; - jumbo = ap->rx_return_ring[idx].flags & DFLG_RX_JUMBO; - - if (jumbo){ - oldskb = ap->rx_jumbo_skbuff[oldidx]; - prdidx = ap->rx_jumbo_skbprd; - newrxdesc = &ap->rx_jumbo_ring[prdidx]; - oldrxdesc = &ap->rx_jumbo_ring[oldidx]; - }else{ - oldskb = ap->rx_std_skbuff[oldidx]; - prdidx = ap->rx_std_skbprd; - newrxdesc = &ap->rx_std_ring[prdidx]; - oldrxdesc = &ap->rx_std_ring[oldidx]; - } - size = oldrxdesc->size; + skbidx = ap->rx_return_ring[idx].idx; + desc_type = ap->rx_return_ring[idx].flags & + (BD_FLG_JUMBO | BD_FLG_MINI); - if (size < PKT_COPY_THRESHOLD) { - skb = alloc_skb(size + 2, GFP_ATOMIC); - if (skb == NULL){ - printk(KERN_ERR "%s: Out of memory\n", - dev->name); - goto error; - } + switch(desc_type) { /* - * Make sure the real data is aligned + * Normal frames do not have any flags set + * + * Mini and normal frames arrive frequently, + * so use a local counter to avoid doing + * atomic operations for each packet arriving. */ - - skb_reserve(skb, 2); - memcpy(skb_put(skb, size), oldskb->data, size); - addr = get_aceaddr_bus(&oldrxdesc->addr); - newskb = oldskb; - }else{ - skb = oldskb; - - skb_put(skb, size); - - newskb = alloc_skb(size + 2, GFP_ATOMIC); - if (newskb == NULL){ - printk(KERN_ERR "%s: Out of memory\n", - dev->name); - goto error; - } - - /* - * Make sure we DMA directly into nicely - * aligned receive buffers - */ - skb_reserve(newskb, 2); - addr = (void *)virt_to_bus(newskb->data); + case 0: + oldskb_p = &ap->skb->rx_std_skbuff[skbidx]; + rxdesc = &ap->rx_std_ring[skbidx]; + std_count++; + break; + case BD_FLG_JUMBO: + oldskb_p = &ap->skb->rx_jumbo_skbuff[skbidx]; + rxdesc = &ap->rx_jumbo_ring[skbidx]; + atomic_dec(&ap->cur_jumbo_bufs); + break; + case BD_FLG_MINI: + oldskb_p = &ap->skb->rx_mini_skbuff[skbidx]; + rxdesc = &ap->rx_mini_ring[skbidx]; + mini_count++; + break; + default: + printk(KERN_INFO "%s: unknown frame type (0x%02x) " + "returned by NIC\n", dev->name, + ap->rx_return_ring[idx].flags); + goto error; } - set_aceaddr_bus(&newrxdesc->addr, addr); - newrxdesc->size = size; - - newrxdesc->flags = oldrxdesc->flags; - newrxdesc->idx = prdidx; - newrxdesc->type = DESC_RX; -#if (BITS_PER_LONG == 32) - newrxdesc->addr.addrhi = 0; -#endif - - oldrxdesc->size = 0; - set_aceaddr_bus(&oldrxdesc->addr, 0); - - if (jumbo){ - ap->rx_jumbo_skbuff[oldidx] = NULL; - ap->rx_jumbo_skbuff[prdidx] = newskb; - - prdidx = (prdidx + 1) % RX_JUMBO_RING_ENTRIES; - ap->rx_jumbo_skbprd = prdidx; - }else{ - ap->rx_std_skbuff[oldidx] = NULL; - ap->rx_std_skbuff[prdidx] = newskb; - - prdidx = (prdidx + 1) % RX_STD_RING_ENTRIES; - ap->rx_std_skbprd = prdidx; + skb = *oldskb_p; +#if DEBUG + if (skb == NULL) { + printk("Mayday! illegal skb received! (idx %i)\n", skbidx); + goto error; } +#endif + *oldskb_p = NULL; + skb_put(skb, rxdesc->size); + rxdesc->size = 0; /* * Fly baby, fly! @@ -1178,28 +1417,25 @@ static int ace_rx_int(struct device *dev, u32 rxretprd, u32 rxretcsm) ap->stats.rx_packets++; ap->stats.rx_bytes += skb->len; - if ((prdidx & 0x7) == 0){ - struct cmd cmd; - if (jumbo) - cmd.evt = C_SET_RX_JUMBO_PRD_IDX; - else - cmd.evt = C_SET_RX_PRD_IDX; - cmd.code = 0; - cmd.idx = prdidx; - ace_issue_cmd(regs, &cmd); - } - idx = (idx + 1) % RX_RETURN_RING_ENTRIES; } + + atomic_sub(std_count, &ap->cur_rx_bufs); + if (!ACE_IS_TIGON_I(ap)) + atomic_sub(mini_count, &ap->cur_mini_bufs); + out: /* * According to the documentation RxRetCsm is obsolete with - * the 12.3.x Firmware - my Tigon I NIC's seem to disagree! + * the 12.3.x Firmware - my Tigon I NICs seem to disagree! */ - writel(idx, ®s->RxRetCsm); + if (ACE_IS_TIGON_I(ap)) { + struct ace_regs *regs = ap->regs; + writel(idx, ®s->RxRetCsm); + } ap->cur_rx = idx; - return idx; + return; error: idx = rxretprd; goto out; @@ -1210,24 +1446,21 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct ace_private *ap; struct ace_regs *regs; - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; + u32 idx; u32 txcsm, rxretcsm, rxretprd; u32 evtcsm, evtprd; ap = (struct ace_private *)dev->priv; regs = ap->regs; - spin_lock(&ap->lock); - /* * In case of PCI shared interrupts or spurious interrupts, * we want to make sure it is actually our interrupt before * spending any time in here. */ - if (!(readl(®s->HostCtrl) & IN_INT)){ - spin_unlock(&ap->lock); + if (!(readl(®s->HostCtrl) & IN_INT)) return; - } /* * Tell the card not to generate interrupts while we are in here. @@ -1235,25 +1468,35 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) writel(1, ®s->Mb0Lo); /* - * Service RX ints before TX + * There is no conflict between transmit handling in + * start_xmit and receive processing, thus there is no reason + * to take a spin lock for RX handling. Wait until we start + * working on the other stuff - hey we don't need a spin lock + * anymore. */ rxretprd = ap->rx_ret_prd; rxretcsm = ap->cur_rx; if (rxretprd != rxretcsm) - rxretprd = ace_rx_int(dev, rxretprd, rxretcsm); + ace_rx_int(dev, rxretprd, rxretcsm); txcsm = ap->tx_csm; - if (txcsm != ap->tx_ret_csm) { - u32 idx = ap->tx_ret_csm; + idx = ap->tx_ret_csm; + if (txcsm != idx) { do { ap->stats.tx_packets++; - ap->stats.tx_bytes += ap->tx_skbuff[idx]->len; - dev_kfree_skb(ap->tx_skbuff[idx]); + ap->stats.tx_bytes += ap->skb->tx_skbuff[idx]->len; + dev_kfree_skb(ap->skb->tx_skbuff[idx]); - ap->tx_skbuff[idx] = NULL; + ap->skb->tx_skbuff[idx] = NULL; + /* + * Question here is whether one should not skip + * these writes - I have never seen any errors + * caused by the NIC actually trying to access + * these incorrectly. + */ #if (BITS_PER_LONG == 64) writel(0, &ap->tx_ring[idx].addr.addrhi); #endif @@ -1263,10 +1506,19 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) idx = (idx + 1) % TX_RING_ENTRIES; } while (idx != txcsm); - if (ap->tx_full && dev->tbusy && - (((ap->tx_prd + 1) % TX_RING_ENTRIES) != txcsm)){ + /* + * Once we actually get to this point the tx ring has + * already been trimmed thus it cannot be full! + * Ie. skip the comparison of the tx producer vs. the + * consumer. + */ + if (ap->tx_full && dev->tbusy) { ap->tx_full = 0; - dev->tbusy = 0; + /* + * This does not need to be atomic (and expensive), + * I've seen cases where it would fail otherwise ;-( + */ + clear_bit(0, &dev->tbusy); mark_bh(NET_BH); /* @@ -1277,23 +1529,84 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) } ap->tx_ret_csm = txcsm; + wmb(); } evtcsm = readl(®s->EvtCsm); evtprd = ap->evt_prd; - if (evtcsm != evtprd){ + if (evtcsm != evtprd) { evtcsm = ace_handle_event(dev, evtcsm, evtprd); + writel(evtcsm, ®s->EvtCsm); } - writel(evtcsm, ®s->EvtCsm); - writel(0, ®s->Mb0Lo); + /* + * This has to go last in the interrupt handler and run with + * the spin lock released ... what lock? + */ + if (dev->start) { + int cur_size; + int run_bh = 0; + + cur_size = atomic_read(&ap->cur_rx_bufs); + if (cur_size < RX_LOW_STD_THRES) { + if ((cur_size < RX_PANIC_STD_THRES) && + !test_and_set_bit(0, &ap->std_refill_busy)) { +#if DEBUG + printk("low on std buffers %i\n", cur_size); +#endif + ace_load_std_rx_ring(ap, + RX_RING_SIZE - cur_size); + } + run_bh = 1; + } - spin_unlock(&ap->lock); + if (!ACE_IS_TIGON_I(ap)) { + cur_size = atomic_read(&ap->cur_mini_bufs); + if (cur_size < RX_LOW_MINI_THRES) { + if ((cur_size < RX_PANIC_MINI_THRES) && + !test_and_set_bit(0, + &ap->mini_refill_busy)) { +#if DEBUG + printk("low on mini buffers %i\n", + cur_size); +#endif + ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size); + } else + run_bh = 1; + } + } + + if (ap->jumbo) { + cur_size = atomic_read(&ap->cur_jumbo_bufs); + if (cur_size < RX_LOW_JUMBO_THRES) { + if ((cur_size < RX_PANIC_JUMBO_THRES) && + !test_and_set_bit(0, + &ap->jumbo_refill_busy)){ +#if DEBUG + printk("low on jumbo buffers %i\n", + cur_size); +#endif + ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size); + } else + run_bh = 1; + } + } + if (run_bh && !ap->bh_pending) { + ap->bh_pending = 1; + queue_task(&ap->immediate, &tq_immediate); + mark_bh(IMMEDIATE_BH); + } + } + + /* + * Allow the card to generate interrupts again + */ + writel(0, ®s->Mb0Lo); } -static int ace_open(struct device *dev) +static int ace_open(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -1303,7 +1616,7 @@ static int ace_open(struct device *dev) regs = ap->regs; if (!(ap->fw_running)){ - printk(KERN_WARNING "%s: firmware not running!\n", dev->name); + printk(KERN_WARNING "%s: Firmware not running!\n", dev->name); return -EBUSY; } @@ -1314,8 +1627,9 @@ static int ace_open(struct device *dev) cmd.idx = 0; ace_issue_cmd(regs, &cmd); - if (ap->jumbo) - ace_load_jumbo_rx_ring(dev); + if (ap->jumbo && + !test_and_set_bit(0, &ap->jumbo_refill_busy)) + ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE); if (dev->flags & IFF_PROMISC){ cmd.evt = C_SET_PROMISC_MODE; @@ -1329,10 +1643,6 @@ static int ace_open(struct device *dev) ap->mcast_all = 0; #if 0 - { long myjif = jiffies + HZ; - while (time_before(jiffies, myjif)); - } - cmd.evt = C_LNK_NEGOTIATION; cmd.code = 0; cmd.idx = 0; @@ -1351,11 +1661,20 @@ static int ace_open(struct device *dev) init_timer(&ap->timer); ap->timer.data = (unsigned long)dev; ap->timer.function = ace_timer; + + /* + * Setup the bottom half rx ring refill handler + */ + ap->immediate.next = NULL; + ap->immediate.sync = 0; + ap->immediate.routine = (void *)(void *)ace_bh; + ap->immediate.data = dev; + return 0; } -static int ace_close(struct device *dev) +static int ace_close(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -1364,7 +1683,7 @@ static int ace_close(struct device *dev) short i; dev->start = 0; - set_bit(0, (void*)&dev->tbusy); + set_bit(0, &dev->tbusy); ap = (struct ace_private *)dev->priv; regs = ap->regs; @@ -1384,56 +1703,74 @@ static int ace_close(struct device *dev) cmd.idx = 0; ace_issue_cmd(regs, &cmd); - spin_lock_irqsave(&ap->lock, flags); + /* + * Make sure one CPU is not processing packets while + * buffers are being released by another. + */ + save_flags(flags); + cli(); for (i = 0; i < TX_RING_ENTRIES; i++) { - if (ap->tx_skbuff[i]) { + if (ap->skb->tx_skbuff[i]) { writel(0, &ap->tx_ring[i].addr.addrhi); writel(0, &ap->tx_ring[i].addr.addrlo); writel(0, &ap->tx_ring[i].flagsize); - dev_kfree_skb(ap->tx_skbuff[i]); + dev_kfree_skb(ap->skb->tx_skbuff[i]); } } if (ap->jumbo) ace_flush_jumbo_rx_ring(dev); - spin_unlock_irqrestore(&ap->lock, flags); + restore_flags(flags); MOD_DEC_USE_COUNT; return 0; } -static int ace_start_xmit(struct sk_buff *skb, struct device *dev) +static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ace_private *ap = (struct ace_private *)dev->priv; struct ace_regs *regs = ap->regs; - unsigned long flags; unsigned long addr; u32 idx, flagsize; - spin_lock_irqsave(&ap->lock, flags); + if (test_and_set_bit(0, &dev->tbusy)) + return 1; idx = ap->tx_prd; - ap->tx_skbuff[idx] = skb; + if ((idx + 1) % TX_RING_ENTRIES == ap->tx_ret_csm) { + ap->tx_full = 1; +#if DEBUG + printk("%s: trying to transmit while the tx ring is full " + "- this should not happen!\n", dev->name); +#endif + return 1; + } + + ap->skb->tx_skbuff[idx] = skb; addr = virt_to_bus(skb->data); #if (BITS_PER_LONG == 64) writel(addr >> 32, &ap->tx_ring[idx].addr.addrhi); #endif writel(addr & 0xffffffff, &ap->tx_ring[idx].addr.addrlo); - flagsize = (skb->len << 16) | (DESC_END) ; + flagsize = (skb->len << 16) | (BD_FLG_END) ; writel(flagsize, &ap->tx_ring[idx].flagsize); - mb(); + wmb(); idx = (idx + 1) % TX_RING_ENTRIES; ap->tx_prd = idx; writel(idx, ®s->TxPrd); + wmb(); - if ((idx + 1) % TX_RING_ENTRIES == ap->tx_ret_csm){ + /* + * tx_csm is set by the NIC whereas we set tx_ret_csm which + * is always trying to catch tx_csm + */ + if ((idx + 2) % TX_RING_ENTRIES == ap->tx_ret_csm){ ap->tx_full = 1; - set_bit(0, (void*)&dev->tbusy); /* * Queue is full, add timer to detect whether the * transmitter is stuck. Use mod_timer as we can get @@ -1441,16 +1778,19 @@ static int ace_start_xmit(struct sk_buff *skb, struct device *dev) * timers. */ mod_timer(&ap->timer, jiffies + (3 * HZ)); + } else { + /* + * No need for it to be atomic - seems it needs to be + */ + clear_bit(0, &dev->tbusy); } - spin_unlock_irqrestore(&ap->lock, flags); - dev->trans_start = jiffies; return 0; } -static int ace_change_mtu(struct device *dev, int new_mtu) +static int ace_change_mtu(struct net_device *dev, int new_mtu) { struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; @@ -1466,7 +1806,8 @@ static int ace_change_mtu(struct device *dev, int new_mtu) printk(KERN_INFO "%s: Enabling Jumbo frame " "support\n", dev->name); ap->jumbo = 1; - ace_load_jumbo_rx_ring(dev); + if (!test_and_set_bit(0, &ap->jumbo_refill_busy)) + ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE); } ap->jumbo = 1; }else{ @@ -1483,10 +1824,130 @@ static int ace_change_mtu(struct device *dev, int new_mtu) } +static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ +#ifdef ETHTOOL + struct ace_private *ap = (struct ace_private *) dev->priv; + struct ace_regs *regs = ap->regs; + struct ethtool_cmd ecmd; + u32 link, speed; + + if (cmd != SIOCETHTOOL) + return -EOPNOTSUPP; + if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd))) + return -EFAULT; + + if (ecmd.cmd == ETH_GSET) { + ecmd.supported = + (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | SUPPORTED_FIBRE); + + ecmd.port = PORT_FIBRE; + ecmd.transceiver = XCVR_INTERNAL; + ecmd.phy_address = 0; + + link = readl(®s->GigLnkState); + if (link & LNK_1000MB) + ecmd.speed = SPEED_1000; + else { + link = readl(®s->FastLnkState); + if (link & LNK_100MB) + ecmd.speed = SPEED_100; + else if (link & LNK_100MB) + ecmd.speed = SPEED_10; + else + ecmd.speed = 0; + } + if (link & LNK_FULL_DUPLEX) + ecmd.duplex = DUPLEX_FULL; + else + ecmd.duplex = DUPLEX_HALF; + + if (link & LNK_NEGOTIATE) + ecmd.autoneg = AUTONEG_ENABLE; + else + ecmd.autoneg = AUTONEG_DISABLE; + + ecmd.trace = readl(®s->TuneTrace); + + ecmd.txcoal = readl(®s->TuneTxCoalTicks); + ecmd.rxcoal = readl(®s->TuneRxCoalTicks); + ecmd.maxtxpkt = readl(®s->TuneMaxTxDesc); + ecmd.maxrxpkt = readl(®s->TuneMaxRxDesc); + + if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } else if (ecmd.cmd == ETH_SSET) { + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + link = readl(®s->GigLnkState); + if (link & LNK_1000MB) + speed = SPEED_1000; + else { + link = readl(®s->FastLnkState); + if (link & LNK_100MB) + speed = SPEED_100; + else if (link & LNK_100MB) + speed = SPEED_10; + else + speed = SPEED_100; + } + + link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB | + LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL; + if (!ACE_IS_TIGON_I(ap)) + link |= LNK_TX_FLOW_CTL_Y; + if (ecmd.autoneg == AUTONEG_ENABLE) + link |= LNK_NEGOTIATE; + if (ecmd.speed != speed) { + link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB); + switch (speed) { + case SPEED_1000: + link |= LNK_1000MB; + break; + case SPEED_100: + link |= LNK_100MB; + break; + case SPEED_10: + link |= LNK_10MB; + break; + } + } + if (ecmd.duplex == DUPLEX_FULL) + link |= LNK_FULL_DUPLEX; + + if (link != ap->link) { + struct cmd cmd; + printk(KERN_INFO "%s: Renegotiating link state\n", + dev->name); + + ap->link = link; + writel(link, ®s->TuneLink); + if (!ACE_IS_TIGON_I(ap)) + writel(link, ®s->TuneFastLink); + wmb(); + + cmd.evt = C_LNK_NEGOTIATION; + cmd.code = 0; + cmd.idx = 0; + ace_issue_cmd(regs, &cmd); + } + return 0; + } +#endif + + return -EOPNOTSUPP; +} + + /* * Set the hardware MAC address. */ -static int ace_set_mac_addr(struct device *dev, void *p) +static int ace_set_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr=p; struct ace_regs *regs; @@ -1495,6 +1956,7 @@ static int ace_set_mac_addr(struct device *dev, void *p) if(dev->start) return -EBUSY; + memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); da = (u16 *)dev->dev_addr; @@ -1512,7 +1974,7 @@ static int ace_set_mac_addr(struct device *dev, void *p) } -static void ace_set_multicast_list(struct device *dev) +static void ace_set_multicast_list(struct net_device *dev) { struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; @@ -1566,7 +2028,7 @@ static void ace_set_multicast_list(struct device *dev) } -static struct net_device_stats *ace_get_stats(struct device *dev) +static struct net_device_stats *ace_get_stats(struct net_device *dev) { struct ace_private *ap = dev->priv; @@ -1592,9 +2054,6 @@ void __init ace_copy(struct ace_regs *regs, void *src, u32 dest, int size) #ifdef __BIG_ENDIAN #error "data must be swapped here" #else -/* - * XXX - special memcpy needed here!!! - */ wsrc = src; for (i = 0; i < (tsize / 4); i++){ writel(wsrc[i], tdest + i*4); @@ -1642,7 +2101,7 @@ void __init ace_clear(struct ace_regs *regs, u32 dest, int size) * This operation requires the NIC to be halted and is performed with * interrupts disabled and with the spinlock hold. */ -int __init ace_load_firmware(struct device *dev) +int __init ace_load_firmware(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -1661,7 +2120,7 @@ int __init ace_load_firmware(struct device *dev) * funny things on NICs with only 512KB SRAM */ ace_clear(regs, 0x2000, 0x80000-0x2000); - if (ap->version == 1){ + if (ACE_IS_TIGON_I(ap)){ ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen); ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen); ace_copy(regs, tigonFwRodata, tigonFwRodataAddr, @@ -1693,7 +2152,7 @@ int __init ace_load_firmware(struct device *dev) * * Oh yes, this is only the beginning! */ -static void eeprom_start(struct ace_regs *regs) +static void __init eeprom_start(struct ace_regs *regs) { u32 local = readl(®s->LocalCtrl); @@ -1716,7 +2175,7 @@ static void eeprom_start(struct ace_regs *regs) } -static void eeprom_prep(struct ace_regs *regs, u8 magic) +static void __init eeprom_prep(struct ace_regs *regs, u8 magic) { short i; u32 local; @@ -1749,7 +2208,7 @@ static void eeprom_prep(struct ace_regs *regs, u8 magic) } -static int eeprom_check_ack(struct ace_regs *regs) +static int __init eeprom_check_ack(struct ace_regs *regs) { int state; u32 local; @@ -1774,7 +2233,7 @@ static int eeprom_check_ack(struct ace_regs *regs) } -static void eeprom_stop(struct ace_regs *regs) +static void __init eeprom_stop(struct ace_regs *regs) { u32 local; @@ -1804,7 +2263,7 @@ static void eeprom_stop(struct ace_regs *regs) /* * Read a whole byte from the EEPROM. */ -static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset) +static u8 __init read_eeprom_byte(struct ace_regs *regs, unsigned long offset) { u32 local; short i; @@ -1876,6 +2335,6 @@ static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset) /* * Local variables: - * compile-command: "gcc -D__KERNEL__ -D__SMP__ -DMODULE -I/data/home/jes/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include /data/home/jes/linux/include/linux/modversions.h -c -o acenic.o acenic.c" + * compile-command: "gcc -D__SMP__ -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c" * End: */ diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index 6f4d67384..d4031dea1 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -14,7 +14,7 @@ * as some of them are in PCI shared memory and it is necessary to use * readl/writel to access them. * - * The addressing code is derived from Pete Beckman's work, but + * The addressing code is derived from Pete Wyckoff's work, but * modified to deal properly with readl/writel usage. */ @@ -143,11 +143,11 @@ struct ace_regs { u32 Mb2Hi; u32 TxPrd; u32 Mb3Hi; - u32 Mb3Lo; + u32 RxStdPrd; /* RxStdPrd */ u32 Mb4Hi; - u32 Mb4Lo; + u32 RxJumboPrd; /* RxJumboPrd */ u32 Mb5Hi; - u32 Mb5Lo; + u32 RxMiniPrd; u32 Mb6Hi; u32 Mb6Lo; u32 Mb7Hi; @@ -197,7 +197,7 @@ struct ace_regs { u32 IfIdx; u32 IfMtu; /* 0x660 */ u32 MaskInt; - u32 LnkState; + u32 GigLnkState; u32 FastLnkState; u32 pad16[4]; /* 0x670 */ u32 RxRetCsm; /* 0x680 */ @@ -279,6 +279,7 @@ struct ace_regs { #define DMA_WRITE_MAX_256 0xc0 #define DMA_WRITE_MAX_1K 0xe0 #define MEM_READ_MULTIPLE 0x00020000 +#define PCI_66MHZ 0x00080000 #define DMA_WRITE_ALL_ALIGN 0x00800000 #define READ_CMD_MEM 0x06000000 #define WRITE_CMD_MEM 0x70000000 @@ -365,6 +366,7 @@ struct event { #define E_LNK_STATE 0x06 #define E_C_LINK_UP 0x01 #define E_C_LINK_DOWN 0x02 +#define E_C_LINK_UP_FAST 0x03 #define E_ERROR 0x07 #define E_C_ERR_INVAL_CMD 0x01 @@ -416,6 +418,10 @@ struct cmd { #define C_C_PROMISC_DISABLE 0x02 #define C_LNK_NEGOTIATION 0x0b +#define C_C_NEGOTIATE_BOTH 0x00 +#define C_C_NEGOTIATE_GIG 0x01 +#define C_C_NEGOTIATE_10_100 0x02 + #define C_SET_MAC_ADDR 0x0c #define C_CLEAR_PROFILE 0x0d @@ -429,33 +435,30 @@ struct cmd { /* - * Descriptor types. + * Descriptor flags */ +#define BD_FLG_TCP_UDP_SUM 0x01 +#define BD_FLG_IP_SUM 0x02 +#define BD_FLG_END 0x04 +#define BD_FLG_JUMBO 0x10 +#define BD_FLG_MINI 0x1000 -#define DESC_TX 0x01 -#define DESC_RX 0x02 -#define DESC_END 0x04 -#define DESC_MORE 0x08 /* - * Control block flags + * Ring Control block flags */ +#define RCB_FLG_TCP_UDP_SUM 0x01 +#define RCB_FLG_IP_SUM 0x02 +#define RCB_FLG_VLAN_ASSIST 0x10 +#define RCB_FLG_COAL_INT_ONLY 0x20 +#define RCB_FLG_IEEE_SNAP_SUM 0x80 +#define RCB_FLG_EXT_RX_BD 0x100 +#define RCB_FLG_RNG_DISABLE 0x200 -#define FLG_RX_TCP_UDP_SUM 0x01 -#define FLG_RX_IP_SUM 0x02 -#define FLG_RX_SPLIT_HDRS 0x04 -#define FLG_RX_NO_PSDO_HDR_SUM 0x08 -#define FLG_RNG_DISABLED 0x200 - -/* - * Descriptor flags - */ -#define DFLG_RX_JUMBO 0x10 /* * TX ring */ - #define TX_RING_ENTRIES 128 #define TX_RING_SIZE (TX_RING_ENTRIES * sizeof(struct tx_desc)) #define TX_RING_BASE 0x3800 @@ -471,12 +474,16 @@ struct tx_desc{ #if __LITTLE_ENDIAN u16 flags; u16 size; + u16 vlan; + u16 reserved; #else u16 size; u16 flags; + u16 reserved; + u16 vlan; #endif #endif - u32 nic_addr; + u32 vlanres; }; @@ -493,9 +500,6 @@ struct tx_desc{ #define RX_RETURN_RING_SIZE (RX_MAX_RETURN_RING_ENTRIES * \ sizeof(struct rx_desc)) -#define RX_RING_THRESH 64 -#define RX_RING_JUMBO_THRESH 48 - struct rx_desc{ aceaddr addr; #ifdef __LITTLE_ENDIAN @@ -520,14 +524,14 @@ struct rx_desc{ u16 tcp_udp_csum; #endif #ifdef __LITTLE_ENDIAN - u16 reserved; + u16 vlan; u16 err_flags; #else u16 err_flags; - u16 reserved; + u16 vlan; #endif - u32 nic_addr; - u32 pad[1]; + u32 reserved; + u32 opague; }; @@ -598,55 +602,72 @@ struct ace_info { aceaddr stats2_ptr; }; + /* - * Struct private for the AceNIC. + * struct ace_skb holding the rings of skb's. This is an awful lot of + * pointers, but I don't see any other smart mode to do this in an + * efficient manner ;-( */ +struct ace_skb +{ + struct sk_buff *tx_skbuff[TX_RING_ENTRIES]; + struct sk_buff *rx_std_skbuff[RX_STD_RING_ENTRIES]; + struct sk_buff *rx_mini_skbuff[RX_MINI_RING_ENTRIES]; + struct sk_buff *rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES]; +}; + +/* + * Struct private for the AceNIC. + * + * Elements are grouped so variables used by the tx handling goes + * together, and will go into the same cache lines etc. in order to + * avoid cache line contention between the rx and tx handling on SMP. + * + * Frequently accessed variables are put at the beginning of the + * struct to help the compiler generate better/shorter code. + */ struct ace_private { + struct ace_skb *skb; struct ace_regs *regs; /* register base */ - volatile __u32 *sgt; - struct sk_buff *pkt_buf; /* Receive buffer */ -/* - * The send ring is located in the shared memory window - */ + int version, fw_running, fw_up, link; + int promisc, mcast_all; + /* + * The send ring is located in the shared memory window + */ + struct ace_info *info; struct tx_desc *tx_ring; - struct rx_desc rx_std_ring[RX_STD_RING_ENTRIES]; + u32 tx_prd, tx_full, tx_ret_csm; + struct timer_list timer; + + unsigned long std_refill_busy + __attribute__ ((aligned (L1_CACHE_BYTES))); + unsigned long mini_refill_busy, jumbo_refill_busy; + atomic_t cur_rx_bufs, + cur_mini_bufs, + cur_jumbo_bufs; + u32 rx_std_skbprd, rx_mini_skbprd, rx_jumbo_skbprd; + u32 cur_rx; + struct tq_struct immediate; + int bh_pending, jumbo; + struct rx_desc rx_std_ring[RX_STD_RING_ENTRIES] + __attribute__ ((aligned (L1_CACHE_BYTES))); struct rx_desc rx_jumbo_ring[RX_JUMBO_RING_ENTRIES]; -#if 0 struct rx_desc rx_mini_ring[RX_MINI_RING_ENTRIES]; -#endif struct rx_desc rx_return_ring[RX_RETURN_RING_ENTRIES]; struct event evt_ring[EVT_RING_ENTRIES]; - struct ace_info *info; - struct sk_buff *tx_skbuff[TX_RING_ENTRIES]; - struct sk_buff *rx_std_skbuff[RX_STD_RING_ENTRIES]; - struct sk_buff *rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES]; - spinlock_t lock; - struct timer_list timer; - u32 cur_rx, tx_prd; - u32 dirty_rx, tx_ret_csm, dirty_event; - u32 rx_std_skbprd, rx_jumbo_skbprd; - u32 tx_full; volatile u32 evt_prd __attribute__ ((aligned (L1_CACHE_BYTES))); volatile u32 rx_ret_prd __attribute__ ((aligned (L1_CACHE_BYTES))); volatile u32 tx_csm __attribute__ ((aligned (L1_CACHE_BYTES))); - struct device *next - __attribute__ ((aligned (L1_CACHE_BYTES))); unsigned char *trace_buf; - int fw_running, fw_up, jumbo, promisc, mcast_all; - int version; - int flags; - u16 vendor; - u16 pci_command; struct pci_dev *pdev; -#if 0 - u8 pci_bus; - u8 pci_dev_fun; -#endif + struct net_device *next; + u16 pci_command; + u8 pci_latency; char name[24]; struct net_device_stats stats; }; @@ -654,21 +675,27 @@ struct ace_private /* * Prototypes */ -static int ace_init(struct device *dev, int board_idx); -static int ace_load_std_rx_ring(struct device *dev); -static int ace_load_jumbo_rx_ring(struct device *dev); -static int ace_flush_jumbo_rx_ring(struct device *dev); +static int ace_init(struct net_device *dev, int board_idx); +static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs); +static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs); +static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs); +static int ace_flush_jumbo_rx_ring(struct net_device *dev); static void ace_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int ace_load_firmware(struct device *dev); -static int ace_open(struct device *dev); -static int ace_start_xmit(struct sk_buff *skb, struct device *dev); -static int ace_close(struct device *dev); +static int ace_load_firmware(struct net_device *dev); +static int ace_open(struct net_device *dev); +static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ace_close(struct net_device *dev); static void ace_timer(unsigned long data); +static void ace_bh(struct net_device *dev); static void ace_dump_trace(struct ace_private *ap); -static void ace_set_multicast_list(struct device *dev); -static int ace_change_mtu(struct device *dev, int new_mtu); -static int ace_set_mac_addr(struct device *dev, void *p); -static struct net_device_stats *ace_get_stats(struct device *dev); +static void ace_set_multicast_list(struct net_device *dev); +static int ace_change_mtu(struct net_device *dev, int new_mtu); +#ifdef SKB_RECYCLE +extern int ace_recycle(struct sk_buff *skb); +#endif +static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int ace_set_mac_addr(struct net_device *dev, void *p); +static struct net_device_stats *ace_get_stats(struct net_device *dev); static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset); #endif /* _ACENIC_H_ */ diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h index b4e81b7e6..563b9b590 100644 --- a/drivers/net/acenic_firmware.h +++ b/drivers/net/acenic_firmware.h @@ -1,32 +1,41 @@ +/* + * Declare these here even if Tigon I support is disabled to avoid + * the compiler complaining about undefined symbols. + */ +#define tigonFwReleaseMajor 0xc +#define tigonFwReleaseMinor 0x3 +#define tigonFwReleaseFix 0xd +#define tigonFwStartAddr 0x00004000 +#define tigonFwTextAddr 0x00004000 +#define tigonFwTextLen 0x10920 +#define tigonFwRodataAddr 0x00014920 +#define tigonFwRodataLen 0xaa0 +#define tigonFwDataAddr 0x000153e0 +#define tigonFwDataLen 0x150 +#define tigonFwSbssAddr 0x00015530 +#define tigonFwSbssLen 0x2c +#define tigonFwBssAddr 0x00015560 +#define tigonFwBssLen 0x2080 +u32 tigonFwText[]; +u32 tigonFwData[]; +u32 tigonFwRodata[]; + +#ifndef CONFIG_ACENIC_OMIT_TIGON_I /* Generated by genfw.c */ -int tigonFwReleaseMajor = 0xc; -int tigonFwReleaseMinor = 0x3; -int tigonFwReleaseFix = 0x5; -u32 tigonFwStartAddr = 0x00004000; -u32 tigonFwTextAddr = 0x00004000; -int tigonFwTextLen = 0x10910; -u32 tigonFwRodataAddr = 0x00014910; -int tigonFwRodataLen = 0xaa0; -u32 tigonFwDataAddr = 0x000153d0; -int tigonFwDataLen = 0x150; -u32 tigonFwSbssAddr = 0x00015520; -int tigonFwSbssLen = 0x2c; -u32 tigonFwBssAddr = 0x00015550; -int tigonFwBssLen = 0x2080; u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, -0x8fbd5404, 0x3a0f021, 0x3c100000, 0x26104000, +0x8fbd5414, 0x3a0f021, 0x3c100000, 0x26104000, 0xc00100c, 0x0, 0xd, 0x27bdffd8, 0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021, 0x3c170013, 0x36f75418, 0x2e02021, 0x340583e8, -0xafbf0024, 0xc00248c, 0xafb00020, 0xc0023ec, -0x0, 0x3c040001, 0x24844970, 0x24050001, -0x2e03021, 0x3821, 0x3c100001, 0x261075d0, -0xafb00010, 0xc002407, 0xafbb0014, 0x3c02000f, +0xafbf0024, 0xc002488, 0xafb00020, 0xc0023e8, +0x0, 0x3c040001, 0x24844984, 0x24050001, +0x2e03021, 0x3821, 0x3c100001, 0x261075e0, +0xafb00010, 0xc002403, 0xafbb0014, 0x3c02000f, 0x3442ffff, 0x2021024, 0x362102b, 0x10400009, -0x24050003, 0x3c040001, 0x2484497c, 0x2003021, -0x3603821, 0x3c020010, 0xafa20010, 0xc002407, +0x24050003, 0x3c040001, 0x24844990, 0x2003021, +0x3603821, 0x3c020010, 0xafa20010, 0xc002403, 0xafa00014, 0x2021, 0x3405c000, 0x3c010001, 0x370821, 0xa02083b0, 0x3c010001, 0x370821, 0xa02083b2, 0x3c010001, 0x370821, 0xa02083b3, @@ -63,17 +72,17 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8ee20450, 0x8ee30454, 0xaee304fc, 0x8ee204fc, 0x2442e000, 0x2c422001, 0x1440000d, 0x26e40030, 0x8ee20450, 0x8ee30454, 0x3c040001, -0x24844988, 0x3c050001, 0xafa00010, 0xafa00014, -0x8ee704fc, 0x34a5f000, 0xc002407, 0x603021, -0x26e40030, 0xc00248c, 0x24050400, 0x27440080, -0xc00248c, 0x24050080, 0x26e4777c, 0xc00248c, +0x2484499c, 0x3c050001, 0xafa00010, 0xafa00014, +0x8ee704fc, 0x34a5f000, 0xc002403, 0x603021, +0x26e40030, 0xc002488, 0x24050400, 0x27440080, +0xc002488, 0x24050080, 0x26e4777c, 0xc002488, 0x24050400, 0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, 0x27450200, 0x24060008, 0xaee20068, -0x24020006, 0xc00249e, 0xaee20064, 0x3c023b9a, +0x24020006, 0xc00249a, 0xaee20064, 0x3c023b9a, 0x3442ca00, 0x2021, 0x24030002, 0xaee30074, 0xaee30070, 0xaee2006c, 0x240203e8, 0xaee20104, 0x24020001, 0xaee30100, 0xaee2010c, 0x3c030001, -0x641821, 0x906353d0, 0x2e41021, 0x24840001, +0x641821, 0x906353e0, 0x2e41021, 0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8, 0x0, 0x8f820040, 0x2e41821, 0x24840001, 0x21702, 0x24420030, 0xa062009c, 0x2e41021, 0xa040009c, @@ -84,10 +93,10 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x96e3047a, 0x96e2046a, 0x14620022, 0x3c020700, 0x8ee204c0, 0x24030001, 0xa2e34e20, 0x34420e00, 0xaee204c0, 0x8f420218, 0x30420100, 0x10400005, -0x0, 0x3c020001, 0x2442e178, 0x800111d, -0x21100, 0x3c020001, 0x2442d36c, 0x21100, +0x0, 0x3c020001, 0x2442e168, 0x800111d, +0x21100, 0x3c020001, 0x2442d35c, 0x21100, 0x21182, 0x3c030800, 0x431025, 0x3c010001, -0xac221238, 0x3c020001, 0x2442f690, 0x21100, +0xac221238, 0x3c020001, 0x2442f680, 0x21100, 0x21182, 0x3c030800, 0x431025, 0x3c010001, 0xac221278, 0x8ee20000, 0x34424000, 0x8001238, 0xaee20000, 0x34423000, 0xafa20018, 0x8ee20608, @@ -119,9 +128,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c, -0xaee90608, 0x3c040001, 0x24844994, 0xafa00010, +0xaee90608, 0x3c040001, 0x248449a8, 0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002407, 0x34a5f000, 0x8001223, 0x0, +0xc002403, 0x34a5f000, 0x8001223, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, @@ -145,29 +154,29 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x14c0001b, 0x0, -0x3c040001, 0x2484499c, 0xafa00010, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002407, +0x3c040001, 0x248449b0, 0xafa00010, 0xafa00014, +0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, -0x8001223, 0x8ee201b0, 0x3c040001, 0x248449a8, +0x8001223, 0x8ee201b0, 0x3c040001, 0x248449bc, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002407, 0x34a5f005, 0x8ee201ac, 0x24420001, +0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20160, 0x3c040001, -0x248449b4, 0x3405f001, 0x24420001, 0xaee20160, +0x248449c8, 0x3405f001, 0x24420001, 0xaee20160, 0x8ee20160, 0x3021, 0x3821, 0xafa00010, -0xc002407, 0xafa00014, 0x8001238, 0x0, -0x3c020001, 0x2442f5b8, 0x21100, 0x21182, +0xc002403, 0xafa00014, 0x8001238, 0x0, +0x3c020001, 0x2442f5a8, 0x21100, 0x21182, 0x431025, 0x3c010001, 0xac221278, 0x96e2045a, 0x30420003, 0x10400025, 0x3c050fff, 0x8ee204c8, 0x34a5ffff, 0x34420a00, 0xaee204c8, 0x8ee304c8, -0x3c040001, 0x248449c0, 0x24020001, 0xa2e204ec, +0x3c040001, 0x248449d4, 0x24020001, 0xa2e204ec, 0xa2e204ed, 0x3c020002, 0x621825, 0x3c020001, -0x2442a3a0, 0x451024, 0x21082, 0xaee304c8, +0x2442a390, 0x451024, 0x21082, 0xaee304c8, 0x3c030800, 0x431025, 0x3c010001, 0xac221220, -0x3c020001, 0x2442ade4, 0x451024, 0x21082, +0x3c020001, 0x2442add4, 0x451024, 0x21082, 0x431025, 0x3c010001, 0xac221280, 0x96e6045a, -0x3821, 0x24050011, 0xafa00010, 0xc002407, +0x3821, 0x24050011, 0xafa00010, 0xc002403, 0xafa00014, 0x8001268, 0x0, 0x3c020001, -0x2442a9e4, 0x21100, 0x21182, 0x3c030800, +0x2442a9d4, 0x21100, 0x21182, 0x3c030800, 0x431025, 0x3c010001, 0xac221280, 0x96e2046a, 0x30420010, 0x14400009, 0x0, 0x96e2047a, 0x30420010, 0x10400112, 0x0, 0x96e2046a, @@ -202,8 +211,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001, -0x24844994, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f000, +0x248449a8, 0xafa00010, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000, 0x800136d, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, @@ -227,18 +236,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, -0x14c0001b, 0x0, 0x3c040001, 0x2484499c, +0x14c0001b, 0x0, 0x3c040001, 0x248449b0, 0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f001, 0x8ee201b0, +0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, 0x800136d, 0x8ee201b0, -0x3c040001, 0x248449a8, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f005, +0x3c040001, 0x248449bc, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, -0x8ee20160, 0x3c040001, 0x248449b4, 0x3405f002, +0x8ee20160, 0x3c040001, 0x248449c8, 0x3405f002, 0x24420001, 0xaee20160, 0x8ee20160, 0x3021, -0x3821, 0xafa00010, 0xc002407, 0xafa00014, -0x96e6047a, 0x96e7046a, 0x3c040001, 0x248449cc, -0x24050012, 0xafa00010, 0xc002407, 0xafa00014, +0x3821, 0xafa00010, 0xc002403, 0xafa00014, +0x96e6047a, 0x96e7046a, 0x3c040001, 0x248449e0, +0x24050012, 0xafa00010, 0xc002403, 0xafa00014, 0xc004500, 0x0, 0xc002318, 0x0, 0x3c060001, 0x34c63800, 0xaee00608, 0xaf400228, 0xaf40022c, 0x96e30458, 0x8ee40000, 0x3c0512d8, @@ -280,8 +289,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001, -0x24844994, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f000, +0x248449a8, 0xafa00010, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000, 0x80014a5, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, @@ -305,12 +314,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, -0x14c0001b, 0x0, 0x3c040001, 0x2484499c, +0x14c0001b, 0x0, 0x3c040001, 0x248449b0, 0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f001, 0x8ee201b0, +0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, 0x80014a5, 0x8ee201b0, -0x3c040001, 0x248449a8, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f005, +0x3c040001, 0x248449bc, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20154, 0x24420001, 0xaee20154, 0xc0014dc, 0x8ee20154, 0x8f8200a0, 0x30420004, 0x1440fffd, @@ -322,7 +331,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee20178, 0x24420001, 0xaee20178, 0x8ee20178, 0x8f8200d8, 0x8f8300d4, 0x431023, 0xaee2726c, 0x8ee2726c, 0x1c400003, 0x3c030001, 0x431021, -0xaee2726c, 0xc004068, 0x0, 0xc004440, +0xaee2726c, 0xc004064, 0x0, 0xc004440, 0xaf800228, 0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028, 0x3e00008, 0x0, 0x3e00008, 0x0, 0x0, 0x0, 0x2402002c, @@ -331,7 +340,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee07b8c, 0xaee07b84, 0x3c010001, 0x370821, 0xac2083bc, 0x3c010001, 0x370821, 0x3e00008, 0xa02083b9, 0x27bdffd8, 0xafbf0024, 0xafb00020, -0x8f820054, 0x3c030001, 0x8c635488, 0x24420067, +0x8f820054, 0x3c030001, 0x8c635498, 0x24420067, 0x1060000d, 0xaf820058, 0x3c020001, 0x571021, 0x904283b8, 0x10400005, 0x3c030200, 0x3c010001, 0x370821, 0x8001503, 0xa02083b8, 0x8ee20000, @@ -349,8 +358,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x3c030001, 0x771821, 0x8c6383d4, 0x8f8200b4, 0x1462007c, 0x0, 0x3c070001, 0xf73821, 0x8ce783d0, 0x8f8200b0, 0x3c040001, -0x24844a40, 0xafa00014, 0xafa20010, 0x8f8600b0, -0x3c050005, 0xc002407, 0x34a50900, 0x8f82011c, +0x24844a50, 0xafa00014, 0xafa20010, 0x8f8600b0, +0x3c050005, 0xc002403, 0x34a50900, 0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001, 0xaf8200b0, 0xaf830104, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, @@ -377,12 +386,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xac820000, 0x24020001, 0xac820004, 0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201e4, 0x3c070001, 0xf73821, 0x8ce783d0, 0x24420001, -0xaee201e4, 0x8ee201e4, 0x3c040001, 0x24844a4c, +0xaee201e4, 0x8ee201e4, 0x3c040001, 0x24844a5c, 0x80015bd, 0xafa00010, 0x8f820104, 0x3c010001, 0x370821, 0xac2283d0, 0x8f8200b4, 0x3c070001, -0xf73821, 0x8ce783d0, 0x3c040001, 0x24844a54, +0xf73821, 0x8ce783d0, 0x3c040001, 0x24844a64, 0x3c010001, 0x370821, 0xac2283d4, 0xafa00010, -0xafa00014, 0x8f8600b0, 0x3c050005, 0xc002407, +0xafa00014, 0x8f8600b0, 0x3c050005, 0xc002403, 0x34a50900, 0x80015cc, 0x0, 0x8f820104, 0x3c010001, 0x370821, 0xac2283d0, 0x8f8200b4, 0x3c010001, 0x370821, 0xac2283d4, 0x8ee27274, @@ -413,9 +422,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600000b, 0x24100001, -0x8ee204e4, 0x3c040001, 0x24844a5c, 0xafa00014, +0x8ee204e4, 0x3c040001, 0x24844a6c, 0xafa00014, 0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002407, 0x34a5f006, 0x16000003, 0x24020001, +0xc002403, 0x34a5f006, 0x16000003, 0x24020001, 0x8001650, 0xa2e204f4, 0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170, 0x8ee204e4, 0xa2e004f4, 0xaee004f0, 0xaee07274, 0xaee204f8, 0x8ee20e1c, @@ -443,8 +452,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600000b, 0x24100001, 0x8ee2724c, 0x3c040001, -0x24844a68, 0xafa00014, 0xafa20010, 0x8ee6724c, -0x8f470280, 0x3c050009, 0xc002407, 0x34a5f008, +0x24844a78, 0xafa00014, 0xafa20010, 0x8ee6724c, +0x8f470280, 0x3c050009, 0xc002403, 0x34a5f008, 0x56000001, 0xaee00e1c, 0x8ee20174, 0x24420001, 0xaee20174, 0x8ee20174, 0x8ee24e24, 0x10400019, 0x0, 0xaee04e24, 0x8f820040, 0x30420001, @@ -554,11 +563,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, 0x24020001, 0x14620003, 0x3c050009, 0x800197c, 0x24100001, 0x3c040001, -0x24844a74, 0xafa00010, 0xafa00014, 0x8f860120, +0x24844a84, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x800187b, 0x34a5f011, 0x3c040001, -0x24844a80, 0xafa00010, 0xafa00014, 0x8f860120, -0x8f870124, 0x34a5f010, 0xc002407, 0x8021, -0x800197c, 0x0, 0x3c040001, 0x24844a8c, +0x24844a90, 0xafa00010, 0xafa00014, 0x8f860120, +0x8f870124, 0x34a5f010, 0xc002403, 0x8021, +0x800197c, 0x0, 0x3c040001, 0x24844a9c, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, 0x8001975, 0x34a5f00f, 0x8ee20608, 0x8f430228, 0x24420001, 0x304900ff, 0x512300e2, 0xafa00010, @@ -589,8 +598,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x5600000c, 0xaee90608, -0x3c040001, 0x24844a98, 0xafa00010, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002407, +0x3c040001, 0x24844aa8, 0xafa00010, 0xafa00014, +0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000, 0x800197c, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, @@ -615,18 +624,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600001d, 0x24100001, 0x3c040001, -0x24844aa0, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f001, +0x24844ab0, 0xafa00010, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, 0x800197c, -0x8ee201b0, 0x3c040001, 0x24844aac, 0xafa00014, +0x8ee201b0, 0x3c040001, 0x24844abc, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f005, -0xc002407, 0x0, 0x8ee201ac, 0x8021, +0xc002403, 0x0, 0x8ee201ac, 0x8021, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x1200000c, 0x24020001, 0x3c010001, 0x370821, 0xa02083b0, 0x8f420238, 0x8ee30158, 0x24630001, 0xaee30158, 0x8ee30158, 0x800198c, 0xaee27278, 0x24020001, 0x3c010001, 0x370821, 0xa02283b0, 0x3c020001, -0x8c425488, 0x10400187, 0x0, 0x8ee27b84, +0x8c425498, 0x10400187, 0x0, 0x8ee27b84, 0x24430001, 0x284200c9, 0x144001a4, 0xaee37b84, 0x8ee204d4, 0x30420002, 0x14400119, 0xaee07b84, 0x8ee204d4, 0x3c030600, 0x34631000, 0x34420002, @@ -690,13 +699,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x56000006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, 0x24020001, 0x10620022, 0x0, 0x3c040001, -0x24844a74, 0xafa00010, 0xafa00014, 0x8f860120, -0x8f870124, 0x3c050009, 0xc002407, 0x34a5f011, -0x8001aad, 0x0, 0x3c040001, 0x24844a80, +0x24844a84, 0xafa00010, 0xafa00014, 0x8f860120, +0x8f870124, 0x3c050009, 0xc002403, 0x34a5f011, +0x8001aad, 0x0, 0x3c040001, 0x24844a90, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, -0xc002407, 0x34a5f010, 0x8001aad, 0x0, -0x3c040001, 0x24844a8c, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002407, 0x34a5f00f, +0xc002403, 0x34a5f010, 0x8001aad, 0x0, +0x3c040001, 0x24844a9c, 0xafa00014, 0x8ee60608, +0x8f470228, 0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee2015c, 0x24420001, 0xaee2015c, 0x8ee2015c, 0x8ee204d4, 0x30420001, 0x10400055, 0x0, @@ -732,7 +741,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf820044, 0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b88, 0x24430001, 0x28421389, 0x14400005, 0xaee37b88, 0x8f820044, 0x38420020, 0xaf820044, -0xaee07b88, 0xc0045c1, 0x0, 0x8fbf0024, +0xaee07b88, 0xc0045c2, 0x0, 0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028, 0x27bdffb8, 0xafbf0044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, @@ -742,18 +751,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee2016c, 0x80022f4, 0x8ee2016c, 0x32c20001, 0x10400004, 0x24020001, 0xaf820064, 0x80022f4, 0x0, 0x32c20002, 0x1440000c, 0x3c050003, -0x3c040001, 0x24844b24, 0x34a50001, 0x2c03021, -0x3821, 0xafa00010, 0xc002407, 0xafa00014, +0x3c040001, 0x24844b34, 0x34a50001, 0x2c03021, +0x3821, 0xafa00010, 0xc002403, 0xafa00014, 0x2402fff8, 0x80022f4, 0xaf820064, 0x8f43022c, 0x8f42010c, 0x5062000c, 0xafa00010, 0x8f42022c, 0x21080, 0x5a1021, 0x8c420300, 0xafa20020, 0x8f42022c, 0x24070001, 0x24420001, 0x3042003f, -0x8001b80, 0xaf42022c, 0x3c040001, 0x24844b30, +0x8001b80, 0xaf42022c, 0x3c040001, 0x24844b40, 0xafa00014, 0x8f46022c, 0x8f47010c, 0x3c050003, -0xc002407, 0x34a5f01f, 0x3821, 0x14e00003, +0xc002403, 0x34a5f01f, 0x3821, 0x14e00003, 0x0, 0x80022ed, 0xaf960064, 0x93a20020, 0x2443ffff, 0x2c620011, 0x10400658, 0x31080, -0x3c010001, 0x220821, 0x8c224be8, 0x400008, +0x3c010001, 0x220821, 0x8c224bf8, 0x400008, 0x0, 0x8fa20020, 0x30420fff, 0xaee20e0c, 0x8f820060, 0x34420200, 0xaf820060, 0x8ee20118, 0x24420001, 0xaee20118, 0x80022e8, 0x8ee20118, @@ -769,8 +778,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f840054, 0x41442, 0x41c82, 0x431021, 0x41cc2, 0x431023, 0x41d02, 0x431021, 0x41d42, 0x431023, 0x8001bd0, 0xaee20078, -0x3c040001, 0x24844b3c, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002407, 0x34a50004, 0x8ee20110, +0x3c040001, 0x24844b4c, 0xafa00014, 0x8fa60020, +0x3c050003, 0xc002403, 0x34a50004, 0x8ee20110, 0x24420001, 0xaee20110, 0x80022e8, 0x8ee20110, 0x27440212, 0xc0022fe, 0x24050006, 0x3049001f, 0x920c0, 0x2e41021, 0x9442727c, 0x30424000, @@ -785,8 +794,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2c820080, 0x1440fff8, 0x410c0, 0x4c10010, 0x618c0, 0x610c0, 0x571821, 0x8c63737c, 0x571021, 0xafa30010, 0x8c427380, 0x3c040001, -0x24844b48, 0xafa20014, 0x8f470214, 0x3c050003, -0xc002407, 0x34a50013, 0x8001c90, 0x3c020800, +0x24844b58, 0xafa20014, 0x8f470214, 0x3c050003, +0xc002403, 0x34a50013, 0x8001c90, 0x3c020800, 0x97440212, 0x771021, 0xa444737e, 0x8f440214, 0x771021, 0x2e31821, 0xac447380, 0x34028000, 0xa462737c, 0x910c0, 0x2e21021, 0x8001c79, @@ -803,8 +812,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24840001, 0x2c820080, 0x1440fff8, 0x410c0, 0x4c10023, 0x618c0, 0x910c0, 0x571821, 0x8c63727c, 0x571021, 0xafa30010, 0x8c427280, -0x3c040001, 0x24844b54, 0xafa20014, 0x8f470214, -0x3c050003, 0xc002407, 0x34a5f017, 0x8001c90, +0x3c040001, 0x24844b64, 0xafa20014, 0x8f470214, +0x3c050003, 0xc002403, 0x34a5f017, 0x8001c90, 0x3c020800, 0x8f430210, 0xb71021, 0xac43777c, 0x8f430214, 0xb71021, 0xac437780, 0x3c020001, 0x571021, 0x8c4283b4, 0x24420001, 0x3c010001, @@ -878,14 +887,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, 0x24020001, -0x10620022, 0x0, 0x3c040001, 0x24844b60, +0x10620022, 0x0, 0x3c040001, 0x24844b70, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002407, 0x34a5f011, 0x8001da0, -0x0, 0x3c040001, 0x24844b6c, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002407, +0x3c050009, 0xc002403, 0x34a5f011, 0x8001da0, +0x0, 0x3c040001, 0x24844b7c, 0xafa00014, +0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010, 0x8001da0, 0x0, 0x3c040001, -0x24844b78, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f00f, 0x8ee201ac, +0x24844b88, 0xafa00014, 0x8ee60608, 0x8f470228, +0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20124, 0x24420001, 0xaee20124, 0x8001f97, 0x8ee20124, 0x27440212, 0xc0022fe, 0x24050006, 0x3049001f, @@ -899,9 +908,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1221004, 0x21027, 0x621824, 0xaf830228, 0x910c0, 0x2e21821, 0x3402c000, 0x8001e4e, 0xa462727c, 0x8f420214, 0xafa20010, 0x910c0, -0x571021, 0x8c42727c, 0x3c040001, 0x24844b84, +0x571021, 0x8c42727c, 0x3c040001, 0x24844b94, 0x3c050003, 0xafa20014, 0x8f470210, 0x34a5f01c, -0xc002407, 0x1203021, 0x8001e83, 0x3c020800, +0xc002403, 0x1203021, 0x8001e83, 0x3c020800, 0xb71021, 0x9443727e, 0x97420212, 0x14620019, 0x918c0, 0xb71021, 0x8c437280, 0x8f420214, 0x14620014, 0x918c0, 0x2e51021, 0x9447727c, @@ -927,9 +936,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x910c0, 0x2e41821, 0x3402c000, 0x15000015, 0xa462737c, 0x910c0, 0x2e21821, 0x34028000, 0x8001e4e, 0xa462727c, 0x571021, 0x8c42727c, -0x3c040001, 0x24844b90, 0x3c050003, 0xafa20010, +0x3c040001, 0x24844ba0, 0x3c050003, 0xafa20010, 0x710c0, 0x571021, 0x8c42737c, 0x34a5001e, -0x1203021, 0xc002407, 0xafa20014, 0x8001e83, +0x1203021, 0xc002403, 0xafa20014, 0x8001e83, 0x3c020800, 0x2021, 0x428c0, 0xb71021, 0x9443777e, 0x97420212, 0x5462002b, 0x24840001, 0xb71021, 0x8c437780, 0x8f420214, 0x54620026, @@ -937,11 +946,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2442ffff, 0x3c010001, 0x370821, 0xac2283b4, 0x3c020001, 0x571021, 0x8c4283b4, 0x809021, 0x242102b, 0x1040000e, 0x24b1777c, 0x24b07784, -0x2f02021, 0x2f12821, 0xc002494, 0x24060008, +0x2f02021, 0x2f12821, 0xc002490, 0x24060008, 0x26310008, 0x3c020001, 0x571021, 0x8c4283b4, 0x26520001, 0x242102b, 0x1440fff5, 0x26100008, 0x3c040001, 0x972021, 0x8c8483b4, 0x24050008, -0x420c0, 0x2484777c, 0xc00248c, 0x2e42021, +0x420c0, 0x2484777c, 0xc002488, 0x2e42021, 0x8001e83, 0x3c020800, 0x2c820080, 0x1440ffcf, 0x428c0, 0x3c020800, 0x34422000, 0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, 0x304a00ff, @@ -1003,14 +1012,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, 0x24020001, 0x10620022, -0x0, 0x3c040001, 0x24844b60, 0xafa00010, +0x0, 0x3c040001, 0x24844b70, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, -0xc002407, 0x34a5f011, 0x8001f93, 0x0, -0x3c040001, 0x24844b6c, 0xafa00014, 0x8f860120, -0x8f870124, 0x3c050009, 0xc002407, 0x34a5f010, -0x8001f93, 0x0, 0x3c040001, 0x24844b78, +0xc002403, 0x34a5f011, 0x8001f93, 0x0, +0x3c040001, 0x24844b7c, 0xafa00014, 0x8f860120, +0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010, +0x8001f93, 0x0, 0x3c040001, 0x24844b88, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002407, 0x34a5f00f, 0x8ee201ac, 0x24420001, +0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20128, 0x24420001, 0xaee20128, 0x8ee20128, 0x8ee20164, 0x24420001, 0xaee20164, 0x80022e8, 0x8ee20164, 0x8fa20020, @@ -1020,8 +1029,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f820228, 0xaee204dc, 0x2402ffff, 0xaf820228, 0x24020001, 0x8001fbe, 0xa2e204d8, 0x92e204d8, 0x5040000c, 0xa2e004d8, 0x8ee204dc, 0xaf820228, -0x8001fbe, 0xa2e004d8, 0x3c040001, 0x24844b98, -0xafa00014, 0x8fa60020, 0x3c050003, 0xc002407, +0x8001fbe, 0xa2e004d8, 0x3c040001, 0x24844ba8, +0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403, 0x34a5f009, 0x8ee2013c, 0x24420001, 0xaee2013c, 0x80022e8, 0x8ee2013c, 0x8fa20020, 0x21200, 0x22502, 0x24020001, 0x10820005, 0x24020002, @@ -1031,8 +1040,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x370821, 0xa02283b2, 0x8001fea, 0xaee40108, 0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024, 0xaf820220, 0x3c010001, 0x370821, 0xa02083b2, -0x8001fea, 0xaee40108, 0x3c040001, 0x24844ba4, -0xafa00014, 0x8fa60020, 0x3c050003, 0xc002407, +0x8001fea, 0xaee40108, 0x3c040001, 0x24844bb4, +0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403, 0x34a5f00a, 0x8ee2012c, 0x24420001, 0xaee2012c, 0x80022e8, 0x8ee2012c, 0x8fa20020, 0x21200, 0x21d02, 0x24020001, 0x10620005, 0x24020002, @@ -1043,27 +1052,27 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x571021, 0x904283b2, 0x3c010001, 0x370821, 0x1440000e, 0xa02083b3, 0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024, 0x8002018, 0xaf820220, -0x3c040001, 0x24844bb0, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002407, 0x34a5f00b, 0x8ee20114, +0x3c040001, 0x24844bc0, 0xafa00014, 0x8fa60020, +0x3c050003, 0xc002403, 0x34a5f00b, 0x8ee20114, 0x24420001, 0xaee20114, 0x80022e8, 0x8ee20114, -0x27840208, 0x27450200, 0xc00249e, 0x24060008, -0x26e40094, 0x27450200, 0xc00249e, 0x24060008, +0x27840208, 0x27450200, 0xc00249a, 0x24060008, +0x26e40094, 0x27450200, 0xc00249a, 0x24060008, 0x8ee20134, 0x24420001, 0xaee20134, 0x80022e8, -0x8ee20134, 0x8f460248, 0x2021, 0xc004fa4, +0x8ee20134, 0x8f460248, 0x2021, 0xc004fa8, 0x24050004, 0x8ee20130, 0x24420001, 0xaee20130, 0x80022e8, 0x8ee20130, 0x8ef301cc, 0x8ef401d0, 0x8ef501d8, 0x8ee20140, 0x26e40030, 0x24420001, 0xaee20140, 0x8ef00140, 0x8ef10074, 0x8ef20070, -0xc00248c, 0x24050400, 0xaef301cc, 0xaef401d0, +0xc002488, 0x24050400, 0xaef301cc, 0xaef401d0, 0xaef501d8, 0xaef00140, 0xaef10074, 0xaef20070, 0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, 0x27450200, 0x24060008, 0xaee20068, 0x24020006, -0xc00249e, 0xaee20064, 0x3c023b9a, 0x3442ca00, +0xc00249a, 0xaee20064, 0x3c023b9a, 0x3442ca00, 0xaee2006c, 0x240203e8, 0x24040002, 0x24030001, 0xaee20104, 0xaee40100, 0xaee3010c, 0x8f820220, 0x30420008, 0x10400004, 0x0, 0xaee30108, 0x8002061, 0x2021, 0xaee40108, 0x2021, -0x3c030001, 0x641821, 0x906353e0, 0x2e41021, +0x3c030001, 0x641821, 0x906353f0, 0x2e41021, 0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8, 0x0, 0x8f820040, 0x2e41821, 0x24840001, 0x21702, 0x24420030, 0xa062009c, 0x2e41021, @@ -1143,24 +1152,24 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, 0x24020001, -0x10620022, 0x0, 0x3c040001, 0x24844b60, +0x10620022, 0x0, 0x3c040001, 0x24844b70, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002407, 0x34a5f011, 0x80021c4, -0x0, 0x3c040001, 0x24844b6c, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002407, +0x3c050009, 0xc002403, 0x34a5f011, 0x80021c4, +0x0, 0x3c040001, 0x24844b7c, 0xafa00014, +0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010, 0x80021c4, 0x0, 0x3c040001, -0x24844b78, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f00f, 0x8ee201ac, +0x24844b88, 0xafa00014, 0x8ee60608, 0x8f470228, +0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20120, 0x24420001, 0xaee20120, 0x8ee20120, 0x8ee20168, 0x24420001, 0xaee20168, 0x80022e8, 0x8ee20168, 0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, -0x27450200, 0x24060008, 0xc00249e, 0xaee20068, +0x27450200, 0x24060008, 0xc00249a, 0xaee20068, 0x8f820220, 0x30420008, 0x14400002, 0x24020001, 0x24020002, 0xaee20108, 0x8ee2011c, 0x24420001, 0xaee2011c, 0x80022e8, 0x8ee2011c, 0x3c040001, -0x24844bbc, 0xafa00010, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002407, 0x34a5f00f, 0x93a20020, +0x24844bcc, 0xafa00010, 0xafa00014, 0x8fa60020, +0x3c050003, 0xc002403, 0x34a5f00f, 0x93a20020, 0x3c030700, 0x34631000, 0x431025, 0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, 0x304900ff, 0x512300e2, 0xafa00010, 0x8ee20608, 0x210c0, @@ -1190,9 +1199,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, -0x54e0000c, 0xaee90608, 0x3c040001, 0x24844bc4, +0x54e0000c, 0xaee90608, 0x3c040001, 0x24844bd4, 0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f000, 0x80022e0, +0x3c050009, 0xc002403, 0x34a5f000, 0x80022e0, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, @@ -1216,12 +1225,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x14e0001b, -0x0, 0x3c040001, 0x24844bcc, 0xafa00010, +0x0, 0x3c040001, 0x24844bdc, 0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002407, 0x34a5f001, 0x8ee201b0, 0x24420001, +0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, 0x80022e0, 0x8ee201b0, 0x3c040001, -0x24844bd8, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002407, 0x34a5f005, 0x8ee201ac, +0x24844be8, 0xafa00014, 0x8ee60608, 0x8f470228, +0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20150, 0x24420001, 0xaee20150, 0x8ee20150, 0x8ee20160, 0x24420001, 0xaee20160, 0x8ee20160, 0x8f43022c, @@ -1237,7 +1246,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24c60001, 0x2cc20008, 0x1440fff7, 0x73842, 0x25290001, 0x125102b, 0x1440fff0, 0x0, 0x1001021, 0x3e00008, 0x27bd0008, 0x27bdffe8, -0x27642800, 0xafbf0010, 0xc00248c, 0x24051000, +0x27642800, 0xafbf0010, 0xc002488, 0x24051000, 0x24020021, 0xaf800100, 0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114, 0xaf800118, 0xaf800120, 0xaf800124, 0xaf800128, 0xaf800130, 0xaf800134, @@ -1247,32 +1256,31 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf82011c, 0x8fbf0010, 0x3e00008, 0x27bd0018, 0x27bdffe0, 0xafbf0018, 0x8f820104, 0xafa20010, 0x8f820100, 0x3c050002, 0xafa20014, 0x8f8600b0, -0x8f87011c, 0x3c040001, 0x24844c8c, 0xc002407, +0x8f87011c, 0x3c040001, 0x24844ca0, 0xc002403, 0x34a5f000, 0x8f8300b0, 0x3c027f00, 0x621824, -0x3c020400, 0x1062002b, 0x43102b, 0x14400008, -0x3c022000, 0x3c020100, 0x10620026, 0x3c020200, -0x10620013, 0x0, 0x8002376, 0x0, -0x1062000a, 0x43102b, 0x1040001e, 0x3c024000, -0x1462001c, 0x0, 0x8ee20190, 0x24420001, -0xaee20190, 0x8002376, 0x8ee20190, 0x8ee2018c, -0x24420001, 0xaee2018c, 0x8002376, 0x8ee2018c, -0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104, -0x8f8200b0, 0x34420001, 0xaf8200b0, 0xaf830104, -0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, -0x8ee201a0, 0x24420001, 0xaee201a0, 0x8002379, -0x8ee201a0, 0x8f8200b0, 0x34420001, 0xaf8200b0, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0, -0xafbf001c, 0xafb00018, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c050001, 0xafa20014, 0x8f8600a0, -0x8f87011c, 0x3c040001, 0x24844c98, 0xc002407, -0x34a5f000, 0x8f8300a0, 0x3c027f00, 0x621824, -0x3c020400, 0x10620055, 0x8021, 0x43102b, -0x14400008, 0x3c042000, 0x3c020100, 0x1062004f, -0x3c020200, 0x1062003c, 0x0, 0x80023e4, -0x0, 0x10640005, 0x83102b, 0x10400047, +0x3c020400, 0x10620029, 0x43102b, 0x14400008, +0x3c022000, 0x3c020100, 0x10620024, 0x3c020200, +0x10620011, 0x0, 0x8002374, 0x0, +0x10620008, 0x3c024000, 0x1462001c, 0x0, +0x8ee20190, 0x24420001, 0xaee20190, 0x8002374, +0x8ee20190, 0x8ee2018c, 0x24420001, 0xaee2018c, +0x8002374, 0x8ee2018c, 0x8f82011c, 0x34420002, +0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001, +0xaf8200b0, 0xaf830104, 0x8f82011c, 0x2403fffd, +0x431024, 0xaf82011c, 0x8ee201a0, 0x24420001, +0xaee201a0, 0x8002377, 0x8ee201a0, 0x8f8200b0, +0x34420001, 0xaf8200b0, 0x8fbf0018, 0x3e00008, +0x27bd0020, 0x27bdffe0, 0xafbf001c, 0xafb00018, +0x8f820120, 0xafa20010, 0x8f820124, 0x3c050001, +0xafa20014, 0x8f8600a0, 0x8f87011c, 0x3c040001, +0x24844cac, 0xc002403, 0x34a5f000, 0x8f8300a0, +0x3c027f00, 0x621824, 0x3c020400, 0x10620053, +0x8021, 0x43102b, 0x14400008, 0x3c042000, +0x3c020100, 0x1062004d, 0x3c020200, 0x1062003a, +0x0, 0x80023e0, 0x0, 0x10640003, 0x3c024000, 0x14620045, 0x0, 0x8f8200a0, 0x441024, 0x10400006, 0x0, 0x8ee20194, -0x24420001, 0xaee20194, 0x80023ad, 0x8ee20194, +0x24420001, 0xaee20194, 0x80023a9, 0x8ee20194, 0x8ee20198, 0x24420001, 0xaee20198, 0x8ee20198, 0x8f82011c, 0x34420002, 0xaf82011c, 0x8f82011c, 0x30420200, 0x1040001b, 0x0, 0x8f8300a0, @@ -1281,52 +1289,52 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24100001, 0x24020001, 0x1200000d, 0xaf8200a0, 0x8f820124, 0x2442ffe0, 0xaf820124, 0x8f820124, 0x8f820124, 0x27633000, 0x43102b, 0x10400005, -0x276237e0, 0xaf820124, 0x80023ce, 0x0, +0x276237e0, 0xaf820124, 0x80023ca, 0x0, 0xaf840124, 0x8f82011c, 0x2403fffd, 0x431024, -0x80023e7, 0xaf82011c, 0x8f82011c, 0x34420002, +0x80023e3, 0xaf82011c, 0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001, 0xaf8200a0, 0xaf830124, 0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ee2019c, 0x24420001, -0xaee2019c, 0x80023e7, 0x8ee2019c, 0x8f8200a0, +0xaee2019c, 0x80023e3, 0x8ee2019c, 0x8f8200a0, 0x34420001, 0xaf8200a0, 0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, 0x0, 0x3c020001, -0x8c425408, 0x27bdffe8, 0xafbf0014, 0x14400012, -0xafb00010, 0x3c100001, 0x26105550, 0x2002021, -0xc00248c, 0x24052000, 0x26021fe0, 0x3c010001, -0xac225524, 0x3c010001, 0xac225520, 0xaf420250, +0x8c425418, 0x27bdffe8, 0xafbf0014, 0x14400012, +0xafb00010, 0x3c100001, 0x26105560, 0x2002021, +0xc002488, 0x24052000, 0x26021fe0, 0x3c010001, +0xac225534, 0x3c010001, 0xac225530, 0xaf420250, 0x24022000, 0xaf500254, 0xaf420258, 0x24020001, -0x3c010001, 0xac225408, 0x8fbf0014, 0x8fb00010, -0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635524, +0x3c010001, 0xac225418, 0x8fbf0014, 0x8fb00010, +0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635534, 0x8c820000, 0x8fa80010, 0x8fa90014, 0xac620000, -0x3c020001, 0x8c425524, 0x8c830004, 0xac430004, +0x3c020001, 0x8c425534, 0x8c830004, 0xac430004, 0xac450008, 0x8f840054, 0x2443ffe0, 0xac460010, 0xac470014, 0xac480018, 0xac49001c, 0x3c010001, -0xac235524, 0xac44000c, 0x3c020001, 0x24425550, +0xac235534, 0xac44000c, 0x3c020001, 0x24425560, 0x62182b, 0x10600005, 0x0, 0x3c020001, -0x8c425520, 0x3c010001, 0xac225524, 0x3c030001, -0x8c635524, 0x3c020001, 0x8c4253f0, 0xac620000, -0x3c030001, 0x8c635524, 0x3c020001, 0x8c4253f0, +0x8c425530, 0x3c010001, 0xac225534, 0x3c030001, +0x8c635534, 0x3c020001, 0x8c425400, 0xac620000, +0x3c030001, 0x8c635534, 0x3c020001, 0x8c425400, 0xac620004, 0x3e00008, 0xaf430250, 0x3c030001, -0x8c635524, 0x3c020001, 0x8c4253f0, 0x27bdffd0, +0x8c635534, 0x3c020001, 0x8c425400, 0x27bdffd0, 0xafb40020, 0x8fb40040, 0xafb00010, 0x808021, 0xafb50024, 0x8fb50044, 0x8fa40048, 0xafb10014, 0xa08821, 0xafbf0028, 0xafb3001c, 0xafb20018, -0xac620000, 0x3c050001, 0x8ca55524, 0x3c020001, -0x8c4253f0, 0xc09021, 0xe09821, 0x10800006, -0xaca20004, 0x24a50008, 0xc002494, 0x24060018, -0x8002452, 0x0, 0x24a40008, 0xc00248c, -0x24050018, 0x3c020001, 0x8c425524, 0x3c050001, -0x24a55550, 0x2442ffe0, 0x3c010001, 0xac225524, +0xac620000, 0x3c050001, 0x8ca55534, 0x3c020001, +0x8c425400, 0xc09021, 0xe09821, 0x10800006, +0xaca20004, 0x24a50008, 0xc002490, 0x24060018, +0x800244e, 0x0, 0x24a40008, 0xc002488, +0x24050018, 0x3c020001, 0x8c425534, 0x3c050001, +0x24a55560, 0x2442ffe0, 0x3c010001, 0xac225534, 0x45102b, 0x10400005, 0x0, 0x3c020001, -0x8c425520, 0x3c010001, 0xac225524, 0x3c030001, -0x8c635524, 0x8e020000, 0xac620000, 0x3c030001, -0x8c635524, 0x8e020004, 0xac620004, 0xac710008, -0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225524, +0x8c425530, 0x3c010001, 0xac225534, 0x3c030001, +0x8c635534, 0x8e020000, 0xac620000, 0x3c030001, +0x8c635534, 0x8e020004, 0xac620004, 0xac710008, +0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225534, 0x45102b, 0xac720010, 0xac730014, 0xac740018, 0xac75001c, 0x10400005, 0xac64000c, 0x3c020001, -0x8c425520, 0x3c010001, 0xac225524, 0x3c030001, -0x8c635524, 0x3c020001, 0x8c4253f0, 0xac620000, -0x3c030001, 0x8c635524, 0x3c020001, 0x8c4253f0, +0x8c425530, 0x3c010001, 0xac225534, 0x3c030001, +0x8c635534, 0x3c020001, 0x8c425400, 0xac620000, +0x3c030001, 0x8c635534, 0x3c020001, 0x8c425400, 0xac620004, 0xaf430250, 0x8fbf0028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0030, 0x10a00005, @@ -1347,13 +1355,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3c030001, 0x431021, 0xaee2726c, 0x8ee2725c, 0x8ee3726c, 0x441021, 0x62182b, 0x10600006, 0x31a20004, 0x8ee201b8, 0x24420001, 0xaee201b8, -0x80028e5, 0x8ee201b8, 0x10400240, 0x31a20200, +0x80028e1, 0x8ee201b8, 0x10400240, 0x31a20200, 0x1040014d, 0x4821, 0x96e2045a, 0x30420010, 0x10400149, 0x0, 0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x10a20004, 0x0, 0x8f820104, 0x14a20006, 0x2402000c, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x8002530, 0x8ee201a8, 0xac8a0000, +0xaee201a8, 0x800252c, 0x8ee201a8, 0xac8a0000, 0xac8b0004, 0x8ee37264, 0x24060005, 0xa482000e, 0xac860018, 0xac830008, 0x8ee204e4, 0xac82001c, 0x8ee204c8, 0xac820010, 0xaf850100, 0x92e204ec, @@ -1363,17 +1371,17 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, -0x0, 0x800251a, 0x0, 0x14a00005, +0x0, 0x8002516, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x8002530, 0x0, 0x8ee24e28, +0xac800000, 0x800252c, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x3c040001, 0xafab0010, 0x8ee27264, 0x3c040001, -0x24844f00, 0x3c050004, 0xafa20014, 0x8ee604e4, -0x80028c2, 0x34a5f114, 0x8ee27264, 0x34843800, +0x24844f10, 0x3c050004, 0xafa20014, 0x8ee604e4, +0x80028be, 0x34a5f114, 0x8ee27264, 0x34843800, 0x3641821, 0x24420010, 0x43102b, 0x14400073, 0x0, 0x8ee27264, 0x24480010, 0x3641021, 0x102102b, 0x14400002, 0x3c02ffff, 0x1024021, @@ -1381,7 +1389,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50400001, 0x27662800, 0x8f820108, 0x10c20004, 0x0, 0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8, -0x80025a4, 0x8ee201a8, 0x2c64000c, 0x1441021, +0x80025a0, 0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca80008, 0xaca20018, 0x8ee204e4, 0xaca2001c, 0x8ee204c8, 0x3c030002, 0x431025, @@ -1392,22 +1400,22 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, -0x0, 0x800258e, 0x0, 0x14a00005, +0x0, 0x800258a, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x80025a4, 0x0, 0x8ee24e28, +0xac800000, 0x80025a0, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010, 0x8ee27264, 0x3c040001, -0x24844f00, 0x3c050004, 0xafa20014, 0x8ee604e4, -0x80028c2, 0x34a5f125, 0x34028100, 0xa5020000, -0x9582000e, 0x8002621, 0xa5020002, 0x8f850100, +0x24844f10, 0x3c050004, 0xafa20014, 0x8ee604e4, +0x80028be, 0x34a5f125, 0x34028100, 0xa5020000, +0x9582000e, 0x800261d, 0xa5020002, 0x8f850100, 0x27623000, 0x24a60020, 0xc2102b, 0x50400001, 0x27662800, 0x8f820108, 0x10c20004, 0x0, 0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8, -0x4821, 0x24420001, 0xaee201a8, 0x8002611, +0x4821, 0x24420001, 0xaee201a8, 0x800260d, 0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, 0x8ee37264, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca20018, 0x24630010, 0xaca30008, @@ -1419,23 +1427,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, -0x10a20005, 0x0, 0x80025fb, 0x0, +0x10a20005, 0x0, 0x80025f7, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x8002611, 0x0, +0x50400013, 0xac800000, 0x800260d, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x34028100, 0xafab0010, 0x8ee27264, -0x3c040001, 0x24844f00, 0x3c050004, 0xafa20014, -0x8ee604e4, 0x80028c2, 0x34a5f015, 0x8ee37264, +0x3c040001, 0x24844f10, 0x3c050004, 0xafa20014, +0x8ee604e4, 0x80028be, 0x34a5f015, 0x8ee37264, 0xa462000c, 0x8ee37264, 0x9582000e, 0xa462000e, -0x8002685, 0x24e70004, 0x8f840100, 0x27623000, +0x8002681, 0x24e70004, 0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x10a20004, 0x0, 0x8f820104, 0x14a20007, 0x24020006, 0x8ee201a8, 0x4821, -0x24420001, 0xaee201a8, 0x800267b, 0x8ee201a8, +0x24420001, 0xaee201a8, 0x8002677, 0x8ee201a8, 0xac8a0000, 0xac8b0004, 0x8ee37264, 0xa487000e, 0xac820018, 0xac830008, 0x8ee204e4, 0xac82001c, 0x8ee204c8, 0x3c030002, 0x431025, 0xac820010, @@ -1446,16 +1454,16 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x8002665, 0x0, 0x14a00005, 0x0, +0x8002661, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x800267b, 0x0, 0x8ee24e28, 0x24030040, +0x8002677, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x15200009, 0x3c050004, -0xafab0010, 0x8ee27264, 0x3c040001, 0x24844f00, -0xafa20014, 0x8ee604e4, 0x80028c2, 0x34a5f004, +0xafab0010, 0x8ee27264, 0x3c040001, 0x24844f10, +0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f004, 0x8ee2725c, 0x30e7ffff, 0x471021, 0xaee2725c, 0x8ee204e4, 0x8ee304fc, 0x8ee47258, 0x21100, 0x431021, 0xac44000c, 0x8ee27258, 0xafa20018, @@ -1470,34 +1478,34 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee27264, 0x8f8200f0, 0x24470008, 0x27621800, 0xe2102b, 0x50400001, 0x27671000, 0x8f8200f4, 0x14e20007, 0x0, 0x8ee201b4, 0x4821, -0x24420001, 0xaee201b4, 0x80026c8, 0x8ee201b4, +0x24420001, 0xaee201b4, 0x80026c4, 0x8ee201b4, 0x8f8200f0, 0x24090001, 0x8fa30018, 0x8fa4001c, 0xac430000, 0xac440004, 0xaf8700f0, 0x15200012, 0xd1142, 0x8f8200f0, 0xafa20010, 0x8f8200f4, -0x3c040001, 0x24844f0c, 0xafa20014, 0x8fa60018, -0x8fa7001c, 0x3c050004, 0xc002407, 0x34a5f005, +0x3c040001, 0x24844f1c, 0xafa20014, 0x8fa60018, +0x8fa7001c, 0x3c050004, 0xc002403, 0x34a5f005, 0x8ee20088, 0x24420001, 0xaee20088, 0x8ee20088, -0x80028d7, 0xaee0725c, 0x30430003, 0x24020002, +0x80028d3, 0xaee0725c, 0x30430003, 0x24020002, 0x10620016, 0x28620003, 0x10400005, 0x24020001, -0x10620008, 0x0, 0x8002707, 0x0, -0x24020003, 0x10620017, 0x0, 0x8002707, +0x10620008, 0x0, 0x8002703, 0x0, +0x24020003, 0x10620017, 0x0, 0x8002703, 0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001, 0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, -0x8ee200e8, 0x8002707, 0x8ee300ec, 0x8ee200f0, +0x8ee200e8, 0x8002703, 0x8ee300ec, 0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, -0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002707, +0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002703, 0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, 0x8ee200f8, 0x8ee300fc, 0x8ee2725c, 0x8ee400e0, 0x8ee500e4, 0x401821, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400e0, -0xaee500e4, 0x80028d7, 0xaee0725c, 0x30e2ffff, +0xaee500e4, 0x80028d3, 0xaee0725c, 0x30e2ffff, 0x104001c1, 0x31a20200, 0x1040014d, 0x4821, 0x96e2045a, 0x30420010, 0x10400149, 0x0, 0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x10a20004, 0x0, 0x8f820104, 0x14a20006, 0x2402000c, -0x8ee201a8, 0x24420001, 0xaee201a8, 0x8002772, +0x8ee201a8, 0x24420001, 0xaee201a8, 0x800276e, 0x8ee201a8, 0xac8a0000, 0xac8b0004, 0x8ee37264, 0x24060005, 0xa482000e, 0xac860018, 0xac830008, 0x8ee204e4, 0xac82001c, 0x8ee204c8, 0xac820010, @@ -1507,17 +1515,17 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x800275c, +0x24420001, 0x10a20005, 0x0, 0x8002758, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002772, +0x2c420011, 0x50400013, 0xac800000, 0x800276e, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x3c040001, 0xafab0010, -0x8ee27264, 0x3c040001, 0x24844f00, 0x3c050004, -0xafa20014, 0x8ee604e4, 0x80028c2, 0x34a5f014, +0x8ee27264, 0x3c040001, 0x24844f10, 0x3c050004, +0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f014, 0x8ee27264, 0x34843800, 0x3641821, 0x24420010, 0x43102b, 0x14400073, 0x0, 0x8ee27264, 0x24480010, 0x3641021, 0x102102b, 0x14400002, @@ -1525,7 +1533,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24a60020, 0xc2102b, 0x50400001, 0x27662800, 0x8f820108, 0x10c20004, 0x0, 0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8, 0x4821, -0x24420001, 0xaee201a8, 0x80027e6, 0x8ee201a8, +0x24420001, 0xaee201a8, 0x80027e2, 0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca80008, 0xaca20018, 0x8ee204e4, 0xaca2001c, 0x8ee204c8, @@ -1536,23 +1544,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x80027d0, +0x24420001, 0x10a20005, 0x0, 0x80027cc, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x80027e6, +0x2c420011, 0x50400013, 0xac800000, 0x80027e2, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010, -0x8ee27264, 0x3c040001, 0x24844f00, 0x3c050004, -0xafa20014, 0x8ee604e4, 0x80028c2, 0x34a5f015, -0x34028100, 0xa5020000, 0x9582000e, 0x8002863, +0x8ee27264, 0x3c040001, 0x24844f10, 0x3c050004, +0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f015, +0x34028100, 0xa5020000, 0x9582000e, 0x800285f, 0xa5020002, 0x8f850100, 0x27623000, 0x24a60020, 0xc2102b, 0x50400001, 0x27662800, 0x8f820108, 0x10c20004, 0x0, 0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8, 0x4821, 0x24420001, -0xaee201a8, 0x8002853, 0x8ee201a8, 0x2c64000c, +0xaee201a8, 0x800284f, 0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, 0x8ee37264, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca20018, 0x24630010, 0xaca30008, 0x8ee204e4, 0xaca2001c, @@ -1564,23 +1572,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x800283d, 0x0, 0x14a00005, 0x0, +0x8002839, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8002853, 0x0, 0x8ee24e28, 0x24030040, +0x800284f, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x34028100, -0xafab0010, 0x8ee27264, 0x3c040001, 0x24844f00, -0x3c050004, 0xafa20014, 0x8ee604e4, 0x80028c2, +0xafab0010, 0x8ee27264, 0x3c040001, 0x24844f10, +0x3c050004, 0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f016, 0x8ee37264, 0xa462000c, 0x8ee37264, -0x9582000e, 0xa462000e, 0x80028c6, 0x24e70004, +0x9582000e, 0xa462000e, 0x80028c2, 0x24e70004, 0x8f830100, 0x27623000, 0x24640020, 0x82102b, 0x50400001, 0x27642800, 0x8f820108, 0x10820004, 0x0, 0x8f820104, 0x14820007, 0x24050005, 0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8, -0x80028ba, 0x8ee201a8, 0xac6a0000, 0xac6b0004, +0x80028b6, 0x8ee201a8, 0xac6a0000, 0xac6b0004, 0x8ee27264, 0xa467000e, 0xac650018, 0xac620008, 0x8ee204e4, 0xac62001c, 0x8ee204c8, 0xac620010, 0xaf840100, 0x92e204ec, 0x14400036, 0x24090001, @@ -1589,17 +1597,17 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x80028a4, +0x24420001, 0x10a20005, 0x0, 0x80028a0, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x80028ba, +0x2c420011, 0x50400013, 0xac800000, 0x80028b6, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000b, 0x3c050004, 0x3c040001, -0x24844f18, 0xafab0010, 0xafa00014, 0x8ee604e4, -0x34a5f017, 0xc002407, 0x30e7ffff, 0x80028e5, +0x24844f28, 0xafab0010, 0xafa00014, 0x8ee604e4, +0x34a5f017, 0xc002403, 0x30e7ffff, 0x80028e1, 0x0, 0x8ee27264, 0x3c050001, 0x30e4ffff, 0x441021, 0xaee27264, 0x8ee2725c, 0x8ee37264, 0x34a53800, 0x441021, 0xaee2725c, 0x3651021, @@ -1620,14 +1628,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaee27264, 0x8ee37264, 0x42400, 0x3651021, 0x3c010001, 0x370821, 0xac2483dc, 0x62182b, 0x14600005, 0x24e70004, 0x8ee27264, 0x3c03ffff, -0x431021, 0xaee27264, 0x8ee27264, 0x800291b, +0x431021, 0xaee27264, 0x8ee27264, 0x8002917, 0xaee27258, 0x8ee604c8, 0x8ee2726c, 0x30e4ffff, 0x44102a, 0x10400015, 0x0, 0x8f8200d8, 0x8ee37258, 0x431023, 0xaee2726c, 0x8ee2726c, 0x1c400007, 0x44102a, 0x8ee2726c, 0x3c030001, 0x431021, 0xaee2726c, 0x8ee2726c, 0x44102a, 0x10400006, 0x0, 0x8ee201b8, 0x24420001, -0xaee201b8, 0x8002a76, 0x8ee201b8, 0x3c020001, +0xaee201b8, 0x8002a72, 0x8ee201b8, 0x3c020001, 0x571021, 0x8c4283d8, 0x54400001, 0x24e7fffc, 0x31420004, 0x104000b9, 0x30e2ffff, 0x3c020001, 0x571021, 0x8c4283d8, 0x1040002f, 0x5021, @@ -1642,11 +1650,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e21821, 0x24020015, 0xac620000, 0x24020001, -0x80029c3, 0xac620004, 0x8f840100, 0x27623000, +0x80029bf, 0xac620004, 0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x10a20004, 0x0, 0x8f820104, 0x14a20006, 0x24020006, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x80029c3, 0x8ee201a8, 0xac880000, +0xaee201a8, 0x80029bf, 0x8ee201a8, 0xac880000, 0xac890004, 0x8ee37264, 0xa487000e, 0xac820018, 0xac830008, 0x8ee204e8, 0xac860010, 0xac82001c, 0xaf850100, 0x92e204ec, 0x14400037, 0x240a0001, @@ -1656,16 +1664,16 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x80029ad, 0x0, 0x14a00005, 0x0, +0x80029a9, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x80029c3, 0x0, 0x8ee24e28, 0x24030040, +0x80029bf, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1540000a, 0x24020001, -0xafa90010, 0x8ee27264, 0x3c040001, 0x24844f00, -0x3c050004, 0xafa20014, 0x8ee604e4, 0x8002a53, +0xafa90010, 0x8ee27264, 0x3c040001, 0x24844f10, +0x3c050004, 0xafa20014, 0x8ee604e4, 0x8002a4f, 0x34a5f204, 0xa2e204ed, 0x8ee204e8, 0x8ee304fc, 0x8ee47258, 0x3c060001, 0x34c63800, 0x3c010001, 0x370821, 0xac2083d8, 0x3c010001, 0x370821, @@ -1675,12 +1683,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee2726c, 0x8ee47258, 0x651824, 0x431023, 0xaee2726c, 0x3661021, 0x82202b, 0x14800004, 0x3c03ffff, 0x8ee27258, 0x431021, 0xaee27258, -0x8ee27258, 0x8002a68, 0xaee27264, 0x10400073, +0x8ee27258, 0x8002a64, 0xaee27264, 0x10400073, 0x0, 0x8f830100, 0x27623000, 0x24640020, 0x82102b, 0x14400002, 0x5021, 0x27642800, 0x8f820108, 0x10820004, 0x0, 0x8f820104, 0x14820006, 0x24050005, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x8002a4a, 0x8ee201a8, 0xac680000, +0xaee201a8, 0x8002a46, 0x8ee201a8, 0xac680000, 0xac690004, 0x8ee27264, 0xa467000e, 0xac650018, 0xac620008, 0x8ee204e8, 0xac660010, 0xac62001c, 0xaf840100, 0x92e204ec, 0x14400036, 0x240a0001, @@ -1689,18 +1697,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x8002a34, +0x24420001, 0x10a20005, 0x0, 0x8002a30, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002a4a, +0x2c420011, 0x50400013, 0xac800000, 0x8002a46, 0x0, 0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1540000c, 0x30e5ffff, 0x3c040001, -0x24844f18, 0x3c050004, 0xafa90010, 0xafa00014, -0x8ee604e4, 0x34a5f237, 0xc002407, 0x30e7ffff, -0x8002a76, 0x0, 0x8ee27264, 0x451021, +0x24844f28, 0x3c050004, 0xafa90010, 0xafa00014, +0x8ee604e4, 0x34a5f237, 0xc002403, 0x30e7ffff, +0x8002a72, 0x0, 0x8ee27264, 0x451021, 0xaee27264, 0x8ee2726c, 0x8ee37264, 0x3c040001, 0x34843800, 0xa2e004ed, 0x451023, 0xaee2726c, 0x3641021, 0x62182b, 0x14600004, 0x3c03ffff, @@ -1715,21 +1723,21 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420001, 0xaee24e2c, 0x8ee24e2c, 0x8ee34e2c, 0x210c0, 0x24424e38, 0x2e22021, 0x8ee24e28, 0x8c870004, 0x14620007, 0xa03021, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8002aa6, +0x24420020, 0xaf820108, 0x8f820108, 0x8002aa2, 0xac800000, 0x8ee24e2c, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e2c, 0x24420001, 0x210c0, 0x24424e38, 0x2e22021, 0x8c820004, 0x8f830108, 0x21140, 0x621821, 0xaf830108, 0xac800000, 0x8cc20018, 0x2443fffe, 0x2c620013, 0x104000c1, 0x31080, 0x3c010001, 0x220821, -0x8c224f40, 0x400008, 0x0, 0x8ee204f0, +0x8c224f50, 0x400008, 0x0, 0x8ee204f0, 0x471021, 0xaee204f0, 0x8ee204f0, 0x8f43023c, 0x43102b, 0x144000be, 0x0, 0x8ee304e4, 0x8ee204f8, 0x506200ba, 0xa2e004f4, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8002b16, +0x8021, 0x24420001, 0xaee201a4, 0x8002b12, 0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, @@ -1740,38 +1748,38 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007, 0x0, 0x8ee24e34, -0x24420001, 0x10a20005, 0x0, 0x8002b00, +0x24420001, 0x10a20005, 0x0, 0x8002afc, 0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002b16, +0x2c420011, 0x50400013, 0xac800000, 0x8002b12, 0x0, 0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600000b, 0x24100001, 0x8ee204e4, -0x3c040001, 0x24844f24, 0xafa00014, 0xafa20010, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002407, -0x34a5f006, 0x16000003, 0x24020001, 0x8002b75, +0x3c040001, 0x24844f34, 0xafa00014, 0xafa20010, +0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, +0x34a5f006, 0x16000003, 0x24020001, 0x8002b71, 0xa2e204f4, 0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170, 0x8ee204e4, 0xa2e004f4, 0xaee004f0, 0xaee204f8, 0x8f42023c, 0x50400045, 0xaee07274, 0x8ee20184, 0x24420001, 0xaee20184, 0x8ee20184, -0x8002b75, 0xaee07274, 0x8ee20504, 0x24030040, +0x8002b71, 0xaee07274, 0x8ee20504, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee20504, 0x24420001, 0xaee20504, 0x8ee20504, 0x8cc30018, 0x21080, 0x571021, 0x8c440508, 0x24020003, 0x1462000f, 0x0, 0x3c020001, 0x571021, 0x904283b1, 0x10400014, 0x0, 0x8ee201d0, 0x8ee35240, 0x441021, 0xaee201d0, 0x8ee201d8, -0x641821, 0x306300ff, 0x8002b5d, 0xaee35240, +0x641821, 0x306300ff, 0x8002b59, 0xaee35240, 0x8ee201cc, 0x8ee30e10, 0x441021, 0xaee201cc, 0x8ee201d8, 0x641821, 0x306301ff, 0xaee30e10, 0x441021, 0xaee201d8, 0x8ee20000, 0x34420040, -0x8002b75, 0xaee20000, 0x8ee2014c, 0x3c010001, +0x8002b71, 0xaee20000, 0x8ee2014c, 0x3c010001, 0x370821, 0xa02083e0, 0x24420001, 0xaee2014c, -0x8002b75, 0x8ee2014c, 0x94c7000e, 0x8cc2001c, -0x3c040001, 0x24844f30, 0xafa60014, 0xafa20010, -0x8cc60018, 0x3c050008, 0xc002407, 0x34a50910, +0x8002b71, 0x8ee2014c, 0x94c7000e, 0x8cc2001c, +0x3c040001, 0x24844f40, 0xafa60014, 0xafa20010, +0x8cc60018, 0x3c050008, 0xc002403, 0x34a50910, 0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, 0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb60058, 0xafb50054, 0xafb40050, 0xafb3004c, 0xafb20048, @@ -1779,7 +1787,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xafa00024, 0x106203e7, 0xafa0002c, 0x3c1e0001, 0x37de3800, 0x3c0bffff, 0x8f930108, 0x8e620018, 0x8f830104, 0x2443fffe, 0x2c620014, 0x104003cf, -0x31080, 0x3c010001, 0x220821, 0x8c224f90, +0x31080, 0x3c010001, 0x220821, 0x8c224fa0, 0x400008, 0x0, 0x9663000e, 0x8ee2725c, 0x8ee404f0, 0x431021, 0xaee2725c, 0x8e63001c, 0x96e20458, 0x24840001, 0xaee404f0, 0x24630001, @@ -1788,7 +1796,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8002c02, +0x8021, 0x24420001, 0xaee201a4, 0x8002bfe, 0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, @@ -1799,19 +1807,19 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e34, 0x1062001b, 0x240c0040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8002bec, +0x24420001, 0x10620005, 0x0, 0x8002be8, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002c02, +0x2c420011, 0x50400013, 0xac800000, 0x8002bfe, 0x0, 0x8ee24e30, 0x240c0040, 0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0x240c0001, 0xac820000, 0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204e4, -0x3c040001, 0x24844f24, 0xafa00014, 0xafa20010, +0x3c040001, 0x24844f34, 0xafa00014, 0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f006, -0xc002407, 0xafab0038, 0x8fab0038, 0x1200030a, -0x240c0001, 0x8002f1d, 0x0, 0x966c001c, +0xc002403, 0xafab0038, 0x8fab0038, 0x1200030a, +0x240c0001, 0x8002f19, 0x0, 0x966c001c, 0xafac002c, 0x9662001e, 0x3c0c8000, 0xafac0024, 0xae62001c, 0x8e75001c, 0x8ee204fc, 0x8ee404fc, 0x151900, 0x621021, 0x8c52000c, 0x92e27b98, @@ -1821,8 +1829,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8e63001c, 0x8ee204fc, 0x32100, 0x821021, 0x8c42000c, 0x37e1821, 0x24420022, 0x43102b, 0x1440000a, 0x24050014, 0x8ee204fc, 0x821021, -0x8c44000c, 0xafab0038, 0xc002f79, 0x2484000e, -0x8fab0038, 0x8002c56, 0x3050ffff, 0x8ee204fc, +0x8c44000c, 0xafab0038, 0xc002f75, 0x2484000e, +0x8fab0038, 0x8002c52, 0x3050ffff, 0x8ee204fc, 0x821021, 0x8c42000c, 0x9450000e, 0x94430010, 0x94440012, 0x94450014, 0x2038021, 0x2048021, 0x2058021, 0x94430016, 0x94440018, 0x9445001a, @@ -1833,7 +1841,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xa21021, 0x8c43000c, 0x3202ffff, 0x828021, 0x37e1021, 0x24630018, 0x62182b, 0x14600009, 0x0, 0x8ee204fc, 0xa21021, 0x8c43000c, -0x101027, 0x3c01ffff, 0x230821, 0x8002c73, +0x101027, 0x3c01ffff, 0x230821, 0x8002c6f, 0xa4220018, 0x8ee204fc, 0xa21021, 0x8c43000c, 0x101027, 0xa4620018, 0x96e2045a, 0x8821, 0x30420008, 0x14400063, 0xa021, 0x8e63001c, @@ -1851,7 +1859,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x94e20000, 0x24e70002, 0x2228821, 0x37e1021, 0xe2102b, 0x50400001, 0xeb3821, 0x94e20000, 0x24e70002, 0x2228821, 0x37e1021, 0xe2102b, -0x50400001, 0xeb3821, 0x94e20000, 0x8002cd4, +0x50400001, 0xeb3821, 0x94e20000, 0x8002cd0, 0x2228821, 0x8ee204fc, 0xc21021, 0x8c43000c, 0x8ee204fc, 0x94710010, 0x8ee304fc, 0xc21021, 0x8c44000c, 0xc31821, 0x8c62000c, 0x2634ffec, @@ -1867,8 +1875,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x240c0001, 0xa2ec7b98, 0xaef57b9c, 0xaef27ba4, 0x8ee304fc, 0x151100, 0x431021, 0x8c47000c, 0x37e1821, 0x24e2000e, 0x43102b, -0x14400008, 0xe02021, 0x2405000e, 0xc002f79, -0xafab0038, 0x3042ffff, 0x8fab0038, 0x8002d0d, +0x14400008, 0xe02021, 0x2405000e, 0xc002f75, +0xafab0038, 0x3042ffff, 0x8fab0038, 0x8002d09, 0x2028021, 0x94e60000, 0x24e70002, 0x94e50000, 0x24e70002, 0x94e30000, 0x24e70002, 0x94e20000, 0x24e70002, 0x94e40000, 0x24e70002, 0x2068021, @@ -1876,7 +1884,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x94e30002, 0x2048021, 0x2028021, 0x2038021, 0x101c02, 0x3202ffff, 0x628021, 0x101c02, 0x3202ffff, 0x8ee47b9c, 0x628021, 0x14950004, -0x3205ffff, 0x96620016, 0x8002d1b, 0x512021, +0x3205ffff, 0x96620016, 0x8002d17, 0x512021, 0x96620016, 0x542021, 0x41402, 0x3083ffff, 0x432021, 0x852023, 0x41402, 0x822021, 0x3084ffff, 0x50800001, 0x3404ffff, 0x8ee27ba4, @@ -1889,11 +1897,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3082ffff, 0x622021, 0x32c20100, 0x14400004, 0x41027, 0x92e27b98, 0x14400002, 0x41027, 0x3044ffff, 0x8ee27ba4, 0x3c01ffff, 0x220821, -0x8002d8e, 0xa4240028, 0x8ee27b9c, 0x12a20008, +0x8002d8a, 0xa4240028, 0x8ee27b9c, 0x12a20008, 0x32c20100, 0x8ee27ba4, 0x94420028, 0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x32c20100, 0x14400004, 0x41027, 0x92e27b98, 0x14400002, -0x41027, 0x3044ffff, 0x8ee27ba4, 0x8002d8e, +0x41027, 0x3044ffff, 0x8ee27ba4, 0x8002d8a, 0xa4440028, 0x1462002f, 0x37e1821, 0x8ee27ba4, 0x24420032, 0x43102b, 0x14400018, 0x0, 0x8ee27b9c, 0x12a2000a, 0x32c20100, 0x8ee27ba4, @@ -1901,7 +1909,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x41c02, 0x3082ffff, 0x622021, 0x32c20100, 0x14400004, 0x41027, 0x92e27b98, 0x14400002, 0x41027, 0x3044ffff, 0x8ee27ba4, 0x3c01ffff, -0x220821, 0x8002d8e, 0xa4240032, 0x8ee27b9c, +0x220821, 0x8002d8a, 0xa4240032, 0x8ee27b9c, 0x12a20008, 0x32c20100, 0x8ee27ba4, 0x94420032, 0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x32c20100, 0x14400004, 0x41027, 0x92e27b98, @@ -1914,7 +1922,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x37e1021, 0x62102b, 0x50400001, 0x6b1821, 0x8c620000, 0xac820000, 0x34028100, 0xa4620000, 0x24630002, 0x37e1021, 0x62102b, 0x50400001, -0x6b1821, 0x97ac002e, 0x8002db8, 0xa46c0000, +0x6b1821, 0x97ac002e, 0x8002db4, 0xa46c0000, 0x8e420004, 0x8e440008, 0xa6430008, 0x97ac002e, 0xa64c000a, 0xae420000, 0xae440004, 0x9662000e, 0x2652fffc, 0x24420004, 0xa662000e, 0x9662000e, @@ -1924,55 +1932,55 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xafa2001c, 0x32c20080, 0x1040000c, 0x32c20100, 0x8ee27ba8, 0x24430001, 0x210c0, 0x571021, 0xaee37ba8, 0x8fa30018, 0x8fa4001c, 0xac437bac, -0xac447bb0, 0x8002ea4, 0xaee0725c, 0x10400072, +0xac447bb0, 0x8002ea0, 0xaee0725c, 0x10400072, 0x0, 0x8ee27ba8, 0x24430001, 0x210c0, 0x571021, 0xaee37ba8, 0x8fa30018, 0x8fa4001c, 0xac437bac, 0xac447bb0, 0x8ee27ba8, 0x10400063, 0x4821, 0x5021, 0x8f8200f0, 0x24480008, 0x27621800, 0x102102b, 0x50400001, 0x27681000, 0x8f8200f4, 0x15020007, 0x0, 0x8ee201b4, -0x8021, 0x24420001, 0xaee201b4, 0x8002dfe, +0x8021, 0x24420001, 0xaee201b4, 0x8002dfa, 0x8ee201b4, 0x8f8300f0, 0x24100001, 0x1571021, 0x8c447bac, 0x8c457bb0, 0xac640000, 0xac650004, 0xaf8800f0, 0x16000006, 0x2ea1021, 0x8ee20088, -0x24420001, 0xaee20088, 0x8002e43, 0x8ee20088, +0x24420001, 0xaee20088, 0x8002e3f, 0x8ee20088, 0x8c427bb0, 0x8ee400e0, 0x8ee500e4, 0x8ee67b9c, 0x401821, 0x1021, 0xa32821, 0xa3382b, 0x822021, 0x872021, 0x8ee204fc, 0xc93021, 0x63100, 0xaee400e0, 0xaee500e4, 0xc23021, 0x94c2000a, 0x240c0002, 0x21142, 0x30430003, 0x106c0016, 0x28620003, 0x10400005, 0x240c0001, -0x106c0008, 0x0, 0x8002e43, 0x0, -0x240c0003, 0x106c0017, 0x0, 0x8002e43, +0x106c0008, 0x0, 0x8002e3f, 0x0, +0x240c0003, 0x106c0017, 0x0, 0x8002e3f, 0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001, 0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, -0x8ee200e8, 0x8002e43, 0x8ee300ec, 0x8ee200f0, +0x8ee200e8, 0x8002e3f, 0x8ee300ec, 0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, -0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002e43, +0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002e3f, 0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, 0x8ee200f8, 0x8ee300fc, 0x8ee27ba8, 0x25290001, 0x122102b, 0x1440ffa0, 0x254a0008, 0xa2e07b98, -0x8002ea3, 0xaee07ba8, 0x8f8200f0, 0x24470008, +0x8002e9f, 0xaee07ba8, 0x8f8200f0, 0x24470008, 0x27621800, 0xe2102b, 0x50400001, 0x27671000, 0x8f8200f4, 0x14e20007, 0x0, 0x8ee201b4, -0x8021, 0x24420001, 0xaee201b4, 0x8002e61, +0x8021, 0x24420001, 0xaee201b4, 0x8002e5d, 0x8ee201b4, 0x8f8200f0, 0x24100001, 0x8fa30018, 0x8fa4001c, 0xac430000, 0xac440004, 0xaf8700f0, 0x16000007, 0x0, 0x8ee20088, 0x24420001, -0xaee20088, 0x8ee20088, 0x8002ea4, 0xaee0725c, +0xaee20088, 0x8ee20088, 0x8002ea0, 0xaee0725c, 0x8ee2725c, 0x8ee400e0, 0x8ee500e4, 0x240c0002, 0x401821, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0x161142, 0x30430003, 0xaee400e0, 0xaee500e4, 0x106c0017, 0x2c620003, 0x10400005, 0x240c0001, 0x106c0008, 0x0, -0x8002ea4, 0xaee0725c, 0x240c0003, 0x106c0019, -0x0, 0x8002ea4, 0xaee0725c, 0x8ee200e8, +0x8002ea0, 0xaee0725c, 0x240c0003, 0x106c0019, +0x0, 0x8002ea0, 0xaee0725c, 0x8ee200e8, 0x8ee300ec, 0x24630001, 0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, 0x8ee200e8, 0x8ee300ec, -0x8002ea4, 0xaee0725c, 0x8ee200f0, 0x8ee300f4, +0x8002ea0, 0xaee0725c, 0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, 0xaee200f0, -0xaee300f4, 0x8ee200f0, 0x8ee300f4, 0x8002ea4, +0xaee300f4, 0x8ee200f0, 0x8ee300f4, 0x8002ea0, 0xaee0725c, 0x8ee200f8, 0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, 0x8ee200f8, 0x8ee300fc, 0xaee0725c, 0x8e62001c, @@ -1983,7 +1991,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8002f0b, 0x8ee201a4, 0x8ee204e4, 0xac62001c, +0x8002f07, 0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, @@ -1994,22 +2002,22 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8002ef5, 0x0, 0x14600005, 0x0, +0x8002ef1, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8002f0b, 0x0, 0x8ee24e30, 0x240c0040, +0x8002f07, 0x0, 0x8ee24e30, 0x240c0040, 0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020012, 0x240c0001, 0xac820000, 0xac8c0004, 0x5600000d, 0x24100001, -0x8ee204e4, 0x3c040001, 0x24844f24, 0xafa00014, +0x8ee204e4, 0x3c040001, 0x24844f34, 0xafa00014, 0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009, -0x34a5f006, 0xc002407, 0xafab0038, 0x8fab0038, -0x16000003, 0x240c0001, 0x8002f60, 0xa2ec04f4, +0x34a5f006, 0xc002403, 0xafab0038, 0x8fab0038, +0x16000003, 0x240c0001, 0x8002f5c, 0xa2ec04f4, 0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170, 0x8ee204e4, 0xa2e004f4, 0xaee004f0, 0xaee07274, 0xaee204f8, 0x8f42023c, 0x10400038, 0x0, -0x8ee20184, 0x24420001, 0xaee20184, 0x8002f60, +0x8ee20184, 0x24420001, 0xaee20184, 0x8002f5c, 0x8ee20184, 0x8ee20504, 0x240c0040, 0x24420001, 0x504c0003, 0x1021, 0x8ee20504, 0x24420001, 0xaee20504, 0x8ee20504, 0x8e630018, 0x240c0003, @@ -2017,10 +2025,10 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3c020001, 0x571021, 0x904283b1, 0x10400014, 0x0, 0x8ee201d0, 0x8ee35240, 0x441021, 0xaee201d0, 0x8ee201d8, 0x641821, 0x306300ff, -0x8002f53, 0xaee35240, 0x8ee201cc, 0x8ee30e10, +0x8002f4f, 0xaee35240, 0x8ee201cc, 0x8ee30e10, 0x441021, 0xaee201cc, 0x8ee201d8, 0x641821, 0x306301ff, 0xaee30e10, 0x441021, 0xaee201d8, -0x8ee20000, 0x34420040, 0x8002f60, 0xaee20000, +0x8ee20000, 0x34420040, 0x8002f5c, 0xaee20000, 0x8ee2014c, 0x3c010001, 0x370821, 0xa02083e0, 0x24420001, 0xaee2014c, 0x8ee2014c, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8f820108, @@ -2049,40 +2057,40 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, 0xaf8700e4, -0x80034d0, 0xaf8700e8, 0x3c020001, 0x571021, +0x80034cc, 0xaf8700e8, 0x3c020001, 0x571021, 0x904283c0, 0x1040000b, 0x0, 0x3c140001, 0x297a021, 0x8e9483c4, 0x3c130001, 0x2779821, -0x8e7383c8, 0x3c120001, 0x2579021, 0x8003197, +0x8e7383c8, 0x3c120001, 0x2579021, 0x8003193, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, 0x10430007, 0x8821, 0x8f8200e4, 0x24110001, 0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, 0x1620000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010, 0x8f8200c8, -0x3c040001, 0x24845040, 0xafa20014, 0x8f8600e0, -0x8f8700e4, 0x3c050006, 0xc002407, 0x34a5f000, -0x80034d0, 0x0, 0x8fa3001c, 0x8fb20018, +0x3c040001, 0x24845050, 0xafa20014, 0x8f8600e0, +0x8f8700e4, 0x3c050006, 0xc002403, 0x34a5f000, +0x80034cc, 0x0, 0x8fa3001c, 0x8fb20018, 0x3074ffff, 0x2694fffc, 0x621024, 0x10400058, 0x2409821, 0x3c020080, 0x621024, 0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001, 0xaee201fc, -0x80034ca, 0x8ee201fc, 0x3c060004, 0x3c0b0001, +0x80034c6, 0x8ee201fc, 0x3c060004, 0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, 0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021, 0xc3102b, 0x14400007, 0x0, 0x106b0011, -0x0, 0x106a0015, 0x0, 0x800304d, +0x0, 0x106a0015, 0x0, 0x8003049, 0x42042, 0x10650023, 0xa3102b, 0x14400005, -0x0, 0x10690019, 0x0, 0x800304d, -0x42042, 0x10680021, 0x0, 0x800304d, +0x0, 0x10690019, 0x0, 0x8003049, +0x42042, 0x10680021, 0x0, 0x8003049, 0x42042, 0x8ee20034, 0x24420001, 0xaee20034, -0x8ee20034, 0x800304d, 0x42042, 0x8ee201ec, -0x24420001, 0xaee201ec, 0x8ee201ec, 0x800304d, +0x8ee20034, 0x8003049, 0x42042, 0x8ee201ec, +0x24420001, 0xaee201ec, 0x8ee201ec, 0x8003049, 0x42042, 0x8ee201f0, 0x24420001, 0xaee201f0, -0x8ee201f0, 0x800304d, 0x42042, 0x8ee201f4, -0x24420001, 0xaee201f4, 0x8ee201f4, 0x800304d, +0x8ee201f0, 0x8003049, 0x42042, 0x8ee201f4, +0x24420001, 0xaee201f4, 0x8ee201f4, 0x8003049, 0x42042, 0x8ee20030, 0x24420001, 0xaee20030, -0x8ee20030, 0x800304d, 0x42042, 0x8ee201f8, +0x8ee20030, 0x8003049, 0x42042, 0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8, 0x42042, -0x1087047c, 0x0, 0x8003012, 0x0, +0x1087047c, 0x0, 0x800300e, 0x0, 0x3c020001, 0x571021, 0x904283b2, 0x14400084, 0x24020001, 0x3c030001, 0x771821, 0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000, 0x621024, @@ -2097,7 +2105,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x94437782, 0x96620004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, -0x10400440, 0x0, 0x80030d9, 0x0, +0x10400440, 0x0, 0x80030d5, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x14400434, 0xb71021, 0x9443727e, 0x96620000, @@ -2106,14 +2114,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x94437282, 0x96620004, 0x10620035, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x14400421, 0x2e31021, 0x944b727c, 0x96670000, 0xb28c0, -0xb71021, 0x9442737e, 0x80030bb, 0x3021, +0xb71021, 0x9442737e, 0x80030b7, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x944b737c, 0x30638000, 0x14600010, 0xb28c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1602021, 0xb71021, 0x94437380, 0x96620002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96620004, 0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, -0x10400400, 0x0, 0x80030d9, 0x0, +0x10400400, 0x0, 0x80030d5, 0x0, 0x97430202, 0x96420000, 0x146203fa, 0x0, 0x97430204, 0x96420002, 0x146203f6, 0x0, 0x97430206, 0x96420004, 0x146203f2, 0x0, @@ -2130,7 +2138,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x971021, 0x94437782, 0x96620004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x14400044, 0x240f0003, 0x80034ca, +0x30e200ff, 0x14400044, 0x240f0003, 0x80034c6, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x144003af, 0xb71021, 0x9443727e, @@ -2139,14 +2147,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xb71021, 0x94437282, 0x96620004, 0x10620027, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x1440039c, 0x2e31021, 0x944b727c, 0x96670000, -0xb28c0, 0xb71021, 0x9442737e, 0x8003140, +0xb28c0, 0xb71021, 0x9442737e, 0x800313c, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x944b737c, 0x30638000, 0x14600010, 0xb28c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1602021, 0xb71021, 0x94437380, 0x96620002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96620004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x1040037b, 0x0, 0x8003153, +0x30c200ff, 0x1040037b, 0x0, 0x800314f, 0x240f0003, 0x240f0001, 0xafaf002c, 0x8f420260, 0x54102b, 0x1040003a, 0x0, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, @@ -2155,14 +2163,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, 0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845048, +0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845058, 0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002407, 0x34a5f003, 0x80034d0, 0x0, +0xc002403, 0x34a5f003, 0x80034cc, 0x0, 0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x24845054, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0x3c050006, 0xc002407, 0x34a5f002, 0x8ee201c0, +0x24845064, 0xafa20014, 0x8ee60e10, 0x8ee70e18, +0x3c050006, 0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001, 0xaee201c0, 0x8ee20000, 0x8ee301c0, -0x2403ffbf, 0x431024, 0x8003474, 0xaee20000, +0x2403ffbf, 0x431024, 0x8003470, 0xaee20000, 0x96e20468, 0x54102b, 0x10400003, 0x0, 0x240f0001, 0xa3af0027, 0x12800301, 0x24160007, 0x24150040, 0x241e0001, 0x240e0012, 0x8ee2724c, @@ -2170,7 +2178,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x93a20027, 0x10400014, 0x0, 0x8ee35240, 0x8ee25244, 0x10620009, 0x26ed5244, 0x8ee65244, 0x8ee35244, 0x21140, 0x24425248, -0x2e28021, 0x24630001, 0x80031c3, 0x306b00ff, +0x2e28021, 0x24630001, 0x80031bf, 0x306b00ff, 0x92e27248, 0x1440ffca, 0x0, 0x8ee201e0, 0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10, 0x8ee20e18, 0x1062ffc2, 0x26ed0e18, 0x8ee60e18, @@ -2193,7 +2201,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50400001, 0x27693000, 0x8f820128, 0x11220004, 0x0, 0x8f820124, 0x15220007, 0x1401821, 0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4, -0x8003250, 0x8ee201a4, 0x8e040000, 0x8e050004, +0x800324c, 0x8ee201a4, 0x8e040000, 0x8e050004, 0x1021, 0xad130008, 0xa507000e, 0xad160018, 0xad06001c, 0xa3302b, 0xa32823, 0x822023, 0x862023, 0xad040000, 0xad050004, 0x8ee204c0, @@ -2204,26 +2212,26 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10550007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x800323d, 0x0, 0x14600005, 0x0, +0x8003239, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x8003250, 0x0, 0x8ee24e30, 0x24420001, +0x800324c, 0x0, 0x8ee24e30, 0x24420001, 0x50550003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac960000, 0xac9e0004, 0x16200018, -0x3c050006, 0x8e020018, 0x3c040001, 0x24845060, +0x3c050006, 0x8e020018, 0x3c040001, 0x24845070, 0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009, -0x2003021, 0xc002407, 0xafa30014, 0x93a20037, +0x2003021, 0xc002403, 0xafa30014, 0x93a20037, 0x10400216, 0x340f8100, 0x8e420004, 0x8e430008, 0x8e44000c, 0xa64f000c, 0xae420000, 0xae430004, -0xae440008, 0x96020016, 0x8003474, 0xa642000e, +0xae440008, 0x96020016, 0x8003470, 0xa642000e, 0x14ec0168, 0x28a1823, 0x960c000a, 0x9603000e, 0x28a1023, 0xa602000a, 0x34620004, 0xa602000e, 0x8f880120, 0x27623800, 0x25090020, 0x122102b, 0x14400002, 0x306affff, 0x27693000, 0x8f820128, 0x11220004, 0x0, 0x8f820124, 0x15220007, 0x24040020, 0x8ee201a4, 0x8821, 0x24420001, -0xaee201a4, 0x80032ce, 0x8ee201a4, 0x8ee5724c, +0xaee201a4, 0x80032ca, 0x8ee201a4, 0x8ee5724c, 0x8ee60490, 0x8ee70494, 0xa504000e, 0x24040004, 0xad100008, 0xad040018, 0x52940, 0xa01821, 0x1021, 0xe33821, 0xe3202b, 0xc23021, @@ -2235,22 +2243,22 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10550007, 0x0, 0x8ee24e34, 0x24420001, -0x10620005, 0x0, 0x80032bb, 0x0, +0x10620005, 0x0, 0x80032b7, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400010, 0xac800000, 0x80032ce, 0x0, +0x50400010, 0xac800000, 0x80032ca, 0x0, 0x8ee24e30, 0x24420001, 0x50550003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac960000, 0xac9e0004, 0x1620000d, 0x0, 0xa60c000a, 0xa60a000e, 0x8f820100, 0xafa20010, 0x8f820104, -0x3c040001, 0x2484506c, 0x3c050006, 0xafa20014, -0x8ee6724c, 0x800343f, 0x34a5f00b, 0x3c010001, +0x3c040001, 0x2484507c, 0x3c050006, 0xafa20014, +0x8ee6724c, 0x800343b, 0x34a5f00b, 0x3c010001, 0x370821, 0xa02083c0, 0xadab0000, 0x8ee201d8, 0x8ee3724c, 0x2442ffff, 0xaee201d8, 0x8ee201d8, 0x24630001, 0x306307ff, 0x26e25244, 0x15a20006, 0xaee3724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0, -0x80032f3, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, +0x80032ef, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, 0xaee201cc, 0x8ee201cc, 0x8f420240, 0x10400073, 0x0, 0x8ee20e1c, 0x24420001, 0xaee20e1c, 0x8f430240, 0x43102b, 0x14400176, 0xa021, @@ -2258,7 +2266,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4, -0x8003353, 0x8ee201a4, 0x8ee2724c, 0xac62001c, +0x800334f, 0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, @@ -2268,23 +2276,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10550007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8003340, +0x24420001, 0x10620005, 0x0, 0x800333c, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x8003353, +0x2c420011, 0x50400010, 0xac800000, 0x800334f, 0x0, 0x8ee24e30, 0x24420001, 0x50550003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac8e0000, 0xac9e0004, 0x5620000d, 0x24110001, -0x8ee2724c, 0x3c040001, 0x24845078, 0xafa00014, +0x8ee2724c, 0x3c040001, 0x24845088, 0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280, 0x3c050009, -0x34a5f008, 0xc002407, 0xafae0048, 0x8fae0048, +0x34a5f008, 0xc002403, 0xafae0048, 0x8fae0048, 0x56200001, 0xaee00e1c, 0x8ee20188, 0x24420001, -0xaee20188, 0x80033cc, 0x8ee20188, 0x8f830120, +0xaee20188, 0x80033c8, 0x8ee20188, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8821, 0x24420001, 0xaee201a4, 0x80033be, +0x8821, 0x24420001, 0xaee201a4, 0x80033ba, 0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, @@ -2295,24 +2303,24 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10550007, 0x0, 0x8ee24e34, 0x24420001, -0x10620005, 0x0, 0x80033ab, 0x0, +0x10620005, 0x0, 0x80033a7, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400010, 0xac800000, 0x80033be, 0x0, +0x50400010, 0xac800000, 0x80033ba, 0x0, 0x8ee24e30, 0x24420001, 0x50550003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac8e0000, 0xac9e0004, 0x1620000d, 0x0, 0x8ee2724c, -0x3c040001, 0x24845078, 0xafa00014, 0xafa20010, +0x3c040001, 0x24845088, 0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280, 0x3c050009, 0x34a5f008, -0xc002407, 0xafae0048, 0x8fae0048, 0x8ee20174, -0x24420001, 0xaee20174, 0x8ee20174, 0x8003472, +0xc002403, 0xafae0048, 0x8fae0048, 0x8ee20174, +0x24420001, 0xaee20174, 0x8ee20174, 0x800346e, 0xa021, 0x960c000a, 0x183102b, 0x54400001, 0x1801821, 0xa603000a, 0x8f880120, 0x27623800, 0x25090020, 0x122102b, 0x50400001, 0x27693000, 0x8f820128, 0x11220004, 0x0, 0x8f820124, 0x15220007, 0x24040020, 0x8ee201a4, 0x8821, -0x24420001, 0xaee201a4, 0x8003433, 0x8ee201a4, +0x24420001, 0xaee201a4, 0x800342f, 0x8ee201a4, 0x8ee5724c, 0x8ee60490, 0x8ee70494, 0xa504000e, 0x24040004, 0xad100008, 0xad040018, 0x52940, 0xa01821, 0x1021, 0xe33821, 0xe3202b, @@ -2324,21 +2332,21 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10550007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8003420, +0x24420001, 0x10620005, 0x0, 0x800341c, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x8003433, +0x2c420011, 0x50400010, 0xac800000, 0x800342f, 0x0, 0x8ee24e30, 0x24420001, 0x50550003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac960000, 0xac9e0004, 0x1620001d, 0x0, 0xa60c000a, 0x8f820100, 0xafa20010, 0x8f820104, -0x3c040001, 0x2484506c, 0x3c050006, 0xafa20014, -0x8ee6724c, 0x34a5f00d, 0xc002407, 0x2003821, +0x3c040001, 0x2484507c, 0x3c050006, 0xafa20014, +0x8ee6724c, 0x34a5f00d, 0xc002403, 0x2003821, 0x93a20037, 0x10400031, 0x340f8100, 0x8e420004, 0x8e430008, 0x8e44000c, 0xa64f000c, 0xae420000, 0xae430004, 0xae440008, 0x96020016, 0xa642000e, -0x9602000e, 0x3042fdff, 0x8003474, 0xa602000e, +0x9602000e, 0x3042fdff, 0x8003470, 0xa602000e, 0x8ee201d8, 0x2442ffff, 0xaee201d8, 0x8ee201d8, 0x8ee201cc, 0x3c04001f, 0x3c010001, 0x370821, 0xa03e83c0, 0x2442ffff, 0xaee201cc, 0x9603000a, @@ -2355,8 +2363,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420004, 0x3c010001, 0x370821, 0xac2283cc, 0x8ee2724c, 0x8f430280, 0x24420001, 0x304207ff, 0x14620006, 0x0, 0x8ee201c4, 0x24420001, -0xaee201c4, 0x80034d0, 0x8ee201c4, 0x8ee201bc, -0x24420001, 0xaee201bc, 0x80034d0, 0x8ee201bc, +0xaee201c4, 0x80034cc, 0x8ee201c4, 0x8ee201bc, +0x24420001, 0xaee201bc, 0x80034cc, 0x8ee201bc, 0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4, @@ -2364,9 +2372,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x14400017, 0x24020003, 0x15e20015, 0x0, 0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, 0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0, -0x80034ca, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, +0x80034c6, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, 0x2c640001, 0x441021, 0xaee200d8, -0xaee300dc, 0x8ee200d8, 0x80034ca, 0x8ee300dc, +0xaee300dc, 0x8ee200d8, 0x80034c6, 0x8ee300dc, 0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, @@ -2387,40 +2395,40 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, -0xaf8700e4, 0x8003854, 0xaf8700e8, 0x3c020001, +0xaf8700e4, 0x8003850, 0xaf8700e8, 0x3c020001, 0x571021, 0x904283c0, 0x1040000b, 0x0, 0x3c130001, 0x2779821, 0x8e7383c4, 0x3c110001, 0x2378821, 0x8e3183c8, 0x3c120001, 0x2579021, -0x80036ec, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, +0x80036e8, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, 0x10430007, 0x4821, 0x8f8200e4, 0x24090001, 0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, 0x1520000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010, -0x8f8200c8, 0x3c040001, 0x24845040, 0xafa20014, -0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002407, -0x34a5f000, 0x8003854, 0x0, 0x8fa3001c, +0x8f8200c8, 0x3c040001, 0x24845050, 0xafa20014, +0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403, +0x34a5f000, 0x8003850, 0x0, 0x8fa3001c, 0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024, 0x10400058, 0x2408821, 0x3c020080, 0x621024, 0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001, -0xaee201fc, 0x800384e, 0x8ee201fc, 0x3c060004, +0xaee201fc, 0x800384a, 0x8ee201fc, 0x3c060004, 0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, 0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021, 0xc3102b, 0x14400007, 0x0, 0x106b0011, 0x0, 0x106a0015, 0x0, -0x8003596, 0x42042, 0x10650023, 0xa3102b, +0x8003592, 0x42042, 0x10650023, 0xa3102b, 0x14400005, 0x0, 0x10690019, 0x0, -0x8003596, 0x42042, 0x10680021, 0x0, -0x8003596, 0x42042, 0x8ee20034, 0x24420001, -0xaee20034, 0x8ee20034, 0x8003596, 0x42042, +0x8003592, 0x42042, 0x10680021, 0x0, +0x8003592, 0x42042, 0x8ee20034, 0x24420001, +0xaee20034, 0x8ee20034, 0x8003592, 0x42042, 0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec, -0x8003596, 0x42042, 0x8ee201f0, 0x24420001, -0xaee201f0, 0x8ee201f0, 0x8003596, 0x42042, +0x8003592, 0x42042, 0x8ee201f0, 0x24420001, +0xaee201f0, 0x8ee201f0, 0x8003592, 0x42042, 0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4, -0x8003596, 0x42042, 0x8ee20030, 0x24420001, -0xaee20030, 0x8ee20030, 0x8003596, 0x42042, +0x8003592, 0x42042, 0x8ee20030, 0x24420001, +0xaee20030, 0x8ee20030, 0x8003592, 0x42042, 0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8, -0x42042, 0x108702b7, 0x0, 0x800355b, +0x42042, 0x108702b7, 0x0, 0x8003557, 0x0, 0x3c020001, 0x571021, 0x904283b2, 0x14400084, 0x24020001, 0x3c030001, 0x771821, 0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000, @@ -2435,7 +2443,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x971021, 0x94437782, 0x96220004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x1040027b, 0x0, 0x8003622, +0x30e200ff, 0x1040027b, 0x0, 0x800361e, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x1440026f, 0xb71021, 0x9443727e, @@ -2444,14 +2452,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xb71021, 0x94437282, 0x96220004, 0x10620035, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x1440025c, 0x2e31021, 0x9448727c, 0x96270000, -0x828c0, 0xb71021, 0x9442737e, 0x8003604, +0x828c0, 0xb71021, 0x9442737e, 0x8003600, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x9448737c, 0x30638000, 0x14600010, 0x828c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1002021, 0xb71021, 0x94437380, 0x96220002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96220004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x1040023b, 0x0, 0x8003622, +0x30c200ff, 0x1040023b, 0x0, 0x800361e, 0x0, 0x97430202, 0x96420000, 0x14620235, 0x0, 0x97430204, 0x96420002, 0x14620231, 0x0, 0x97430206, 0x96420004, 0x1462022d, @@ -2469,7 +2477,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, 0x14400044, 0x24140003, -0x800384e, 0x0, 0x2402021, 0xc0022fe, +0x800384a, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x144001ea, 0xb71021, 0x9443727e, 0x96220000, 0x1462000b, 0x418c0, @@ -2478,14 +2486,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10620027, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x144001d7, 0x2e31021, 0x9448727c, 0x96270000, 0x828c0, 0xb71021, 0x9442737e, -0x8003689, 0x3021, 0x420c0, 0x2e41021, +0x8003685, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x9448737c, 0x30638000, 0x14600010, 0x828c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1002021, 0xb71021, 0x94437380, 0x96220002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96220004, 0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, 0x104001b6, 0x0, -0x800369c, 0x24140003, 0x24140001, 0x8f420260, +0x8003698, 0x24140003, 0x24140001, 0x8f420260, 0x53102b, 0x10400049, 0x0, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821, @@ -2493,25 +2501,25 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, 0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845048, +0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845058, 0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002407, 0x34a5f003, 0x8003854, 0x0, +0xc002403, 0x34a5f003, 0x8003850, 0x0, 0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x24845054, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0xc002407, 0x34a5f002, 0x8ee201c0, 0x24420001, +0x24845064, 0xafa20014, 0x8ee60e10, 0x8ee70e18, +0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001, 0xaee201c0, 0x8ee20000, 0x8ee301c0, 0x2403ffbf, -0x431024, 0x80037fc, 0xaee20000, 0x8ee25240, -0xafa20010, 0x8ee25244, 0x3c040001, 0x24845054, +0x431024, 0x80037f8, 0xaee20000, 0x8ee25240, +0xafa20010, 0x8ee25244, 0x3c040001, 0x24845064, 0xafa20014, 0x8ee60e10, 0x8ee70e18, 0x3c050006, -0xc002407, 0x34a5f002, 0x8ee201c0, 0x24420001, -0xaee201c0, 0x80037fc, 0x8ee201c0, 0x96e20468, +0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001, +0xaee201c0, 0x80037f8, 0x8ee201c0, 0x96e20468, 0x53102b, 0x54400001, 0x3c158000, 0x12600131, 0x3c0c001f, 0x358cffff, 0x8ee2724c, 0x8f430280, 0x24420001, 0x304207ff, 0x10620108, 0x0, 0x12a00014, 0x0, 0x8ee35240, 0x8ee25244, 0x10620009, 0x26ee5244, 0x8eeb5244, 0x8ee35244, 0x21140, 0x24425248, 0x2e28021, 0x24630001, -0x8003716, 0x306800ff, 0x92e27248, 0x1440ffc0, +0x8003712, 0x306800ff, 0x92e27248, 0x1440ffc0, 0x3c050006, 0x8ee201e0, 0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10, 0x8ee20e18, 0x1062ffcb, 0x26ee0e18, 0x8eeb0e18, 0xa821, 0x8ee30e18, @@ -2532,7 +2540,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x10600013, 0x26220010, 0x182102b, 0x1040000e, 0x0, 0x3c07fff5, 0xf13821, -0x94e71010, 0x8003762, 0x24e7000e, 0x92220017, +0x94e71010, 0x800375e, 0x24e7000e, 0x92220017, 0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x50600004, 0xae110018, 0x96270010, 0x24e7000e, 0xae110018, 0x3c020001, 0x571021, @@ -2541,7 +2549,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x2402000b, 0x8ee201a4, 0x4821, 0x24420001, -0xaee201a4, 0x80037c3, 0x8ee201a4, 0x8e040000, +0xaee201a4, 0x80037bf, 0x8ee201a4, 0x8e040000, 0x8e050004, 0xac620018, 0x1751025, 0x491025, 0xac710008, 0xa467000e, 0xac62001c, 0xac640000, 0xac650004, 0x8ee204c0, 0xac620010, 0xaf860120, @@ -2552,23 +2560,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24420001, 0xac820004, 0x8ee34e34, 0x8ee54e30, 0x24020040, 0x24630001, 0x10620007, 0x0, 0x8ee24e34, 0x24420001, 0x10a20005, 0x0, -0x80037ad, 0x0, 0x14a00005, 0x0, +0x80037a9, 0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x80037c3, 0x0, 0x8ee24e30, 0x24030040, +0x80037bf, 0x0, 0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x15200018, 0x3c050006, -0x8e020018, 0x3c040001, 0x24845060, 0xafa20010, +0x8e020018, 0x3c040001, 0x24845070, 0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021, -0xc002407, 0xafa30014, 0x32c200ff, 0x1040002b, +0xc002403, 0xafa30014, 0x32c200ff, 0x1040002b, 0x34028100, 0x8e430004, 0x8e440008, 0x8e45000c, 0xa642000c, 0xae430000, 0xae440004, 0xae450008, -0x96020016, 0x80037fc, 0xa642000e, 0x154d000a, +0x96020016, 0x80037f8, 0xa642000e, 0x154d000a, 0x0, 0x9602000e, 0xa613000a, 0x34420004, 0xa602000e, 0x3c010001, 0x370821, 0xa02083c0, -0x80037fa, 0x9821, 0x9604000a, 0x93102b, +0x80037f6, 0x9821, 0x9604000a, 0x93102b, 0x10400002, 0x2601821, 0x801821, 0x24020001, 0xa603000a, 0x3c010001, 0x370821, 0xa02283c0, 0x9604000a, 0x2248821, 0x191102b, 0x10400003, @@ -2580,8 +2588,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x571021, 0x8c4283cc, 0x24420004, 0x3c010001, 0x370821, 0xac2283cc, 0x8ee2724c, 0x8f430280, 0x24420001, 0x14620006, 0x0, 0x8ee201c4, -0x24420001, 0xaee201c4, 0x8003854, 0x8ee201c4, -0x8ee201bc, 0x24420001, 0xaee201bc, 0x8003854, +0x24420001, 0xaee201c4, 0x8003850, 0x8ee201c4, +0x8ee201bc, 0x24420001, 0xaee201bc, 0x8003850, 0x8ee201bc, 0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0x24020002, @@ -2589,9 +2597,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x14400017, 0x24020003, 0x16820015, 0x0, 0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, 0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0, -0x800384e, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, +0x800384a, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, 0x2c640001, 0x441021, 0xaee200d8, -0xaee300dc, 0x8ee200d8, 0x800384e, 0x8ee300dc, +0xaee300dc, 0x8ee200d8, 0x800384a, 0x8ee300dc, 0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, @@ -2612,40 +2620,40 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, -0xaf8700e4, 0x8003c5f, 0xaf8700e8, 0x3c020001, +0xaf8700e4, 0x8003c5b, 0xaf8700e8, 0x3c020001, 0x571021, 0x904283c0, 0x1040000b, 0x0, 0x3c130001, 0x2779821, 0x8e7383c4, 0x3c100001, 0x2178021, 0x8e1083c8, 0x3c120001, 0x2579021, -0x8003a5d, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, +0x8003a59, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, 0x10430007, 0x3821, 0x8f8200e4, 0x24070001, 0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, 0x14e0000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010, -0x8f8200c8, 0x3c040001, 0x24845084, 0xafa20014, -0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002407, -0x34a5f200, 0x8003c5f, 0x0, 0x8fa3001c, +0x8f8200c8, 0x3c040001, 0x24845094, 0xafa20014, +0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403, +0x34a5f200, 0x8003c5b, 0x0, 0x8fa3001c, 0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024, 0x10400058, 0x2408021, 0x3c020080, 0x621024, 0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001, -0xaee201fc, 0x8003c59, 0x8ee201fc, 0x3c060004, +0xaee201fc, 0x8003c55, 0x8ee201fc, 0x3c060004, 0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, 0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021, 0xc3102b, 0x14400007, 0x0, 0x106b0011, 0x0, 0x106a0015, 0x0, -0x800391a, 0x42042, 0x10650023, 0xa3102b, +0x8003916, 0x42042, 0x10650023, 0xa3102b, 0x14400005, 0x0, 0x10690019, 0x0, -0x800391a, 0x42042, 0x10680021, 0x0, -0x800391a, 0x42042, 0x8ee20034, 0x24420001, -0xaee20034, 0x8ee20034, 0x800391a, 0x42042, +0x8003916, 0x42042, 0x10680021, 0x0, +0x8003916, 0x42042, 0x8ee20034, 0x24420001, +0xaee20034, 0x8ee20034, 0x8003916, 0x42042, 0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec, -0x800391a, 0x42042, 0x8ee201f0, 0x24420001, -0xaee201f0, 0x8ee201f0, 0x800391a, 0x42042, +0x8003916, 0x42042, 0x8ee201f0, 0x24420001, +0xaee201f0, 0x8ee201f0, 0x8003916, 0x42042, 0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4, -0x800391a, 0x42042, 0x8ee20030, 0x24420001, -0xaee20030, 0x8ee20030, 0x800391a, 0x42042, +0x8003916, 0x42042, 0x8ee20030, 0x24420001, +0xaee20030, 0x8ee20030, 0x8003916, 0x42042, 0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8, -0x42042, 0x1087033e, 0x0, 0x80038df, +0x42042, 0x1087033e, 0x0, 0x80038db, 0x0, 0x3c020001, 0x571021, 0x904283b2, 0x14400084, 0x24020001, 0x3c030001, 0x771821, 0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000, @@ -2660,7 +2668,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x971021, 0x94437782, 0x96020004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x10400302, 0x0, 0x80039a6, +0x30e200ff, 0x10400302, 0x0, 0x80039a2, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x144002f6, 0xb71021, 0x9443727e, @@ -2669,14 +2677,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xb71021, 0x94437282, 0x96020004, 0x10620035, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x144002e3, 0x2e31021, 0x944d727c, 0x96070000, -0xd28c0, 0xb71021, 0x9442737e, 0x8003988, +0xd28c0, 0xb71021, 0x9442737e, 0x8003984, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x944d737c, 0x30638000, 0x14600010, 0xd28c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1a02021, 0xb71021, 0x94437380, 0x96020002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96020004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x104002c2, 0x0, 0x80039a6, +0x30c200ff, 0x104002c2, 0x0, 0x80039a2, 0x0, 0x97430202, 0x96420000, 0x146202bc, 0x0, 0x97430204, 0x96420002, 0x146202b8, 0x0, 0x97430206, 0x96420004, 0x146202b4, @@ -2694,7 +2702,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, 0x14400044, 0x24150003, -0x8003c59, 0x0, 0x2402021, 0xc0022fe, +0x8003c55, 0x0, 0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, 0x30424000, 0x14400271, 0xb71021, 0x9443727e, 0x96020000, 0x1462000b, 0x418c0, @@ -2703,14 +2711,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10620027, 0x418c0, 0x2e31021, 0x9442727c, 0x30428000, 0x1440025e, 0x2e31021, 0x944d727c, 0x96070000, 0xd28c0, 0xb71021, 0x9442737e, -0x8003a0d, 0x3021, 0x420c0, 0x2e41021, +0x8003a09, 0x3021, 0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, 0x944d737c, 0x30638000, 0x14600010, 0xd28c0, 0xb71021, 0x9442737e, 0x1447fff5, 0x1a02021, 0xb71021, 0x94437380, 0x96020002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437382, 0x96020004, 0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, 0x1040023d, 0x0, -0x8003a20, 0x24150003, 0x24150001, 0x8f420260, +0x8003a1c, 0x24150003, 0x24150001, 0x8f420260, 0x53102b, 0x10400036, 0x0, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821, @@ -2718,13 +2726,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, 0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845090, +0xafa20010, 0x8f8200e4, 0x3c040001, 0x248450a0, 0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002407, 0x34a5f203, 0x8003c5f, 0x0, +0xc002403, 0x34a5f203, 0x8003c5b, 0x0, 0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x2484509c, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0x3c050006, 0xc002407, 0x34a5f202, 0x8ee201c0, -0x24420001, 0xaee201c0, 0x8003c06, 0x8ee201c0, +0x248450ac, 0xafa20014, 0x8ee60e10, 0x8ee70e18, +0x3c050006, 0xc002403, 0x34a5f202, 0x8ee201c0, +0x24420001, 0xaee201c0, 0x8003c02, 0x8ee201c0, 0x96e20468, 0x53102b, 0x54400001, 0x3c168000, 0x126001cb, 0x3c0e001f, 0x35ceffff, 0x3c0ffff5, 0x35ef1000, 0x241e0040, 0x8ee2724c, 0x8f430280, @@ -2732,7 +2740,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x12c00012, 0x0, 0x8ee35240, 0x8ee25244, 0x1062000a, 0x26f85244, 0x8ef45244, 0xafb80024, 0x8ee35244, 0x21140, 0x24425248, 0x2e28821, -0x24630001, 0x8003a89, 0x306d00ff, 0x8ee201e0, +0x24630001, 0x8003a85, 0x306d00ff, 0x8ee201e0, 0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10, 0x8ee20e18, 0x1062ffca, 0x26f80e18, 0x8ef40e18, 0xb021, 0xafb80024, 0x8ee30e18, 0x21140, @@ -2751,7 +2759,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2418fff8, 0x58c824, 0x6a1821, 0x79102b, 0x10400002, 0x3206021, 0x606021, 0x1801821, 0x24620007, 0x2418fff8, 0x586024, 0x26c102b, -0x14400004, 0x1932823, 0x1832823, 0x8003ac7, +0x14400004, 0x1932823, 0x1832823, 0x8003ac3, 0xc31021, 0xd31021, 0x4a2023, 0x1c4102b, 0x54400001, 0x8f2021, 0x25420040, 0x4c102b, 0x14400035, 0x5821, 0x94c3000c, 0x24020800, @@ -2761,7 +2769,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x461021, 0x90421017, 0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x10600014, 0x24c20010, 0x1c2102b, 0x1040000e, 0x0, -0x3c0bfff5, 0x1665821, 0x956b1010, 0x8003af8, +0x3c0bfff5, 0x1665821, 0x956b1010, 0x8003af4, 0x2562000e, 0x90c20017, 0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x10600005, 0x1601821, 0x94cb0010, 0x2562000e, 0x4a5821, @@ -2774,13 +2782,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1c4102b, 0x10400002, 0x24a5ffff, 0x8f2021, 0x50a00012, 0x81c02, 0x2ca20002, 0x54400009, 0x24a5ffff, 0x94820000, 0x24840002, 0x1024021, -0x1c4102b, 0x10400006, 0x24a5fffe, 0x8003b25, +0x1c4102b, 0x10400006, 0x24a5fffe, 0x8003b21, 0x8f2021, 0x90820000, 0x21200, 0x1024021, 0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff, 0x624021, 0x3108ffff, 0x1402821, 0x11400011, 0x2002021, 0x2ca20002, 0x54400009, 0x24a5ffff, 0x94820000, 0x24840002, 0x1024021, 0x1c4102b, -0x10400006, 0x24a5fffe, 0x8003b3c, 0x8f2021, +0x10400006, 0x24a5fffe, 0x8003b38, 0x8f2021, 0x90820000, 0x21200, 0x1024021, 0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff, 0x624021, 0x81c02, 0x3102ffff, 0x8f890120, 0x624021, @@ -2788,7 +2796,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3108ffff, 0x27633000, 0x8f820128, 0x10620004, 0x0, 0x8f820124, 0x14620007, 0x1402821, 0x8ee201a4, 0x3821, 0x24420001, 0xaee201a4, -0x8003bcd, 0x8ee201a4, 0x8e260000, 0x8e270004, +0x8003bc9, 0x8ee201a4, 0x8e260000, 0x8e270004, 0x81400, 0x3448000b, 0xad300008, 0xa52b000e, 0xad280018, 0x8fb80044, 0x2021, 0x2961025, 0x581025, 0xad22001c, 0xe5102b, 0xe53823, @@ -2801,32 +2809,32 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee34e30, 0x8ee24e34, 0x1062000b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x105e002a, 0x0, -0x8003bac, 0x0, 0x8ee24e30, 0x24420001, +0x8003ba8, 0x0, 0x8ee24e30, 0x24420001, 0x505e0003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8003bca, 0x24020012, 0x8ee24e30, +0x2e22021, 0x8003bc6, 0x24020012, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x105e0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8003bb8, +0x24420001, 0x10620005, 0x0, 0x8003bb4, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400012, 0xac800000, 0x8003bcd, +0x2c420011, 0x50400012, 0xac800000, 0x8003bc9, 0x0, 0x8ee24e30, 0x24420001, 0x505e0003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, -0x14e00019, 0x3c050006, 0x3c040001, 0x24845060, +0x14e00019, 0x3c050006, 0x3c040001, 0x24845070, 0x8e220018, 0x34a5f209, 0xafa20010, 0x8e220000, -0x8e230004, 0x2203021, 0x1603821, 0xc002407, +0x8e230004, 0x2203021, 0x1603821, 0xc002403, 0xafa30014, 0x93a2002f, 0x1040002a, 0x34028100, 0x8e430004, 0x8e440008, 0x8e45000c, 0xa642000c, 0xae430000, 0xae440004, 0xae450008, 0x96220016, -0x8003c06, 0xa642000e, 0x1599000a, 0x26a1823, +0x8003c02, 0xa642000e, 0x1599000a, 0x26a1823, 0x9622000e, 0xa623000a, 0x34420004, 0xa622000e, -0x3c010001, 0x370821, 0xa02083c0, 0x8003c03, +0x3c010001, 0x370821, 0xa02083c0, 0x8003bff, 0x9821, 0x9624000a, 0x83102b, 0x54400001, 0x801821, 0x24020001, 0xa623000a, 0x3c010001, 0x370821, 0xa02283c0, 0x9622000a, 0x4a1821, @@ -2839,18 +2847,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x571021, 0x8c4283cc, 0x24420004, 0x3c010001, 0x370821, 0xac2283cc, 0x8f430280, 0x8ee2724c, 0x14620006, 0x0, 0x8ee201c4, 0x24420001, -0xaee201c4, 0x8003c5f, 0x8ee201c4, 0x8ee201bc, -0x24420001, 0xaee201bc, 0x8003c5f, 0x8ee201bc, +0xaee201c4, 0x8003c5b, 0x8ee201c4, 0x8ee201bc, +0x24420001, 0xaee201bc, 0x8003c5b, 0x8ee201bc, 0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0x24020002, 0xaee400c0, 0xaee500c4, 0x12a2000f, 0x2aa20003, 0x14400017, 0x24020003, 0x16a20015, 0x0, 0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, 0x441021, -0xaee200d0, 0xaee300d4, 0x8ee200d0, 0x8003c59, +0xaee200d0, 0xaee300d4, 0x8ee200d0, 0x8003c55, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, 0x2c640001, 0x441021, 0xaee200d8, 0xaee300dc, -0x8ee200d8, 0x8003c59, 0x8ee300dc, 0x8ee200c8, +0x8ee200d8, 0x8003c55, 0x8ee300dc, 0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, @@ -2861,14 +2869,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee20e0c, 0x10620074, 0x0, 0x8ee30e0c, 0x8ee20e14, 0x622023, 0x4820001, 0x24840200, 0x8ee30e18, 0x8ee20e14, 0x43102b, 0x14400004, -0x24020200, 0x8ee30e14, 0x8003c81, 0x431823, +0x24020200, 0x8ee30e14, 0x8003c7d, 0x431823, 0x8ee20e18, 0x8ee30e14, 0x431023, 0x2443ffff, 0x804821, 0x69102a, 0x54400001, 0x604821, 0x8f870100, 0x27623000, 0x24e80020, 0x102102b, 0x50400001, 0x27682800, 0x8f820108, 0x11020004, 0x0, 0x8f820104, 0x15020007, 0x1021, 0x8ee201a8, 0x2021, 0x24420001, 0xaee201a8, -0x8003cc3, 0x8ee201a8, 0x8ee40e14, 0x42140, +0x8003cbf, 0x8ee201a8, 0x8ee40e14, 0x42140, 0x801821, 0x8ee40460, 0x8ee50464, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004, 0x8ee30e14, 0x91140, 0xa4e2000e, @@ -2882,7 +2890,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24020001, 0xac620004, 0x1480000e, 0x24030040, 0x8ee20e14, 0xafa20010, 0x8ee20e18, 0x3c050007, 0xafa20014, 0x8ee60e0c, 0x8ee70e10, 0x3c040001, -0x248450a4, 0xc002407, 0x34a5f001, 0x8003ce1, +0x248450b4, 0xc002403, 0x34a5f001, 0x8003cdd, 0x0, 0x8ee20500, 0x24420001, 0x50430003, 0x1021, 0x8ee20500, 0x24420001, 0xaee20500, 0x8ee20500, 0x21080, 0x571021, 0xac490508, @@ -2894,13 +2902,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8ee35238, 0x8ee2523c, 0x622023, 0x4820001, 0x24840100, 0x8ee35244, 0x8ee2523c, 0x43102b, 0x14400004, 0x24020100, 0x8ee3523c, -0x8003d03, 0x431823, 0x8ee25244, 0x8ee3523c, +0x8003cff, 0x431823, 0x8ee25244, 0x8ee3523c, 0x431023, 0x2443ffff, 0x804821, 0x69102a, 0x54400001, 0x604821, 0x8f870100, 0x27623000, 0x24e80020, 0x102102b, 0x50400001, 0x27682800, 0x8f820108, 0x11020004, 0x0, 0x8f820104, 0x15020007, 0x1021, 0x8ee201a8, 0x2021, -0x24420001, 0xaee201a8, 0x8003d45, 0x8ee201a8, +0x24420001, 0xaee201a8, 0x8003d41, 0x8ee201a8, 0x8ee4523c, 0x42140, 0x801821, 0x8ee40470, 0x8ee50474, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004, 0x8ee3523c, @@ -2914,8 +2922,8 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24020003, 0xac620000, 0x24020001, 0xac620004, 0x1480000e, 0x24030040, 0x8ee2523c, 0xafa20010, 0x8ee25244, 0x3c050007, 0xafa20014, 0x8ee65238, -0x8ee75240, 0x3c040001, 0x248450b0, 0xc002407, -0x34a5f010, 0x8003d63, 0x0, 0x8ee20500, +0x8ee75240, 0x3c040001, 0x248450c0, 0xc002403, +0x34a5f010, 0x8003d5f, 0x0, 0x8ee20500, 0x24420001, 0x50430003, 0x1021, 0x8ee20500, 0x24420001, 0xaee20500, 0x8ee20500, 0x21080, 0x571021, 0xac490508, 0x8ee2523c, 0x491021, @@ -2927,14 +2935,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1021, 0x8ee24e34, 0x24420001, 0xaee24e34, 0x8ee24e34, 0x8ee44e34, 0x8ee34e30, 0x210c0, 0x24425038, 0x14830007, 0x2e22821, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8003d96, +0x24420020, 0xaf820128, 0x8f820128, 0x8003d92, 0xaca00000, 0x8ee24e34, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e34, 0x24420001, 0x210c0, 0x24425038, 0x2e22821, 0x8ca20004, 0x8f830128, 0x21140, 0x621821, 0xaf830128, 0xaca00000, 0x8cc20018, 0x2443fffe, 0x2c620012, 0x10400008, 0x31080, 0x3c010001, 0x220821, -0x8c2250c0, 0x400008, 0x0, 0x24020001, +0x8c2250d0, 0x400008, 0x0, 0x24020001, 0xaee24e24, 0x3e00008, 0x0, 0x27bdffc8, 0xafbf0030, 0xafb5002c, 0xafb40028, 0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f830128, @@ -2943,15 +2951,15 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24140040, 0x8f8c0128, 0x8f820128, 0x24420020, 0xaf820128, 0x9182001b, 0x8f830128, 0x2443fffe, 0x2c620012, 0x1040029c, 0x31080, 0x3c010001, -0x220821, 0x8c225118, 0x400008, 0x0, +0x220821, 0x8c225128, 0x400008, 0x0, 0x8f420218, 0x30420100, 0x10400007, 0x0, 0x95830016, 0x95820018, 0x621823, 0x31402, 0x431021, 0xa5820016, 0x8d82001c, 0x3c038000, 0x3044ffff, 0x436824, 0x3c030800, 0x431824, -0x11a00004, 0xad84001c, 0x41140, 0x8003ddc, +0x11a00004, 0xad84001c, 0x41140, 0x8003dd8, 0x24425248, 0x41140, 0x24420e20, 0x2e25821, 0x9562000e, 0x3042fffc, 0x10600004, 0xa562000e, -0x95840016, 0x8003ec4, 0x0, 0x8d690018, +0x95840016, 0x8003ec0, 0x0, 0x8d690018, 0x4021, 0x952a0000, 0x25290002, 0x95270000, 0x25290002, 0x95260000, 0x25290002, 0x95250000, 0x25290002, 0x95240000, 0x25290002, 0x95230000, @@ -2965,7 +2973,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x721821, 0x94620000, 0x24630002, 0x24a5ffff, 0x14a0fff9, 0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x41402, 0x3083ffff, 0x431021, -0x3042ffff, 0x8003e37, 0x1425021, 0x952a0000, +0x3042ffff, 0x8003e33, 0x1425021, 0x952a0000, 0x25290002, 0x95280000, 0x25290002, 0x95270000, 0x25290002, 0x95260000, 0x25290002, 0x95250000, 0x25290002, 0x95230000, 0x25290002, 0x95220000, @@ -2982,7 +2990,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10400034, 0x24690010, 0x229102b, 0x54400001, 0x1324821, 0x95250000, 0x24690014, 0x229102b, 0x10400002, 0x24a5ffec, 0x1324821, 0x95220000, -0x30420fff, 0x14400003, 0x25290002, 0x8003e64, +0x30420fff, 0x14400003, 0x25290002, 0x8003e60, 0x24130001, 0x9821, 0xa03021, 0x229102b, 0x54400001, 0x1324821, 0x91220001, 0x25290002, 0xa22821, 0x229102b, 0x54400001, 0x1324821, @@ -2991,9 +2999,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x54400001, 0x1324821, 0x95220000, 0x25290002, 0xa22821, 0x229102b, 0x54400001, 0x1324821, 0x95220000, 0x25290002, 0xa22821, 0x229102b, -0x54400001, 0x1324821, 0x95220000, 0x8003e9d, +0x54400001, 0x1324821, 0x95220000, 0x8003e99, 0xa22821, 0x94650010, 0x94620014, 0x24690016, -0x30420fff, 0x14400003, 0x24a5ffec, 0x8003e90, +0x30420fff, 0x14400003, 0x24a5ffec, 0x8003e8c, 0x24130001, 0x9821, 0xa03021, 0x91230001, 0x25290004, 0x95220000, 0x25290002, 0x95240000, 0x25290002, 0xa32821, 0xa22821, 0x95220000, @@ -3013,7 +3021,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x122102b, 0x50400001, 0x27693000, 0x8f820128, 0x11220004, 0x0, 0x8f820124, 0x15220007, 0x24040020, 0x8ee201a4, 0x8021, 0x24420001, -0xaee201a4, 0x8003f53, 0x8ee201a4, 0x8ee5724c, +0xaee201a4, 0x8003f4f, 0x8ee201a4, 0x8ee5724c, 0x8ee60490, 0x8ee70494, 0xad0b0008, 0xa504000e, 0xad0a0018, 0x52940, 0xa01821, 0x1021, 0xe33821, 0xe3202b, 0xc23021, 0xc43021, @@ -3026,41 +3034,41 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8ee34e30, 0x8ee24e34, 0x1062000b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x1054002b, -0x0, 0x8003f32, 0x0, 0x8ee24e30, +0x0, 0x8003f2e, 0x0, 0x8ee24e30, 0x24420001, 0x50540003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020001, 0x8003f52, +0x24425038, 0x2e22021, 0x24020001, 0x8003f4e, 0xac950000, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8003f3e, 0x0, 0x14600005, +0x0, 0x8003f3a, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400012, -0xac800000, 0x8003f53, 0x0, 0x8ee24e30, +0xac800000, 0x8003f4f, 0x0, 0x8ee24e30, 0x24420001, 0x50540003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x1600000d, 0x0, -0x8f820120, 0x3c040001, 0x24845108, 0xafa00014, +0x8f820120, 0x3c040001, 0x24845118, 0xafa00014, 0xafa20010, 0x8d86001c, 0x8f870124, 0x3c050008, -0xc002407, 0x34a50001, 0x800405b, 0x0, +0xc002403, 0x34a50001, 0x8004057, 0x0, 0x8ee2724c, 0x24420001, 0x304207ff, 0x11a00006, 0xaee2724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0, -0x8003f6f, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, +0x8003f6b, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, 0xaee201cc, 0x8ee201cc, 0x8ee201d8, 0x2442ffff, -0xaee201d8, 0x800405b, 0x8ee201d8, 0x8f420240, +0xaee201d8, 0x8004057, 0x8ee201d8, 0x8f420240, 0x104000e5, 0x0, 0x8ee20e1c, 0x24420001, -0x800405b, 0xaee20e1c, 0x9582001e, 0xad82001c, +0x8004057, 0xaee20e1c, 0x9582001e, 0xad82001c, 0x8f420240, 0x10400072, 0x0, 0x8ee20e1c, 0x24420001, 0xaee20e1c, 0x8f430240, 0x43102b, 0x144000d5, 0x0, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, 0x8021, -0x24420001, 0xaee201a4, 0x8003fde, 0x8ee201a4, +0x24420001, 0xaee201a4, 0x8003fda, 0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, @@ -3071,23 +3079,23 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8003fca, 0x0, 0x14600005, +0x0, 0x8003fc6, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400011, -0xac800000, 0x8003fde, 0x0, 0x8ee24e30, +0xac800000, 0x8003fda, 0x0, 0x8ee24e30, 0x24420001, 0x50540003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020001, 0xac950000, 0xac820004, 0x5600000b, 0x24100001, 0x8ee2724c, -0x3c040001, 0x24845078, 0xafa00014, 0xafa20010, -0x8ee6724c, 0x8f470280, 0x3c050009, 0xc002407, +0x3c040001, 0x24845088, 0xafa00014, 0xafa20010, +0x8ee6724c, 0x8f470280, 0x3c050009, 0xc002403, 0x34a5f008, 0x56000001, 0xaee00e1c, 0x8ee20188, -0x24420001, 0xaee20188, 0x8004054, 0x8ee20188, +0x24420001, 0xaee20188, 0x8004050, 0x8ee20188, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8004048, 0x8ee201a4, 0x8ee2724c, 0xac62001c, +0x8004044, 0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, @@ -3097,64 +3105,64 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8004034, +0x24420001, 0x10620005, 0x0, 0x8004030, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400011, 0xac800000, 0x8004048, +0x2c420011, 0x50400011, 0xac800000, 0x8004044, 0x0, 0x8ee24e30, 0x24420001, 0x50540003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0x24020001, 0xac950000, 0xac820004, 0x1600000b, -0x0, 0x8ee2724c, 0x3c040001, 0x24845078, +0x0, 0x8ee2724c, 0x3c040001, 0x24845088, 0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280, -0x3c050009, 0xc002407, 0x34a5f008, 0x8ee20174, -0x24420001, 0xaee20174, 0x800405b, 0x8ee20174, +0x3c050009, 0xc002403, 0x34a5f008, 0x8ee20174, +0x24420001, 0xaee20174, 0x8004057, 0x8ee20174, 0x24020001, 0xaee24e24, 0x8f830128, 0x8f820124, 0x1462fd58, 0x0, 0x8fbf0030, 0x8fb5002c, 0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038, 0x27bdffe8, 0x27840208, 0x27450200, 0x24060008, 0xafbf0014, -0xc00249e, 0xafb00010, 0x2021, 0x24100001, +0xc00249a, 0xafb00010, 0x2021, 0x24100001, 0x2402241f, 0xaf900210, 0xaf900200, 0xaf800204, 0xaf820214, 0x8f460248, 0x24030004, 0x3c020040, -0x3c010001, 0xac235474, 0x3c010001, 0xac235478, -0x3c010001, 0xac20552c, 0x3c010001, 0xac225470, -0x3c010001, 0xac235478, 0xc004fa4, 0x24050004, -0xc004784, 0x0, 0x8ee20000, 0x3c03feff, +0x3c010001, 0xac235484, 0x3c010001, 0xac235488, +0x3c010001, 0xac20553c, 0x3c010001, 0xac225480, +0x3c010001, 0xac235488, 0xc004fa8, 0x24050004, +0xc004785, 0x0, 0x8ee20000, 0x3c03feff, 0x3463fffd, 0x431024, 0xaee20000, 0x3c023c00, 0xaf82021c, 0x3c010001, 0x370821, 0xac3083ac, 0x8fbf0014, 0x8fb00010, 0x3e00008, 0x27bd0018, 0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018, 0xafa00010, 0xafa00014, 0x8f860200, 0x3c040001, -0x248451c0, 0xc002407, 0x3821, 0x8ee20280, +0x248451d0, 0xc002403, 0x3821, 0x8ee20280, 0x24420001, 0xaee20280, 0x8ee20280, 0x8f830200, 0x3c023f00, 0x621824, 0x8fbf0018, 0x3c020400, 0x3e00008, 0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c, 0xafb00018, 0x8f900220, 0x8ee20214, 0x3821, 0x24420001, 0xaee20214, 0x8ee20214, 0x3c020300, 0x2021024, 0x10400027, 0x3c110400, -0xc00429f, 0x0, 0x3c020100, 0x2021024, +0xc00429b, 0x0, 0x3c020100, 0x2021024, 0x10400007, 0x0, 0x8ee20218, 0x24420001, -0xaee20218, 0x8ee20218, 0x80040ca, 0x3c03fdff, +0xaee20218, 0x8ee20218, 0x80040c6, 0x3c03fdff, 0x8ee2021c, 0x24420001, 0xaee2021c, 0x8ee2021c, 0x3c03fdff, 0x3463ffff, 0x3c0808ff, 0x3508ffff, -0x8ee20000, 0x3c040001, 0x248451cc, 0x3c050008, +0x8ee20000, 0x3c040001, 0x248451dc, 0x3c050008, 0x2003021, 0x431024, 0xaee20000, 0x8f820220, 0x3821, 0x3c030300, 0x481024, 0x431025, -0xaf820220, 0xafa00010, 0xc002407, 0xafa00014, -0x800429a, 0x0, 0x2111024, 0x1040001f, +0xaf820220, 0xafa00010, 0xc002403, 0xafa00014, +0x8004296, 0x0, 0x2111024, 0x1040001f, 0x3c024000, 0x8f830224, 0x24021402, 0x1462000b, -0x3c03fdff, 0x3c040001, 0x248451d8, 0x3c050008, +0x3c03fdff, 0x3c040001, 0x248451e8, 0x3c050008, 0xafa00010, 0xafa00014, 0x8f860224, 0x34a5ffff, -0xc002407, 0x3821, 0x3c03fdff, 0x8ee20000, -0x3463ffff, 0x2002021, 0x431024, 0xc004cf0, +0xc002403, 0x3821, 0x3c03fdff, 0x8ee20000, +0x3463ffff, 0x2002021, 0x431024, 0xc004cf4, 0xaee20000, 0x8ee20220, 0x24420001, 0xaee20220, 0x8ee20220, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x8004299, 0x511025, 0x2021024, +0x431024, 0x8004295, 0x511025, 0x2021024, 0x10400142, 0x0, 0x8ee2022c, 0x24420001, 0xaee2022c, 0x8ee2022c, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004, 0xaf820220, -0x8f830054, 0x8f820054, 0x8004112, 0x24630002, +0x8f830054, 0x8f820054, 0x800410e, 0x24630002, 0x8f820054, 0x621023, 0x2c420003, 0x1440fffc, 0x0, 0x8f8600e0, 0x8f8400e4, 0x30c20007, 0x10400012, 0x0, 0x8f8300e4, 0x2402fff8, @@ -3167,7 +3175,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xc23024, 0xaf8600e0, 0x8f8300c4, 0x3c02001f, 0x3442ffff, 0x24680008, 0x48102b, 0x10400003, 0x3c02fff5, 0x34421000, 0x1024021, 0x8f8b00c8, -0x8f850120, 0x8f840124, 0x8004149, 0x6021, +0x8f850120, 0x8f840124, 0x8004145, 0x6021, 0x27623800, 0x82102b, 0x50400001, 0x27643000, 0x10a40010, 0x318200ff, 0x8c820018, 0x38430007, 0x2c630001, 0x3842000b, 0x2c420001, 0x621825, @@ -3177,19 +3185,19 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x571021, 0x904283c0, 0x14400060, 0x0, 0x8f8400e4, 0xc41023, 0x218c3, 0x4620001, 0x24630200, 0x8f8900c4, 0x10600005, 0x24020001, -0x10620009, 0x0, 0x800418b, 0x0, +0x10620009, 0x0, 0x8004187, 0x0, 0x8ee20230, 0x1205821, 0x24420001, 0xaee20230, -0x80041c0, 0x8ee20230, 0x8ee20234, 0x3c05000a, +0x80041bc, 0x8ee20230, 0x8ee20234, 0x3c05000a, 0x24420001, 0xaee20234, 0x8c8b0000, 0x34a5f000, 0x8ee20234, 0x12b1823, 0xa3102b, 0x54400001, 0x651821, 0x2c62233f, 0x14400040, 0x0, 0x8f8200e8, 0x24420008, 0xaf8200e8, 0x8f8200e8, 0x8f8200e4, 0x1205821, 0x24420008, 0xaf8200e4, -0x80041c0, 0x8f8200e4, 0x8ee20238, 0x3c03000a, +0x80041bc, 0x8f8200e4, 0x8ee20238, 0x3c03000a, 0x24420001, 0xaee20238, 0x8c840000, 0x3463f000, 0x8ee20238, 0x883823, 0x67102b, 0x54400001, 0xe33821, 0x3c020003, 0x34420d40, 0x47102b, -0x10400003, 0x0, 0x80041c0, 0x805821, +0x10400003, 0x0, 0x80041bc, 0x805821, 0x8f8200e4, 0x24440008, 0xaf8400e4, 0x8f8400e4, 0x10860018, 0x3c05000a, 0x34a5f000, 0x3c0a0003, 0x354a0d40, 0x8ee2007c, 0x24420001, 0xaee2007c, @@ -3197,19 +3205,19 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x54400001, 0xe53821, 0x147102b, 0x54400007, 0x605821, 0x8f8200e4, 0x24440008, 0xaf8400e4, 0x8f8400e4, 0x1486ffef, 0x0, 0x14860005, -0x0, 0x1205821, 0xaf8600e4, 0x80041c0, +0x0, 0x1205821, 0xaf8600e4, 0x80041bc, 0xaf8600e8, 0xaf8400e4, 0xaf8400e8, 0x8f8200c8, 0x3c03000a, 0x3463f000, 0x483823, 0x67102b, 0x54400001, 0xe33821, 0x3c020003, 0x34420d3f, 0x47102b, 0x54400007, 0x6021, 0x1683823, -0x67102b, 0x54400003, 0xe33821, 0x80041d3, +0x67102b, 0x54400003, 0xe33821, 0x80041cf, 0x3c020003, 0x3c020003, 0x34420d3f, 0x47102b, 0x14400016, 0x318200ff, 0x14400006, 0x0, 0x3c020001, 0x571021, 0x904283c0, 0x1040000f, 0x0, 0x8ee2023c, 0x3c04fdff, 0x8ee30000, 0x3484ffff, 0x24420001, 0xaee2023c, 0x8ee2023c, 0x24020001, 0x641824, 0x3c010001, 0x370821, -0xa02283b8, 0x8004230, 0xaee30000, 0xaf8b00c8, +0xa02283b8, 0x800422c, 0xaee30000, 0xaf8b00c8, 0x8f8300c8, 0x8f8200c4, 0x3c04000a, 0x3484f000, 0x623823, 0x87102b, 0x54400001, 0xe43821, 0x3c020003, 0x34420d40, 0x47102b, 0x2ce30001, @@ -3218,7 +3226,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x431025, 0xaf820220, 0x8f8600e0, 0x8f8400e4, 0x10c4002a, 0x0, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x24c2fff8, 0xaf8200e0, -0x3c020001, 0x8c4275b0, 0x3c030008, 0x8f8600e0, +0x3c020001, 0x8c4275c0, 0x3c030008, 0x8f8600e0, 0x431024, 0x1040001d, 0x0, 0x10c4001b, 0x240dfff8, 0x3c0a000a, 0x354af000, 0x3c0c0080, 0x24850008, 0x27622800, 0x50a20001, 0x27651800, @@ -3228,14 +3236,14 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x12a4821, 0x10690002, 0x10c1025, 0xac820004, 0xa02021, 0x14c4ffeb, 0x24850008, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420002, -0xaf820220, 0x8f830054, 0x8f820054, 0x800423b, +0xaf820220, 0x8f830054, 0x8f820054, 0x8004237, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220, 0x6010055, 0x0, 0x8ee20228, 0x24420001, 0xaee20228, 0x8ee20228, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004, 0xaf820220, 0x8f830054, -0x8f820054, 0x8004255, 0x24630002, 0x8f820054, +0x8f820054, 0x8004251, 0x24630002, 0x8f820054, 0x621023, 0x2c420003, 0x1440fffc, 0x0, 0x8f8600e0, 0x30c20007, 0x10400012, 0x0, 0x8f8300e4, 0x2402fff8, 0xc21024, 0x1043000d, @@ -3250,16 +3258,16 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8ee2007c, 0x3c0408ff, 0x3484ffff, 0x471021, 0xaee2007c, 0x8f820220, 0x3c038000, 0x34630002, 0x441024, 0x431025, 0xaf820220, 0x8f830054, -0x8f820054, 0x8004291, 0x24630001, 0x8f820054, +0x8f820054, 0x800428d, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425488, +0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425498, 0x27bdffd8, 0x10400012, 0xafbf0020, 0x3c040001, -0x248451e4, 0x3c050008, 0x24020001, 0x3c010001, +0x248451f4, 0x3c050008, 0x24020001, 0x3c010001, 0x370821, 0xac2283ac, 0xafa00010, 0xafa00014, -0x8f860220, 0x34a50498, 0x3c010001, 0xac205488, -0x3c010001, 0xac22547c, 0xc002407, 0x3821, +0x8f860220, 0x34a50498, 0x3c010001, 0xac205498, +0x3c010001, 0xac22548c, 0xc002403, 0x3821, 0x8f420268, 0x3c037fff, 0x3463ffff, 0x431024, 0xaf420268, 0x8ee204d0, 0x8ee404d4, 0x2403fffe, 0x431024, 0x30840002, 0x1080011e, 0xaee204d0, @@ -3275,7 +3283,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128, 0x11020004, 0x0, 0x8f820124, 0x15020007, 0x1021, 0x8ee201a4, -0x2821, 0x24420001, 0xaee201a4, 0x8004341, +0x2821, 0x24420001, 0xaee201a4, 0x800433d, 0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004, @@ -3288,10 +3296,10 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x800432e, 0x0, 0x14600005, +0x0, 0x800432a, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x8004341, 0x0, 0x8ee24e30, +0xac800000, 0x800433d, 0x0, 0x8ee24e30, 0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac8d0000, 0xac8e0004, @@ -3305,7 +3313,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x50400001, 0x27663000, 0x8f820128, 0x10c20004, 0x0, 0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, 0x2821, 0x24420001, 0xaee201a4, -0x80043ad, 0x8ee201a4, 0x8ee20608, 0xac62001c, +0x80043a9, 0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, 0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, @@ -3315,34 +3323,34 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10470007, 0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x800439a, 0x0, 0x14600005, +0x0, 0x8004396, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x80043ad, 0x0, 0x8ee24e30, +0xac800000, 0x80043a9, 0x0, 0x8ee24e30, 0x24420001, 0x50470003, 0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, 0xac880000, 0xac8a0004, 0x54a00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, -0x24020001, 0x54620003, 0xafa00010, 0x80043da, -0x0, 0x3c040001, 0x248451f0, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002407, -0x34a5f011, 0x80043da, 0x0, 0x3c040001, -0x248451fc, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002407, 0x34a5f010, 0x80043da, -0x0, 0x3c040001, 0x24845208, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002407, +0x24020001, 0x54620003, 0xafa00010, 0x80043d6, +0x0, 0x3c040001, 0x24845200, 0xafa00014, +0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, +0x34a5f011, 0x80043d6, 0x0, 0x3c040001, +0x2484520c, 0xafa00014, 0x8f860120, 0x8f870124, +0x3c050009, 0xc002403, 0x34a5f010, 0x80043d6, +0x0, 0x3c040001, 0x24845218, 0xafa00014, +0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee2015c, 0x24420001, 0xaee2015c, 0x8ee2015c, 0x8fbf0020, 0x3e00008, 0x27bd0028, -0x3c020001, 0x8c425488, 0x27bdffe0, 0x1440000d, -0xafbf0018, 0x3c040001, 0x24845214, 0x3c050008, +0x3c020001, 0x8c425498, 0x27bdffe0, 0x1440000d, +0xafbf0018, 0x3c040001, 0x24845224, 0x3c050008, 0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499, -0x24020001, 0x3c010001, 0xac225488, 0xc002407, +0x24020001, 0x3c010001, 0xac225498, 0xc002403, 0x3821, 0x8ee204d0, 0x3c030001, 0x771821, 0x946383b2, 0x34420001, 0x10600007, 0xaee204d0, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, -0x34420008, 0xaf820220, 0x2021, 0xc0050af, +0x34420008, 0xaf820220, 0x2021, 0xc0050b3, 0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -3358,8 +3366,9 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c120001, -0x26521200, 0x3c140001, 0x8e945400, 0x3c100001, +0x26521200, 0x3c140001, 0x8e945410, 0x3c100001, 0x26101120, 0x3c15c000, 0x36b50060, 0x8e8a0000, 0x8eb30000, 0x26a400b, 0x248000a, 0x200f821, 0x0, 0xd, 0x0, 0x0, @@ -3376,19 +3385,19 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80014d6, 0x0, 0x80014d8, 0x3c0a0001, 0x80014d8, -0x3c0a0002, 0x80014d8, 0x0, 0x80024aa, +0x3c0a0002, 0x80014d8, 0x0, 0x80024a6, 0x0, 0x80014d8, 0x3c0a0003, 0x80014d8, -0x3c0a0004, 0x8002f90, 0x0, 0x80014d8, -0x3c0a0005, 0x8003cec, 0x0, 0x8003c6a, +0x3c0a0004, 0x8002f8c, 0x0, 0x80014d8, +0x3c0a0005, 0x8003ce8, 0x0, 0x8003c66, 0x0, 0x80014d8, 0x3c0a0006, 0x80014d8, 0x3c0a0007, 0x80014d8, 0x0, 0x80014d8, -0x0, 0x80014d8, 0x0, 0x8002a79, +0x0, 0x80014d8, 0x0, 0x8002a75, 0x0, 0x80014d8, 0x3c0a000b, 0x80014d8, -0x3c0a000c, 0x80014d8, 0x3c0a000d, 0x800237c, +0x3c0a000c, 0x80014d8, 0x3c0a000d, 0x800237a, 0x0, 0x8002339, 0x0, 0x80014d8, -0x3c0a000e, 0x8001b3c, 0x0, 0x80024a8, -0x0, 0x80014d8, 0x3c0a000f, 0x80040ab, -0x0, 0x8004095, 0x0, 0x80014d8, +0x3c0a000e, 0x8001b3c, 0x0, 0x80024a4, +0x0, 0x80014d8, 0x3c0a000f, 0x80040a7, +0x0, 0x8004091, 0x0, 0x80014d8, 0x3c0a0010, 0x80014ee, 0x0, 0x80014d8, 0x3c0a0011, 0x80014d8, 0x3c0a0012, 0x80014d8, 0x3c0a0013, 0x0, 0x0, 0x0, @@ -3420,863 +3429,864 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1062000c, 0x43102b, 0x14400006, 0x3c026000, 0x3c024000, 0x10620008, 0x24020800, 0x8004539, 0x0, 0x10620004, 0x24020800, 0x8004539, -0x0, 0x24020700, 0x3c010001, 0xac22548c, +0x0, 0x24020700, 0x3c010001, 0xac22549c, 0x3e00008, 0x0, 0x27bdffd0, 0xafbf0028, -0x3c010001, 0xc004ccd, 0xac205474, 0x24040001, -0x2821, 0x27a60020, 0x34028000, 0xc0048ea, +0x3c010001, 0xc004cd1, 0xac205484, 0x24040001, +0x2821, 0x27a60020, 0x34028000, 0xc0048ee, 0xa7a20020, 0x8f830054, 0x8f820054, 0x800454b, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050001, 0xc0048a8, +0x1440fffc, 0x24040001, 0x24050001, 0xc0048ac, 0x27a60020, 0x8f830054, 0x8f820054, 0x8004557, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050001, 0xc0048a8, +0x1440fffc, 0x24040001, 0x24050001, 0xc0048ac, 0x27a60020, 0x8f830054, 0x8f820054, 0x8004563, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050002, 0xc0048a8, +0x1440fffc, 0x24040001, 0x24050002, 0xc0048ac, 0x27a60018, 0x8f830054, 0x8f820054, 0x800456f, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050003, 0xc0048a8, -0x27a6001a, 0x97a20020, 0x10400027, 0x24030001, -0x3c020001, 0x8c425474, 0x97a30018, 0x34420001, -0x3c010001, 0xac225474, 0x24020015, 0x1462000d, -0x0, 0x97a2001a, 0x3843f423, 0x2c630001, -0x3842f430, 0x2c420001, 0x621825, 0x10600005, -0x24020003, 0x3c010001, 0xac225540, 0x80045a7, -0x3c08fff0, 0x97a30018, 0x24027810, 0x1462000a, -0x24020002, 0x97a3001a, 0x24020001, 0x14620006, -0x24020002, 0x24020004, 0x3c010001, 0xac225540, -0x80045a7, 0x3c08fff0, 0x3c010001, 0xac225540, -0x80045a7, 0x3c08fff0, 0x3c020001, 0x8c425474, -0x3c010001, 0xac235540, 0x34420004, 0x3c010001, -0xac225474, 0x3c08fff0, 0x3508bdc0, 0x8f830054, -0x97a60018, 0x3c070001, 0x8ce75540, 0x3c040001, -0x24845280, 0x24020001, 0x3c010001, 0xac22547c, -0xafa60010, 0x3c060001, 0x8cc65474, 0x97a2001a, -0x3c05000d, 0x34a50100, 0x3c010001, 0xac205478, -0x681821, 0x3c010001, 0xac235538, 0xc002407, -0xafa20014, 0x8fbf0028, 0x3e00008, 0x27bd0030, -0x27bdffe8, 0x24070004, 0x3c040001, 0x8c845478, -0x3021, 0x24020001, 0x1482000a, 0xafbf0010, -0x3c020001, 0x8c4275bc, 0x3c050004, 0x30428000, -0x1040000c, 0x34a593e0, 0x3c05000f, 0x80045da, -0x34a54240, 0x3c020001, 0x8c4275bc, 0x3c05000f, -0x30428000, 0x10400003, 0x34a54240, 0x3c05001e, -0x34a58480, 0x3c020001, 0x8c425538, 0x8f830054, -0x451021, 0x431023, 0x45102b, 0x1440002e, -0x0, 0x3c020001, 0x8c425480, 0x1440002a, -0x2cc20001, 0x7182b, 0x431024, 0x1040001d, -0x0, 0x3c090001, 0x8d295474, 0x240b0001, -0x3c054000, 0x3c080001, 0x250875bc, 0x250afffc, -0x42042, 0x14800002, 0x24e7ffff, 0x24040008, -0x891024, 0x5040000b, 0x2cc20001, 0x148b0004, -0x0, 0x8d020000, 0x80045ff, 0x451024, -0x8d420000, 0x451024, 0x54400001, 0x24060001, -0x2cc20001, 0x7182b, 0x431024, 0x5440ffed, -0x42042, 0x3c010001, 0x10c00024, 0xac245478, -0x8f830054, 0x24020001, 0x3c010001, 0xac22547c, -0x3c010001, 0xac235538, 0x3c020001, 0x8c42547c, -0x10400006, 0x24020001, 0x3c010001, 0xac20547c, -0x3c010001, 0x370821, 0xac2283ac, 0x3c030001, -0x771821, 0x8c6383ac, 0x24020008, 0x10620005, -0x24020001, 0xc00462f, 0x0, 0x800462c, -0x0, 0x3c030001, 0x8c635478, 0x10620007, -0x2402000e, 0x3c030001, 0x8c637550, 0x10620003, -0x0, 0xc004cf0, 0x8f840220, 0x8fbf0010, -0x3e00008, 0x27bd0018, 0x27bdffe0, 0x3c02fdff, -0xafbf0018, 0x8ee30000, 0x3c050001, 0x8ca55478, -0x3c040001, 0x8c845498, 0x3442ffff, 0x621824, -0x14a40008, 0xaee30000, 0x3c030001, 0x771821, -0x8c6383ac, 0x3c020001, 0x8c42549c, 0x10620008, +0x1440fffc, 0x24040001, 0x24050003, 0xc0048ac, +0x27a6001a, 0x97a20020, 0x10400028, 0x24030001, +0x3c020001, 0x8c425484, 0x97a30018, 0x34420001, +0x3c010001, 0xac225484, 0x24020015, 0x1462000e, +0x0, 0x97a2001a, 0x3042fff0, 0x3843f420, +0x2c630001, 0x3842f430, 0x2c420001, 0x621825, +0x10600005, 0x24020003, 0x3c010001, 0xac225550, +0x80045a8, 0x3c08fff0, 0x97a30018, 0x24027810, +0x1462000a, 0x24020002, 0x97a2001a, 0x3042fff0, +0x14400006, 0x24020002, 0x24020004, 0x3c010001, +0xac225550, 0x80045a8, 0x3c08fff0, 0x3c010001, +0xac225550, 0x80045a8, 0x3c08fff0, 0x3c020001, +0x8c425484, 0x3c010001, 0xac235550, 0x34420004, +0x3c010001, 0xac225484, 0x3c08fff0, 0x3508bdc0, +0x8f830054, 0x97a60018, 0x3c070001, 0x8ce75550, +0x3c040001, 0x24845290, 0x24020001, 0x3c010001, +0xac22548c, 0xafa60010, 0x3c060001, 0x8cc65484, +0x97a2001a, 0x3c05000d, 0x34a50100, 0x3c010001, +0xac205488, 0x681821, 0x3c010001, 0xac235548, +0xc002403, 0xafa20014, 0x8fbf0028, 0x3e00008, +0x27bd0030, 0x27bdffe8, 0x24070004, 0x3c040001, +0x8c845488, 0x3021, 0x24020001, 0x1482000a, +0xafbf0010, 0x3c020001, 0x8c4275cc, 0x3c050004, +0x30428000, 0x1040000c, 0x34a593e0, 0x3c05000f, +0x80045db, 0x34a54240, 0x3c020001, 0x8c4275cc, +0x3c05000f, 0x30428000, 0x10400003, 0x34a54240, +0x3c05001e, 0x34a58480, 0x3c020001, 0x8c425548, +0x8f830054, 0x451021, 0x431023, 0x45102b, +0x1440002e, 0x0, 0x3c020001, 0x8c425490, +0x1440002a, 0x2cc20001, 0x7182b, 0x431024, +0x1040001d, 0x0, 0x3c090001, 0x8d295484, +0x240b0001, 0x3c054000, 0x3c080001, 0x250875cc, +0x250afffc, 0x42042, 0x14800002, 0x24e7ffff, +0x24040008, 0x891024, 0x5040000b, 0x2cc20001, +0x148b0004, 0x0, 0x8d020000, 0x8004600, +0x451024, 0x8d420000, 0x451024, 0x54400001, +0x24060001, 0x2cc20001, 0x7182b, 0x431024, +0x5440ffed, 0x42042, 0x3c010001, 0x10c00024, +0xac245488, 0x8f830054, 0x24020001, 0x3c010001, +0xac22548c, 0x3c010001, 0xac235548, 0x3c020001, +0x8c42548c, 0x10400006, 0x24020001, 0x3c010001, +0xac20548c, 0x3c010001, 0x370821, 0xac2283ac, +0x3c030001, 0x771821, 0x8c6383ac, 0x24020008, +0x10620005, 0x24020001, 0xc004630, 0x0, +0x800462d, 0x0, 0x3c030001, 0x8c635488, +0x10620007, 0x2402000e, 0x3c030001, 0x8c637560, +0x10620003, 0x0, 0xc004cf4, 0x8f840220, +0x8fbf0010, 0x3e00008, 0x27bd0018, 0x27bdffe0, +0x3c02fdff, 0xafbf0018, 0x8ee30000, 0x3c050001, +0x8ca55488, 0x3c040001, 0x8c8454a8, 0x3442ffff, +0x621824, 0x14a40008, 0xaee30000, 0x3c030001, +0x771821, 0x8c6383ac, 0x3c020001, 0x8c4254ac, +0x10620008, 0x0, 0x3c020001, 0x571021, +0x8c4283ac, 0x3c010001, 0xac2554a8, 0x3c010001, +0xac2254ac, 0x3c030001, 0x8c635488, 0x24020002, +0x10620131, 0x2c620003, 0x10400005, 0x24020001, +0x10620008, 0x0, 0x800477f, 0x0, +0x24020004, 0x10620079, 0x24020001, 0x8004780, 0x0, 0x3c020001, 0x571021, 0x8c4283ac, -0x3c010001, 0xac255498, 0x3c010001, 0xac22549c, -0x3c030001, 0x8c635478, 0x24020002, 0x10620131, -0x2c620003, 0x10400005, 0x24020001, 0x10620008, -0x0, 0x800477e, 0x0, 0x24020004, -0x10620079, 0x24020001, 0x800477f, 0x0, -0x3c020001, 0x571021, 0x8c4283ac, 0x2443ffff, -0x2c620008, 0x10400122, 0x31080, 0x3c010001, -0x220821, 0x8c225298, 0x400008, 0x0, -0xc004784, 0x0, 0x3c020001, 0x8c425484, -0x3c010001, 0xac205410, 0x104000bd, 0x24020002, -0x3c010001, 0x370821, 0xac2283ac, 0x3c010001, -0x8004781, 0xac205484, 0xc00492b, 0x0, -0x3c030001, 0x8c6354a0, 0x80046f0, 0x24020011, -0x3c050001, 0x8ca55478, 0x3c060001, 0x8cc675bc, -0xc004fa4, 0x2021, 0x24020005, 0x3c010001, -0xac205484, 0x3c010001, 0x370821, 0x8004781, -0xac2283ac, 0x3c040001, 0x2484528c, 0x3c05000f, -0x34a50100, 0x3021, 0x3821, 0xafa00010, -0xc002407, 0xafa00014, 0x8004781, 0x0, -0x8f820220, 0x3c03f700, 0x431025, 0x8004719, -0xaf820220, 0x8f820220, 0x3c030004, 0x431024, -0x14400090, 0x24020007, 0x8f830054, 0x3c020001, -0x8c425530, 0x2463d8f0, 0x431023, 0x2c422710, -0x144000df, 0x24020001, 0x800477f, 0x0, -0x3c050001, 0x8ca55478, 0xc0050af, 0x2021, -0xc00517a, 0x2021, 0x3c030001, 0x8c6375b4, -0x46100d1, 0x24020001, 0x3c020008, 0x621024, -0x10400006, 0x0, 0x8f820214, 0x3c03ffff, -0x431024, 0x80046bc, 0x3442251f, 0x8f820214, -0x3c03ffff, 0x431024, 0x3442241f, 0xaf820214, -0x8ee20000, 0x3c030200, 0x431025, 0xaee20000, +0x2443ffff, 0x2c620008, 0x10400122, 0x31080, +0x3c010001, 0x220821, 0x8c2252a8, 0x400008, +0x0, 0xc004785, 0x0, 0x3c020001, +0x8c425494, 0x3c010001, 0xac205420, 0x104000bd, +0x24020002, 0x3c010001, 0x370821, 0xac2283ac, +0x3c010001, 0x8004782, 0xac205494, 0xc00492f, +0x0, 0x3c030001, 0x8c6354b0, 0x80046f1, +0x24020011, 0x3c050001, 0x8ca55488, 0x3c060001, +0x8cc675cc, 0xc004fa8, 0x2021, 0x24020005, +0x3c010001, 0xac205494, 0x3c010001, 0x370821, +0x8004782, 0xac2283ac, 0x3c040001, 0x2484529c, +0x3c05000f, 0x34a50100, 0x3021, 0x3821, +0xafa00010, 0xc002403, 0xafa00014, 0x8004782, +0x0, 0x8f820220, 0x3c03f700, 0x431025, +0x800471a, 0xaf820220, 0x8f820220, 0x3c030004, +0x431024, 0x14400090, 0x24020007, 0x8f830054, +0x3c020001, 0x8c425540, 0x2463d8f0, 0x431023, +0x2c422710, 0x144000df, 0x24020001, 0x8004780, +0x0, 0x3c050001, 0x8ca55488, 0xc0050b3, +0x2021, 0xc00517e, 0x2021, 0x3c030001, +0x8c6375c4, 0x46100d1, 0x24020001, 0x3c020008, +0x621024, 0x10400006, 0x0, 0x8f820214, +0x3c03ffff, 0x431024, 0x80046bd, 0x3442251f, +0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f, +0xaf820214, 0x8ee20000, 0x3c030200, 0x431025, +0xaee20000, 0x8f820220, 0x2403fffb, 0x431024, +0xaf820220, 0x8f820220, 0x34420002, 0xaf820220, +0x24020008, 0x3c010001, 0x370821, 0xc0043dd, +0xac2283ac, 0x8004782, 0x0, 0x3c020001, +0x571021, 0x8c4283ac, 0x2443ffff, 0x2c620008, +0x104000ac, 0x31080, 0x3c010001, 0x220821, +0x8c2252c8, 0x400008, 0x0, 0xc00429b, +0x0, 0x3c010001, 0xac20548c, 0xaf800204, +0x3c010001, 0xc004785, 0xac2075b0, 0x24020001, +0x3c010001, 0xac2254a0, 0x24020002, 0x3c010001, +0x370821, 0x8004782, 0xac2283ac, 0xc004802, +0x0, 0x3c030001, 0x8c6354a0, 0x24020009, +0x14620090, 0x24020003, 0x3c010001, 0x370821, +0x8004782, 0xac2283ac, 0x3c020001, 0x8c4275c8, +0x30424000, 0x10400005, 0x0, 0x8f820044, +0x3c03ffff, 0x8004702, 0x34637fff, 0x8f820044, +0x2403ff7f, 0x431024, 0xaf820044, 0x8f830054, +0x800471c, 0x24020004, 0x8f830054, 0x3c020001, +0x8c425540, 0x2463d8f0, 0x431023, 0x2c422710, +0x14400074, 0x24020005, 0x3c010001, 0x370821, +0x8004782, 0xac2283ac, 0x8f820220, 0x3c03f700, +0x431025, 0xaf820220, 0xaf800204, 0x3c010001, +0xac2075b0, 0x8f830054, 0x24020006, 0x3c010001, +0x370821, 0xac2283ac, 0x3c010001, 0x8004782, +0xac235540, 0x8f830054, 0x3c020001, 0x8c425540, +0x2463fff6, 0x431023, 0x2c42000a, 0x14400059, +0x0, 0x24020007, 0x3c010001, 0x370821, +0x8004782, 0xac2283ac, 0x8f820220, 0x3c04f700, +0x441025, 0xaf820220, 0x8f820220, 0x3c030300, +0x431024, 0x14400005, 0x1821, 0x8f820220, +0x24030001, 0x441025, 0xaf820220, 0x10600043, +0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001, +0x8c845538, 0x431024, 0x3442251f, 0xaf820214, +0x24020008, 0x3c010001, 0x370821, 0x1080000b, +0xac2283ac, 0x3c020001, 0x8c425514, 0x14400007, +0x24020001, 0x3c010001, 0xac227560, 0xc004cf4, +0x8f840220, 0x800476f, 0x0, 0x8f820220, +0x3c030008, 0x431024, 0x14400017, 0x2402000e, +0x3c010001, 0xac227560, 0x8ee20000, 0x2021, +0x3c030200, 0x431025, 0xc00517e, 0xaee20000, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, -0x8f820220, 0x34420002, 0xaf820220, 0x24020008, -0x3c010001, 0x370821, 0xc0043e1, 0xac2283ac, -0x8004781, 0x0, 0x3c020001, 0x571021, -0x8c4283ac, 0x2443ffff, 0x2c620008, 0x104000ac, -0x31080, 0x3c010001, 0x220821, 0x8c2252b8, -0x400008, 0x0, 0xc00429f, 0x0, -0x3c010001, 0xac20547c, 0xaf800204, 0x3c010001, -0xc004784, 0xac2075a0, 0x24020001, 0x3c010001, -0xac225490, 0x24020002, 0x3c010001, 0x370821, -0x8004781, 0xac2283ac, 0xc004801, 0x0, -0x3c030001, 0x8c635490, 0x24020009, 0x14620090, -0x24020003, 0x3c010001, 0x370821, 0x8004781, -0xac2283ac, 0x3c020001, 0x8c4275b8, 0x30424000, -0x10400005, 0x0, 0x8f820044, 0x3c03ffff, -0x8004701, 0x34637fff, 0x8f820044, 0x2403ff7f, -0x431024, 0xaf820044, 0x8f830054, 0x800471b, -0x24020004, 0x8f830054, 0x3c020001, 0x8c425530, -0x2463d8f0, 0x431023, 0x2c422710, 0x14400074, -0x24020005, 0x3c010001, 0x370821, 0x8004781, -0xac2283ac, 0x8f820220, 0x3c03f700, 0x431025, -0xaf820220, 0xaf800204, 0x3c010001, 0xac2075a0, -0x8f830054, 0x24020006, 0x3c010001, 0x370821, -0xac2283ac, 0x3c010001, 0x8004781, 0xac235530, -0x8f830054, 0x3c020001, 0x8c425530, 0x2463fff6, -0x431023, 0x2c42000a, 0x14400059, 0x0, -0x24020007, 0x3c010001, 0x370821, 0x8004781, -0xac2283ac, 0x8f820220, 0x3c04f700, 0x441025, -0xaf820220, 0x8f820220, 0x3c030300, 0x431024, -0x14400005, 0x1821, 0x8f820220, 0x24030001, -0x441025, 0xaf820220, 0x10600043, 0x24020001, -0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c845528, -0x431024, 0x3442251f, 0xaf820214, 0x24020008, -0x3c010001, 0x370821, 0x1080000b, 0xac2283ac, -0x3c020001, 0x8c425504, 0x14400007, 0x24020001, -0x3c010001, 0xac227550, 0xc004cf0, 0x8f840220, -0x800476e, 0x0, 0x8f820220, 0x3c030008, -0x431024, 0x14400017, 0x2402000e, 0x3c010001, -0xac227550, 0x8ee20000, 0x2021, 0x3c030200, -0x431025, 0xc00517a, 0xaee20000, 0x8f820220, -0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0xc0043e1, 0xaf820220, 0x3c050001, -0x8ca55478, 0xc0050af, 0x2021, 0x8004781, -0x0, 0x3c020001, 0x8c425504, 0x10400010, -0x0, 0x3c020001, 0x8c425500, 0x2442ffff, -0x3c010001, 0xac225500, 0x14400009, 0x24020002, -0x3c010001, 0xac205504, 0x3c010001, 0x8004781, -0xac225500, 0x24020001, 0x3c010001, 0xac22547c, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f820200, -0x8f820220, 0x8f820220, 0x34420004, 0xaf820220, -0x8f820200, 0x3c060001, 0x8cc65478, 0x34420004, -0xaf820200, 0x24020002, 0x10c2003a, 0x2cc20003, -0x10400005, 0x24020001, 0x10c20008, 0x0, -0x80047ca, 0x0, 0x24020004, 0x10c20013, -0x24020001, 0x80047ca, 0x0, 0x3c030001, -0x8c635468, 0x3c020001, 0x8c425470, 0x3c040001, -0x8c84548c, 0x3c050001, 0x8ca5546c, 0xaf860200, -0xaf860220, 0x34630022, 0x441025, 0x451025, -0x34420002, 0x80047c9, 0xaf830200, 0x3c030001, -0x8c635528, 0xaf820200, 0x10600009, 0xaf820220, -0x3c020001, 0x8c425504, 0x14400005, 0x3c033f00, -0x3c020001, 0x8c425460, 0x80047bd, 0x346300e0, -0x3c020001, 0x8c425460, 0x3c033f00, 0x346300e2, -0x431025, 0xaf820200, 0x3c030001, 0x8c635464, -0x3c04f700, 0x3c020001, 0x8c425470, 0x3c050001, -0x8ca5548c, 0x641825, 0x431025, 0x451025, -0xaf820220, 0x3e00008, 0x0, 0x8f820220, -0x3c030001, 0x8c635478, 0x34420004, 0xaf820220, -0x24020001, 0x1062000f, 0x0, 0x8f830054, -0x8f820054, 0x24630002, 0x621023, 0x2c420003, -0x10400011, 0x0, 0x8f820054, 0x621023, -0x2c420003, 0x1040000c, 0x0, 0x80047db, -0x0, 0x8f830054, 0x8f820054, 0x80047e7, -0x24630007, 0x8f820054, 0x621023, 0x2c420008, -0x1440fffc, 0x0, 0x8f8400e0, 0x30820007, -0x1040000d, 0x0, 0x8f820054, 0x8f8300e0, -0x14830009, 0x24450032, 0x8f820054, 0xa21023, -0x2c420033, 0x10400004, 0x0, 0x8f8200e0, -0x1082fff9, 0x0, 0x8f820220, 0x2403fffd, -0x431024, 0xaf820220, 0x3e00008, 0x0, -0x3c030001, 0x8c635490, 0x3c020001, 0x8c425494, -0x50620004, 0x2463ffff, 0x3c010001, 0xac235494, -0x2463ffff, 0x2c620009, 0x10400099, 0x31080, -0x3c010001, 0x220821, 0x8c2252d8, 0x400008, -0x0, 0x8f820044, 0x34428080, 0xaf820044, -0x8f830054, 0x8004896, 0x24020002, 0x8f830054, -0x3c020001, 0x8c425534, 0x2463d8f0, 0x431023, -0x2c422710, 0x14400086, 0x24020003, 0x80048a3, -0x0, 0x8f820044, 0x3c03ffff, 0x34637fff, -0x431024, 0xaf820044, 0x8f830054, 0x8004896, -0x24020004, 0x8f830054, 0x3c020001, 0x8c425534, -0x2463fff6, 0x431023, 0x2c42000a, 0x14400074, -0x24020005, 0x80048a3, 0x0, 0x8f820220, -0x3c03f700, 0x431025, 0xaf820220, 0x8f820220, -0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0xaf820220, 0x3c023f00, 0x344200e0, -0xaf820200, 0x8f820200, 0x2403fffd, 0x431024, -0xaf820200, 0x24040001, 0x3405ffff, 0xaf840204, -0x8f830054, 0x8f820054, 0x800484e, 0x24630001, -0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, -0x0, 0x8f820224, 0x42040, 0xa4102b, -0x1040fff2, 0x0, 0x8f820220, 0x3c03f700, -0x431025, 0xaf820220, 0x8f820214, 0x3c03ffff, -0x431024, 0x3442251f, 0xaf820214, 0x8f820220, -0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x3c04f700, 0x34840008, 0x34420002, 0xaf820220, -0x8f820220, 0x3c033f00, 0x346300e2, 0x441025, -0xaf820220, 0xaf830200, 0x8f8400f0, 0x276217f8, -0x14820002, 0x24850008, 0x27651000, 0x8f8200f4, -0x10a20007, 0x3c038000, 0x34630040, 0x3c020001, -0x24425420, 0xac820000, 0xac830004, 0xaf8500f0, -0x8f830054, 0x8004896, 0x24020006, 0x8f830054, -0x3c020001, 0x8c425534, 0x2463fff6, 0x431023, -0x2c42000a, 0x1440001e, 0x24020007, 0x80048a3, -0x0, 0x8f8200e0, 0xaf8200e4, 0x8f8200e0, -0xaf8200e8, 0x8f820220, 0x34420004, 0xaf820220, -0x8f820044, 0x34428080, 0xaf820044, 0x8f830054, -0x24020008, 0x3c010001, 0xac225490, 0x3c010001, -0x80048a5, 0xac235534, 0x8f830054, 0x3c020001, -0x8c425534, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400003, 0x24020009, 0x3c010001, 0xac225490, -0x3e00008, 0x0, 0x0, 0x27bdffd8, +0x8f820220, 0x34420002, 0xc0043dd, 0xaf820220, +0x3c050001, 0x8ca55488, 0xc0050b3, 0x2021, +0x8004782, 0x0, 0x3c020001, 0x8c425514, +0x10400010, 0x0, 0x3c020001, 0x8c425510, +0x2442ffff, 0x3c010001, 0xac225510, 0x14400009, +0x24020002, 0x3c010001, 0xac205514, 0x3c010001, +0x8004782, 0xac225510, 0x24020001, 0x3c010001, +0xac22548c, 0x8fbf0018, 0x3e00008, 0x27bd0020, +0x8f820200, 0x8f820220, 0x8f820220, 0x34420004, +0xaf820220, 0x8f820200, 0x3c060001, 0x8cc65488, +0x34420004, 0xaf820200, 0x24020002, 0x10c2003a, +0x2cc20003, 0x10400005, 0x24020001, 0x10c20008, +0x0, 0x80047cb, 0x0, 0x24020004, +0x10c20013, 0x24020001, 0x80047cb, 0x0, +0x3c030001, 0x8c635478, 0x3c020001, 0x8c425480, +0x3c040001, 0x8c84549c, 0x3c050001, 0x8ca5547c, +0xaf860200, 0xaf860220, 0x34630022, 0x441025, +0x451025, 0x34420002, 0x80047ca, 0xaf830200, +0x3c030001, 0x8c635538, 0xaf820200, 0x10600009, +0xaf820220, 0x3c020001, 0x8c425514, 0x14400005, +0x3c033f00, 0x3c020001, 0x8c425470, 0x80047be, +0x346300e0, 0x3c020001, 0x8c425470, 0x3c033f00, +0x346300e2, 0x431025, 0xaf820200, 0x3c030001, +0x8c635474, 0x3c04f700, 0x3c020001, 0x8c425480, +0x3c050001, 0x8ca5549c, 0x641825, 0x431025, +0x451025, 0xaf820220, 0x3e00008, 0x0, +0x8f820220, 0x3c030001, 0x8c635488, 0x34420004, +0xaf820220, 0x24020001, 0x1062000f, 0x0, +0x8f830054, 0x8f820054, 0x24630002, 0x621023, +0x2c420003, 0x10400011, 0x0, 0x8f820054, +0x621023, 0x2c420003, 0x1040000c, 0x0, +0x80047dc, 0x0, 0x8f830054, 0x8f820054, +0x80047e8, 0x24630007, 0x8f820054, 0x621023, +0x2c420008, 0x1440fffc, 0x0, 0x8f8400e0, +0x30820007, 0x1040000d, 0x0, 0x8f820054, +0x8f8300e0, 0x14830009, 0x24450032, 0x8f820054, +0xa21023, 0x2c420033, 0x10400004, 0x0, +0x8f8200e0, 0x1082fff9, 0x0, 0x8f820220, +0x2403fffd, 0x431024, 0xaf820220, 0x3e00008, +0x0, 0x3c030001, 0x8c6354a0, 0x3c020001, +0x8c4254a4, 0x50620004, 0x2463ffff, 0x3c010001, +0xac2354a4, 0x2463ffff, 0x2c620009, 0x1040009d, +0x31080, 0x3c010001, 0x220821, 0x8c2252e8, +0x400008, 0x0, 0x8f820044, 0x34428080, +0xaf820044, 0x8f830054, 0x800489b, 0x24020002, +0x8f830054, 0x3c020001, 0x8c425544, 0x2463d8f0, +0x431023, 0x2c422710, 0x1440008a, 0x24020003, +0x80048a8, 0x0, 0x8f820044, 0x3c03ffff, +0x34637fff, 0x431024, 0xaf820044, 0x8f830054, +0x800489b, 0x24020004, 0x8f830054, 0x3c020001, +0x8c425544, 0x2463fff6, 0x431023, 0x2c42000a, +0x14400078, 0x24020005, 0x80048a8, 0x0, +0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, +0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, +0x8f820220, 0x34420002, 0xaf820220, 0x3c023f00, +0x344200e0, 0xaf820200, 0x8f820200, 0x2403fffd, +0x431024, 0xaf820200, 0x24040001, 0x3405ffff, +0xaf840204, 0x8f830054, 0x8f820054, 0x800484f, +0x24630001, 0x8f820054, 0x621023, 0x2c420002, +0x1440fffc, 0x0, 0x8f820224, 0x42040, +0xa4102b, 0x1040fff2, 0x0, 0x8f820220, +0x3c03f700, 0x431025, 0xaf820220, 0x8f820214, +0x3c03ffff, 0x431024, 0x3442251f, 0xaf820214, +0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, +0x8f820220, 0x3c04f700, 0x34840008, 0x34420002, +0xaf820220, 0x8f820220, 0x3c033f00, 0x346300e2, +0x441025, 0xaf820220, 0xaf830200, 0x8f8400f0, +0x276217f8, 0x14820002, 0x24850008, 0x27651000, +0x8f8200f4, 0x10a20007, 0x3c038000, 0x34630040, +0x3c020001, 0x24425430, 0xac820000, 0xac830004, +0xaf8500f0, 0x8f830054, 0x800489b, 0x24020006, +0x8f830054, 0x3c020001, 0x8c425544, 0x2463fff6, +0x431023, 0x2c42000a, 0x14400022, 0x24020007, +0x80048a8, 0x0, 0x8f8200e0, 0xaf8200e4, +0x8f8200e0, 0xaf8200e8, 0x8f820220, 0x34420004, +0xaf820220, 0x8f820220, 0x2403fff7, 0x431024, +0xaf820220, 0x8f820044, 0x34428080, 0xaf820044, +0x8f830054, 0x24020008, 0x3c010001, 0xac2254a0, +0x3c010001, 0x80048aa, 0xac235544, 0x8f830054, +0x3c020001, 0x8c425544, 0x2463d8f0, 0x431023, +0x2c422710, 0x14400003, 0x24020009, 0x3c010001, +0xac2254a0, 0x3e00008, 0x0, 0x27bdffd8, 0xafb20018, 0x809021, 0xafb3001c, 0xa09821, 0xafb10014, 0xc08821, 0xafb00010, 0x8021, -0xafbf0020, 0xa6200000, 0xc004ca7, 0x24040001, +0xafbf0020, 0xa6200000, 0xc004cab, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004ca7, 0x2021, 0xc004ca7, 0x24040001, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x2021, 0xc004cab, 0x24040001, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x24100010, 0x2501024, 0x10400002, 0x2021, -0x24040001, 0xc004ca7, 0x108042, 0x1600fffa, +0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x2501024, 0x24100010, 0x2701024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fffa, 0x2701024, 0xc004ccd, 0x34108000, -0xc004ccd, 0x0, 0xc004c87, 0x0, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fffa, 0x2701024, 0xc004cd1, 0x34108000, +0xc004cd1, 0x0, 0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004ccd, 0x0, 0x8fbf0020, 0x8fb3001c, +0xc004cd1, 0x0, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821, 0xafb20018, 0xa09021, 0xafb3001c, 0xc09821, -0xafb00010, 0x8021, 0xafbf0020, 0xc004ca7, +0xafb00010, 0x8021, 0xafbf0020, 0xc004cab, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004ca7, 0x2021, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0xc004ca7, +0x0, 0xc004cab, 0x2021, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0xc004cab, 0x24040001, 0x24100010, 0x2301024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, +0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x2301024, 0x24100010, 0x2501024, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, -0x108042, 0x1600fffa, 0x2501024, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004cab, +0x108042, 0x1600fffa, 0x2501024, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96620000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004ca7, 0x108042, 0x1600fff8, -0x0, 0xc004ccd, 0x0, 0x8fbf0020, +0x24040001, 0xc004cab, 0x108042, 0x1600fff8, +0x0, 0xc004cd1, 0x0, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, -0x3e00008, 0x27bd0028, 0x3c030001, 0x8c6354a0, -0x3c020001, 0x8c4254e4, 0x27bdffd8, 0xafbf0020, +0x3e00008, 0x27bd0028, 0x3c030001, 0x8c6354b0, +0x3c020001, 0x8c4254f4, 0x27bdffd8, 0xafbf0020, 0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001, -0xac2354e4, 0x2463ffff, 0x2c620013, 0x10400349, -0x31080, 0x3c010001, 0x220821, 0x8c225300, -0x400008, 0x0, 0xc004ccd, 0x8021, -0x34028000, 0xa7a20010, 0x27b10010, 0xc004ca7, +0xac2354f4, 0x2463ffff, 0x2c620013, 0x10400349, +0x31080, 0x3c010001, 0x220821, 0x8c225310, +0x400008, 0x0, 0xc004cd1, 0x8021, +0x34028000, 0xa7a20010, 0x27b10010, 0xc004cab, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004ca7, 0x2021, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0xc004ca7, +0x0, 0xc004cab, 0x2021, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0xc004cab, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0xc004ca7, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fffa, 0x32020001, 0x24100010, 0xc004cab, 0x2021, 0x108042, 0x1600fffc, 0x0, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8004c80, 0x24020002, 0x27b10010, 0xa7a00010, -0x8021, 0xc004ca7, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004ca7, -0x2021, 0xc004ca7, 0x24040001, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0x24100010, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8004c84, 0x24020002, 0x27b10010, 0xa7a00010, +0x8021, 0xc004cab, 0x24040001, 0x26100001, +0x2e020020, 0x1440fffb, 0x0, 0xc004cab, +0x2021, 0xc004cab, 0x24040001, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0xc004ca7, 0x2021, 0x108042, -0x1600fffc, 0x0, 0xc004ccd, 0x34108000, -0xc004ccd, 0x0, 0xc004c87, 0x0, +0xc004cab, 0x108042, 0x1600fffa, 0x32020001, +0x24100010, 0xc004cab, 0x2021, 0x108042, +0x1600fffc, 0x0, 0xc004cd1, 0x34108000, +0xc004cd1, 0x0, 0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004ccd, 0x0, 0x97a20010, 0x30428000, -0x144002dc, 0x24020003, 0x8004c80, 0x0, +0xc004cd1, 0x0, 0x97a20010, 0x30428000, +0x144002dc, 0x24020003, 0x8004c84, 0x0, 0x24021200, 0xa7a20010, 0x27b10010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0xc004ca7, 0x2021, 0x108042, 0x1600fffc, -0x0, 0xc004ca7, 0x24040001, 0xc004ca7, +0xc004cab, 0x2021, 0x108042, 0x1600fffc, +0x0, 0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, -0x108042, 0x1600fff8, 0x0, 0xc004ccd, -0x0, 0x8f830054, 0x8004c72, 0x24020004, -0x8f830054, 0x3c020001, 0x8c42553c, 0x2463ff9c, +0x10400002, 0x2021, 0x24040001, 0xc004cab, +0x108042, 0x1600fff8, 0x0, 0xc004cd1, +0x0, 0x8f830054, 0x8004c76, 0x24020004, +0x8f830054, 0x3c020001, 0x8c42554c, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440029e, 0x24020002, -0x3c030001, 0x8c635540, 0x10620297, 0x2c620003, +0x3c030001, 0x8c635550, 0x10620297, 0x2c620003, 0x14400296, 0x24020011, 0x24020003, 0x10620005, -0x24020004, 0x10620291, 0x2402000f, 0x8004c80, -0x24020011, 0x8004c80, 0x24020005, 0x24020014, -0xa7a20010, 0x27b10010, 0x8021, 0xc004ca7, +0x24020004, 0x10620291, 0x2402000f, 0x8004c84, +0x24020011, 0x8004c84, 0x24020005, 0x24020014, +0xa7a20010, 0x27b10010, 0x8021, 0xc004cab, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004ca7, 0x2021, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0xc004ca7, +0x0, 0xc004cab, 0x2021, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0xc004cab, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, +0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020012, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, -0x108042, 0x1600fffa, 0x32020012, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004cab, +0x108042, 0x1600fffa, 0x32020012, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004ca7, 0x108042, 0x1600fff8, -0x0, 0xc004ccd, 0x0, 0x8f830054, -0x8004c72, 0x24020006, 0x8f830054, 0x3c020001, -0x8c42553c, 0x2463ff9c, 0x431023, 0x2c420064, -0x14400250, 0x24020007, 0x8004c80, 0x0, +0x24040001, 0xc004cab, 0x108042, 0x1600fff8, +0x0, 0xc004cd1, 0x0, 0x8f830054, +0x8004c76, 0x24020006, 0x8f830054, 0x3c020001, +0x8c42554c, 0x2463ff9c, 0x431023, 0x2c420064, +0x14400250, 0x24020007, 0x8004c84, 0x0, 0x24020006, 0xa7a20010, 0x27b10010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020013, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020013, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x108042, 0x1600fffa, 0x32020013, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8f830054, 0x8004c72, 0x24020008, 0x8f830054, -0x3c020001, 0x8c42553c, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440020f, 0x24020009, 0x8004c80, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8f830054, 0x8004c76, 0x24020008, 0x8f830054, +0x3c020001, 0x8c42554c, 0x2463ff9c, 0x431023, +0x2c420064, 0x1440020f, 0x24020009, 0x8004c84, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x24040001, -0xc004ca7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x24040001, +0xc004cab, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020018, -0xc004ccd, 0x34108000, 0xc004ccd, 0x0, -0xc004c87, 0x0, 0x50400005, 0x108042, +0xc004cab, 0x108042, 0x1600fffa, 0x32020018, +0xc004cd1, 0x34108000, 0xc004cd1, 0x0, +0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004ccd, 0x8021, +0x1600fff7, 0x0, 0xc004cd1, 0x8021, 0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020018, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x108042, 0x1600fffa, 0x32020018, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8f830054, 0x8004c72, 0x2402000a, 0x8f830054, -0x3c020001, 0x8c42553c, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440019b, 0x2402000b, 0x8004c80, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8f830054, 0x8004c76, 0x2402000a, 0x8f830054, +0x3c020001, 0x8c42554c, 0x2463ff9c, 0x431023, +0x2c420064, 0x1440019b, 0x2402000b, 0x8004c84, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x24040001, -0xc004ca7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x24040001, +0xc004cab, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020017, -0xc004ccd, 0x34108000, 0xc004ccd, 0x0, -0xc004c87, 0x0, 0x50400005, 0x108042, +0xc004cab, 0x108042, 0x1600fffa, 0x32020017, +0xc004cd1, 0x34108000, 0xc004cd1, 0x0, +0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004ccd, 0x8021, +0x1600fff7, 0x0, 0xc004cd1, 0x8021, 0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020017, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x108042, 0x1600fffa, 0x32020017, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8f830054, 0x8004c72, 0x2402000c, 0x8f830054, -0x3c020001, 0x8c42553c, 0x2463ff9c, 0x431023, -0x2c420064, 0x14400127, 0x24020012, 0x8004c80, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8f830054, 0x8004c76, 0x2402000c, 0x8f830054, +0x3c020001, 0x8c42554c, 0x2463ff9c, 0x431023, +0x2c420064, 0x14400127, 0x24020012, 0x8004c84, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x24040001, -0xc004ca7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x24040001, +0xc004cab, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020014, -0xc004ccd, 0x34108000, 0xc004ccd, 0x0, -0xc004c87, 0x0, 0x50400005, 0x108042, +0xc004cab, 0x108042, 0x1600fffa, 0x32020014, +0xc004cd1, 0x34108000, 0xc004cd1, 0x0, +0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004ccd, 0x8021, +0x1600fff7, 0x0, 0xc004cd1, 0x8021, 0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020014, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x108042, 0x1600fffa, 0x32020014, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8f830054, 0x8004c72, 0x24020013, 0x8f830054, -0x3c020001, 0x8c42553c, 0x2463ff9c, 0x431023, -0x2c420064, 0x144000b3, 0x2402000d, 0x8004c80, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8f830054, 0x8004c76, 0x24020013, 0x8f830054, +0x3c020001, 0x8c42554c, 0x2463ff9c, 0x431023, +0x2c420064, 0x144000b3, 0x2402000d, 0x8004c84, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x24040001, -0xc004ca7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x24040001, +0xc004cab, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020018, -0xc004ccd, 0x34108000, 0xc004ccd, 0x0, -0xc004c87, 0x0, 0x50400005, 0x108042, +0xc004cab, 0x108042, 0x1600fffa, 0x32020018, +0xc004cd1, 0x34108000, 0xc004cd1, 0x0, +0xc004c8b, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004ccd, 0x8021, +0x1600fff7, 0x0, 0xc004cd1, 0x8021, 0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010, -0xc004ca7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, -0xc004ca7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, +0xc004cab, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, +0xc004cab, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004ca7, 0x108042, 0x1600fffa, 0x32020018, -0xc004ca7, 0x24040001, 0xc004ca7, 0x2021, +0xc004cab, 0x108042, 0x1600fffa, 0x32020018, +0xc004cab, 0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, -0x1600fff8, 0x0, 0xc004ccd, 0x0, -0x8f830054, 0x8004c72, 0x2402000e, 0x24020840, -0xa7a20010, 0x27b10010, 0x8021, 0xc004ca7, +0x2021, 0x24040001, 0xc004cab, 0x108042, +0x1600fff8, 0x0, 0xc004cd1, 0x0, +0x8f830054, 0x8004c76, 0x2402000e, 0x24020840, +0xa7a20010, 0x27b10010, 0x8021, 0xc004cab, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004ca7, 0x2021, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0xc004ca7, +0x0, 0xc004cab, 0x2021, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0xc004cab, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004ca7, 0x108042, +0x2021, 0x24040001, 0xc004cab, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020013, -0x10400002, 0x2021, 0x24040001, 0xc004ca7, -0x108042, 0x1600fffa, 0x32020013, 0xc004ca7, -0x24040001, 0xc004ca7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004cab, +0x108042, 0x1600fffa, 0x32020013, 0xc004cab, +0x24040001, 0xc004cab, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004ca7, 0x108042, 0x1600fff8, -0x0, 0xc004ccd, 0x0, 0x8f830054, -0x24020010, 0x3c010001, 0xac2254a0, 0x3c010001, -0x8004c82, 0xac23553c, 0x8f830054, 0x3c020001, -0x8c42553c, 0x2463ff9c, 0x431023, 0x2c420064, +0x24040001, 0xc004cab, 0x108042, 0x1600fff8, +0x0, 0xc004cd1, 0x0, 0x8f830054, +0x24020010, 0x3c010001, 0xac2254b0, 0x3c010001, +0x8004c86, 0xac23554c, 0x8f830054, 0x3c020001, +0x8c42554c, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400004, 0x0, 0x24020011, 0x3c010001, -0xac2254a0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, +0xac2254b0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044, 0x3c030001, 0x431025, 0x3c030008, 0xaf820044, -0x8f840054, 0x8f820054, 0xa32824, 0x8004c93, +0x8f840054, 0x8f820054, 0xa32824, 0x8004c97, 0x24840001, 0x8f820054, 0x821023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, -0x8f820054, 0x8004ca1, 0x24630001, 0x8f820054, +0x8f820054, 0x8004ca5, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0, 0x3442ffff, 0x42480, 0x621824, 0x3c020002, 0x822025, 0x641825, 0xaf830044, 0x8f820044, 0x3c030001, 0x431025, 0xaf820044, 0x8f830054, -0x8f820054, 0x8004cb9, 0x24630001, 0x8f820054, +0x8f820054, 0x8004cbd, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, -0xaf820044, 0x8f830054, 0x8f820054, 0x8004cc7, +0xaf820044, 0x8f830054, 0x8f820054, 0x8004ccb, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0x0, 0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024, 0xaf820044, 0x8f820044, 0x3c030001, 0x431025, -0xaf820044, 0x8f830054, 0x8f820054, 0x8004cdb, +0xaf820044, 0x8f830054, 0x8f820054, 0x8004cdf, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, -0x8f820054, 0x8004ce9, 0x24630001, 0x8f820054, +0x8f820054, 0x8004ced, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0x0, 0x0, 0x27bdffe8, 0xafbf0010, 0x3c030001, 0x771821, 0x8c6383ac, 0x24020008, 0x1462022c, 0x803021, 0x3c020001, -0x8c425528, 0x14400033, 0x0, 0x8f850224, +0x8c425538, 0x14400033, 0x0, 0x8f850224, 0x38a30020, 0x2c630001, 0x38a20010, 0x2c420001, 0x621825, 0x1460000d, 0x38a30030, 0x2c630001, 0x38a20400, 0x2c420001, 0x621825, 0x14600007, 0x38a30402, 0x2c630001, 0x38a20404, 0x2c420001, -0x621825, 0x10600005, 0x0, 0xc00429f, -0x0, 0x8004d29, 0x2402000e, 0xc0043e1, -0x0, 0x3c050001, 0x8ca55478, 0xc0050af, -0x2021, 0x3c030001, 0x8c635478, 0x24020004, -0x14620005, 0x2403fffb, 0x3c020001, 0x8c425474, -0x8004d25, 0x2403fff7, 0x3c020001, 0x8c425474, -0x431024, 0x3c010001, 0xac225474, 0x2402000e, -0x3c010001, 0xc00429f, 0xac227550, 0x8004f23, +0x621825, 0x10600005, 0x0, 0xc00429b, +0x0, 0x8004d2d, 0x2402000e, 0xc0043dd, +0x0, 0x3c050001, 0x8ca55488, 0xc0050b3, +0x2021, 0x3c030001, 0x8c635488, 0x24020004, +0x14620005, 0x2403fffb, 0x3c020001, 0x8c425484, +0x8004d29, 0x2403fff7, 0x3c020001, 0x8c425484, +0x431024, 0x3c010001, 0xac225484, 0x2402000e, +0x3c010001, 0xc00429b, 0xac227560, 0x8004f27, 0x0, 0x8f820220, 0x3c030400, 0x431024, 0x10400027, 0x2403ffbf, 0x8f850224, 0x3c020001, -0x8c42755c, 0xa32024, 0x431024, 0x1482000c, -0x0, 0x3c020001, 0x8c427560, 0x24420001, -0x3c010001, 0xac227560, 0x2c420002, 0x14400008, -0x24020001, 0x3c010001, 0x8004d49, 0xac227580, -0x3c010001, 0xac207560, 0x3c010001, 0xac207580, -0x3c020001, 0x8c427580, 0x10400006, 0x30a20040, -0x10400004, 0x24020001, 0x3c010001, 0x8004d54, -0xac227584, 0x3c010001, 0xac207584, 0x3c010001, -0xac25755c, 0x3c010001, 0x8004d64, 0xac207590, -0x24020001, 0x3c010001, 0xac227590, 0x3c010001, -0xac207580, 0x3c010001, 0xac207560, 0x3c010001, -0xac207584, 0x3c010001, 0xac20755c, 0x3c030001, -0x8c637550, 0x3c020001, 0x8c427554, 0x10620003, -0x3c020200, 0x3c010001, 0xac237554, 0xc21024, +0x8c42756c, 0xa32024, 0x431024, 0x1482000c, +0x0, 0x3c020001, 0x8c427570, 0x24420001, +0x3c010001, 0xac227570, 0x2c420002, 0x14400008, +0x24020001, 0x3c010001, 0x8004d4d, 0xac227590, +0x3c010001, 0xac207570, 0x3c010001, 0xac207590, +0x3c020001, 0x8c427590, 0x10400006, 0x30a20040, +0x10400004, 0x24020001, 0x3c010001, 0x8004d58, +0xac227594, 0x3c010001, 0xac207594, 0x3c010001, +0xac25756c, 0x3c010001, 0x8004d68, 0xac2075a0, +0x24020001, 0x3c010001, 0xac2275a0, 0x3c010001, +0xac207590, 0x3c010001, 0xac207570, 0x3c010001, +0xac207594, 0x3c010001, 0xac20756c, 0x3c030001, +0x8c637560, 0x3c020001, 0x8c427564, 0x10620003, +0x3c020200, 0x3c010001, 0xac237564, 0xc21024, 0x10400007, 0x2463ffff, 0x8f820220, 0x24030001, -0x3c010001, 0xac23547c, 0x8004f21, 0x3c03f700, +0x3c010001, 0xac23548c, 0x8004f25, 0x3c03f700, 0x2c62000e, 0x104001a8, 0x31080, 0x3c010001, -0x220821, 0x8c225350, 0x400008, 0x0, -0x3c010001, 0xac207580, 0x3c010001, 0xac207560, -0x3c010001, 0xac20755c, 0x3c010001, 0xac207584, -0x3c010001, 0xac207578, 0x3c010001, 0xac207570, -0xc0047cc, 0xaf800224, 0x24020002, 0x3c010001, -0xac227550, 0x3c020001, 0x8c427590, 0x14400056, +0x220821, 0x8c225360, 0x400008, 0x0, +0x3c010001, 0xac207590, 0x3c010001, 0xac207570, +0x3c010001, 0xac20756c, 0x3c010001, 0xac207594, +0x3c010001, 0xac207588, 0x3c010001, 0xac207580, +0xc0047cd, 0xaf800224, 0x24020002, 0x3c010001, +0xac227560, 0x3c020001, 0x8c4275a0, 0x14400056, 0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024, -0xc00429f, 0xaee20000, 0xaf800204, 0x8f820200, +0xc00429b, 0xaee20000, 0xaf800204, 0x8f820200, 0x2403fffd, 0x431024, 0xaf820200, 0x3c010001, -0xac2075a0, 0x8f830054, 0x3c020001, 0x8c427578, -0x24040001, 0x3c010001, 0xac24758c, 0x24420001, -0x3c010001, 0xac227578, 0x2c420004, 0x3c010001, -0xac237574, 0x14400006, 0x24020003, 0x3c010001, -0xac24547c, 0x3c010001, 0x8004f1f, 0xac207578, -0x3c010001, 0x8004f1f, 0xac227550, 0x8f830054, -0x3c020001, 0x8c427574, 0x2463d8f0, 0x431023, +0xac2075b0, 0x8f830054, 0x3c020001, 0x8c427588, +0x24040001, 0x3c010001, 0xac24759c, 0x24420001, +0x3c010001, 0xac227588, 0x2c420004, 0x3c010001, +0xac237584, 0x14400006, 0x24020003, 0x3c010001, +0xac24548c, 0x3c010001, 0x8004f23, 0xac207588, +0x3c010001, 0x8004f23, 0xac227560, 0x8f830054, +0x3c020001, 0x8c427584, 0x2463d8f0, 0x431023, 0x2c422710, 0x14400003, 0x24020004, 0x3c010001, -0xac227550, 0x3c020001, 0x8c427590, 0x14400026, +0xac227560, 0x3c020001, 0x8c4275a0, 0x14400026, 0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024, -0x8004f1f, 0xaee20000, 0x3c040001, 0x8c84552c, -0x3c010001, 0xc004f26, 0xac207568, 0x3c020001, -0x8c42759c, 0xaf820204, 0x3c020001, 0x8c427590, +0x8004f23, 0xaee20000, 0x3c040001, 0x8c84553c, +0x3c010001, 0xc004f2a, 0xac207578, 0x3c020001, +0x8c4275ac, 0xaf820204, 0x3c020001, 0x8c4275a0, 0x14400015, 0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024, 0xaee20000, 0x8f820204, 0x30420030, -0x1440013c, 0x24020002, 0x3c030001, 0x8c63759c, -0x24020005, 0x3c010001, 0xac227550, 0x3c010001, -0x8004f1f, 0xac2375a0, 0x3c020001, 0x8c427590, -0x10400010, 0x3c03fdff, 0x3c020001, 0x8c4254fc, -0x24420001, 0x3c010001, 0xac2254fc, 0x2c420002, -0x14400131, 0x24020001, 0x3c010001, 0xac225504, -0x3c010001, 0xac2054fc, 0x3c010001, 0x8004f1f, -0xac22547c, 0x8ee20000, 0x3463ffff, 0x431024, -0xaee20000, 0x3c020001, 0x8c427580, 0x10400122, -0x0, 0x3c020001, 0x8c42755c, 0x1040011e, -0x0, 0x3c010001, 0xac227588, 0x24020003, -0x3c010001, 0xac227560, 0x8004ec0, 0x24020006, -0x3c010001, 0xac207568, 0x8f820204, 0x34420040, -0xaf820204, 0x3c020001, 0x8c4275a0, 0x24030007, -0x3c010001, 0xac237550, 0x34420040, 0x3c010001, -0xac2275a0, 0x3c020001, 0x8c427580, 0x10400005, -0x0, 0x3c020001, 0x8c42755c, 0x104000f9, -0x24020002, 0x3c050001, 0x24a57560, 0x8ca20000, +0x1440013c, 0x24020002, 0x3c030001, 0x8c6375ac, +0x24020005, 0x3c010001, 0xac227560, 0x3c010001, +0x8004f23, 0xac2375b0, 0x3c020001, 0x8c4275a0, +0x10400010, 0x3c03fdff, 0x3c020001, 0x8c42550c, +0x24420001, 0x3c010001, 0xac22550c, 0x2c420002, +0x14400131, 0x24020001, 0x3c010001, 0xac225514, +0x3c010001, 0xac20550c, 0x3c010001, 0x8004f23, +0xac22548c, 0x8ee20000, 0x3463ffff, 0x431024, +0xaee20000, 0x3c020001, 0x8c427590, 0x10400122, +0x0, 0x3c020001, 0x8c42756c, 0x1040011e, +0x0, 0x3c010001, 0xac227598, 0x24020003, +0x3c010001, 0xac227570, 0x8004ec4, 0x24020006, +0x3c010001, 0xac207578, 0x8f820204, 0x34420040, +0xaf820204, 0x3c020001, 0x8c4275b0, 0x24030007, +0x3c010001, 0xac237560, 0x34420040, 0x3c010001, +0xac2275b0, 0x3c020001, 0x8c427590, 0x10400005, +0x0, 0x3c020001, 0x8c42756c, 0x104000f9, +0x24020002, 0x3c050001, 0x24a57570, 0x8ca20000, 0x2c424e21, 0x104000f3, 0x24020002, 0x3c020001, -0x8c427584, 0x104000f8, 0x2404ffbf, 0x3c020001, -0x8c42755c, 0x3c030001, 0x8c637588, 0x441024, +0x8c427594, 0x104000f8, 0x2404ffbf, 0x3c020001, +0x8c42756c, 0x3c030001, 0x8c637598, 0x441024, 0x641824, 0x10430004, 0x24020001, 0x3c010001, -0x8004f1f, 0xac227550, 0x24020003, 0xaca20000, -0x24020008, 0x3c010001, 0xac227550, 0x3c020001, -0x8c42758c, 0x1040000c, 0x24020001, 0x3c040001, -0xc004f33, 0x8c84755c, 0x3c020001, 0x8c4275a8, -0x14400005, 0x24020001, 0x3c020001, 0x8c4275a4, -0x10400006, 0x24020001, 0x3c010001, 0xac22547c, -0x3c010001, 0x8004f1f, 0xac207578, 0x3c020001, -0x8c427570, 0x3c030001, 0x8c63755c, 0x2c420001, -0x210c0, 0x30630008, 0x3c010001, 0xac227570, -0x3c010001, 0xac23756c, 0x8f830054, 0x24020009, -0x3c010001, 0xac227550, 0x3c010001, 0x8004f1f, -0xac237574, 0x8f830054, 0x3c020001, 0x8c427574, +0x8004f23, 0xac227560, 0x24020003, 0xaca20000, +0x24020008, 0x3c010001, 0xac227560, 0x3c020001, +0x8c42759c, 0x1040000c, 0x24020001, 0x3c040001, +0xc004f37, 0x8c84756c, 0x3c020001, 0x8c4275b8, +0x14400005, 0x24020001, 0x3c020001, 0x8c4275b4, +0x10400006, 0x24020001, 0x3c010001, 0xac22548c, +0x3c010001, 0x8004f23, 0xac207588, 0x3c020001, +0x8c427580, 0x3c030001, 0x8c63756c, 0x2c420001, +0x210c0, 0x30630008, 0x3c010001, 0xac227580, +0x3c010001, 0xac23757c, 0x8f830054, 0x24020009, +0x3c010001, 0xac227560, 0x3c010001, 0x8004f23, +0xac237584, 0x8f830054, 0x3c020001, 0x8c427584, 0x2463d8f0, 0x431023, 0x2c422710, 0x144000a8, -0x0, 0x3c020001, 0x8c427580, 0x10400005, -0x0, 0x3c020001, 0x8c42755c, 0x104000a9, -0x24020002, 0x3c030001, 0x24637560, 0x8c620000, +0x0, 0x3c020001, 0x8c427590, 0x10400005, +0x0, 0x3c020001, 0x8c42756c, 0x104000a9, +0x24020002, 0x3c030001, 0x24637570, 0x8c620000, 0x2c424e21, 0x104000a3, 0x24020002, 0x3c020001, -0x8c42758c, 0x1040000e, 0x0, 0x3c020001, -0x8c42755c, 0x3c010001, 0xac20758c, 0x30420080, +0x8c42759c, 0x1040000e, 0x0, 0x3c020001, +0x8c42756c, 0x3c010001, 0xac20759c, 0x30420080, 0x1040002f, 0x2402000c, 0x8f820204, 0x30420080, -0x1440000c, 0x24020003, 0x8004ead, 0x2402000c, -0x3c020001, 0x8c42755c, 0x30420080, 0x14400005, +0x1440000c, 0x24020003, 0x8004eb1, 0x2402000c, +0x3c020001, 0x8c42756c, 0x30420080, 0x14400005, 0x24020003, 0x8f820204, 0x30420080, 0x1040001f, 0x24020003, 0xac620000, 0x2402000a, 0x3c010001, -0xac227550, 0x3c040001, 0x24847598, 0x8c820000, -0x3c030001, 0x8c637570, 0x431025, 0xaf820204, -0x8c830000, 0x3c040001, 0x8c847570, 0x2402000b, -0x3c010001, 0xac227550, 0x641825, 0x3c010001, -0xac2375a0, 0x3c050001, 0x24a57560, 0x8ca20000, +0xac227560, 0x3c040001, 0x248475a8, 0x8c820000, +0x3c030001, 0x8c637580, 0x431025, 0xaf820204, +0x8c830000, 0x3c040001, 0x8c847580, 0x2402000b, +0x3c010001, 0xac227560, 0x641825, 0x3c010001, +0xac2375b0, 0x3c050001, 0x24a57570, 0x8ca20000, 0x2c424e21, 0x1040006f, 0x24020002, 0x3c020001, -0x8c427590, 0x10400005, 0x0, 0x2402000c, -0x3c010001, 0x8004f1f, 0xac227550, 0x3c020001, -0x8c427580, 0x1040006c, 0x0, 0x3c040001, -0x8c84755c, 0x1080005e, 0x30820008, 0x3c030001, -0x8c63756c, 0x10620064, 0x24020003, 0x3c010001, -0xac247588, 0xaca20000, 0x24020006, 0x3c010001, -0x8004f1f, 0xac227550, 0x8f820200, 0x34420002, +0x8c4275a0, 0x10400005, 0x0, 0x2402000c, +0x3c010001, 0x8004f23, 0xac227560, 0x3c020001, +0x8c427590, 0x1040006c, 0x0, 0x3c040001, +0x8c84756c, 0x1080005e, 0x30820008, 0x3c030001, +0x8c63757c, 0x10620064, 0x24020003, 0x3c010001, +0xac247598, 0xaca20000, 0x24020006, 0x3c010001, +0x8004f23, 0xac227560, 0x8f820200, 0x34420002, 0xaf820200, 0x8f830054, 0x2402000d, 0x3c010001, -0xac227550, 0x3c010001, 0xac237574, 0x8f830054, -0x3c020001, 0x8c427574, 0x2463d8f0, 0x431023, +0xac227560, 0x3c010001, 0xac237584, 0x8f830054, +0x3c020001, 0x8c427584, 0x2463d8f0, 0x431023, 0x2c422710, 0x1440003a, 0x0, 0x3c020001, -0x8c427590, 0x10400029, 0x2402000e, 0x3c030001, -0x8c6375a4, 0x3c010001, 0x14600015, 0xac227550, -0xc0043e1, 0x0, 0x3c050001, 0x8ca55478, -0xc0050af, 0x2021, 0x3c030001, 0x8c635478, +0x8c4275a0, 0x10400029, 0x2402000e, 0x3c030001, +0x8c6375b4, 0x3c010001, 0x14600015, 0xac227560, +0xc0043dd, 0x0, 0x3c050001, 0x8ca55488, +0xc0050b3, 0x2021, 0x3c030001, 0x8c635488, 0x24020004, 0x14620005, 0x2403fffb, 0x3c020001, -0x8c425474, 0x8004eee, 0x2403fff7, 0x3c020001, -0x8c425474, 0x431024, 0x3c010001, 0xac225474, +0x8c425484, 0x8004ef2, 0x2403fff7, 0x3c020001, +0x8c425484, 0x431024, 0x3c010001, 0xac225484, 0x8ee20000, 0x3c030200, 0x431025, 0xaee20000, -0x8f820224, 0x3c010001, 0xac2275ac, 0x8f820220, +0x8f820224, 0x3c010001, 0xac2275bc, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0x8004f1f, 0xaf820220, 0x3c020001, -0x8c427580, 0x10400005, 0x0, 0x3c020001, -0x8c42755c, 0x1040000f, 0x24020002, 0x3c020001, -0x8c427560, 0x2c424e21, 0x1040000a, 0x24020002, -0x3c020001, 0x8c427580, 0x1040000f, 0x0, -0x3c020001, 0x8c42755c, 0x1440000b, 0x0, -0x24020002, 0x3c010001, 0x8004f1f, 0xac227550, -0x3c020001, 0x8c427580, 0x10400003, 0x0, -0xc00429f, 0x0, 0x8f820220, 0x3c03f700, +0x34420002, 0x8004f23, 0xaf820220, 0x3c020001, +0x8c427590, 0x10400005, 0x0, 0x3c020001, +0x8c42756c, 0x1040000f, 0x24020002, 0x3c020001, +0x8c427570, 0x2c424e21, 0x1040000a, 0x24020002, +0x3c020001, 0x8c427590, 0x1040000f, 0x0, +0x3c020001, 0x8c42756c, 0x1440000b, 0x0, +0x24020002, 0x3c010001, 0x8004f23, 0xac227560, +0x3c020001, 0x8c427590, 0x10400003, 0x0, +0xc00429b, 0x0, 0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, 0x8fbf0010, 0x3e00008, -0x27bd0018, 0x3c030001, 0x246375a8, 0x8c620000, -0x10400005, 0x34422000, 0x3c010001, 0xac22759c, -0x8004f31, 0xac600000, 0x3c010001, 0xac24759c, +0x27bd0018, 0x3c030001, 0x246375b8, 0x8c620000, +0x10400005, 0x34422000, 0x3c010001, 0xac2275ac, +0x8004f35, 0xac600000, 0x3c010001, 0xac2475ac, 0x3e00008, 0x0, 0x27bdffe0, 0x30820030, -0xafbf0018, 0x3c010001, 0xac2275a4, 0x14400067, +0xafbf0018, 0x3c010001, 0xac2275b4, 0x14400067, 0x3c02ffff, 0x34421f0e, 0x821024, 0x14400061, 0x24020030, 0x30822000, 0x1040005d, 0x30838000, 0x31a02, 0x30820001, 0x21200, 0x3c040001, -0x8c84552c, 0x621825, 0x331c2, 0x3c030001, -0x24635508, 0x30828000, 0x21202, 0x30840001, +0x8c84553c, 0x621825, 0x331c2, 0x3c030001, +0x24635518, 0x30828000, 0x21202, 0x30840001, 0x42200, 0x441025, 0x239c2, 0x61080, 0x431021, 0x471021, 0x90430000, 0x24020001, 0x10620025, 0x0, 0x10600007, 0x24020002, 0x10620013, 0x24020003, 0x1062002c, 0x3c05000f, -0x8004f95, 0x0, 0x8f820200, 0x2403feff, +0x8004f99, 0x0, 0x8f820200, 0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, 0x3c010001, -0xac2075c4, 0x3c010001, 0x8004fa0, 0xac2075cc, +0xac2075d4, 0x3c010001, 0x8004fa4, 0xac2075dc, 0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, -0x24020100, 0x3c010001, 0xac2275c4, 0x3c010001, -0x8004fa0, 0xac2075cc, 0x8f820200, 0x2403feff, +0x24020100, 0x3c010001, 0xac2275d4, 0x3c010001, +0x8004fa4, 0xac2075dc, 0x8f820200, 0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c030001, -0x431025, 0xaf820220, 0x3c010001, 0xac2075c4, -0x3c010001, 0x8004fa0, 0xac2375cc, 0x8f820200, +0x431025, 0xaf820220, 0x3c010001, 0xac2075d4, +0x3c010001, 0x8004fa4, 0xac2375dc, 0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c030001, 0x431025, 0xaf820220, 0x24020100, 0x3c010001, -0xac2275c4, 0x3c010001, 0x8004fa0, 0xac2375cc, -0x34a5ffff, 0x3c040001, 0x24845388, 0xafa30010, -0xc002407, 0xafa00014, 0x8004fa0, 0x0, -0x24020030, 0x3c010001, 0xac2275a8, 0x8fbf0018, +0xac2275d4, 0x3c010001, 0x8004fa4, 0xac2375dc, +0x34a5ffff, 0x3c040001, 0x24845398, 0xafa30010, +0xc002403, 0xafa00014, 0x8004fa4, 0x0, +0x24020030, 0x3c010001, 0xac2275b8, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x0, 0x27bdffc8, 0xafb10024, 0x808821, 0xafb3002c, 0xa09821, -0xafb00020, 0xc08021, 0x3c040001, 0x248453a0, -0x3c050009, 0x3c020001, 0x8c425478, 0x34a59001, +0xafb00020, 0xc08021, 0x3c040001, 0x248453b0, +0x3c050009, 0x3c020001, 0x8c425488, 0x34a59001, 0x2203021, 0x2603821, 0xafbf0030, 0xafb20028, -0xa7a0001a, 0xafb00014, 0xc002407, 0xafa20010, +0xa7a0001a, 0xafb00014, 0xc002403, 0xafa20010, 0x24020002, 0x126200ed, 0x2e620003, 0x10400005, -0x24020001, 0x1262000a, 0x3c02fffb, 0x80050a8, +0x24020001, 0x1262000a, 0x3c02fffb, 0x80050ac, 0x0, 0x24020004, 0x1262006d, 0x24020008, -0x1262006c, 0x3c02ffec, 0x80050a8, 0x0, +0x1262006c, 0x3c02ffec, 0x80050ac, 0x0, 0x3442ffff, 0x2028024, 0x119140, 0x3c010001, -0x320821, 0xac3075bc, 0x3c024000, 0x2021024, +0x320821, 0xac3075cc, 0x3c024000, 0x2021024, 0x10400046, 0x1023c2, 0x30840030, 0x101382, -0x3042000c, 0x3c030001, 0x246354a4, 0x431021, +0x3042000c, 0x3c030001, 0x246354b4, 0x431021, 0x823821, 0x3c020020, 0x2021024, 0x10400006, -0x24020100, 0x3c010001, 0x320821, 0xac2275c0, -0x8004fe7, 0x3c020080, 0x3c010001, 0x320821, -0xac2075c0, 0x3c020080, 0x2021024, 0x10400006, +0x24020100, 0x3c010001, 0x320821, 0xac2275d0, +0x8004feb, 0x3c020080, 0x3c010001, 0x320821, +0xac2075d0, 0x3c020080, 0x2021024, 0x10400006, 0x111940, 0x3c020001, 0x3c010001, 0x230821, -0x8004ff3, 0xac2275c8, 0x111140, 0x3c010001, -0x220821, 0xac2075c8, 0x94e30000, 0x32024000, +0x8004ff7, 0xac2275d8, 0x111140, 0x3c010001, +0x220821, 0xac2075d8, 0x94e30000, 0x32024000, 0x10400003, 0xa7a30018, 0x34624000, 0xa7a20018, 0x24040001, 0x94e20002, 0x24050004, 0x24e60002, -0x34420001, 0xc0048ea, 0xa4e20002, 0x24040001, -0x2821, 0xc0048ea, 0x27a60018, 0x3c020001, -0x8c425478, 0x24110001, 0x3c010001, 0xac315484, -0x14530004, 0x32028000, 0xc00429f, 0x0, -0x32028000, 0x10400099, 0x0, 0xc00429f, -0x0, 0x24020002, 0x3c010001, 0xac31547c, -0x3c010001, 0x80050a8, 0xac225478, 0x24040001, -0x24050004, 0x27b0001a, 0xc0048ea, 0x2003021, -0x24040001, 0x2821, 0xc0048ea, 0x2003021, -0x3c020001, 0x521021, 0x8c4275b4, 0x3c040001, -0x8c845478, 0x3c03bfff, 0x3463ffff, 0x3c010001, -0xac335484, 0x431024, 0x3c010001, 0x320821, -0x10930078, 0xac2275b4, 0x80050a8, 0x0, +0x34420001, 0xc0048ee, 0xa4e20002, 0x24040001, +0x2821, 0xc0048ee, 0x27a60018, 0x3c020001, +0x8c425488, 0x24110001, 0x3c010001, 0xac315494, +0x14530004, 0x32028000, 0xc00429b, 0x0, +0x32028000, 0x10400099, 0x0, 0xc00429b, +0x0, 0x24020002, 0x3c010001, 0xac31548c, +0x3c010001, 0x80050ac, 0xac225488, 0x24040001, +0x24050004, 0x27b0001a, 0xc0048ee, 0x2003021, +0x24040001, 0x2821, 0xc0048ee, 0x2003021, +0x3c020001, 0x521021, 0x8c4275c4, 0x3c040001, +0x8c845488, 0x3c03bfff, 0x3463ffff, 0x3c010001, +0xac335494, 0x431024, 0x3c010001, 0x320821, +0x10930078, 0xac2275c4, 0x80050ac, 0x0, 0x3c02ffec, 0x3442ffff, 0x2028024, 0x3c020008, 0x2028025, 0x111140, 0x3c010001, 0x220821, -0xac3075b8, 0x3c022000, 0x2021024, 0x10400009, -0x0, 0x3c020001, 0x8c425504, 0x14400005, -0x24020001, 0x3c010001, 0xac225528, 0x8005049, -0x3c024000, 0x3c010001, 0xac205528, 0x3c024000, +0xac3075c8, 0x3c022000, 0x2021024, 0x10400009, +0x0, 0x3c020001, 0x8c425514, 0x14400005, +0x24020001, 0x3c010001, 0xac225538, 0x800504d, +0x3c024000, 0x3c010001, 0xac205538, 0x3c024000, 0x2021024, 0x1440001c, 0x0, 0x3c020001, -0x8c425528, 0x10400007, 0x24022020, 0x3c010001, -0xac22552c, 0x24020001, 0x3c010001, 0x370821, +0x8c425538, 0x10400007, 0x24022020, 0x3c010001, +0xac22553c, 0x24020001, 0x3c010001, 0x370821, 0xac2283ac, 0x3c04bfff, 0x111940, 0x3c020001, -0x431021, 0x8c4275b0, 0x3c050001, 0x8ca55478, +0x431021, 0x8c4275c0, 0x3c050001, 0x8ca55488, 0x3484ffff, 0x441024, 0x3c010001, 0x230821, -0xac2275b0, 0x24020001, 0x10a20044, 0x0, -0x80050a6, 0x0, 0x3c020001, 0x8c425528, -0x1040001c, 0x24022000, 0x3c010001, 0xac22552c, +0xac2275c0, 0x24020001, 0x10a20044, 0x0, +0x80050aa, 0x0, 0x3c020001, 0x8c425538, +0x1040001c, 0x24022000, 0x3c010001, 0xac22553c, 0x3c0300a0, 0x2031024, 0x14430005, 0x111140, -0x3402a000, 0x3c010001, 0x80050a1, 0xac22552c, -0x3c030001, 0x621821, 0x8c6375b8, 0x3c020020, +0x3402a000, 0x3c010001, 0x80050a5, 0xac22553c, +0x3c030001, 0x621821, 0x8c6375c8, 0x3c020020, 0x621024, 0x10400004, 0x24022001, 0x3c010001, -0x80050a1, 0xac22552c, 0x3c020080, 0x621024, -0x1040001f, 0x3402a001, 0x3c010001, 0x80050a1, -0xac22552c, 0x3c020020, 0x2021024, 0x10400007, +0x80050a5, 0xac22553c, 0x3c020080, 0x621024, +0x1040001f, 0x3402a001, 0x3c010001, 0x80050a5, +0xac22553c, 0x3c020020, 0x2021024, 0x10400007, 0x111940, 0x24020100, 0x3c010001, 0x230821, -0xac2275c4, 0x8005095, 0x3c020080, 0x111140, -0x3c010001, 0x220821, 0xac2075c4, 0x3c020080, +0xac2275d4, 0x8005099, 0x3c020080, 0x111140, +0x3c010001, 0x220821, 0xac2075d4, 0x3c020080, 0x2021024, 0x10400006, 0x111940, 0x3c020001, -0x3c010001, 0x230821, 0x80050a1, 0xac2275cc, -0x111140, 0x3c010001, 0x220821, 0xac2075cc, -0x3c030001, 0x8c635478, 0x24020001, 0x10620003, -0x0, 0xc00429f, 0x0, 0x8fbf0030, +0x3c010001, 0x230821, 0x80050a5, 0xac2275dc, +0x111140, 0x3c010001, 0x220821, 0xac2075dc, +0x3c030001, 0x8c635488, 0x24020001, 0x10620003, +0x0, 0xc00429b, 0x0, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, 0x27bd0038, 0x27bdffd0, 0xafb40028, 0x80a021, 0xafb20020, 0x9021, 0xafb30024, 0x9821, 0xafb1001c, 0x8821, 0x24020002, 0xafbf002c, 0xafb00018, 0xa7a00012, 0x10a20068, 0xa7a00010, 0x2ca20003, 0x10400005, 0x24020001, -0x10a2000a, 0x148140, 0x8005172, 0x2201021, +0x10a2000a, 0x148140, 0x8005176, 0x2201021, 0x24020004, 0x10a2005e, 0x24020008, 0x10a2005d, -0x142940, 0x8005172, 0x2201021, 0x3c030001, -0x701821, 0x8c6375bc, 0x3c024000, 0x621024, +0x142940, 0x8005176, 0x2201021, 0x3c030001, +0x701821, 0x8c6375cc, 0x3c024000, 0x621024, 0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff, -0x628824, 0x3c010001, 0x300821, 0xac3175b4, -0x8005172, 0x2201021, 0x24050001, 0xc0048a8, -0x27a60010, 0x24040001, 0x24050001, 0xc0048a8, +0x628824, 0x3c010001, 0x300821, 0xac3175c4, +0x8005176, 0x2201021, 0x24050001, 0xc0048ac, +0x27a60010, 0x24040001, 0x24050001, 0xc0048ac, 0x27a60010, 0x97a20010, 0x30420004, 0x10400034, -0x3c114000, 0x3c030001, 0x8c635540, 0x24020003, +0x3c114000, 0x3c030001, 0x8c635550, 0x24020003, 0x10620008, 0x2c620004, 0x14400029, 0x3c028000, -0x24020004, 0x10620014, 0x24040001, 0x8005115, +0x24020004, 0x10620014, 0x24040001, 0x8005119, 0x3c028000, 0x24040001, 0x24050011, 0x27b00012, -0xc0048a8, 0x2003021, 0x24040001, 0x24050011, -0xc0048a8, 0x2003021, 0x97a30012, 0x30624000, +0xc0048ac, 0x2003021, 0x24040001, 0x24050011, +0xc0048ac, 0x2003021, 0x97a30012, 0x30624000, 0x10400002, 0x3c130010, 0x3c130008, 0x3c120001, -0x8005112, 0x30628000, 0x24050014, 0x27b00012, -0xc0048a8, 0x2003021, 0x24040001, 0x24050014, -0xc0048a8, 0x2003021, 0x97a30012, 0x30621000, +0x8005116, 0x30628000, 0x24050014, 0x27b00012, +0xc0048ac, 0x2003021, 0x24040001, 0x24050014, +0xc0048ac, 0x2003021, 0x97a30012, 0x30621000, 0x10400002, 0x3c130010, 0x3c130008, 0x3c120001, 0x30620800, 0x54400001, 0x3c120002, 0x3c028000, -0x2221025, 0x2531825, 0x800511f, 0x438825, -0x3c110001, 0x2308821, 0x8e3175bc, 0x3c027fff, +0x2221025, 0x2531825, 0x8005123, 0x438825, +0x3c110001, 0x2308821, 0x8e3175cc, 0x3c027fff, 0x3442ffff, 0x2228824, 0x141140, 0x3c010001, -0x220821, 0xac3175b4, 0x8005172, 0x2201021, -0x142940, 0x3c030001, 0x651821, 0x8c6375b8, +0x220821, 0xac3175c4, 0x8005176, 0x2201021, +0x142940, 0x3c030001, 0x651821, 0x8c6375c8, 0x3c024000, 0x621024, 0x14400008, 0x3c027fff, 0x3442ffff, 0x628824, 0x3c010001, 0x250821, -0xac3175b0, 0x8005172, 0x2201021, 0x3c020001, -0x8c425488, 0x10400033, 0x3c11c00c, 0x3c020001, -0x8c425504, 0x3c04c00c, 0x34842000, 0x3c030001, -0x8c635528, 0x2102b, 0x21023, 0x441024, +0xac3175c0, 0x8005176, 0x2201021, 0x3c020001, +0x8c425498, 0x10400033, 0x3c11c00c, 0x3c020001, +0x8c425514, 0x3c04c00c, 0x34842000, 0x3c030001, +0x8c635538, 0x2102b, 0x21023, 0x441024, 0x10600003, 0x518825, 0x3c022000, 0x2228825, -0x3c020001, 0x451021, 0x8c4275c4, 0x10400003, -0x3c020020, 0x800514f, 0x2228825, 0x3c02ffdf, +0x3c020001, 0x451021, 0x8c4275d4, 0x10400003, +0x3c020020, 0x8005153, 0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824, 0x141140, 0x3c010001, -0x220821, 0x8c2275cc, 0x10400003, 0x3c020080, -0x800515a, 0x2228825, 0x3c02ff7f, 0x3442ffff, -0x2228824, 0x3c020001, 0x8c4254f0, 0x10400002, -0x3c020800, 0x2228825, 0x3c020001, 0x8c4254f4, +0x220821, 0x8c2275dc, 0x10400003, 0x3c020080, +0x800515e, 0x2228825, 0x3c02ff7f, 0x3442ffff, +0x2228824, 0x3c020001, 0x8c425500, 0x10400002, +0x3c020800, 0x2228825, 0x3c020001, 0x8c425504, 0x10400002, 0x3c020400, 0x2228825, 0x3c020001, -0x8c4254f8, 0x10400006, 0x3c020100, 0x800516d, +0x8c425508, 0x10400006, 0x3c020100, 0x8005171, 0x2228825, 0x3c027fff, 0x3442ffff, 0x628824, -0x141140, 0x3c010001, 0x220821, 0xac3175b0, +0x141140, 0x3c010001, 0x220821, 0xac3175c0, 0x2201021, 0x8fbf002c, 0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffd8, 0xafb40020, 0x80a021, 0xafbf0024, 0xafb3001c, 0xafb20018, 0xafb10014, -0xafb00010, 0x8f900200, 0x3c030001, 0x8c635478, +0xafb00010, 0x8f900200, 0x3c030001, 0x8c635488, 0x8f930220, 0x24020002, 0x106200b4, 0x2c620003, 0x10400005, 0x24020001, 0x1062000a, 0x141940, -0x800523c, 0x0, 0x24020004, 0x1062005a, -0x24020008, 0x10620059, 0x149140, 0x800523c, -0x0, 0x3c040001, 0x832021, 0x8c8475bc, -0x3c110001, 0x2238821, 0x8e3175b4, 0x3c024000, +0x8005240, 0x0, 0x24020004, 0x1062005a, +0x24020008, 0x10620059, 0x149140, 0x8005240, +0x0, 0x3c040001, 0x832021, 0x8c8475cc, +0x3c110001, 0x2238821, 0x8e3175c4, 0x3c024000, 0x821024, 0x1040003e, 0x3c020008, 0x2221024, 0x10400020, 0x36100002, 0x3c020001, 0x431021, -0x8c4275c0, 0x10400005, 0x36100020, 0x36100100, -0x3c020020, 0x80051b1, 0x2228825, 0x2402feff, +0x8c4275d0, 0x10400005, 0x36100020, 0x36100100, +0x3c020020, 0x80051b5, 0x2228825, 0x2402feff, 0x2028024, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x141140, 0x3c010001, 0x220821, 0x8c2275c8, +0x141140, 0x3c010001, 0x220821, 0x8c2275d8, 0x10400005, 0x3c020001, 0x2629825, 0x3c020080, -0x80051d0, 0x2228825, 0x3c02fffe, 0x3442ffff, -0x2629824, 0x3c02ff7f, 0x3442ffff, 0x80051d0, +0x80051d4, 0x2228825, 0x3c02fffe, 0x3442ffff, +0x2629824, 0x3c02ff7f, 0x3442ffff, 0x80051d4, 0x2228824, 0x2402fedf, 0x2028024, 0x3c02fffe, 0x3442ffff, 0x2629824, 0x3c02ff5f, 0x3442ffff, -0x2228824, 0x3c010001, 0x230821, 0xac2075c0, -0x3c010001, 0x230821, 0xac2075c8, 0xc0047cc, +0x2228824, 0x3c010001, 0x230821, 0xac2075d0, +0x3c010001, 0x230821, 0xac2075d8, 0xc0047cd, 0x0, 0xaf900200, 0xaf930220, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0xaf820220, 0x80051e7, 0x141140, -0x8f820200, 0x2403fffd, 0x431024, 0xc0047cc, -0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429f, +0x34420002, 0xaf820220, 0x80051eb, 0x141140, +0x8f820200, 0x2403fffd, 0x431024, 0xc0047cd, +0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b, 0x2228824, 0x141140, 0x3c010001, 0x220821, -0x800523c, 0xac3175b4, 0x149140, 0x3c040001, -0x922021, 0x8c8475b8, 0x3c110001, 0x2328821, -0x8e3175b0, 0x3c024000, 0x821024, 0x14400011, -0x0, 0x3c020001, 0x8c425528, 0x14400006, -0x3c02bfff, 0x8f820200, 0x34420002, 0xc0047cc, -0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429f, -0x2228824, 0x3c010001, 0x320821, 0x800523c, -0xac3175b0, 0x3c020001, 0x8c425528, 0x10400005, -0x3c020020, 0x3c020001, 0x8c425504, 0x1040002b, +0x8005240, 0xac3175c4, 0x149140, 0x3c040001, +0x922021, 0x8c8475c8, 0x3c110001, 0x2328821, +0x8e3175c0, 0x3c024000, 0x821024, 0x14400011, +0x0, 0x3c020001, 0x8c425538, 0x14400006, +0x3c02bfff, 0x8f820200, 0x34420002, 0xc0047cd, +0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b, +0x2228824, 0x3c010001, 0x320821, 0x8005240, +0xac3175c0, 0x3c020001, 0x8c425538, 0x10400005, +0x3c020020, 0x3c020001, 0x8c425514, 0x1040002b, 0x3c020020, 0x821024, 0x10400007, 0x36100020, -0x24020100, 0x3c010001, 0x320821, 0xac2275c4, -0x800521c, 0x36100100, 0x3c010001, 0x320821, -0xac2075c4, 0x2402feff, 0x2028024, 0x3c020080, +0x24020100, 0x3c010001, 0x320821, 0xac2275d4, +0x8005220, 0x36100100, 0x3c010001, 0x320821, +0xac2075d4, 0x2402feff, 0x2028024, 0x3c020080, 0x821024, 0x10400007, 0x141940, 0x3c020001, -0x3c010001, 0x230821, 0xac2275cc, 0x800522d, +0x3c010001, 0x230821, 0xac2275dc, 0x8005231, 0x2629825, 0x141140, 0x3c010001, 0x220821, -0xac2075cc, 0x3c02fffe, 0x3442ffff, 0x2629824, -0xc0047cc, 0x0, 0xaf900200, 0xaf930220, +0xac2075dc, 0x3c02fffe, 0x3442ffff, 0x2629824, +0xc0047cd, 0x0, 0xaf900200, 0xaf930220, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, 0x34420002, 0xaf820220, 0x141140, -0x3c010001, 0x220821, 0xac3175b0, 0x8fbf0024, +0x3c010001, 0x220821, 0xac3175c0, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 }; u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f66, -0x776d6169, 0x6e2e632c, 0x7620312e, 0x312e322e, -0x31312031, 0x3939382f, 0x30342f32, 0x37203232, -0x3a31333a, 0x34322073, 0x6875616e, 0x67204578, -0x70202400, 0x7468655f, 0x4441574e, 0x0, -0x53544143, 0x4b5f3120, 0x0, 0x42616453, -0x6e64526e, 0x67000000, 0x3f456e71, 0x45767400, -0x3f6e6f51, 0x64457650, 0x0, 0x6576526e, -0x6746756c, 0x6c000000, 0x496c6c43, 0x6f6e6652, -0x78000000, 0x53656e64, 0x436b5375, 0x6d000000, -0x52656376, 0x566c616e, 0x0, 0x0, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f66776d, 0x61696e2e, 0x632c7620, 0x312e312e, +0x322e3131, 0x20313939, 0x382f3034, 0x2f323720, +0x32323a31, 0x333a3432, 0x20736875, 0x616e6720, +0x45787020, 0x24000000, 0x7468655f, 0x4441574e, +0x0, 0x53544143, 0x4b5f3120, 0x0, +0x42616453, 0x6e64526e, 0x67000000, 0x3f456e71, +0x45767400, 0x3f6e6f51, 0x64457650, 0x0, +0x6576526e, 0x6746756c, 0x6c000000, 0x496c6c43, +0x6f6e6652, 0x78000000, 0x53656e64, 0x436b5375, +0x6d000000, 0x52656376, 0x566c616e, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f74, -0x696d6572, 0x2e632c76, 0x20312e31, 0x2e322e38, -0x20313939, 0x382f3037, 0x2f333120, 0x31373a35, -0x383a3435, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x542d446d, 0x61526431, 0x0, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f74696d, 0x65722e63, 0x2c762031, 0x2e312e32, +0x2e382031, 0x3939382f, 0x30372f33, 0x31203137, +0x3a35383a, 0x34352073, 0x6875616e, 0x67204578, +0x70202400, 0x542d446d, 0x61526431, 0x0, 0x542d446d, 0x61424200, 0x542d446d, 0x61320000, 0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51, 0x64527845, 0x0, 0x656e714d, 0x45765046, @@ -4286,11 +4296,11 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x6576526e, 0x6746756c, 0x6c000000, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f63, -0x6f6d6d61, 0x6e642e63, 0x2c762031, 0x2e312e32, -0x2e313020, 0x31393938, 0x2f31312f, 0x31382031, -0x373a3131, 0x3a313820, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x3f4d626f, 0x78457674, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f636f6d, 0x6d616e64, 0x2e632c76, 0x20312e31, +0x2e322e31, 0x30203139, 0x39382f31, 0x312f3138, +0x2031373a, 0x31313a31, 0x38207368, 0x75616e67, +0x20457870, 0x20240000, 0x3f4d626f, 0x78457674, 0x0, 0x4e4f636f, 0x6d616e64, 0x0, 0x68737465, 0x5f455252, 0x0, 0x412d4572, 0x72427563, 0x0, 0x4552524f, 0x522d4164, @@ -4309,29 +4319,29 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x7e70, 0x80cc, 0x6e64, 0x81cc, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f64, -0x6d612e63, 0x2c762031, 0x2e312e32, 0x2e332031, -0x3939382f, 0x30342f32, 0x37203232, 0x3a31333a, -0x34312073, 0x6875616e, 0x67204578, 0x70202400, -0x646d6172, 0x6441544e, 0x0, 0x646d6177, -0x7241544e, 0x0, 0x0, 0x0, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f646d61, 0x2e632c76, 0x20312e31, 0x2e322e33, +0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, +0x333a3431, 0x20736875, 0x616e6720, 0x45787020, +0x24000000, 0x646d6172, 0x6441544e, 0x0, +0x646d6177, 0x7241544e, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f74, -0x72616365, 0x2e632c76, 0x20312e31, 0x2e322e32, -0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, -0x333a3530, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x24486561, 0x6465723a, 0x202f7072, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f747261, 0x63652e63, 0x2c762031, 0x2e312e32, +0x2e322031, 0x3939382f, 0x30342f32, 0x37203232, +0x3a31333a, 0x35302073, 0x6875616e, 0x67204578, +0x70202400, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f64, -0x6174612e, 0x632c7620, 0x312e312e, 0x322e3220, -0x31393938, 0x2f30342f, 0x32372032, 0x323a3133, -0x3a343020, 0x73687561, 0x6e672045, 0x78702024, -0x0, 0x46575f56, 0x45525349, 0x4f4e3a20, -0x2331204d, 0x6f6e2046, 0x65622031, 0x2031363a, -0x35393a30, 0x31205053, 0x54203139, 0x39390000, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f646174, 0x612e632c, 0x7620312e, 0x312e322e, +0x32203139, 0x39382f30, 0x342f3237, 0x2032323a, +0x31333a34, 0x30207368, 0x75616e67, 0x20457870, +0x20240000, 0x46575f56, 0x45525349, 0x4f4e3a20, +0x23312054, 0x68752041, 0x75672031, 0x32203135, +0x3a34393a, 0x35332050, 0x44542031, 0x39393900, 0x46575f43, 0x4f4d5049, 0x4c455f54, 0x494d453a, -0x2031363a, 0x35393a30, 0x31000000, 0x46575f43, +0x2031353a, 0x34393a35, 0x33000000, 0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049, 0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465, 0x0, @@ -4342,37 +4352,37 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x2e320000, 0x0, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f6d, -0x656d2e63, 0x2c762031, 0x2e312e32, 0x2e322031, -0x3939382f, 0x30342f32, 0x37203232, 0x3a31333a, -0x34342073, 0x6875616e, 0x67204578, 0x70202400, -0x0, 0x24486561, 0x6465723a, 0x202f7072, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f6d656d, 0x2e632c76, 0x20312e31, 0x2e322e32, +0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, +0x333a3434, 0x20736875, 0x616e6720, 0x45787020, +0x24000000, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f73, -0x656e642e, 0x632c7620, 0x312e312e, 0x322e3131, -0x20313939, 0x382f3132, 0x2f323220, 0x31373a31, -0x373a3535, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x736e6464, 0x654e6f51, 0x20000000, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f73656e, 0x642e632c, 0x7620312e, 0x312e322e, +0x31312031, 0x3939382f, 0x31322f32, 0x32203137, +0x3a31373a, 0x35352073, 0x6875616e, 0x67204578, +0x70202400, 0x736e6464, 0x654e6f51, 0x20000000, 0x6e6f454e, 0x515f5458, 0x0, 0x736e6464, 0x744e6f51, 0x20000000, 0x3f6e6f51, 0x64547845, 0x0, 0x756e6b72, 0x64747970, 0x65000000, -0x0, 0xacdc, 0xacdc, 0xadac, -0xaac0, 0xaac0, 0xadac, 0xadac, -0xadac, 0xadac, 0xadac, 0xadac, -0xadac, 0xadac, 0xadac, 0xadac, -0xadac, 0xadac, 0xadac, 0xad8c, -0x0, 0xbcb8, 0xbcb8, 0xbd80, -0xae5c, 0xb068, 0xbd80, 0xbd80, -0xbd80, 0xbd80, 0xbd80, 0xbd80, -0xbd80, 0xbd80, 0xbd80, 0xbd80, -0xbd80, 0xbd80, 0xbd80, 0xbd64, -0xb050, 0x24486561, 0x6465723a, 0x202f7072, +0x0, 0xaccc, 0xaccc, 0xad9c, +0xaab0, 0xaab0, 0xad9c, 0xad9c, +0xad9c, 0xad9c, 0xad9c, 0xad9c, +0xad9c, 0xad9c, 0xad9c, 0xad9c, +0xad9c, 0xad9c, 0xad9c, 0xad7c, +0x0, 0xbca8, 0xbca8, 0xbd70, +0xae4c, 0xb058, 0xbd70, 0xbd70, +0xbd70, 0xbd70, 0xbd70, 0xbd70, +0xbd70, 0xbd70, 0xbd70, 0xbd70, +0xbd70, 0xbd70, 0xbd70, 0xbd54, +0xb040, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f72, -0x6563762e, 0x632c7620, 0x312e312e, 0x322e3139, -0x20313939, 0x382f3037, 0x2f323420, 0x32313a33, -0x303a3035, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x706b5278, 0x45525200, 0x66726d32, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f726563, 0x762e632c, 0x7620312e, 0x312e322e, +0x31392031, 0x3939382f, 0x30372f32, 0x34203231, +0x3a33303a, 0x30352073, 0x6875616e, 0x67204578, +0x70202400, 0x706b5278, 0x45525200, 0x66726d32, 0x4c617267, 0x65000000, 0x72784e6f, 0x52784264, 0x0, 0x72785144, 0x6d614446, 0x0, 0x72785144, 0x6d614246, 0x0, 0x3f6e6f51, @@ -4380,23 +4390,23 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x0, 0x66726d32, 0x4c726753, 0x0, 0x72784e6f, 0x42645300, 0x3f724264, 0x446d6146, 0x0, 0x3f724a42, 0x64446d46, 0x0, -0x0, 0xf688, 0xf688, 0xf688, -0xf688, 0xf688, 0xf688, 0xf688, -0xf688, 0xf688, 0xf688, 0xf688, -0xf688, 0xf688, 0xf688, 0xf688, -0xf680, 0xf680, 0xf680, 0x572d444d, -0x41456e46, 0x0, 0x0, 0xfdd0, -0x1016c, 0xfdec, 0x1016c, 0x1016c, -0x1016c, 0x1016c, 0x1016c, 0x1016c, -0xf714, 0x1016c, 0x1016c, 0x1016c, -0x1016c, 0x1016c, 0x10164, 0x10164, -0x10164, 0x24486561, 0x6465723a, 0x202f7072, +0x0, 0xf678, 0xf678, 0xf678, +0xf678, 0xf678, 0xf678, 0xf678, +0xf678, 0xf678, 0xf678, 0xf678, +0xf678, 0xf678, 0xf678, 0xf678, +0xf670, 0xf670, 0xf670, 0x572d444d, +0x41456e46, 0x0, 0x0, 0xfdc0, +0x1015c, 0xfddc, 0x1015c, 0x1015c, +0x1015c, 0x1015c, 0x1015c, 0x1015c, +0xf704, 0x1015c, 0x1015c, 0x1015c, +0x1015c, 0x1015c, 0x10154, 0x10154, +0x10154, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f6d, -0x61632e63, 0x2c762031, 0x2e312e32, 0x2e313220, -0x31393938, 0x2f30342f, 0x32372032, 0x323a3133, -0x3a343220, 0x73687561, 0x6e672045, 0x78702024, -0x0, 0x6d616374, 0x7841544e, 0x0, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f6d6163, 0x2e632c76, 0x20312e31, 0x2e322e31, +0x32203139, 0x39382f30, 0x342f3237, 0x2032323a, +0x31333a34, 0x32207368, 0x75616e67, 0x20457870, +0x20240000, 0x6d616374, 0x7841544e, 0x0, 0x4e745379, 0x6e264c6b, 0x0, 0x72656d61, 0x73737274, 0x0, 0x6c696e6b, 0x444f574e, 0x0, 0x656e714d, 0x45765046, 0x61696c00, @@ -4404,27 +4414,27 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x456e454d, 0x0, 0x6c696e6b, 0x55500000, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f63, -0x6b73756d, 0x2e632c76, 0x20312e31, 0x2e322e32, -0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, -0x333a3339, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x50726f62, 0x65506879, 0x0, -0x6c6e6b41, 0x53535254, 0x0, 0x11994, -0x119cc, 0x119e4, 0x11a18, 0x11a44, -0x11a58, 0x11a94, 0x11e04, 0x11b6c, -0x11bac, 0x11bd8, 0x11c18, 0x11c48, -0x11c84, 0x11cb8, 0x11e04, 0x12048, -0x12060, 0x12088, 0x120a8, 0x120d0, -0x12200, 0x12228, 0x1226c, 0x12294, -0x0, 0x124fc, 0x125cc, 0x126a4, -0x12774, 0x127d0, 0x128ac, 0x128d4, -0x129b0, 0x129d8, 0x12b80, 0x12ba8, -0x12d50, 0x12f48, 0x131dc, 0x130f0, -0x131dc, 0x13208, 0x12d78, 0x12f20, -0x0, 0x135f4, 0x13638, 0x136d0, -0x1371c, 0x1378c, 0x13824, 0x13858, -0x138e0, 0x13978, 0x13a48, 0x13a88, -0x13b0c, 0x13b30, 0x13c64, 0x646f4261, +0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, +0x2f636b73, 0x756d2e63, 0x2c762031, 0x2e312e32, +0x2e322031, 0x3939382f, 0x30342f32, 0x37203232, +0x3a31333a, 0x33392073, 0x6875616e, 0x67204578, +0x70202400, 0x50726f62, 0x65506879, 0x0, +0x6c6e6b41, 0x53535254, 0x0, 0x11998, +0x119d0, 0x119e8, 0x11a1c, 0x11a48, +0x11a5c, 0x11a98, 0x11e08, 0x11b70, +0x11bb0, 0x11bdc, 0x11c1c, 0x11c4c, +0x11c88, 0x11cbc, 0x11e08, 0x1204c, +0x12064, 0x1208c, 0x120ac, 0x120d4, +0x12204, 0x1222c, 0x12280, 0x122a8, +0x0, 0x1250c, 0x125dc, 0x126b4, +0x12784, 0x127e0, 0x128bc, 0x128e4, +0x129c0, 0x129e8, 0x12b90, 0x12bb8, +0x12d60, 0x12f58, 0x131ec, 0x13100, +0x131ec, 0x13218, 0x12d88, 0x12f30, +0x0, 0x13604, 0x13648, 0x136e0, +0x1372c, 0x1379c, 0x13834, 0x13868, +0x138f0, 0x13988, 0x13a58, 0x13a98, +0x13b1c, 0x13b40, 0x13c74, 0x646f4261, 0x73655067, 0x0, 0x0, 0x0, 0x0, 0x73746d61, 0x634c4e4b, 0x0, 0x0, 0x0 }; @@ -4451,28 +4461,29 @@ u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = { 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x30001, 0x1, 0x30201, 0x0, 0x0, 0x0 }; +#endif /* Generated by genfw.c */ -int tigon2FwReleaseMajor = 0xc; -int tigon2FwReleaseMinor = 0x3; -int tigon2FwReleaseFix = 0x5; -u32 tigon2FwStartAddr = 0x00004000; -u32 tigon2FwTextAddr = 0x00004000; -int tigon2FwTextLen = 0xec80; -u32 tigon2FwRodataAddr = 0x00012c80; -int tigon2FwRodataLen = 0xfb0; -u32 tigon2FwDataAddr = 0x00013c50; -int tigon2FwDataLen = 0x170; -u32 tigon2FwSbssAddr = 0x00013dc0; -int tigon2FwSbssLen = 0xbc; -u32 tigon2FwBssAddr = 0x00013e80; -int tigon2FwBssLen = 0x20c0; +#define tigon2FwReleaseMajor 0xc +#define tigon2FwReleaseMinor 0x3 +#define tigon2FwReleaseFix 0xd +#define tigon2FwStartAddr 0x00004000 +#define tigon2FwTextAddr 0x00004000 +#define tigon2FwTextLen 0xeca0 +#define tigon2FwRodataAddr 0x00012ca0 +#define tigon2FwRodataLen 0xff0 +#define tigon2FwDataAddr 0x00013cc0 +#define tigon2FwDataLen 0x170 +#define tigon2FwSbssAddr 0x00013e30 +#define tigon2FwSbssLen 0xbc +#define tigon2FwBssAddr 0x00013ef0 +#define tigon2FwBssLen 0x20c0 u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x10000003, 0x0, 0xd, 0xd, -0x3c1d0001, 0x8fbd3ca0, 0x3a0f021, 0x3c100000, +0x3c1d0001, 0x8fbd3d10, 0x3a0f021, 0x3c100000, 0x26104000, 0xc0010c0, 0x0, 0xd, -0x3c1d0001, 0x8fbd3ca4, 0x3a0f021, 0x3c100000, -0x26104000, 0xc00178d, 0x0, 0xd, +0x3c1d0001, 0x8fbd3d14, 0x3a0f021, 0x3c100000, +0x26104000, 0xc00178e, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -4484,22 +4495,22 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000008, -0x0, 0x80016de, 0x3c0a0001, 0x80016de, -0x3c0a0002, 0x80016de, 0x0, 0x8002acd, -0x0, 0x8002a70, 0x0, 0x80016de, -0x3c0a0004, 0x8003095, 0x0, 0x8001a0e, -0x0, 0x800373f, 0x0, 0x80036e6, -0x0, 0x80016de, 0x3c0a0006, 0x80037ad, -0x3c0a0007, 0x80016de, 0x3c0a0008, 0x80016de, -0x3c0a0009, 0x8003805, 0x0, 0x8002cc0, -0x0, 0x80016de, 0x3c0a000b, 0x80016de, -0x3c0a000c, 0x80016de, 0x3c0a000d, 0x80027ac, -0x0, 0x800275a, 0x0, 0x80016de, -0x3c0a000e, 0x8001f28, 0x0, 0x8001920, -0x0, 0x80019c0, 0x0, 0x8003a70, -0x0, 0x8003a5e, 0x0, 0x80016de, -0x0, 0x80018c6, 0x0, 0x80016de, -0x0, 0x80016de, 0x3c0a0013, 0x80016de, +0x0, 0x80016dd, 0x3c0a0001, 0x80016dd, +0x3c0a0002, 0x80016dd, 0x0, 0x8002ab5, +0x0, 0x8002a58, 0x0, 0x80016dd, +0x3c0a0004, 0x800306c, 0x0, 0x8001a07, +0x0, 0x80036c3, 0x0, 0x8004aad, +0x0, 0x80016dd, 0x3c0a0006, 0x8003731, +0x3c0a0007, 0x80016dd, 0x3c0a0008, 0x80016dd, +0x3c0a0009, 0x8003789, 0x0, 0x8002caf, +0x0, 0x80016dd, 0x3c0a000b, 0x80016dd, +0x3c0a000c, 0x80016dd, 0x3c0a000d, 0x800277b, +0x0, 0x8002710, 0x0, 0x80016dd, +0x3c0a000e, 0x8001f20, 0x0, 0x8001919, +0x0, 0x80019b9, 0x0, 0x8003a08, +0x0, 0x80039f6, 0x0, 0x80016dd, +0x0, 0x80018c6, 0x0, 0x80016dd, +0x0, 0x80016dd, 0x3c0a0013, 0x80016dd, 0x3c0a0014, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -4517,511 +4528,511 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x27bdffe0, 0x3c1cc000, 0xafbf001c, 0xafb00018, 0x8f820140, -0x24030003, 0xaf8300ec, 0x34420004, 0xc0029b8, -0xaf820140, 0x3c0100c0, 0xc001712, 0xac203ffc, -0x403021, 0x3c020008, 0x3c010001, 0xac263dd8, -0x50c2000d, 0x3c020003, 0x3c100010, 0x10d00009, -0x24050100, 0x3c040001, 0x24842d34, 0x3821, -0xafa00010, 0xc0029d3, 0xafa00014, 0x3c010001, -0xac303dd8, 0x3c020003, 0x34422000, 0x3c010001, -0xac223de8, 0x24020008, 0x3c010001, 0xac223df0, -0x2402001f, 0x3c010001, 0xac223e00, 0x24020016, -0x3c010001, 0xac223dd4, 0x3c05fffe, 0x34a56f08, -0x3c020001, 0x8c423dd8, 0x3c030001, 0x24635f40, -0x3c040001, 0x8c843c54, 0x431023, 0x14800002, +0x24030003, 0xaf8300ec, 0x34420004, 0xc0029a0, +0xaf820140, 0x3c0100c0, 0xc001711, 0xac203ffc, +0x403021, 0x3c020008, 0x3c010001, 0xac263e48, +0x50c2000d, 0x24020008, 0x3c100010, 0x10d00009, +0x24050100, 0x3c040001, 0x24842d54, 0x3821, +0xafa00010, 0xc0029bb, 0xafa00014, 0x3c010001, +0xac303e48, 0x24020008, 0x3c010001, 0xac223e60, +0x2402001f, 0x3c010001, 0xac223e70, 0x24020016, +0x3c010001, 0xac223e44, 0x3c05fffe, 0x34a56f08, +0x3c020001, 0x8c423e48, 0x3c030001, 0x24635fb0, +0x3c040001, 0x8c843cc4, 0x431023, 0x14800002, 0x458021, 0x2610fa48, 0x2402f000, 0x2028024, -0xc001734, 0x2002021, 0x2022823, 0x3c040020, +0xc001733, 0x2002021, 0x2022823, 0x3c040020, 0x821823, 0x651823, 0x247bb000, 0x3c03fffe, 0x3463bf08, 0x363b821, 0x3c0600bf, 0x34c6f000, -0x3c070001, 0x8ce73c50, 0x3c0300bf, 0x3463e000, -0x852023, 0x3c010001, 0xac243de4, 0x822023, -0x3c010001, 0xac223dc0, 0x27620ffc, 0x3c010001, -0xac223ca0, 0x27621ffc, 0xdb3023, 0x7b1823, -0x3c010001, 0xac253dcc, 0x3c010001, 0xac243dc4, -0x3c010001, 0xac223ca4, 0xaf860150, 0x10e00011, -0xaf830250, 0x3c1d0001, 0x8fbd3c5c, 0x3a0f021, -0xc0016f8, 0x0, 0x3c020001, 0x8c423c60, -0x3c030001, 0x8c633c64, 0x2442fe00, 0x24630200, -0x3c010001, 0xac223c60, 0x3c010001, 0x10000004, -0xac233c64, 0x3c1d0001, 0x8fbd3ca0, 0x3a0f021, -0x3c020001, 0x8c423c54, 0x1040000d, 0x26fafa48, -0x3c020001, 0x8c423c60, 0x3c030001, 0x8c633c64, -0x3c1a0001, 0x8f5a3c64, 0x2442fa48, 0x246305b8, -0x3c010001, 0xac223c60, 0x3c010001, 0xac233c64, -0x3c020001, 0x8c423c58, 0x14400003, 0x0, -0x3c010001, 0xac203c60, 0xc00114d, 0x0, -0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, -0x3c020001, 0x8c423c60, 0x3c030001, 0x8c633c64, -0x27bdffa0, 0xafb00040, 0x3c100001, 0x8e1036f4, -0x3c040001, 0x24842d40, 0xafbf0058, 0xafbe0054, -0xafb50050, 0xafb3004c, 0xafb20048, 0xafb10044, -0xafa20034, 0xafa30030, 0xafa00010, 0xafa00014, -0x8f860040, 0x24050200, 0xc0029d3, 0x2003821, -0x8f830040, 0x3c02f000, 0x621824, 0x3c026000, -0x1062000b, 0xa3a0003f, 0x240e0001, 0x3c040001, -0x24842d48, 0xa3ae003f, 0xafa00010, 0xafa00014, -0x8f860040, 0x24050300, 0xc0029d3, 0x2003821, -0x8f820240, 0x3c030001, 0x431025, 0xaf820240, -0xaf800048, 0x8f820048, 0x14400005, 0x0, -0xaf800048, 0x8f820048, 0x10400004, 0x0, -0xaf800048, 0x10000003, 0x2e02021, 0xaf80004c, -0x2e02021, 0x3c050001, 0xc002a40, 0x34a540f8, -0x3402021, 0xc002a40, 0x240505b8, 0x3c020001, -0x8c423de4, 0x3c0d0001, 0x8dad3dc4, 0x3c030001, -0x8c633dc0, 0x3c080001, 0x8d083dcc, 0x3c090001, -0x8d293de8, 0x3c0a0001, 0x8d4a3df0, 0x3c0b0001, -0x8d6b3e00, 0x3c0c0001, 0x8d8c3dd4, 0x3c040001, -0x24842d54, 0x24050400, 0xaf420130, 0x8f420130, -0x24060001, 0x24070001, 0xaf400000, 0xaf4d012c, -0xaf430138, 0xaf48013c, 0xaf490140, 0xaf4a0144, -0xaf4b0148, 0xaf4c014c, 0x2442ff80, 0xaf420134, -0x24020001, 0xafa20010, 0xc0029d3, 0xafa00014, -0x8f42012c, 0xafa20010, 0x8f420130, 0xafa20014, -0x8f460138, 0x8f47013c, 0x3c040001, 0x24842d60, -0xc0029d3, 0x24050500, 0xafb70010, 0xafba0014, -0x8f460140, 0x8f470144, 0x3c040001, 0x24842d6c, -0xc0029d3, 0x24050600, 0x3c020001, 0x8c423dd8, -0x3603821, 0x3c060001, 0x24c65f40, 0x2448ffff, -0x1061824, 0xe81024, 0x43102b, 0x10400006, -0x24050900, 0x3c040001, 0x24842d78, 0xafa80010, -0xc0029d3, 0xafa00014, 0x8f82000c, 0xafa20010, -0x8f82003c, 0xafa20014, 0x8f860000, 0x8f870004, -0x3c040001, 0x24842d84, 0xc0029d3, 0x24051000, -0x8c020220, 0x8c030224, 0x8c060218, 0x8c07021c, -0x3c040001, 0x24842d8c, 0x24051100, 0xafa20010, -0xc0029d3, 0xafa30014, 0xaf800054, 0xaf80011c, -0x8c020218, 0x30420002, 0x10400009, 0x0, -0x8c020220, 0x3c030002, 0x34630004, 0x431025, -0xaf42000c, 0x8c02021c, 0x10000008, 0x34420004, -0x8c020220, 0x3c030002, 0x34630006, 0x431025, -0xaf42000c, 0x8c02021c, 0x34420006, 0xaf420014, -0x8c020218, 0x30420010, 0x1040000a, 0x0, -0x8c02021c, 0x34420004, 0xaf420010, 0x8c020220, -0x3c03000a, 0x34630004, 0x431025, 0x10000009, -0xaf420008, 0x8c020220, 0x3c03000a, 0x34630006, -0x431025, 0xaf420008, 0x8c02021c, 0x34420006, -0xaf420010, 0x24020001, 0xaf8200a0, 0xaf8200b0, -0x8f830054, 0x8f820054, 0x10000002, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x0, 0x8c040208, 0x8c05020c, 0x26e20028, -0xaee20020, 0x24020490, 0xaee20010, 0xaee40008, -0xaee5000c, 0x26e40008, 0x8c820000, 0x8c830004, -0xaf820090, 0xaf830094, 0x8c820018, 0xaf8200b4, -0x9482000a, 0xaf82009c, 0x8f8200b0, 0x8f430014, -0x431025, 0xaf8200b0, 0x8f8200b0, 0x30420004, -0x1440fffd, 0x24051200, 0x96e20472, 0x96e60452, -0x96e70462, 0xafa20010, 0x96e20482, 0x3c040001, -0x24842d94, 0xc0029d3, 0xafa20014, 0x96f00452, -0x32020001, 0x10400002, 0xb021, 0x24160001, -0x32020002, 0x54400001, 0x36d60002, 0x32020008, -0x54400001, 0x36d60004, 0x32020010, 0x54400001, -0x36d60008, 0x32020020, 0x54400001, 0x36d60010, -0x32020040, 0x54400001, 0x36d60020, 0x32020080, -0x54400001, 0x36d60040, 0x96e60482, 0x30c20200, -0x54400001, 0x36d64000, 0x96e30472, 0x30620200, -0x10400003, 0x30620100, 0x10000003, 0x36d62000, -0x54400001, 0x36d61000, 0x96f00462, 0x32c24000, -0x14400004, 0x3207009b, 0x30c2009b, 0x14e20007, -0x240e0001, 0x32c22000, 0x1440000d, 0x32020001, -0x3062009b, 0x10e20009, 0x240e0001, 0x3c040001, -0x24842da0, 0x24051300, 0x2003821, 0xa3ae003f, -0xafa30010, 0xc0029d3, 0xafa00014, 0x32020001, -0x54400001, 0x36d60080, 0x32020002, 0x54400001, -0x36d60100, 0x32020008, 0x54400001, 0x36d60200, -0x32020010, 0x54400001, 0x36d60400, 0x32020080, -0x54400001, 0x36d60800, 0x8c020218, 0x30420200, -0x10400002, 0x3c020008, 0x2c2b025, 0x8c020218, -0x30420800, 0x10400002, 0x3c020080, 0x2c2b025, -0x8c020218, 0x30420400, 0x10400002, 0x3c020100, -0x2c2b025, 0x8c020218, 0x30420100, 0x10400002, -0x3c020200, 0x2c2b025, 0x8c020218, 0x30420080, -0x10400002, 0x3c020400, 0x2c2b025, 0x8c020218, -0x30422000, 0x10400002, 0x3c020010, 0x2c2b025, -0x8c020218, 0x30424000, 0x10400002, 0x3c020020, -0x2c2b025, 0x8c020218, 0x30421000, 0x10400002, -0x3c020040, 0x2c2b025, 0x8ee20498, 0x8ee3049c, -0xaf420150, 0xaf430154, 0x8ee204a0, 0x8ee304a4, -0xaf420158, 0xaf43015c, 0x8ee204a8, 0x8ee304ac, -0xaf420160, 0xaf430164, 0x8ee20428, 0x8ee3042c, -0xaf420168, 0xaf43016c, 0x8ee20448, 0x8ee3044c, -0xaf420170, 0xaf430174, 0x8ee20458, 0x8ee3045c, -0xaf420178, 0xaf43017c, 0x8ee20468, 0x8ee3046c, -0xaf420180, 0xaf430184, 0x8ee20478, 0x8ee3047c, -0xaf420188, 0xaf43018c, 0x8ee20488, 0x8ee3048c, -0xaf420190, 0xaf430194, 0x8ee204b0, 0x8ee304b4, -0x24040080, 0xaf420198, 0xaf43019c, 0xc002a40, -0x24050080, 0x8c02025c, 0x27440214, 0xaf4201e0, -0x8c020260, 0x24050200, 0x24060008, 0xc002a57, -0xaf4201e8, 0x3c043b9a, 0x3484ca00, 0x3821, -0x24020006, 0x24030002, 0xaf4201e4, 0x240203e8, -0xaf4301f4, 0xaf4301f0, 0xaf4401ec, 0xaf420284, -0x24020001, 0xaf430280, 0xaf42028c, 0x3c030001, -0x671821, 0x90633c68, 0x3471021, 0x24e70001, -0xa043021c, 0x2ce2000f, 0x1440fff8, 0x3471821, -0x24e70001, 0x3c080001, 0x350840f8, 0x8f820040, -0x3c040001, 0x24842dac, 0x24051400, 0x21702, -0x24420030, 0xa062021c, 0x3471021, 0xa040021c, -0x8c070218, 0x2c03021, 0x240205b8, 0xafa20010, -0xc0029d3, 0xafa80014, 0x3c040001, 0x24842db8, -0x3c050000, 0x24a55b3c, 0x24060010, 0x27b10030, -0x2203821, 0x27b30034, 0xc001750, 0xafb30010, -0x3c030001, 0x8c633c58, 0x1060000a, 0x408021, -0x8fa30030, 0x2405ff00, 0x8fa20034, 0x246400ff, -0x852024, 0x831823, 0x431023, 0xafa20034, -0xafa40030, 0xafb30010, 0x3c040001, 0x24842dc4, -0x3c050000, 0x24a54100, 0x24060108, 0xc001750, -0x2203821, 0x409021, 0x32c20003, 0x50400045, -0x2203821, 0x8f820050, 0x3c030010, 0x431024, +0x3c070001, 0x8ce73cc0, 0x3c0300bf, 0x3463e000, +0x852023, 0x3c010001, 0xac243e54, 0x822023, +0x3c010001, 0xac253e3c, 0x52842, 0x3c010001, +0xac223e30, 0x27620ffc, 0x3c010001, 0xac223d10, +0x27621ffc, 0xdb3023, 0x7b1823, 0x3c010001, +0xac243e34, 0x3c010001, 0xac253e58, 0x3c010001, +0xac223d14, 0xaf860150, 0x10e00011, 0xaf830250, +0x3c1d0001, 0x8fbd3ccc, 0x3a0f021, 0xc0016f7, +0x0, 0x3c020001, 0x8c423cd0, 0x3c030001, +0x8c633cd4, 0x2442fe00, 0x24630200, 0x3c010001, +0xac223cd0, 0x3c010001, 0x10000004, 0xac233cd4, +0x3c1d0001, 0x8fbd3d10, 0x3a0f021, 0x3c020001, +0x8c423cc4, 0x1040000d, 0x26fafa48, 0x3c020001, +0x8c423cd0, 0x3c030001, 0x8c633cd4, 0x3c1a0001, +0x8f5a3cd4, 0x2442fa48, 0x246305b8, 0x3c010001, +0xac223cd0, 0x3c010001, 0xac233cd4, 0x3c020001, +0x8c423cc8, 0x14400003, 0x0, 0x3c010001, +0xac203cd0, 0xc00114c, 0x0, 0x8fbf001c, +0x8fb00018, 0x3e00008, 0x27bd0020, 0x3c020001, +0x8c423cd0, 0x3c030001, 0x8c633cd4, 0x27bdffa0, +0xafb00040, 0x3c100001, 0x8e103738, 0x3c040001, +0x24842d60, 0xafbf0058, 0xafbe0054, 0xafb50050, +0xafb3004c, 0xafb20048, 0xafb10044, 0xafa20034, +0xafa30030, 0xafa00010, 0xafa00014, 0x8f860040, +0x24050200, 0xc0029bb, 0x2003821, 0x8f830040, +0x3c02f000, 0x621824, 0x3c026000, 0x1062000b, +0xa3a0003f, 0x240e0001, 0x3c040001, 0x24842d68, +0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f860040, +0x24050300, 0xc0029bb, 0x2003821, 0x8f820240, +0x3c030001, 0x431025, 0xaf820240, 0xaf800048, +0x8f820048, 0x14400005, 0x0, 0xaf800048, +0x8f820048, 0x10400004, 0x0, 0xaf800048, +0x10000003, 0x2e02021, 0xaf80004c, 0x2e02021, +0x3c050001, 0xc002a28, 0x34a540f8, 0x3402021, +0xc002a28, 0x240505b8, 0x3c020001, 0x8c423e54, +0x3c0d0001, 0x8dad3e34, 0x3c030001, 0x8c633e30, +0x3c080001, 0x8d083e3c, 0x3c090001, 0x8d293e58, +0x3c0a0001, 0x8d4a3e60, 0x3c0b0001, 0x8d6b3e70, +0x3c0c0001, 0x8d8c3e44, 0x3c040001, 0x24842d74, +0x24050400, 0xaf420130, 0x8f420130, 0x24060001, +0x24070001, 0xaf400000, 0xaf4d012c, 0xaf430138, +0xaf48013c, 0xaf490140, 0xaf4a0144, 0xaf4b0148, +0xaf4c014c, 0x2442ff80, 0xaf420134, 0x24020001, +0xafa20010, 0xc0029bb, 0xafa00014, 0x8f42012c, +0xafa20010, 0x8f420130, 0xafa20014, 0x8f460138, +0x8f47013c, 0x3c040001, 0x24842d80, 0xc0029bb, +0x24050500, 0xafb70010, 0xafba0014, 0x8f460140, +0x8f470144, 0x3c040001, 0x24842d8c, 0xc0029bb, +0x24050600, 0x3c020001, 0x8c423e48, 0x3603821, +0x3c060001, 0x24c65fb0, 0x2448ffff, 0x1061824, +0xe81024, 0x43102b, 0x10400006, 0x24050900, +0x3c040001, 0x24842d98, 0xafa80010, 0xc0029bb, +0xafa00014, 0x8f82000c, 0xafa20010, 0x8f82003c, +0xafa20014, 0x8f860000, 0x8f870004, 0x3c040001, +0x24842da4, 0xc0029bb, 0x24051000, 0x8c020220, +0x8c030224, 0x8c060218, 0x8c07021c, 0x3c040001, +0x24842dac, 0x24051100, 0xafa20010, 0xc0029bb, +0xafa30014, 0xaf800054, 0xaf80011c, 0x8c020218, +0x30420002, 0x10400009, 0x0, 0x8c020220, +0x3c030002, 0x34630004, 0x431025, 0xaf42000c, +0x8c02021c, 0x10000008, 0x34420004, 0x8c020220, +0x3c030002, 0x34630006, 0x431025, 0xaf42000c, +0x8c02021c, 0x34420006, 0xaf420014, 0x8c020218, +0x30420010, 0x1040000a, 0x0, 0x8c02021c, +0x34420004, 0xaf420010, 0x8c020220, 0x3c03000a, +0x34630004, 0x431025, 0x10000009, 0xaf420008, +0x8c020220, 0x3c03000a, 0x34630006, 0x431025, +0xaf420008, 0x8c02021c, 0x34420006, 0xaf420010, +0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054, +0x8f820054, 0x10000002, 0x24630064, 0x8f820054, +0x621023, 0x2c420065, 0x1440fffc, 0x0, +0x8c040208, 0x8c05020c, 0x26e20028, 0xaee20020, +0x24020490, 0xaee20010, 0xaee40008, 0xaee5000c, +0x26e40008, 0x8c820000, 0x8c830004, 0xaf820090, +0xaf830094, 0x8c820018, 0xaf8200b4, 0x9482000a, +0xaf82009c, 0x8f8200b0, 0x8f430014, 0x431025, +0xaf8200b0, 0x8f8200b0, 0x30420004, 0x1440fffd, +0x24051200, 0x96e20472, 0x96e60452, 0x96e70462, +0xafa20010, 0x96e20482, 0x3c040001, 0x24842db4, +0xc0029bb, 0xafa20014, 0x96f00452, 0x32020001, +0x10400002, 0xb021, 0x24160001, 0x32020002, +0x54400001, 0x36d60002, 0x32020008, 0x54400001, +0x36d60004, 0x32020010, 0x54400001, 0x36d60008, +0x32020020, 0x54400001, 0x36d60010, 0x32020040, +0x54400001, 0x36d60020, 0x32020080, 0x54400001, +0x36d60040, 0x96e60482, 0x30c20200, 0x54400001, +0x36d64000, 0x96e30472, 0x30620200, 0x10400003, +0x30620100, 0x10000003, 0x36d62000, 0x54400001, +0x36d61000, 0x96f00462, 0x32c24000, 0x14400004, +0x3207009b, 0x30c2009b, 0x14e20007, 0x240e0001, +0x32c22000, 0x1440000d, 0x32020001, 0x3062009b, +0x10e20009, 0x240e0001, 0x3c040001, 0x24842dc0, +0x24051300, 0x2003821, 0xa3ae003f, 0xafa30010, +0xc0029bb, 0xafa00014, 0x32020001, 0x54400001, +0x36d60080, 0x32020002, 0x54400001, 0x36d60100, +0x32020008, 0x54400001, 0x36d60200, 0x32020010, +0x54400001, 0x36d60400, 0x32020080, 0x54400001, +0x36d60800, 0x8c020218, 0x30420200, 0x10400002, +0x3c020008, 0x2c2b025, 0x8c020218, 0x30420800, +0x10400002, 0x3c020080, 0x2c2b025, 0x8c020218, +0x30420400, 0x10400002, 0x3c020100, 0x2c2b025, +0x8c020218, 0x30420100, 0x10400002, 0x3c020200, +0x2c2b025, 0x8c020218, 0x30420080, 0x10400002, +0x3c020400, 0x2c2b025, 0x8c020218, 0x30422000, +0x10400002, 0x3c020010, 0x2c2b025, 0x8c020218, +0x30424000, 0x10400002, 0x3c020020, 0x2c2b025, +0x8c020218, 0x30421000, 0x10400002, 0x3c020040, +0x2c2b025, 0x8ee20498, 0x8ee3049c, 0xaf420150, +0xaf430154, 0x8ee204a0, 0x8ee304a4, 0xaf420158, +0xaf43015c, 0x8ee204a8, 0x8ee304ac, 0xaf420160, +0xaf430164, 0x8ee20428, 0x8ee3042c, 0xaf420168, +0xaf43016c, 0x8ee20448, 0x8ee3044c, 0xaf420170, +0xaf430174, 0x8ee20458, 0x8ee3045c, 0xaf420178, +0xaf43017c, 0x8ee20468, 0x8ee3046c, 0xaf420180, +0xaf430184, 0x8ee20478, 0x8ee3047c, 0xaf420188, +0xaf43018c, 0x8ee20488, 0x8ee3048c, 0xaf420190, +0xaf430194, 0x8ee204b0, 0x8ee304b4, 0x24040080, +0xaf420198, 0xaf43019c, 0xc002a28, 0x24050080, +0x8c02025c, 0x27440214, 0xaf4201e0, 0x8c020260, +0x24050200, 0x24060008, 0xc002a3f, 0xaf4201e8, +0x3c043b9a, 0x3484ca00, 0x3821, 0x24020006, +0x24030002, 0xaf4201e4, 0x240203e8, 0xaf4301f4, +0xaf4301f0, 0xaf4401ec, 0xaf420284, 0x24020001, +0xaf430280, 0xaf42028c, 0x3c030001, 0x671821, +0x90633cd8, 0x3471021, 0x24e70001, 0xa043021c, +0x2ce2000f, 0x1440fff8, 0x3471821, 0x24e70001, +0x3c080001, 0x350840f8, 0x8f820040, 0x3c040001, +0x24842dcc, 0x24051400, 0x21702, 0x24420030, +0xa062021c, 0x3471021, 0xa040021c, 0x8c070218, +0x2c03021, 0x240205b8, 0xafa20010, 0xc0029bb, +0xafa80014, 0x3c040001, 0x24842dd8, 0x3c050000, +0x24a55b38, 0x24060010, 0x27b10030, 0x2203821, +0x27b30034, 0xc001751, 0xafb30010, 0x3c030001, +0x8c633cc8, 0x1060000a, 0x408021, 0x8fa30030, +0x2405ff00, 0x8fa20034, 0x246400ff, 0x852024, +0x831823, 0x431023, 0xafa20034, 0xafa40030, +0xafb30010, 0x3c040001, 0x24842de4, 0x3c050000, +0x24a54100, 0x24060108, 0xc001751, 0x2203821, +0x409021, 0x32c20003, 0x50400045, 0x2203821, +0x8f820050, 0x3c030010, 0x431024, 0x10400016, +0x0, 0x8c020218, 0x30420040, 0x1040000f, +0x24020001, 0x8f820050, 0x8c030218, 0x240e0001, +0x3c040001, 0x24842df0, 0xa3ae003f, 0xafa20010, +0xafa30014, 0x8f870040, 0x24051500, 0xc0029bb, +0x2c03021, 0x10000004, 0x0, 0x3c010001, +0x370821, 0xa02240f4, 0x3c040001, 0x24842dfc, +0x3c050001, 0x24a52c20, 0x3c060001, 0x24c62c8c, +0xc53023, 0x8f420010, 0x27b30030, 0x2603821, +0x27b10034, 0x34420a00, 0xaf420010, 0xc001751, +0xafb10010, 0x3c040001, 0x24842e10, 0x3c050001, +0x24a5af38, 0x3c060001, 0x24c6b2b4, 0xc53023, +0x2603821, 0xaf420108, 0xc001751, 0xafb10010, +0x3c040001, 0x24842e2c, 0x3c050001, 0x24a5b6c4, +0x3c060001, 0x24c6c1a8, 0xc53023, 0x2603821, +0x3c010001, 0xac223ea0, 0xc001751, 0xafb10010, +0x3c040001, 0x24842e44, 0x10000024, 0x24051600, +0x3c040001, 0x24842e4c, 0x3c050001, 0x24a59b0c, +0x3c060001, 0x24c69c38, 0xc53023, 0xc001751, +0xafb30010, 0x3c040001, 0x24842e5c, 0x3c050001, +0x24a5aad4, 0x3c060001, 0x24c6af30, 0xc53023, +0x2203821, 0xaf420108, 0xc001751, 0xafb30010, +0x3c040001, 0x24842e70, 0x3c050001, 0x24a5b2bc, +0x3c060001, 0x24c6b6bc, 0xc53023, 0x2203821, +0x3c010001, 0xac223ea0, 0xc001751, 0xafb30010, +0x3c040001, 0x24842e84, 0x24051650, 0x2c03021, +0x3821, 0x3c010001, 0xac223ea4, 0xafa00010, +0xc0029bb, 0xafa00014, 0x32c20020, 0x10400021, +0x27a70030, 0x3c040001, 0x24842e90, 0x3c050001, +0x24a5a960, 0x3c060001, 0x24c6aacc, 0xc53023, +0x24022000, 0xaf42001c, 0x27a20034, 0xc001751, +0xafa20010, 0x21900, 0x31982, 0x3c040800, +0x641825, 0xae430028, 0x24030010, 0xaf43003c, +0x96e30450, 0xaf430040, 0x8f430040, 0x3c040001, +0x24842ea4, 0xafa00014, 0xafa30010, 0x8f47001c, +0x24051660, 0x3c010001, 0xac223e9c, 0x10000025, +0x32c60020, 0x8ee20448, 0x8ee3044c, 0xaf43001c, +0x8f42001c, 0x2442e000, 0x2c422001, 0x1440000a, +0x240e0001, 0x3c040001, 0x24842eb0, 0xa3ae003f, +0xafa00010, 0xafa00014, 0x8f46001c, 0x24051700, +0xc0029bb, 0x3821, 0x3c020000, 0x24425b74, +0x21100, 0x21182, 0x3c030800, 0x431025, +0xae420028, 0x24020008, 0xaf42003c, 0x96e20450, +0xaf420040, 0x8f420040, 0x3c040001, 0x24842ebc, +0xafa00014, 0xafa20010, 0x8f47001c, 0x24051800, +0x32c60020, 0xc0029bb, 0x0, 0x3c030001, +0x8c633ea0, 0x3c050fff, 0x34a5ffff, 0x3c020001, +0x8c423ea4, 0x3c040800, 0x651824, 0x31882, +0x641825, 0x451024, 0x21082, 0x441025, +0xae420080, 0x32c20180, 0x10400056, 0xae430020, +0x8f82005c, 0x3c030080, 0x431024, 0x1040000d, +0x0, 0x8f820050, 0xafa20010, 0x8f82005c, +0x240e0001, 0x3c040001, 0x24842ec8, 0xa3ae003f, +0xafa20014, 0x8f870040, 0x24051900, 0xc0029bb, +0x2c03021, 0x8f820050, 0x3c030010, 0x431024, 0x10400016, 0x0, 0x8c020218, 0x30420040, 0x1040000f, 0x24020001, 0x8f820050, 0x8c030218, -0x240e0001, 0x3c040001, 0x24842dd0, 0xa3ae003f, -0xafa20010, 0xafa30014, 0x8f870040, 0x24051500, -0xc0029d3, 0x2c03021, 0x10000004, 0x0, +0x240e0001, 0x3c040001, 0x24842df0, 0xa3ae003f, +0xafa20010, 0xafa30014, 0x8f870040, 0x24052000, +0xc0029bb, 0x2c03021, 0x10000004, 0x0, 0x3c010001, 0x370821, 0xa02240f4, 0x3c040001, -0x24842ddc, 0x3c050001, 0x24a59ce8, 0x3c060001, -0x24c69d60, 0xc53023, 0x8f420010, 0x27b30030, -0x2603821, 0x27b10034, 0x34420a00, 0xaf420010, -0xc001750, 0xafb10010, 0x3c040001, 0x24842df0, -0x3c050001, 0x24a5af7c, 0x3c060001, 0x24c6b2f8, -0xc53023, 0x2603821, 0xaf420108, 0xc001750, -0xafb10010, 0x3c040001, 0x24842e0c, 0x3c050001, -0x24a5b714, 0x3c060001, 0x24c6c1d4, 0xc53023, -0x2603821, 0x3c010001, 0xac223e30, 0xc001750, -0xafb10010, 0x3c040001, 0x24842e24, 0x10000024, -0x24051600, 0x3c040001, 0x24842e2c, 0x3c050001, -0x24a59bb4, 0x3c060001, 0x24c69ce0, 0xc53023, -0xc001750, 0xafb30010, 0x3c040001, 0x24842e3c, -0x3c050001, 0x24a5ab34, 0x3c060001, 0x24c6af74, -0xc53023, 0x2203821, 0xaf420108, 0xc001750, -0xafb30010, 0x3c040001, 0x24842e50, 0x3c050001, -0x24a5b300, 0x3c060001, 0x24c6b70c, 0xc53023, -0x2203821, 0x3c010001, 0xac223e30, 0xc001750, -0xafb30010, 0x3c040001, 0x24842e64, 0x24051650, -0x2c03021, 0x3821, 0x3c010001, 0xac223e34, -0xafa00010, 0xc0029d3, 0xafa00014, 0x32c20020, -0x10400021, 0x27a70030, 0x3c040001, 0x24842e70, -0x3c050001, 0x24a5a9c0, 0x3c060001, 0x24c6ab2c, -0xc53023, 0x24022000, 0xaf42001c, 0x27a20034, -0xc001750, 0xafa20010, 0x21900, 0x31982, -0x3c040800, 0x641825, 0xae430028, 0x24030010, -0xaf43003c, 0x96e30450, 0xaf430040, 0x8f430040, -0x3c040001, 0x24842e84, 0xafa00014, 0xafa30010, -0x8f47001c, 0x24051660, 0x3c010001, 0xac223e2c, -0x10000025, 0x32c60020, 0x8ee20448, 0x8ee3044c, -0xaf43001c, 0x8f42001c, 0x2442e000, 0x2c422001, -0x1440000a, 0x240e0001, 0x3c040001, 0x24842e90, -0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f46001c, -0x24051700, 0xc0029d3, 0x3821, 0x3c020000, -0x24425b78, 0x21100, 0x21182, 0x3c030800, -0x431025, 0xae420028, 0x24020008, 0xaf42003c, -0x96e20450, 0xaf420040, 0x8f420040, 0x3c040001, -0x24842e9c, 0xafa00014, 0xafa20010, 0x8f47001c, -0x24051800, 0x32c60020, 0xc0029d3, 0x0, -0x3c030001, 0x8c633e30, 0x3c050fff, 0x34a5ffff, -0x3c020001, 0x8c423e34, 0x3c040800, 0x651824, -0x31882, 0x641825, 0x451024, 0x21082, -0x441025, 0xae420080, 0x32c20180, 0x10400056, -0xae430020, 0x8f82005c, 0x3c030080, 0x431024, -0x1040000d, 0x0, 0x8f820050, 0xafa20010, -0x8f82005c, 0x240e0001, 0x3c040001, 0x24842ea8, -0xa3ae003f, 0xafa20014, 0x8f870040, 0x24051900, -0xc0029d3, 0x2c03021, 0x8f820050, 0x3c030010, -0x431024, 0x10400016, 0x0, 0x8c020218, -0x30420040, 0x1040000f, 0x24020001, 0x8f820050, -0x8c030218, 0x240e0001, 0x3c040001, 0x24842dd0, -0xa3ae003f, 0xafa20010, 0xafa30014, 0x8f870040, -0x24052000, 0xc0029d3, 0x2c03021, 0x10000004, -0x0, 0x3c010001, 0x370821, 0xa02240f4, -0x3c040001, 0x24842eb4, 0x3c050001, 0x24a59b2c, -0x3c060001, 0x24c69bac, 0xc53023, 0x8f420008, -0x27b30030, 0x2603821, 0x27b10034, 0x34420e00, -0xaf420008, 0xc001750, 0xafb10010, 0x3c040001, -0x24842ecc, 0x3c050001, 0x24a5d090, 0x3c060001, -0x24c6db90, 0xc53023, 0x2603821, 0xaf42010c, -0xc001750, 0xafb10010, 0x3c040001, 0x24842ee4, -0x3c050001, 0x24a5e174, 0x3c060001, 0x24c6e860, -0xc53023, 0x2603821, 0x3c010001, 0xac223e40, -0xc001750, 0xafb10010, 0x3c040001, 0x24842efc, -0x10000027, 0x24052100, 0x3c040001, 0x24842f04, -0x3c050001, 0x24a599e8, 0x3c060001, 0x24c69b24, -0xc53023, 0x27b10030, 0x2203821, 0x27b30034, -0xc001750, 0xafb30010, 0x3c040001, 0x24842f14, -0x3c050001, 0x24a5c300, 0x3c060001, 0x24c6d088, -0xc53023, 0x2203821, 0xaf42010c, 0xc001750, -0xafb30010, 0x3c040001, 0x24842f24, 0x3c050001, -0x24a5e014, 0x3c060001, 0x24c6e16c, 0xc53023, -0x2203821, 0x3c010001, 0xac223e40, 0xc001750, -0xafb30010, 0x3c040001, 0x24842f38, 0x24052150, -0x2c03021, 0x3821, 0x3c010001, 0xac223e4c, -0xafa00010, 0xc0029d3, 0xafa00014, 0x3c030001, -0x8c633e40, 0x3c110fff, 0x3631ffff, 0x3c020001, -0x8c423e4c, 0x3c1e0800, 0x711824, 0x31882, -0x7e1825, 0x511024, 0x21082, 0x5e1025, -0xae430038, 0xae420078, 0x8c020218, 0x30420040, -0x14400004, 0x24020001, 0x3c010001, 0x370821, -0xa02240f4, 0x3c040001, 0x24842f44, 0x3c050001, -0x24a5db98, 0x3c060001, 0x24c6dcf4, 0xc53023, -0x27b50030, 0x2a03821, 0x27b30034, 0xc001750, -0xafb30010, 0x3c010001, 0xac223e38, 0x511024, -0x21082, 0x5e1025, 0xae420050, 0x32c22000, -0x10400005, 0x2a03821, 0x3c020000, 0x24425b78, -0x1000000d, 0x511024, 0x3c040001, 0x24842f58, -0x3c050001, 0x24a5dcfc, 0x3c060001, 0x24c6deac, -0xc53023, 0xc001750, 0xafb30010, 0x3c010001, -0xac223e50, 0x511024, 0x21082, 0x5e1025, -0xae420048, 0x32c24000, 0x10400005, 0x27a70030, -0x3c020000, 0x24425b78, 0x1000000e, 0x21100, -0x3c040001, 0x24842f70, 0x3c050001, 0x24a5deb4, -0x3c060001, 0x24c6e00c, 0xc53023, 0x27a20034, -0xc001750, 0xafa20010, 0x3c010001, 0xac223e44, -0x21100, 0x21182, 0x3c030800, 0x431025, -0xae420060, 0x3c040001, 0x24842f88, 0x3c050000, -0x24a57ca0, 0x3c060001, 0x24c680c4, 0xc53023, -0x27b10030, 0x2203821, 0x27b30034, 0xc001750, -0xafb30010, 0x3c1e0fff, 0x37deffff, 0x3c040001, -0x24842f94, 0x3c050000, 0x24a56318, 0x3c060000, -0x24c66478, 0xc53023, 0x2203821, 0x3c010001, -0xac223e18, 0x5e1024, 0x21082, 0x3c150800, -0x551025, 0xae4200b8, 0xc001750, 0xafb30010, -0x3c040001, 0x24842fa0, 0x3c050000, 0x24a56480, -0x3c060000, 0x24c666f8, 0xc53023, 0x2203821, -0x3c010001, 0xac223e0c, 0x5e1024, 0x21082, -0x551025, 0xae4200e8, 0xc001750, 0xafb30010, -0x3c040001, 0x24842fb8, 0x3c050000, 0x24a56700, -0x3c060000, 0x24c66830, 0xc53023, 0x2203821, -0x3c010001, 0xac223e04, 0x5e1024, 0x21082, -0x551025, 0xae4200c0, 0xc001750, 0xafb30010, -0x3c040001, 0x24842fd0, 0x3c050001, 0x24a5f240, -0x3c060001, 0x24c6f318, 0xc53023, 0x2203821, -0x3c010001, 0xac223e10, 0x5e1024, 0x21082, -0x551025, 0xae4200c8, 0xc001750, 0xafb30010, -0x3c040001, 0x24842fdc, 0x3c050001, 0x24a5c1e0, -0x3c060001, 0x24c6c21c, 0xc53023, 0x2203821, -0xaf420110, 0xc001750, 0xafb30010, 0x3c040001, -0x24842fec, 0x3c050001, 0x24a5c224, 0x3c060001, -0x24c6c24c, 0xc53023, 0x2203821, 0xaf420114, -0xc001750, 0xafb30010, 0x3c040001, 0x24842ff8, -0x3c050001, 0x24a5e9c0, 0x3c060001, 0x24c6eeac, -0xc53023, 0x2203821, 0xaf420118, 0xc001750, -0xafb30010, 0x3c010001, 0xac223e54, 0x5e1024, -0x21082, 0x551025, 0xc003d9f, 0xae4200d0, -0xc003a1c, 0x0, 0xc002630, 0x0, -0xac000228, 0xac00022c, 0x96e20450, 0x2442ffff, -0xaf420038, 0x96e20460, 0xaf420080, 0x32c24000, -0x14400003, 0x0, 0x96e20480, 0xaf420084, -0x96e70490, 0x50e00001, 0x24070800, 0x24e2ffff, -0xaf420088, 0xaf42007c, 0x24020800, 0x10e2000f, -0x32c24000, 0x10400003, 0x24020400, 0x10e2000b, -0x0, 0x240e0001, 0x3c040001, 0x24843008, -0xa3ae003f, 0x96e60490, 0x24052170, 0x2c03821, -0xafa00010, 0xc0029d3, 0xafa00014, 0x8f43012c, -0x8f44012c, 0x24020001, 0xa34205b3, 0xaf430094, -0xaf440098, 0xafa00010, 0xafa00014, 0x8f460080, -0x8f470084, 0x3c040001, 0x24843014, 0xc0029d3, -0x24052200, 0xc00232c, 0x3c110800, 0x3c1433d8, -0x3694cb58, 0x3c020800, 0x34420080, 0x3c040001, -0x24843020, 0x3c050000, 0x24a55bbc, 0x3c060000, -0x24c65bd8, 0xc53023, 0x27a70030, 0xaf820060, -0x2402ffff, 0xaf820064, 0x27a20034, 0xc001750, -0xafa20010, 0x3c010001, 0xac223df4, 0x21100, -0x21182, 0x511025, 0xc0018a8, 0xae420000, -0x8f820240, 0x3c030001, 0x431025, 0xaf820240, -0x3c020000, 0x24424034, 0xaf820244, 0xaf800240, -0x8f820060, 0x511024, 0x14400005, 0x3c030800, -0x8f820060, 0x431024, 0x1040fffd, 0x0, -0xc003a29, 0x8821, 0x3c020100, 0xafa20020, -0x8f530018, 0x240200ff, 0x56620001, 0x26710001, -0x8c020228, 0x1622000e, 0x1330c0, 0x8f42032c, -0x24420001, 0xaf42032c, 0x8f42032c, 0x8c020228, -0x3c040001, 0x24842ce4, 0x3c050009, 0xafa00014, -0xafa20010, 0x8fa60020, 0x1000003f, 0x34a50100, -0xd71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, -0xac4404c4, 0xc01821, 0x8f440168, 0x8f45016c, -0x1021, 0x24070004, 0xafa70010, 0xafb10014, -0x8f48000c, 0x24c604c0, 0x2e63021, 0xafa80018, -0x8f48010c, 0x24070008, 0xa32821, 0xa3482b, -0x822021, 0x100f809, 0x892021, 0x1440000b, -0x24070008, 0x8f820120, 0xafa20010, 0x8f820124, -0x3c040001, 0x24842cec, 0x3c050009, 0xafa20014, -0x8fa60020, 0x1000001c, 0x34a50200, 0x8f440150, -0x8f450154, 0x8f43000c, 0xaf510018, 0x8f860120, -0x24020010, 0xafa20010, 0xafb10014, 0xafa30018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x14400010, -0x0, 0x8f420330, 0x24420001, 0xaf420330, -0x8f420330, 0x8f820120, 0xafa20010, 0x8f820124, -0x3c040001, 0x24842cf4, 0x3c050009, 0xafa20014, -0x8fa60020, 0x34a50300, 0xc0029d3, 0x2603821, -0x8f4202d4, 0x24420001, 0xaf4202d4, 0x8f4202d4, -0x93a2003f, 0x10400069, 0x3c020700, 0x34423000, -0xafa20028, 0x8f530018, 0x240200ff, 0x12620002, -0x8821, 0x26710001, 0x8c020228, 0x1622000e, -0x1330c0, 0x8f42032c, 0x24420001, 0xaf42032c, -0x8f42032c, 0x8c020228, 0x3c040001, 0x24842ce4, -0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60028, -0x1000003f, 0x34a50100, 0xd71021, 0x8fa30028, -0x8fa4002c, 0xac4304c0, 0xac4404c4, 0xc01821, -0x8f440168, 0x8f45016c, 0x1021, 0x24070004, -0xafa70010, 0xafb10014, 0x8f48000c, 0x24c604c0, -0x2e63021, 0xafa80018, 0x8f48010c, 0x24070008, -0xa32821, 0xa3482b, 0x822021, 0x100f809, -0x892021, 0x1440000b, 0x24070008, 0x8f820120, -0xafa20010, 0x8f820124, 0x3c040001, 0x24842cec, -0x3c050009, 0xafa20014, 0x8fa60028, 0x1000001c, -0x34a50200, 0x8f440150, 0x8f450154, 0x8f43000c, -0xaf510018, 0x8f860120, 0x24020010, 0xafa20010, -0xafb10014, 0xafa30018, 0x8f42010c, 0x40f809, -0x24c6001c, 0x14400010, 0x0, 0x8f420330, -0x24420001, 0xaf420330, 0x8f420330, 0x8f820120, -0xafa20010, 0x8f820124, 0x3c040001, 0x24842cf4, -0x3c050009, 0xafa20014, 0x8fa60028, 0x34a50300, -0xc0029d3, 0x2603821, 0x8f4202e0, 0x24420001, -0xaf4202e0, 0x8f4202e0, 0x3c040001, 0x24843030, -0xafa00010, 0xafa00014, 0x8fa60028, 0x24052300, -0xc0029d3, 0x3821, 0x10000004, 0x0, -0x8c020264, 0x10400005, 0x0, 0x8f8200a0, -0x30420004, 0x1440fffa, 0x0, 0x8f820044, -0x34420004, 0xaf820044, 0x8f4202f8, 0x24420001, -0xaf4202f8, 0x8f4202f8, 0x8f8200d8, 0x8f8300d4, -0x431023, 0x2442ff80, 0xaf420090, 0x8f420090, -0x2842ff81, 0x10400006, 0x24020001, 0x8f420090, -0x8f430138, 0x431021, 0xaf420090, 0x24020001, -0xaf42008c, 0x32c20008, 0x10400006, 0x0, -0x8f820214, 0x3c038100, 0x3042ffff, 0x431025, -0xaf820214, 0x3c020001, 0x8c423d14, 0x30420001, -0x10400009, 0x0, 0x3c040001, 0x2484303c, -0x3c050000, 0x24a56c40, 0x3c060000, 0x24c670e8, -0x10000008, 0xc53023, 0x3c040001, 0x2484304c, -0x3c050000, 0x24a56838, 0x3c060000, 0x24c66c38, -0xc53023, 0x27a70030, 0x27a20034, 0xc001750, -0xafa20010, 0x3c010001, 0xac223e08, 0x3c020001, -0x8c423e08, 0x3c030800, 0x21100, 0x21182, -0x431025, 0xae420040, 0x8f8200a0, 0xafa20010, -0x8f8200b0, 0xafa20014, 0x8f86005c, 0x8f87011c, -0x3c040001, 0x2484305c, 0x3c010001, 0xac363de0, -0x3c010001, 0xac203dd0, 0x3c010001, 0xac3c3dc8, -0x3c010001, 0xac3b3df8, 0x3c010001, 0xac373dfc, -0x3c010001, 0xac3a3ddc, 0xc0029d3, 0x24052400, -0x8f820200, 0xafa20010, 0x8f820220, 0xafa20014, -0x8f860044, 0x8f870050, 0x3c040001, 0x24843068, -0xc0029d3, 0x24052500, 0x8f830060, 0x74100b, -0x242000a, 0x200f821, 0x0, 0xd, -0x8fbf0058, 0x8fbe0054, 0x8fb50050, 0x8fb3004c, -0x8fb20048, 0x8fb10044, 0x8fb00040, 0x3e00008, -0x27bd0060, 0x27bdffe0, 0x3c040001, 0x24843074, -0x24052600, 0x3021, 0x3821, 0xafbf0018, -0xafa00010, 0xc0029d3, 0xafa00014, 0x8fbf0018, -0x3e00008, 0x27bd0020, 0x3e00008, 0x0, -0x3e00008, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x3e00008, -0x0, 0x3e00008, 0x0, 0x27bdfde0, -0x27a50018, 0x3c04dead, 0x3484beef, 0xafbf0218, -0x8f820150, 0x3c03001f, 0x3463ffff, 0xafa40018, -0xa22823, 0xa32824, 0x8ca20000, 0x1044000a, -0x0, 0xafa50010, 0x8ca20000, 0xafa20014, -0x8f860150, 0x8f870250, 0x3c040001, 0x2484307c, -0xc0029d3, 0x24052700, 0x8fbf0218, 0x3e00008, -0x27bd0220, 0x27bdffe0, 0x3c06abba, 0x34c6babe, -0xafb00018, 0x3c100004, 0x3c07007f, 0x34e7ffff, -0xafbf001c, 0x102840, 0x8e040000, 0x8ca30000, -0xaca00000, 0xae060000, 0x8ca20000, 0xaca30000, -0x10460005, 0xae040000, 0xa08021, 0xf0102b, -0x1040fff5, 0x102840, 0x3c040001, 0x24843088, -0x24052800, 0x2003021, 0x3821, 0xafa00010, -0xc0029d3, 0xafa00014, 0x2001021, 0x8fbf001c, -0x8fb00018, 0x3e00008, 0x27bd0020, 0x8c020224, -0x3047003f, 0x10e00010, 0x803021, 0x2821, -0x24030020, 0xe31024, 0x10400002, 0x63042, -0xa62821, 0x31842, 0x1460fffb, 0xe31024, -0x2402f000, 0xa22824, 0x3403ffff, 0x65102b, -0x14400003, 0x851023, 0x10000006, 0x3c020001, -0x62102b, 0x14400003, 0xa01021, 0x3c02ffff, -0x821021, 0x3e00008, 0x0, 0x27bdffd0, -0xafb50028, 0x8fb50040, 0xafb20020, 0xa09021, -0xafb1001c, 0x24c60003, 0xafbf002c, 0xafb30024, -0xafb00018, 0x8ea20000, 0x2403fffc, 0xc38024, -0x50102b, 0x1440001b, 0xe08821, 0x8e330000, -0xafb00010, 0x8ea20000, 0xafa20014, 0x8e270000, -0x24053000, 0xc0029d3, 0x2403021, 0x8e230000, -0x702021, 0x64102b, 0x10400007, 0x2402821, -0x8ca20000, 0xac620000, 0x24630004, 0x64102b, -0x1440fffb, 0x24a50004, 0x8ea20000, 0x501023, -0xaea20000, 0x8e220000, 0x501021, 0x1000000b, -0xae220000, 0x2402002d, 0xa0820000, 0xafb00010, -0x8ea20000, 0x2409821, 0xafa20014, 0x8e270000, -0x24053100, 0xc0029d3, 0x2603021, 0x2601021, -0x8fbf002c, 0x8fb50028, 0x8fb30024, 0x8fb20020, -0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0030, -0x27bdffe8, 0x3c1cc000, 0x3c05fffe, 0x3c030001, -0x8c633dc0, 0x3c040001, 0x8c843dcc, 0x34a5bf08, -0x24021ffc, 0x3c010001, 0xac223c60, 0x3c0200c0, -0x3c010001, 0xac223c64, 0x3c020020, 0xafbf0010, -0x3c0100c0, 0xac201ffc, 0x431023, 0x441023, -0x245bb000, 0x365b821, 0x3c1d0001, 0x8fbd3c5c, -0x3a0f021, 0x3c0400c0, 0x34840200, 0x3c1a00c0, -0x3c0300c0, 0x346307b8, 0x24021dfc, 0x3c010001, -0xac223c60, 0x24021844, 0x3c010001, 0xac243c64, -0x3c010001, 0xac223c60, 0x3c010001, 0xac233c64, -0xc0017ba, 0x375a0200, 0x8fbf0010, 0x3e00008, -0x27bd0018, 0x27bdffc8, 0x3c040001, 0x24843094, -0x24053200, 0x3c020001, 0x8c423c60, 0x3c030001, -0x8c633c64, 0x3021, 0x3603821, 0xafbf0030, -0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, -0xafa2001c, 0xafa30018, 0xafb70010, 0xc0029d3, -0xafba0014, 0xc0018c2, 0x0, 0x8f820240, -0x34420004, 0xaf820240, 0x24020001, 0xaf420000, -0x3c020001, 0x571021, 0x904240f4, 0x10400092, -0x2403fffc, 0x3c100001, 0x2610a6d3, 0x3c120001, -0x2652a2ac, 0x2121023, 0x438024, 0x8fa3001c, -0x3c040001, 0x248430a0, 0x70102b, 0x1440001a, -0x27b30018, 0x8fb10018, 0x24053000, 0x2403021, -0xafb00010, 0xafa30014, 0xc0029d3, 0x2203821, -0x8fa30018, 0x702021, 0x64102b, 0x10400007, -0x2403021, 0x8cc20000, 0xac620000, 0x24630004, -0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c, -0x501023, 0xafa2001c, 0x8e620000, 0x501021, -0x1000000a, 0xae620000, 0x2408821, 0x24053100, -0xafb00010, 0xafa30014, 0x8fa70018, 0x2203021, -0x2402002d, 0xc0029d3, 0xa0820000, 0x24070020, -0x8fa3001c, 0x3c040001, 0x248430bc, 0x24120020, -0x3c010001, 0xac313dec, 0x2c620020, 0x1440001d, -0x27b10018, 0x8fb00018, 0x24053000, 0x3c060001, -0x24c63e80, 0xafa70010, 0xafa30014, 0xc0029d3, -0x2003821, 0x8fa30018, 0x3c040001, 0x24843e80, -0x24650020, 0x65102b, 0x10400007, 0x0, -0x8c820000, 0xac620000, 0x24630004, 0x65102b, -0x1440fffb, 0x24840004, 0x8fa2001c, 0x521023, -0xafa2001c, 0x8e220000, 0x521021, 0x1000000b, -0xae220000, 0x3c100001, 0x26103e80, 0x24053100, -0xafa70010, 0xafa30014, 0x8fa70018, 0x2003021, -0x2402002d, 0xc0029d3, 0xa0820000, 0x24070020, -0x3c040001, 0x248430d0, 0x8fa3001c, 0x24120020, -0x3c010001, 0xac303e20, 0x2c620020, 0x1440001d, -0x27b10018, 0x8fb00018, 0x24053000, 0x3c060001, -0x24c63ea0, 0xafa70010, 0xafa30014, 0xc0029d3, -0x2003821, 0x8fa30018, 0x3c040001, 0x24843ea0, -0x24650020, 0x65102b, 0x10400007, 0x0, -0x8c820000, 0xac620000, 0x24630004, 0x65102b, -0x1440fffb, 0x24840004, 0x8fa2001c, 0x521023, -0xafa2001c, 0x8e220000, 0x521021, 0x1000000b, -0xae220000, 0x3c100001, 0x26103ea0, 0x24053100, -0xafa70010, 0xafa30014, 0x8fa70018, 0x2003021, -0x2402002d, 0xc0029d3, 0xa0820000, 0x3c010001, -0x10000031, 0xac303e1c, 0x3c100000, 0x26107c8f, -0x3c120000, 0x26527b0c, 0x2121023, 0x438024, -0x8fa3001c, 0x3c040001, 0x248430e4, 0x70102b, +0x24842ed4, 0x3c050001, 0x24a52ba0, 0x3c060001, +0x24c62c18, 0xc53023, 0x8f420008, 0x27b30030, +0x2603821, 0x27b10034, 0x34420e00, 0xaf420008, +0xc001751, 0xafb10010, 0x3c040001, 0x24842eec, +0x3c050001, 0x24a5cffc, 0x3c060001, 0x24c6db04, +0xc53023, 0x2603821, 0xaf42010c, 0xc001751, +0xafb10010, 0x3c040001, 0x24842f04, 0x3c050001, +0x24a5df84, 0x3c060001, 0x24c6e6bc, 0xc53023, +0x2603821, 0x3c010001, 0xac223eb0, 0xc001751, +0xafb10010, 0x3c040001, 0x24842f1c, 0x10000027, +0x24052100, 0x3c040001, 0x24842f24, 0x3c050001, +0x24a599c8, 0x3c060001, 0x24c69b04, 0xc53023, +0x27b10030, 0x2203821, 0x27b30034, 0xc001751, +0xafb30010, 0x3c040001, 0x24842f34, 0x3c050001, +0x24a5c25c, 0x3c060001, 0x24c6cff4, 0xc53023, +0x2203821, 0xaf42010c, 0xc001751, 0xafb30010, +0x3c040001, 0x24842f44, 0x3c050001, 0x24a5de24, +0x3c060001, 0x24c6df7c, 0xc53023, 0x2203821, +0x3c010001, 0xac223eb0, 0xc001751, 0xafb30010, +0x3c040001, 0x24842f58, 0x24052150, 0x2c03021, +0x3821, 0x3c010001, 0xac223ebc, 0xafa00010, +0xc0029bb, 0xafa00014, 0x3c030001, 0x8c633eb0, +0x3c110fff, 0x3631ffff, 0x3c020001, 0x8c423ebc, +0x3c1e0800, 0x711824, 0x31882, 0x7e1825, +0x511024, 0x21082, 0x5e1025, 0xae430038, +0xae420078, 0x8c020218, 0x30420040, 0x14400004, +0x24020001, 0x3c010001, 0x370821, 0xa02240f4, +0x3c040001, 0x24842f64, 0x3c050001, 0x24a52ab4, +0x3c060001, 0x24c62b90, 0xc53023, 0x27b50030, +0x2a03821, 0x27b30034, 0xc001751, 0xafb30010, +0x3c010001, 0xac223ea8, 0x511024, 0x21082, +0x5e1025, 0xae420050, 0x32c22000, 0x10400005, +0x2a03821, 0x3c020000, 0x24425b74, 0x1000000d, +0x511024, 0x3c040001, 0x24842f78, 0x3c050001, +0x24a5db0c, 0x3c060001, 0x24c6dcbc, 0xc53023, +0xc001751, 0xafb30010, 0x3c010001, 0xac223ec0, +0x511024, 0x21082, 0x5e1025, 0xae420048, +0x32c24000, 0x10400005, 0x27a70030, 0x3c020000, +0x24425b74, 0x1000000e, 0x21100, 0x3c040001, +0x24842f90, 0x3c050001, 0x24a5dcc4, 0x3c060001, +0x24c6de1c, 0xc53023, 0x27a20034, 0xc001751, +0xafa20010, 0x3c010001, 0xac223eb4, 0x21100, +0x21182, 0x3c030800, 0x431025, 0xae420060, +0x3c040001, 0x24842fa8, 0x3c050000, 0x24a57c80, +0x3c060001, 0x24c680a4, 0xc53023, 0x27b10030, +0x2203821, 0x27b30034, 0xc001751, 0xafb30010, +0x3c1e0fff, 0x37deffff, 0x3c040001, 0x24842fb4, +0x3c050000, 0x24a56318, 0x3c060000, 0x24c6645c, +0xc53023, 0x2203821, 0x3c010001, 0xac223e88, +0x5e1024, 0x21082, 0x3c150800, 0x551025, +0xae4200b8, 0xc001751, 0xafb30010, 0x3c040001, +0x24842fc0, 0x3c050000, 0x24a56464, 0x3c060000, +0x24c666dc, 0xc53023, 0x2203821, 0x3c010001, +0xac223e7c, 0x5e1024, 0x21082, 0x551025, +0xae4200e8, 0xc001751, 0xafb30010, 0x3c040001, +0x24842fd8, 0x3c050000, 0x24a566e4, 0x3c060000, +0x24c66814, 0xc53023, 0x2203821, 0x3c010001, +0xac223e74, 0x5e1024, 0x21082, 0x551025, +0xae4200c0, 0xc001751, 0xafb30010, 0x3c040001, +0x24842ff0, 0x3c050001, 0x24a5efb0, 0x3c060001, +0x24c6f088, 0xc53023, 0x2203821, 0x3c010001, +0xac223e80, 0x5e1024, 0x21082, 0x551025, +0xae4200c8, 0xc001751, 0xafb30010, 0x3c040001, +0x24842ffc, 0x3c050001, 0x24a529f0, 0x3c060001, +0x24c62a78, 0xc53023, 0x2203821, 0xaf420110, +0xc001751, 0xafb30010, 0x3c040001, 0x2484300c, +0x3c050001, 0x24a52a80, 0x3c060001, 0x24c62aac, +0xc53023, 0x2203821, 0xaf420114, 0xc001751, +0xafb30010, 0x3c040001, 0x24843018, 0x3c050001, +0x24a5e820, 0x3c060001, 0x24c6ec24, 0xc53023, +0x2203821, 0xaf420118, 0xc001751, 0xafb30010, +0x3c010001, 0xac223ec4, 0x5e1024, 0x21082, +0x551025, 0xc003cfb, 0xae4200d0, 0xc0039b4, +0x0, 0xc002628, 0x0, 0xac000228, +0xac00022c, 0x96e20450, 0x2442ffff, 0xaf420038, +0x96e20460, 0xaf420080, 0x32c24000, 0x14400003, +0x0, 0x96e20480, 0xaf420084, 0x96e70490, +0x50e00001, 0x24070800, 0x24e2ffff, 0xaf420088, +0xaf42007c, 0x24020800, 0x10e2000f, 0x32c24000, +0x10400003, 0x24020400, 0x10e2000b, 0x0, +0x240e0001, 0x3c040001, 0x24843028, 0xa3ae003f, +0x96e60490, 0x24052170, 0x2c03821, 0xafa00010, +0xc0029bb, 0xafa00014, 0x8f43012c, 0x8f44012c, +0x24020001, 0xa34205b3, 0xaf430094, 0xaf440098, +0xafa00010, 0xafa00014, 0x8f460080, 0x8f470084, +0x3c040001, 0x24843034, 0xc0029bb, 0x24052200, +0xc002324, 0x3c110800, 0x3c1433d8, 0x3694cb58, +0x3c020800, 0x34420080, 0x3c040001, 0x24843040, +0x3c050000, 0x24a55bb8, 0x3c060000, 0x24c65bd4, +0xc53023, 0x27a70030, 0xaf820060, 0x2402ffff, +0xaf820064, 0x27a20034, 0xc001751, 0xafa20010, +0x3c010001, 0xac223e64, 0x21100, 0x21182, +0x511025, 0xc0018a8, 0xae420000, 0x8f820240, +0x3c030001, 0x431025, 0xaf820240, 0x3c020000, +0x24424034, 0xaf820244, 0xaf800240, 0x8f820060, +0x511024, 0x14400005, 0x3c030800, 0x8f820060, +0x431024, 0x1040fffd, 0x0, 0xc0039c1, +0x8821, 0x3c020100, 0xafa20020, 0x8f530018, +0x240200ff, 0x56620001, 0x26710001, 0x8c020228, +0x1622000e, 0x1330c0, 0x8f42032c, 0x24420001, +0xaf42032c, 0x8f42032c, 0x8c020228, 0x3c040001, +0x24842d04, 0x3c050009, 0xafa00014, 0xafa20010, +0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021, +0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, +0xc01821, 0x8f440168, 0x8f45016c, 0x1021, +0x24070004, 0xafa70010, 0xafb10014, 0x8f48000c, +0x24c604c0, 0x2e63021, 0xafa80018, 0x8f48010c, +0x24070008, 0xa32821, 0xa3482b, 0x822021, +0x100f809, 0x892021, 0x1440000b, 0x24070008, +0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001, +0x24842d0c, 0x3c050009, 0xafa20014, 0x8fa60020, +0x1000001c, 0x34a50200, 0x8f440150, 0x8f450154, +0x8f43000c, 0xaf510018, 0x8f860120, 0x24020010, +0xafa20010, 0xafb10014, 0xafa30018, 0x8f42010c, +0x40f809, 0x24c6001c, 0x14400010, 0x0, +0x8f420330, 0x24420001, 0xaf420330, 0x8f420330, +0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001, +0x24842d14, 0x3c050009, 0xafa20014, 0x8fa60020, +0x34a50300, 0xc0029bb, 0x2603821, 0x8f4202d4, +0x24420001, 0xaf4202d4, 0x8f4202d4, 0x93a2003f, +0x10400069, 0x3c020700, 0x34423000, 0xafa20028, +0x8f530018, 0x240200ff, 0x12620002, 0x8821, +0x26710001, 0x8c020228, 0x1622000e, 0x1330c0, +0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, +0x8c020228, 0x3c040001, 0x24842d04, 0x3c050009, +0xafa00014, 0xafa20010, 0x8fa60028, 0x1000003f, +0x34a50100, 0xd71021, 0x8fa30028, 0x8fa4002c, +0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440168, +0x8f45016c, 0x1021, 0x24070004, 0xafa70010, +0xafb10014, 0x8f48000c, 0x24c604c0, 0x2e63021, +0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, +0xa3482b, 0x822021, 0x100f809, 0x892021, +0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, +0x8f820124, 0x3c040001, 0x24842d0c, 0x3c050009, +0xafa20014, 0x8fa60028, 0x1000001c, 0x34a50200, +0x8f440150, 0x8f450154, 0x8f43000c, 0xaf510018, +0x8f860120, 0x24020010, 0xafa20010, 0xafb10014, +0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, +0x14400010, 0x0, 0x8f420330, 0x24420001, +0xaf420330, 0x8f420330, 0x8f820120, 0xafa20010, +0x8f820124, 0x3c040001, 0x24842d14, 0x3c050009, +0xafa20014, 0x8fa60028, 0x34a50300, 0xc0029bb, +0x2603821, 0x8f4202e0, 0x24420001, 0xaf4202e0, +0x8f4202e0, 0x3c040001, 0x24843050, 0xafa00010, +0xafa00014, 0x8fa60028, 0x24052300, 0xc0029bb, +0x3821, 0x10000004, 0x0, 0x8c020264, +0x10400005, 0x0, 0x8f8200a0, 0x30420004, +0x1440fffa, 0x0, 0x8f820044, 0x34420004, +0xaf820044, 0x8f4202f8, 0x24420001, 0xaf4202f8, +0x8f4202f8, 0x8f8200d8, 0x8f8300d4, 0x431023, +0x2442ff80, 0xaf420090, 0x8f420090, 0x2842ff81, +0x10400006, 0x24020001, 0x8f420090, 0x8f430138, +0x431021, 0xaf420090, 0x24020001, 0xaf42008c, +0x32c20008, 0x10400006, 0x0, 0x8f820214, +0x3c038100, 0x3042ffff, 0x431025, 0xaf820214, +0x3c020001, 0x8c423d84, 0x30420001, 0x10400009, +0x0, 0x3c040001, 0x2484305c, 0x3c050000, +0x24a56c24, 0x3c060000, 0x24c670cc, 0x10000008, +0xc53023, 0x3c040001, 0x2484306c, 0x3c050000, +0x24a5681c, 0x3c060000, 0x24c66c1c, 0xc53023, +0x27a70030, 0x27a20034, 0xc001751, 0xafa20010, +0x3c010001, 0xac223e78, 0x3c020001, 0x8c423e78, +0x3c030800, 0x21100, 0x21182, 0x431025, +0xae420040, 0x8f8200a0, 0xafa20010, 0x8f8200b0, +0xafa20014, 0x8f86005c, 0x8f87011c, 0x3c040001, +0x2484307c, 0x3c010001, 0xac363e50, 0x3c010001, +0xac203e40, 0x3c010001, 0xac3c3e38, 0x3c010001, +0xac3b3e68, 0x3c010001, 0xac373e6c, 0x3c010001, +0xac3a3e4c, 0xc0029bb, 0x24052400, 0x8f820200, +0xafa20010, 0x8f820220, 0xafa20014, 0x8f860044, +0x8f870050, 0x3c040001, 0x24843088, 0xc0029bb, +0x24052500, 0x8f830060, 0x74100b, 0x242000a, +0x200f821, 0x0, 0xd, 0x8fbf0058, +0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048, +0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060, +0x27bdffe0, 0x3c040001, 0x24843094, 0x24052600, +0x3021, 0x3821, 0xafbf0018, 0xafa00010, +0xc0029bb, 0xafa00014, 0x8fbf0018, 0x3e00008, +0x27bd0020, 0x3e00008, 0x0, 0x3e00008, +0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x3e00008, 0x0, +0x3e00008, 0x0, 0x27bdfde0, 0x27a50018, +0x3c04dead, 0x3484beef, 0xafbf0218, 0x8f820150, +0x3c03001f, 0x3463ffff, 0xafa40018, 0xa22823, +0xa32824, 0x8ca20000, 0x1044000a, 0x0, +0xafa50010, 0x8ca20000, 0xafa20014, 0x8f860150, +0x8f870250, 0x3c040001, 0x2484309c, 0xc0029bb, +0x24052700, 0x8fbf0218, 0x3e00008, 0x27bd0220, +0x27bdffe0, 0x3c06abba, 0x34c6babe, 0xafb00018, +0x3c100004, 0x3c07007f, 0x34e7ffff, 0xafbf001c, +0x102840, 0x8e040000, 0x8ca30000, 0xaca00000, +0xae060000, 0x8ca20000, 0xaca30000, 0x10460005, +0xae040000, 0xa08021, 0xf0102b, 0x1040fff5, +0x102840, 0x3c040001, 0x248430a8, 0x24052800, +0x2003021, 0x3821, 0xafa00010, 0xc0029bb, +0xafa00014, 0x2001021, 0x8fbf001c, 0x8fb00018, +0x3e00008, 0x27bd0020, 0x8c020224, 0x3047003f, +0x10e00010, 0x803021, 0x2821, 0x24030020, +0xe31024, 0x10400002, 0x63042, 0xa62821, +0x31842, 0x1460fffb, 0xe31024, 0x2402f000, +0xa22824, 0x3402ffff, 0x45102b, 0x14400003, +0x3c020001, 0x10000008, 0x3c020001, 0x3442ffff, +0x851823, 0x43102b, 0x14400003, 0xa01021, +0x3c02fffe, 0x821021, 0x3e00008, 0x0, +0x27bdffd0, 0xafb50028, 0x8fb50040, 0xafb20020, +0xa09021, 0xafb1001c, 0x24c60003, 0xafbf002c, +0xafb30024, 0xafb00018, 0x8ea20000, 0x2403fffc, +0xc38024, 0x50102b, 0x1440001b, 0xe08821, +0x8e330000, 0xafb00010, 0x8ea20000, 0xafa20014, +0x8e270000, 0x24053000, 0xc0029bb, 0x2403021, +0x8e230000, 0x702021, 0x64102b, 0x10400007, +0x2402821, 0x8ca20000, 0xac620000, 0x24630004, +0x64102b, 0x1440fffb, 0x24a50004, 0x8ea20000, +0x501023, 0xaea20000, 0x8e220000, 0x501021, +0x1000000b, 0xae220000, 0x2402002d, 0xa0820000, +0xafb00010, 0x8ea20000, 0x2409821, 0xafa20014, +0x8e270000, 0x24053100, 0xc0029bb, 0x2603021, +0x2601021, 0x8fbf002c, 0x8fb50028, 0x8fb30024, +0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, +0x27bd0030, 0x27bdffe8, 0x3c1cc000, 0x3c05fffe, +0x3c030001, 0x8c633e30, 0x3c040001, 0x8c843e3c, +0x34a5bf08, 0x24021ffc, 0x3c010001, 0xac223cd0, +0x3c0200c0, 0x3c010001, 0xac223cd4, 0x3c020020, +0xafbf0010, 0x3c0100c0, 0xac201ffc, 0x431023, +0x441023, 0x245bb000, 0x365b821, 0x3c1d0001, +0x8fbd3ccc, 0x3a0f021, 0x3c0400c0, 0x34840200, +0x3c1a00c0, 0x3c0300c0, 0x346307b8, 0x24021dfc, +0x3c010001, 0xac223cd0, 0x24021844, 0x3c010001, +0xac243cd4, 0x3c010001, 0xac223cd0, 0x3c010001, +0xac233cd4, 0xc0017bb, 0x375a0200, 0x8fbf0010, +0x3e00008, 0x27bd0018, 0x27bdffc8, 0x3c040001, +0x248430b4, 0x24053200, 0x3c020001, 0x8c423cd0, +0x3c030001, 0x8c633cd4, 0x3021, 0x3603821, +0xafbf0030, 0xafb3002c, 0xafb20028, 0xafb10024, +0xafb00020, 0xafa2001c, 0xafa30018, 0xafb70010, +0xc0029bb, 0xafba0014, 0xc0018c2, 0x0, +0x8f820240, 0x34420004, 0xaf820240, 0x24020001, +0xaf420000, 0x3c020001, 0x571021, 0x904240f4, +0x10400092, 0x2403fffc, 0x3c100001, 0x2610a673, +0x3c120001, 0x2652a24c, 0x2121023, 0x438024, +0x8fa3001c, 0x3c040001, 0x248430c0, 0x70102b, 0x1440001a, 0x27b30018, 0x8fb10018, 0x24053000, -0x2403021, 0xafb00010, 0xafa30014, 0xc0029d3, +0x2403021, 0xafb00010, 0xafa30014, 0xc0029bb, 0x2203821, 0x8fa30018, 0x702021, 0x64102b, 0x10400007, 0x2403021, 0x8cc20000, 0xac620000, 0x24630004, 0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c, 0x501023, 0xafa2001c, 0x8e620000, 0x501021, 0x1000000a, 0xae620000, 0x2408821, 0x24053100, 0xafb00010, 0xafa30014, 0x8fa70018, -0x2203021, 0x2402002d, 0xc0029d3, 0xa0820000, -0x3c010001, 0xac313dec, 0x3c030001, 0x8c633dec, -0x24020400, 0x60f809, 0xaf820070, 0x8fbf0030, -0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, -0x3e00008, 0x27bd0038, 0x0, 0x8f820040, +0x2203021, 0x2402002d, 0xc0029bb, 0xa0820000, +0x24070020, 0x8fa3001c, 0x3c040001, 0x248430dc, +0x24120020, 0x3c010001, 0xac313e5c, 0x2c620020, +0x1440001d, 0x27b10018, 0x8fb00018, 0x24053000, +0x3c060001, 0x24c63ef0, 0xafa70010, 0xafa30014, +0xc0029bb, 0x2003821, 0x8fa30018, 0x3c040001, +0x24843ef0, 0x24650020, 0x65102b, 0x10400007, +0x0, 0x8c820000, 0xac620000, 0x24630004, +0x65102b, 0x1440fffb, 0x24840004, 0x8fa2001c, +0x521023, 0xafa2001c, 0x8e220000, 0x521021, +0x1000000b, 0xae220000, 0x3c100001, 0x26103ef0, +0x24053100, 0xafa70010, 0xafa30014, 0x8fa70018, +0x2003021, 0x2402002d, 0xc0029bb, 0xa0820000, +0x24070020, 0x3c040001, 0x248430f0, 0x8fa3001c, +0x24120020, 0x3c010001, 0xac303e90, 0x2c620020, +0x1440001d, 0x27b10018, 0x8fb00018, 0x24053000, +0x3c060001, 0x24c63f10, 0xafa70010, 0xafa30014, +0xc0029bb, 0x2003821, 0x8fa30018, 0x3c040001, +0x24843f10, 0x24650020, 0x65102b, 0x10400007, +0x0, 0x8c820000, 0xac620000, 0x24630004, +0x65102b, 0x1440fffb, 0x24840004, 0x8fa2001c, +0x521023, 0xafa2001c, 0x8e220000, 0x521021, +0x1000000b, 0xae220000, 0x3c100001, 0x26103f10, +0x24053100, 0xafa70010, 0xafa30014, 0x8fa70018, +0x2003021, 0x2402002d, 0xc0029bb, 0xa0820000, +0x3c010001, 0x10000031, 0xac303e8c, 0x3c100000, +0x26107c73, 0x3c120000, 0x26527af0, 0x2121023, +0x438024, 0x8fa3001c, 0x3c040001, 0x24843104, +0x70102b, 0x1440001a, 0x27b30018, 0x8fb10018, +0x24053000, 0x2403021, 0xafb00010, 0xafa30014, +0xc0029bb, 0x2203821, 0x8fa30018, 0x702021, +0x64102b, 0x10400007, 0x2403021, 0x8cc20000, +0xac620000, 0x24630004, 0x64102b, 0x1440fffb, +0x24c60004, 0x8fa2001c, 0x501023, 0xafa2001c, +0x8e620000, 0x501021, 0x1000000a, 0xae620000, +0x2408821, 0x24053100, 0xafb00010, 0xafa30014, +0x8fa70018, 0x2203021, 0x2402002d, 0xc0029bb, +0xa0820000, 0x3c010001, 0xac313e5c, 0x3c030001, +0x8c633e5c, 0x24020400, 0x60f809, 0xaf820070, +0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, +0x8fb00020, 0x3e00008, 0x27bd0038, 0x8f820040, 0x3c03f000, 0x431024, 0x3c036000, 0x14430006, 0x0, 0x8f820050, 0x2403ff80, 0x431024, 0x34420055, 0xaf820050, 0x8f820054, 0x244203e8, @@ -5032,164 +5043,274 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054, 0x244203e8, 0xaf820058, 0x3c020800, 0x2c21024, 0x10400004, 0x3c02f7ff, 0x3442ffff, 0x2c2b024, -0x36940040, 0x3c020001, 0x8c423d28, 0x10400027, -0x0, 0x3c020001, 0x8c423d14, 0x30420001, -0x14400010, 0x0, 0x3c020001, 0x8c423e58, -0x1040000c, 0x0, 0x3c020001, 0x8c423da4, -0x14400008, 0x0, 0x8f830224, 0x3c020001, -0x8c425f1c, 0x10620003, 0x0, 0xc003bad, -0x0, 0x934205b1, 0x10400012, 0x24020001, -0x934305b1, 0x14620004, 0x3c0208ff, 0x24020002, -0x1000000c, 0xa34205b1, 0x3442fffb, 0xa34005b1, -0x8f830220, 0x3c040200, 0x284a025, 0x621824, -0xaf830220, 0x10000004, 0x3c020200, 0xc003f27, -0x0, 0x3c020200, 0x2c21024, 0x10400003, -0x0, 0xc001de7, 0x0, 0x8f4200d8, -0x8f4300dc, 0x24420001, 0xaf4200d8, 0x43102b, -0x14400003, 0x0, 0xaf4000d8, 0x36940080, -0x8c030238, 0x1060000c, 0x0, 0x8f4201a0, -0x244203e8, 0xaf4201a0, 0x43102b, 0x14400006, -0x0, 0x934205b6, 0x14400003, 0x0, -0xc001c3c, 0x0, 0x8fbf0010, 0x3e00008, -0x27bd0018, 0x3e00008, 0x0, 0x27bdffd8, -0xafbf0020, 0x8f43002c, 0x8f420038, 0x10620059, -0x0, 0x3c020001, 0x571021, 0x904240f0, -0x10400026, 0x24070008, 0x8f440160, 0x8f450164, -0x8f48000c, 0x8f860120, 0x24020020, 0xafa20010, -0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, -0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, -0x370821, 0xa02240f0, 0x8f820124, 0xafa20010, -0x8f820128, 0x3c040001, 0x24843184, 0xafa20014, -0x8f46002c, 0x8f870120, 0x3c050009, 0xc0029d3, -0x34a50900, 0x1000005c, 0x0, 0x8f4202f0, -0x24420001, 0xaf4202f0, 0x8f4202f0, 0x8f42002c, -0xa34005b2, 0x10000027, 0xaf420038, 0x8f440160, -0x8f450164, 0x8f43002c, 0x8f48000c, 0x8f860120, -0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, -0x24020001, 0x3c010001, 0x370821, 0xa02240f1, -0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001, -0x24843190, 0xafa20014, 0x8f46002c, 0x8f870120, -0x3c050009, 0xc0029d3, 0x34a51100, 0x10000036, -0x0, 0x8f4202f0, 0x8f43002c, 0x24420001, -0xaf4202f0, 0x8f4202f0, 0x24020001, 0xa34205b2, -0xaf430038, 0x3c010001, 0x370821, 0xa02040f1, -0x3c010001, 0x370821, 0xa02040f0, 0x10000026, -0xaf400034, 0x934205b2, 0x1040001d, 0x0, -0xa34005b2, 0x8f820040, 0x30420001, 0x14400008, -0x2021, 0x8c030104, 0x24020001, 0x50620005, -0x24040001, 0x8c020264, 0x10400003, 0x801021, -0x24040001, 0x801021, 0x10400006, 0x0, -0x8f4202fc, 0x24420001, 0xaf4202fc, 0x10000008, -0x8f4202fc, 0x8f820044, 0x34420004, 0xaf820044, -0x8f4202f8, 0x24420001, 0xaf4202f8, 0x8f4202f8, -0x3c010001, 0x370821, 0xa02040f0, 0x3c010001, -0x370821, 0xa02040f1, 0x8f420000, 0x10400007, -0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd, -0x0, 0x10000005, 0x0, 0xaf800048, -0x8f820048, 0x1040fffd, 0x0, 0x8f820060, -0x3c03ff7f, 0x3463ffff, 0x431024, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x10000002, -0xaf80004c, 0xaf800048, 0x8fbf0020, 0x3e00008, -0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8, -0xafbf0020, 0x8f430044, 0x8f42007c, 0x10620029, -0x24070008, 0x8f440158, 0x8f45015c, 0x8f48000c, -0x8f860120, 0x24020040, 0xafa20010, 0xafa30014, +0x36940040, 0x3c020001, 0x8c423d98, 0x10400020, +0x3c020200, 0x934305b1, 0x10600007, 0x282a025, +0xa34005b1, 0x8f820220, 0x3c0308ff, 0x3463fffb, +0x431024, 0xaf820220, 0x3c020001, 0x8c423ec8, +0x10400016, 0x3c020200, 0x3c020001, 0x8c423e14, +0x14400012, 0x3c020200, 0x3c020001, 0x8c423d84, +0x30420001, 0x1440000d, 0x3c020200, 0x8f830224, +0x3c020001, 0x8c425f8c, 0x10620008, 0x3c020200, +0xc003b0b, 0x0, 0x10000004, 0x3c020200, +0xc003e84, 0x0, 0x3c020200, 0x2c21024, +0x10400003, 0x0, 0xc001de0, 0x0, +0x8f4200d8, 0x8f4300dc, 0x24420001, 0xaf4200d8, +0x43102b, 0x14400003, 0x0, 0xaf4000d8, +0x36940080, 0x8c030238, 0x1060000c, 0x0, +0x8f4201a0, 0x244203e8, 0xaf4201a0, 0x43102b, +0x14400006, 0x0, 0x934205b6, 0x14400003, +0x0, 0xc001c35, 0x0, 0x8fbf0010, +0x3e00008, 0x27bd0018, 0x3e00008, 0x0, +0x27bdffd8, 0xafbf0020, 0x8f43002c, 0x8f420038, +0x10620059, 0x0, 0x3c020001, 0x571021, +0x904240f0, 0x10400026, 0x24070008, 0x8f440160, +0x8f450164, 0x8f48000c, 0x8f860120, 0x24020020, +0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, +0x40f809, 0x24c6001c, 0x14400011, 0x24020001, +0x3c010001, 0x370821, 0xa02240f0, 0x8f820124, +0xafa20010, 0x8f820128, 0x3c040001, 0x248431a8, +0xafa20014, 0x8f46002c, 0x8f870120, 0x3c050009, +0xc0029bb, 0x34a50900, 0x1000005c, 0x0, +0x8f4202f0, 0x24420001, 0xaf4202f0, 0x8f4202f0, +0x8f42002c, 0xa34005b2, 0x10000027, 0xaf420038, +0x8f440160, 0x8f450164, 0x8f43002c, 0x8f48000c, +0x8f860120, 0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, 0x370821, -0xa02240f2, 0x8f820124, 0xafa20010, 0x8f820128, -0x3c040001, 0x24843198, 0xafa20014, 0x8f460044, -0x8f870120, 0x3c050009, 0xc0029d3, 0x34a51300, -0x1000000f, 0x0, 0x8f4202f4, 0x24420001, -0xaf4202f4, 0x8f4202f4, 0x8f420044, 0xaf42007c, -0x3c010001, 0x370821, 0xa02040f2, 0x10000004, -0xaf400078, 0x3c010001, 0x370821, 0xa02040f2, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x3c03feff, 0x3463ffff, -0x431024, 0xaf820060, 0x8f420000, 0x10400003, -0x0, 0x10000002, 0xaf80004c, 0xaf800048, -0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008, -0x0, 0x3c020001, 0x8c423d28, 0x27bdffa8, -0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044, -0xafb20040, 0xafb1003c, 0xafb00038, 0x104000d5, -0x8f900044, 0x8f4200d0, 0x24430001, 0x2842000b, -0x144000e4, 0xaf4300d0, 0x8f420004, 0x30420002, -0x1440009c, 0xaf4000d0, 0x8f420004, 0x3c030001, -0x8c633d18, 0x34420002, 0xaf420004, 0x24020001, -0x14620003, 0x3c020600, 0x10000002, 0x34423000, -0x34421000, 0xafa20020, 0x8f4a0018, 0xafaa0034, -0x27aa0020, 0xafaa002c, 0x8faa0034, 0x240200ff, -0x11420002, 0x1821, 0x25430001, 0x8c020228, -0x609821, 0x1662000e, 0x3c050009, 0x8f42032c, -0x24420001, 0xaf42032c, 0x8f42032c, 0x8c020228, -0x8fa70034, 0x3c040001, 0x24843168, 0xafa00014, -0xafa20010, 0x8fa60020, 0x10000070, 0x34a50500, -0x8faa0034, 0xa38c0, 0xf71021, 0x8fa30020, -0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, +0xa02240f1, 0x8f820124, 0xafa20010, 0x8f820128, +0x3c040001, 0x248431b4, 0xafa20014, 0x8f46002c, +0x8f870120, 0x3c050009, 0xc0029bb, 0x34a51100, +0x10000036, 0x0, 0x8f4202f0, 0x8f43002c, +0x24420001, 0xaf4202f0, 0x8f4202f0, 0x24020001, +0xa34205b2, 0xaf430038, 0x3c010001, 0x370821, +0xa02040f1, 0x3c010001, 0x370821, 0xa02040f0, +0x10000026, 0xaf400034, 0x934205b2, 0x1040001d, +0x0, 0xa34005b2, 0x8f820040, 0x30420001, +0x14400008, 0x2021, 0x8c030104, 0x24020001, +0x50620005, 0x24040001, 0x8c020264, 0x10400003, +0x801021, 0x24040001, 0x801021, 0x10400006, +0x0, 0x8f4202fc, 0x24420001, 0xaf4202fc, +0x10000008, 0x8f4202fc, 0x8f820044, 0x34420004, +0xaf820044, 0x8f4202f8, 0x24420001, 0xaf4202f8, +0x8f4202f8, 0x3c010001, 0x370821, 0xa02040f0, +0x3c010001, 0x370821, 0xa02040f1, 0x8f420000, +0x10400007, 0x0, 0xaf80004c, 0x8f82004c, +0x1040fffd, 0x0, 0x10000005, 0x0, +0xaf800048, 0x8f820048, 0x1040fffd, 0x0, +0x8f820060, 0x3c03ff7f, 0x3463ffff, 0x431024, +0xaf820060, 0x8f420000, 0x10400003, 0x0, +0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0020, +0x3e00008, 0x27bd0028, 0x3e00008, 0x0, +0x27bdffd8, 0xafbf0020, 0x8f430044, 0x8f42007c, +0x10620029, 0x24070008, 0x8f440158, 0x8f45015c, +0x8f48000c, 0x8f860120, 0x24020040, 0xafa20010, +0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, +0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, +0x370821, 0xa02240f2, 0x8f820124, 0xafa20010, +0x8f820128, 0x3c040001, 0x248431bc, 0xafa20014, +0x8f460044, 0x8f870120, 0x3c050009, 0xc0029bb, +0x34a51300, 0x1000000f, 0x0, 0x8f4202f4, +0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8f420044, +0xaf42007c, 0x3c010001, 0x370821, 0xa02040f2, +0x10000004, 0xaf400078, 0x3c010001, 0x370821, +0xa02040f2, 0x8f420000, 0x10400007, 0x0, +0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, +0x10000005, 0x0, 0xaf800048, 0x8f820048, +0x1040fffd, 0x0, 0x8f820060, 0x3c03feff, +0x3463ffff, 0x431024, 0xaf820060, 0x8f420000, +0x10400003, 0x0, 0x10000002, 0xaf80004c, +0xaf800048, 0x8fbf0020, 0x3e00008, 0x27bd0028, +0x3e00008, 0x0, 0x3c020001, 0x8c423d98, +0x27bdffa8, 0xafbf0050, 0xafbe004c, 0xafb50048, +0xafb30044, 0xafb20040, 0xafb1003c, 0xafb00038, +0x104000d5, 0x8f900044, 0x8f4200d0, 0x24430001, +0x2842000b, 0x144000e4, 0xaf4300d0, 0x8f420004, +0x30420002, 0x1440009c, 0xaf4000d0, 0x8f420004, +0x3c030001, 0x8c633d88, 0x34420002, 0xaf420004, +0x24020001, 0x14620003, 0x3c020600, 0x10000002, +0x34423000, 0x34421000, 0xafa20020, 0x8f4a0018, +0xafaa0034, 0x27aa0020, 0xafaa002c, 0x8faa0034, +0x240200ff, 0x11420002, 0x1821, 0x25430001, +0x8c020228, 0x609821, 0x1662000e, 0x3c050009, +0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, +0x8c020228, 0x8fa70034, 0x3c040001, 0x2484318c, +0xafa00014, 0xafa20010, 0x8fa60020, 0x10000070, +0x34a50500, 0x8faa0034, 0xa38c0, 0xf71021, +0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, +0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, +0x2c4203e9, 0x1040001b, 0xa821, 0xe09021, +0x265e04c0, 0x8f440168, 0x8f45016c, 0x2401821, +0x240a0004, 0xafaa0010, 0xafb30014, 0x8f48000c, +0x1021, 0x2fe3021, 0xafa80018, 0x8f48010c, +0x24070008, 0xa32821, 0xa3482b, 0x822021, +0x100f809, 0x892021, 0x54400006, 0x24150001, +0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffe9, +0x0, 0x32a200ff, 0x54400018, 0xaf530018, +0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, +0x8f820120, 0x8faa002c, 0x8fa70034, 0xafa20010, +0x8f820124, 0x3c040001, 0x24843198, 0xafa20014, +0x8d460000, 0x3c050009, 0x10000035, 0x34a50600, +0x8f4202f8, 0x24150001, 0x24420001, 0xaf4202f8, +0x8f4202f8, 0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, -0x1040001b, 0xa821, 0xe09021, 0x265e04c0, -0x8f440168, 0x8f45016c, 0x2401821, 0x240a0004, -0xafaa0010, 0xafb30014, 0x8f48000c, 0x1021, -0x2fe3021, 0xafa80018, 0x8f48010c, 0x24070008, -0xa32821, 0xa3482b, 0x822021, 0x100f809, -0x892021, 0x54400006, 0x24150001, 0x8f820054, -0x2221023, 0x2c4203e9, 0x1440ffe9, 0x0, -0x32a200ff, 0x54400018, 0xaf530018, 0x8f420368, +0x10400016, 0xa821, 0x3c1e0020, 0x24120010, +0x8f42000c, 0x8f440150, 0x8f450154, 0x8f860120, +0xafb20010, 0xafb30014, 0x5e1025, 0xafa20018, +0x8f42010c, 0x24070008, 0x40f809, 0x24c6001c, +0x1440ffe3, 0x0, 0x8f820054, 0x2221023, +0x2c4203e9, 0x1440ffee, 0x0, 0x32a200ff, +0x14400011, 0x3c050009, 0x8f420368, 0x24420001, +0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, +0x8fa70034, 0xafa20010, 0x8f820124, 0x3c040001, +0x248431a0, 0xafa20014, 0x8d460000, 0x34a50700, +0xc0029bb, 0x0, 0x8f4202dc, 0x24420001, +0xaf4202dc, 0x8f4202dc, 0x8f420004, 0x30420001, +0x50400029, 0x36100040, 0x3c020400, 0x2c21024, +0x10400013, 0x2404ffdf, 0x8f420240, 0x8f430244, +0x8f4401a4, 0x14640006, 0x36100040, 0x8f420260, +0x8f430264, 0x8f4401a8, 0x10640007, 0x2402ffdf, +0x8f420240, 0x8f430244, 0x8f440260, 0x8f450264, +0x10000012, 0x3a100020, 0x1000002b, 0x2028024, +0x8f420240, 0x8f430244, 0x8f4501a4, 0x14650006, +0x2048024, 0x8f420260, 0x8f430264, 0x8f4401a8, +0x50640021, 0x36100040, 0x8f420240, 0x8f430244, +0x8f440260, 0x8f450264, 0x3a100040, 0xaf4301a4, +0x10000019, 0xaf4501a8, 0x8f4200d4, 0x24430001, +0x10000011, 0x28420033, 0x8f420004, 0x30420001, +0x10400009, 0x3c020400, 0x2c21024, 0x10400004, +0x2402ffdf, 0x2028024, 0x1000000b, 0x36100040, +0x10000009, 0x36100060, 0x8f4200d4, 0x36100040, +0x24430001, 0x284201f5, 0x14400003, 0xaf4300d4, +0xaf4000d4, 0x3a100020, 0xaf900044, 0x2402ff7f, +0x282a024, 0x8fbf0050, 0x8fbe004c, 0x8fb50048, +0x8fb30044, 0x8fb20040, 0x8fb1003c, 0x8fb00038, +0x3e00008, 0x27bd0058, 0x3e00008, 0x0, +0x3c020001, 0x8c423d98, 0x27bdffb0, 0xafbf0048, +0xafbe0044, 0xafb50040, 0xafb3003c, 0xafb20038, +0xafb10034, 0x104000de, 0xafb00030, 0x8f4200d0, +0x3c040001, 0x8c843d88, 0x24430001, 0x2842000b, +0xaf4400e8, 0x144000fe, 0xaf4300d0, 0x8f420004, +0x30420002, 0x14400095, 0xaf4000d0, 0x8f420004, +0x34420002, 0xaf420004, 0x24020001, 0x14820003, +0x3c020600, 0x10000002, 0x34423000, 0x34421000, +0xafa20020, 0x1821, 0x8f5e0018, 0x27aa0020, +0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001, +0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, +0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, +0x8c020228, 0x3c040001, 0x2484318c, 0x3c050009, +0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d, +0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, +0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, +0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b, +0x9821, 0xe08821, 0x263504c0, 0x8f440168, +0x8f45016c, 0x2201821, 0x240a0004, 0xafaa0010, +0xafb20014, 0x8f48000c, 0x1021, 0x2f53021, +0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, +0xa3482b, 0x822021, 0x100f809, 0x892021, +0x54400006, 0x24130001, 0x8f820054, 0x2021023, +0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff, +0x54400017, 0xaf520018, 0x8f420368, 0x24420001, +0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, +0xafa20010, 0x8f820124, 0x3c040001, 0x24843198, +0x3c050009, 0xafa20014, 0x8d460000, 0x10000035, +0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, +0xaf4202f8, 0x8f4202f8, 0x1000001e, 0x326200ff, +0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, +0x2c4203e9, 0x10400016, 0x9821, 0x3c150020, +0x24110010, 0x8f42000c, 0x8f440150, 0x8f450154, +0x8f860120, 0xafb10010, 0xafb20014, 0x551025, +0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, +0x24c6001c, 0x1440ffe3, 0x0, 0x8f820054, +0x2021023, 0x2c4203e9, 0x1440ffee, 0x0, +0x326200ff, 0x14400011, 0x0, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, -0x8faa002c, 0x8fa70034, 0xafa20010, 0x8f820124, -0x3c040001, 0x24843174, 0xafa20014, 0x8d460000, -0x3c050009, 0x10000035, 0x34a50600, 0x8f4202f8, -0x24150001, 0x24420001, 0xaf4202f8, 0x8f4202f8, -0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054, -0x247103e8, 0x2221023, 0x2c4203e9, 0x10400016, -0xa821, 0x3c1e0020, 0x24120010, 0x8f42000c, -0x8f440150, 0x8f450154, 0x8f860120, 0xafb20010, -0xafb30014, 0x5e1025, 0xafa20018, 0x8f42010c, -0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3, -0x0, 0x8f820054, 0x2221023, 0x2c4203e9, -0x1440ffee, 0x0, 0x32a200ff, 0x14400011, -0x3c050009, 0x8f420368, 0x24420001, 0xaf420368, -0x8f420368, 0x8f820120, 0x8faa002c, 0x8fa70034, -0xafa20010, 0x8f820124, 0x3c040001, 0x2484317c, -0xafa20014, 0x8d460000, 0x34a50700, 0xc0029d3, -0x0, 0x8f4202dc, 0x24420001, 0xaf4202dc, -0x8f4202dc, 0x8f420004, 0x30420001, 0x50400029, -0x36100040, 0x3c020400, 0x2c21024, 0x10400013, -0x2404ffdf, 0x8f420240, 0x8f430244, 0x8f4401a4, -0x14640006, 0x36100040, 0x8f420260, 0x8f430264, -0x8f4401a8, 0x10640007, 0x2402ffdf, 0x8f420240, -0x8f430244, 0x8f440260, 0x8f450264, 0x10000012, -0x3a100020, 0x1000002b, 0x2028024, 0x8f420240, -0x8f430244, 0x8f4501a4, 0x14650006, 0x2048024, -0x8f420260, 0x8f430264, 0x8f4401a8, 0x50640021, -0x36100040, 0x8f420240, 0x8f430244, 0x8f440260, -0x8f450264, 0x3a100040, 0xaf4301a4, 0x10000019, -0xaf4501a8, 0x8f4200d4, 0x24430001, 0x10000011, -0x28420033, 0x8f420004, 0x30420001, 0x10400009, -0x3c020400, 0x2c21024, 0x10400004, 0x2402ffdf, -0x2028024, 0x1000000b, 0x36100040, 0x10000009, -0x36100060, 0x8f4200d4, 0x36100040, 0x24430001, -0x284201f5, 0x14400003, 0xaf4300d4, 0xaf4000d4, -0x3a100020, 0xaf900044, 0x2402ff7f, 0x282a024, -0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044, -0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008, -0x27bd0058, 0x3e00008, 0x0, 0x3c020001, -0x8c423d28, 0x27bdffb0, 0xafbf0048, 0xafbe0044, -0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034, -0x104000de, 0xafb00030, 0x8f4200d0, 0x3c040001, -0x8c843d18, 0x24430001, 0x2842000b, 0xaf4400e8, -0x144000fe, 0xaf4300d0, 0x8f420004, 0x30420002, -0x14400095, 0xaf4000d0, 0x8f420004, 0x34420002, -0xaf420004, 0x24020001, 0x14820003, 0x3c020600, -0x10000002, 0x34423000, 0x34421000, 0xafa20020, +0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001, +0x248431a0, 0x3c050009, 0xafa20014, 0x8d460000, +0x34a50700, 0xc0029bb, 0x3c03821, 0x8f4202dc, +0x24420001, 0xaf4202dc, 0x8f4202dc, 0x8f420004, +0x30420001, 0x10400033, 0x3c020400, 0x2c21024, +0x10400017, 0x0, 0x934205b0, 0x8f440240, +0x8f450244, 0x8f4301a4, 0x34420020, 0x14a30006, +0xa34205b0, 0x8f420260, 0x8f430264, 0x8f4401a8, +0x10640008, 0x0, 0x8f420240, 0x8f430244, +0x934405b0, 0x8f460260, 0x8f470264, 0x10000016, +0x38840040, 0x934205b0, 0x10000048, 0x304200bf, +0x934205b0, 0x8f440240, 0x8f450244, 0x8f4301a4, +0x304200bf, 0x14a30006, 0xa34205b0, 0x8f420260, +0x8f430264, 0x8f4401a8, 0x1064000b, 0x0, +0x8f420240, 0x8f430244, 0x934405b0, 0x8f460260, +0x8f470264, 0x38840020, 0xaf4301a4, 0xaf4701a8, +0x10000033, 0xa34405b0, 0x934205b0, 0x1000002f, +0x34420020, 0x934205b0, 0x8f4300d4, 0x34420020, +0xa34205b0, 0x24620001, 0x10000023, 0x28630033, +0x8f4200e4, 0x8f4300e0, 0x24420001, 0xaf4200e4, +0x43102a, 0x14400006, 0x24030001, 0x8f4200e8, +0x14430002, 0xaf4000e4, 0x24030004, 0xaf4300e8, +0x8f420004, 0x30420001, 0x1040000d, 0x3c020400, +0x2c21024, 0x10400007, 0x0, 0x934205b0, +0x34420040, 0xa34205b0, 0x934205b0, 0x1000000f, +0x304200df, 0x934205b0, 0x1000000c, 0x34420060, +0x934205b0, 0x8f4300d4, 0x34420020, 0xa34205b0, +0x24620001, 0x286300fb, 0x14600005, 0xaf4200d4, +0x934205b0, 0xaf4000d4, 0x38420040, 0xa34205b0, +0x934205b0, 0x8f4300e8, 0x3042007f, 0xa34205b0, +0x24020001, 0x14620005, 0x0, 0x934405b0, +0x42102, 0x10000003, 0x348400f0, 0x934405b0, +0x3484000f, 0xc004a60, 0x0, 0x2402ff7f, +0x282a024, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, +0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, +0x3e00008, 0x27bd0050, 0x3e00008, 0x0, +0x27bdffb0, 0x274401b0, 0x26e30028, 0x24650400, +0x65102b, 0xafbf0048, 0xafbe0044, 0xafb50040, +0xafb3003c, 0xafb20038, 0xafb10034, 0x10400007, +0xafb00030, 0x8c820000, 0xac620000, 0x24630004, +0x65102b, 0x1440fffb, 0x24840004, 0x8c020080, +0xaee20044, 0x8c0200c0, 0xaee20040, 0x8c020084, +0xaee20030, 0x8c020084, 0xaee2023c, 0x8c020088, +0xaee20240, 0x8c02008c, 0xaee20244, 0x8c020090, +0xaee20248, 0x8c020094, 0xaee2024c, 0x8c020098, +0xaee20250, 0x8c02009c, 0xaee20254, 0x8c0200a0, +0xaee20258, 0x8c0200a4, 0xaee2025c, 0x8c0200a8, +0xaee20260, 0x8c0200ac, 0xaee20264, 0x8c0200b0, +0xaee20268, 0x8c0200b4, 0xaee2026c, 0x8c0200b8, +0xaee20270, 0x8c0200bc, 0x24040001, 0xaee20274, +0xaee00034, 0x41080, 0x571021, 0x8ee30034, +0x8c42023c, 0x24840001, 0x621821, 0x2c82000f, +0xaee30034, 0x1440fff8, 0x41080, 0x8c0200cc, +0xaee20048, 0x8c0200d0, 0xaee2004c, 0x8c0200e0, +0xaee201f8, 0x8c0200e4, 0xaee201fc, 0x8c0200e8, +0xaee20200, 0x8c0200ec, 0xaee20204, 0x8c0200f0, +0xaee20208, 0x8ee400c0, 0x8ee500c4, 0x8c0200fc, +0x45102b, 0x1040000b, 0x0, 0x8ee200c0, +0x8ee300c4, 0x24040001, 0x24050000, 0x651821, +0x65302b, 0x441021, 0x461021, 0xaee200c0, +0xaee300c4, 0x8c0200fc, 0x8ee400c0, 0x8ee500c4, +0x2408ffff, 0x24090000, 0x401821, 0x1021, +0x882024, 0xa92824, 0x822025, 0xa32825, +0xaee400c0, 0xaee500c4, 0x8ee400d0, 0x8ee500d4, +0x8c0200f4, 0x45102b, 0x1040000b, 0x0, +0x8ee200d0, 0x8ee300d4, 0x24040001, 0x24050000, +0x651821, 0x65302b, 0x441021, 0x461021, +0xaee200d0, 0xaee300d4, 0x8c0200f4, 0x8ee400d0, +0x8ee500d4, 0x401821, 0x1021, 0x882024, +0xa92824, 0x822025, 0xa32825, 0xaee400d0, +0xaee500d4, 0x8ee400c8, 0x8ee500cc, 0x8c0200f8, +0x45102b, 0x1040000b, 0x0, 0x8ee200c8, +0x8ee300cc, 0x24040001, 0x24050000, 0x651821, +0x65302b, 0x441021, 0x461021, 0xaee200c8, +0xaee300cc, 0x8c0200f8, 0x8ee400c8, 0x8ee500cc, +0x401821, 0x1021, 0x882024, 0xa92824, +0x822025, 0xa32825, 0x24020008, 0xaee400c8, +0xaee500cc, 0xafa20010, 0xafa00014, 0x8f42000c, +0x8c040208, 0x8c05020c, 0xafa20018, 0x8f42010c, +0x26e60028, 0x40f809, 0x24070400, 0x104000f0, +0x3c020400, 0xafa20020, 0x934205b7, 0x10400089, 0x1821, 0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, 0x8c020228, -0x3c040001, 0x24843168, 0x3c050009, 0xafa00014, -0xafa20010, 0x8fa60020, 0x1000006d, 0x34a50500, +0x3c040001, 0x2484318c, 0x3c050009, 0xafa00014, +0xafa20010, 0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b, 0x9821, @@ -5202,241 +5323,129 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1440ffe9, 0x0, 0x326200ff, 0x54400017, 0xaf520018, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x24843174, 0x3c050009, -0xafa20014, 0x8d460000, 0x10000035, 0x34a50600, +0x8f820124, 0x3c040001, 0x24843198, 0x3c050009, +0xafa20014, 0x8d460000, 0x10000033, 0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, 0xaf4202f8, -0x8f4202f8, 0x1000001e, 0x326200ff, 0x8f830054, +0x8f4202f8, 0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9, -0x10400016, 0x9821, 0x3c150020, 0x24110010, -0x8f42000c, 0x8f440150, 0x8f450154, 0x8f860120, -0xafb10010, 0xafb20014, 0x551025, 0xafa20018, -0x8f42010c, 0x24070008, 0x40f809, 0x24c6001c, -0x1440ffe3, 0x0, 0x8f820054, 0x2021023, -0x2c4203e9, 0x1440ffee, 0x0, 0x326200ff, -0x14400011, 0x0, 0x8f420368, 0x24420001, -0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, -0xafa20010, 0x8f820124, 0x3c040001, 0x2484317c, -0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700, -0xc0029d3, 0x3c03821, 0x8f4202dc, 0x24420001, -0xaf4202dc, 0x8f4202dc, 0x8f420004, 0x30420001, -0x10400033, 0x3c020400, 0x2c21024, 0x10400017, -0x0, 0x934205b0, 0x8f440240, 0x8f450244, -0x8f4301a4, 0x34420020, 0x14a30006, 0xa34205b0, -0x8f420260, 0x8f430264, 0x8f4401a8, 0x10640008, -0x0, 0x8f420240, 0x8f430244, 0x934405b0, -0x8f460260, 0x8f470264, 0x10000016, 0x38840040, -0x934205b0, 0x10000048, 0x304200bf, 0x934205b0, -0x8f440240, 0x8f450244, 0x8f4301a4, 0x304200bf, -0x14a30006, 0xa34205b0, 0x8f420260, 0x8f430264, -0x8f4401a8, 0x1064000b, 0x0, 0x8f420240, -0x8f430244, 0x934405b0, 0x8f460260, 0x8f470264, -0x38840020, 0xaf4301a4, 0xaf4701a8, 0x10000033, -0xa34405b0, 0x934205b0, 0x1000002f, 0x34420020, -0x934205b0, 0x8f4300d4, 0x34420020, 0xa34205b0, -0x24620001, 0x10000023, 0x28630033, 0x8f4200e4, -0x8f4300e0, 0x24420001, 0xaf4200e4, 0x43102a, -0x14400006, 0x24030001, 0x8f4200e8, 0x14430002, -0xaf4000e4, 0x24030004, 0xaf4300e8, 0x8f420004, -0x30420001, 0x1040000d, 0x3c020400, 0x2c21024, -0x10400007, 0x0, 0x934205b0, 0x34420040, -0xa34205b0, 0x934205b0, 0x1000000f, 0x304200df, -0x934205b0, 0x1000000c, 0x34420060, 0x934205b0, -0x8f4300d4, 0x34420020, 0xa34205b0, 0x24620001, -0x286300fb, 0x14600005, 0xaf4200d4, 0x934205b0, -0xaf4000d4, 0x38420040, 0xa34205b0, 0x934205b0, -0x8f4300e8, 0x3042007f, 0xa34205b0, 0x24020001, -0x14620005, 0x0, 0x934405b0, 0x42102, -0x10000003, 0x348400f0, 0x934405b0, 0x3484000f, -0xc004b04, 0x0, 0x2402ff7f, 0x282a024, -0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c, -0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, -0x27bd0050, 0x3e00008, 0x0, 0x27bdffb0, -0x274401b0, 0x26e30028, 0x24650400, 0x65102b, -0xafbf0048, 0xafbe0044, 0xafb50040, 0xafb3003c, -0xafb20038, 0xafb10034, 0x10400007, 0xafb00030, -0x8c820000, 0xac620000, 0x24630004, 0x65102b, -0x1440fffb, 0x24840004, 0x8c020080, 0xaee20044, -0x8c0200c0, 0xaee20040, 0x8c020084, 0xaee20030, -0x8c020084, 0xaee2023c, 0x8c020088, 0xaee20240, -0x8c02008c, 0xaee20244, 0x8c020090, 0xaee20248, -0x8c020094, 0xaee2024c, 0x8c020098, 0xaee20250, -0x8c02009c, 0xaee20254, 0x8c0200a0, 0xaee20258, -0x8c0200a4, 0xaee2025c, 0x8c0200a8, 0xaee20260, -0x8c0200ac, 0xaee20264, 0x8c0200b0, 0xaee20268, -0x8c0200b4, 0xaee2026c, 0x8c0200b8, 0xaee20270, -0x8c0200bc, 0x24040001, 0xaee20274, 0xaee00034, -0x41080, 0x571021, 0x8ee30034, 0x8c42023c, -0x24840001, 0x621821, 0x2c82000f, 0xaee30034, -0x1440fff8, 0x41080, 0x8c0200cc, 0xaee20048, -0x8c0200d0, 0xaee2004c, 0x8c0200e0, 0xaee201f8, -0x8c0200e4, 0xaee201fc, 0x8c0200e8, 0xaee20200, -0x8c0200ec, 0xaee20204, 0x8c0200f0, 0xaee20208, -0x8ee400c0, 0x8ee500c4, 0x8c0200fc, 0x45102b, -0x1040000b, 0x0, 0x8ee200c0, 0x8ee300c4, -0x24040001, 0x24050000, 0x651821, 0x65302b, -0x441021, 0x461021, 0xaee200c0, 0xaee300c4, -0x8c0200fc, 0x8ee400c0, 0x8ee500c4, 0x2408ffff, -0x24090000, 0x401821, 0x1021, 0x882024, -0xa92824, 0x822025, 0xa32825, 0xaee400c0, -0xaee500c4, 0x8ee400d0, 0x8ee500d4, 0x8c0200f4, -0x45102b, 0x1040000b, 0x0, 0x8ee200d0, -0x8ee300d4, 0x24040001, 0x24050000, 0x651821, -0x65302b, 0x441021, 0x461021, 0xaee200d0, -0xaee300d4, 0x8c0200f4, 0x8ee400d0, 0x8ee500d4, -0x401821, 0x1021, 0x882024, 0xa92824, -0x822025, 0xa32825, 0xaee400d0, 0xaee500d4, -0x8ee400c8, 0x8ee500cc, 0x8c0200f8, 0x45102b, -0x1040000b, 0x0, 0x8ee200c8, 0x8ee300cc, -0x24040001, 0x24050000, 0x651821, 0x65302b, -0x441021, 0x461021, 0xaee200c8, 0xaee300cc, -0x8c0200f8, 0x8ee400c8, 0x8ee500cc, 0x401821, -0x1021, 0x882024, 0xa92824, 0x822025, -0xa32825, 0x24020008, 0xaee400c8, 0xaee500cc, -0xafa20010, 0xafa00014, 0x8f42000c, 0x8c040208, -0x8c05020c, 0xafa20018, 0x8f42010c, 0x26e60028, -0x40f809, 0x24070400, 0x104000f0, 0x3c020400, -0xafa20020, 0x934205b7, 0x10400089, 0x1821, -0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, -0xafaa002c, 0x27c30001, 0x8c020228, 0x609021, -0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, -0xaf42032c, 0x8f42032c, 0x8c020228, 0x3c040001, -0x24843168, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440168, 0x8f45016c, 0x2201821, -0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, +0x10400014, 0x9821, 0x24110010, 0x8f42000c, +0x8f440150, 0x8f450154, 0x8f860120, 0xafb10010, +0xafb20014, 0xafa20018, 0x8f42010c, 0x24070008, +0x40f809, 0x24c6001c, 0x1440ffe5, 0x0, +0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffef, +0x0, 0x326200ff, 0x54400012, 0x24020001, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124, -0x3c040001, 0x24843174, 0x3c050009, 0xafa20014, -0x8d460000, 0x10000033, 0x34a50600, 0x8f4202f8, -0x24130001, 0x24420001, 0xaf4202f8, 0x8f4202f8, -0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014, -0x9821, 0x24110010, 0x8f42000c, 0x8f440150, -0x8f450154, 0x8f860120, 0xafb10010, 0xafb20014, -0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, -0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054, -0x2021023, 0x2c4203e9, 0x1440ffef, 0x0, -0x326200ff, 0x54400012, 0x24020001, 0x8f420368, -0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, -0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001, -0x2484317c, 0x3c050009, 0xafa20014, 0x8d460000, -0x34a50700, 0xc0029d3, 0x3c03821, 0x1021, -0x1440005b, 0x24020001, 0x10000065, 0x0, -0x8f510018, 0x240200ff, 0x12220002, 0x8021, -0x26300001, 0x8c020228, 0x1602000e, 0x1130c0, -0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, -0x8c020228, 0x3c040001, 0x24843150, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f, -0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024, -0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440168, -0x8f45016c, 0x1021, 0x24070004, 0xafa70010, -0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24843158, 0x3c050009, -0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200, -0x8f440150, 0x8f450154, 0x8f43000c, 0xaf500018, -0x8f860120, 0x24020010, 0xafa20010, 0xafb00014, -0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x54400011, 0x24020001, 0x8f420330, 0x24420001, -0xaf420330, 0x8f420330, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24843160, 0x3c050009, -0xafa20014, 0x8fa60020, 0x34a50300, 0xc0029d3, -0x2203821, 0x1021, 0x1040000d, 0x24020001, -0x8f4202d8, 0xa34005b7, 0xaf4001a0, 0x24420001, -0xaf4202d8, 0x8f4202d8, 0x8ee20150, 0x24420001, -0xaee20150, 0x10000003, 0x8ee20150, 0x24020001, -0xa34205b7, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, -0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, -0x3e00008, 0x27bd0050, 0x27bdffd8, 0xafbf0020, -0x8f8200b0, 0x30420004, 0x10400068, 0x0, -0x8f43011c, 0x8f820104, 0x14620005, 0x0, -0x8f430124, 0x8f8200b4, 0x10620006, 0x0, -0x8f820104, 0xaf42011c, 0x8f8200b4, 0x1000005b, -0xaf420124, 0x8f8200b0, 0x3c030080, 0x431024, -0x1040000d, 0x0, 0x8f82011c, 0x34420002, -0xaf82011c, 0x8f8200b0, 0x2403fffb, 0x431024, -0xaf8200b0, 0x8f82011c, 0x2403fffd, 0x431024, -0x1000004a, 0xaf82011c, 0x8f43011c, 0x8f820104, -0x14620005, 0x0, 0x8f430124, 0x8f8200b4, -0x10620010, 0x0, 0x8f820104, 0xaf42011c, -0x8f8200b4, 0x8f43011c, 0xaf420124, 0xafa30010, -0x8f420124, 0x3c040001, 0x248431a0, 0xafa20014, -0x8f86011c, 0x8f8700b0, 0x3c050005, 0x10000031, -0x34a50900, 0x8f42011c, 0xafa20010, 0x8f420124, -0x3c040001, 0x248431ac, 0xafa20014, 0x8f86011c, -0x8f8700b0, 0x3c050005, 0xc0029d3, 0x34a51000, -0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104, -0x8f8200b0, 0x34420001, 0xaf8200b0, 0x24020008, -0xaf830104, 0xafa20010, 0xafa00014, 0x8f42000c, -0x8c040208, 0x8c05020c, 0xafa20018, 0x8f42010c, -0x26e60028, 0x40f809, 0x24070400, 0x8f82011c, -0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc, -0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f42011c, -0xafa20010, 0x8f420124, 0x3c040001, 0x248431b8, +0x3c040001, 0x248431a0, 0x3c050009, 0xafa20014, +0x8d460000, 0x34a50700, 0xc0029bb, 0x3c03821, +0x1021, 0x1440005b, 0x24020001, 0x10000065, +0x0, 0x8f510018, 0x240200ff, 0x12220002, +0x8021, 0x26300001, 0x8c020228, 0x1602000e, +0x1130c0, 0x8f42032c, 0x24420001, 0xaf42032c, +0x8f42032c, 0x8c020228, 0x3c040001, 0x24843174, +0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020, +0x1000003f, 0x34a50100, 0xd71021, 0x8fa30020, +0x8fa40024, 0xac4304c0, 0xac4404c4, 0xc01821, +0x8f440168, 0x8f45016c, 0x1021, 0x24070004, +0xafa70010, 0xafb00014, 0x8f48000c, 0x24c604c0, +0x2e63021, 0xafa80018, 0x8f48010c, 0x24070008, +0xa32821, 0xa3482b, 0x822021, 0x100f809, +0x892021, 0x1440000b, 0x24070008, 0x8f820120, +0xafa20010, 0x8f820124, 0x3c040001, 0x2484317c, +0x3c050009, 0xafa20014, 0x8fa60020, 0x1000001c, +0x34a50200, 0x8f440150, 0x8f450154, 0x8f43000c, +0xaf500018, 0x8f860120, 0x24020010, 0xafa20010, +0xafb00014, 0xafa30018, 0x8f42010c, 0x40f809, +0x24c6001c, 0x54400011, 0x24020001, 0x8f420330, +0x24420001, 0xaf420330, 0x8f420330, 0x8f820120, +0xafa20010, 0x8f820124, 0x3c040001, 0x24843184, +0x3c050009, 0xafa20014, 0x8fa60020, 0x34a50300, +0xc0029bb, 0x2203821, 0x1021, 0x1040000d, +0x24020001, 0x8f4202d8, 0xa34005b7, 0xaf4001a0, +0x24420001, 0xaf4202d8, 0x8f4202d8, 0x8ee20150, +0x24420001, 0xaee20150, 0x10000003, 0x8ee20150, +0x24020001, 0xa34205b7, 0x8fbf0048, 0x8fbe0044, +0x8fb50040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, +0x8fb00030, 0x3e00008, 0x27bd0050, 0x27bdffd8, +0xafbf0020, 0x8f8200b0, 0x30420004, 0x10400068, +0x0, 0x8f43011c, 0x8f820104, 0x14620005, +0x0, 0x8f430124, 0x8f8200b4, 0x10620006, +0x0, 0x8f820104, 0xaf42011c, 0x8f8200b4, +0x1000005b, 0xaf420124, 0x8f8200b0, 0x3c030080, +0x431024, 0x1040000d, 0x0, 0x8f82011c, +0x34420002, 0xaf82011c, 0x8f8200b0, 0x2403fffb, +0x431024, 0xaf8200b0, 0x8f82011c, 0x2403fffd, +0x431024, 0x1000004a, 0xaf82011c, 0x8f43011c, +0x8f820104, 0x14620005, 0x0, 0x8f430124, +0x8f8200b4, 0x10620010, 0x0, 0x8f820104, +0xaf42011c, 0x8f8200b4, 0x8f43011c, 0xaf420124, +0xafa30010, 0x8f420124, 0x3c040001, 0x248431c4, 0xafa20014, 0x8f86011c, 0x8f8700b0, 0x3c050005, -0x34a51100, 0xc0029d3, 0x0, 0x8f8200a0, -0x30420004, 0x10400069, 0x0, 0x8f430120, -0x8f820124, 0x14620005, 0x0, 0x8f430128, -0x8f8200a4, 0x10620006, 0x0, 0x8f820124, -0xaf420120, 0x8f8200a4, 0x1000005c, 0xaf420128, -0x8f8200a0, 0x3c030080, 0x431024, 0x1040000d, -0x0, 0x8f82011c, 0x34420002, 0xaf82011c, -0x8f8200a0, 0x2403fffb, 0x431024, 0xaf8200a0, -0x8f82011c, 0x2403fffd, 0x431024, 0x1000004b, -0xaf82011c, 0x8f430120, 0x8f820124, 0x14620005, -0x0, 0x8f430128, 0x8f8200a4, 0x10620010, -0x0, 0x8f820124, 0xaf420120, 0x8f8200a4, -0x8f430120, 0xaf420128, 0xafa30010, 0x8f420128, -0x3c040001, 0x248431c4, 0xafa20014, 0x8f86011c, -0x8f8700a0, 0x3c050005, 0x10000032, 0x34a51200, +0x10000031, 0x34a50900, 0x8f42011c, 0xafa20010, +0x8f420124, 0x3c040001, 0x248431d0, 0xafa20014, +0x8f86011c, 0x8f8700b0, 0x3c050005, 0xc0029bb, +0x34a51000, 0x8f82011c, 0x34420002, 0xaf82011c, +0x8f830104, 0x8f8200b0, 0x34420001, 0xaf8200b0, +0x24020008, 0xaf830104, 0xafa20010, 0xafa00014, +0x8f42000c, 0x8c040208, 0x8c05020c, 0xafa20018, +0x8f42010c, 0x26e60028, 0x40f809, 0x24070400, +0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, +0x8ee201dc, 0x24420001, 0xaee201dc, 0x8ee201dc, +0x8f42011c, 0xafa20010, 0x8f420124, 0x3c040001, +0x248431dc, 0xafa20014, 0x8f86011c, 0x8f8700b0, +0x3c050005, 0x34a51100, 0xc0029bb, 0x0, +0x8f8200a0, 0x30420004, 0x10400069, 0x0, +0x8f430120, 0x8f820124, 0x14620005, 0x0, +0x8f430128, 0x8f8200a4, 0x10620006, 0x0, +0x8f820124, 0xaf420120, 0x8f8200a4, 0x1000005c, +0xaf420128, 0x8f8200a0, 0x3c030080, 0x431024, +0x1040000d, 0x0, 0x8f82011c, 0x34420002, +0xaf82011c, 0x8f8200a0, 0x2403fffb, 0x431024, +0xaf8200a0, 0x8f82011c, 0x2403fffd, 0x431024, +0x1000004b, 0xaf82011c, 0x8f430120, 0x8f820124, +0x14620005, 0x0, 0x8f430128, 0x8f8200a4, +0x10620010, 0x0, 0x8f820124, 0xaf420120, +0x8f8200a4, 0x8f430120, 0xaf420128, 0xafa30010, +0x8f420128, 0x3c040001, 0x248431e8, 0xafa20014, +0x8f86011c, 0x8f8700a0, 0x3c050005, 0x10000032, +0x34a51200, 0x8f420120, 0xafa20010, 0x8f420128, +0x3c040001, 0x248431f4, 0xafa20014, 0x8f86011c, +0x8f8700a0, 0x3c050005, 0xc0029bb, 0x34a51300, +0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830124, +0x8f8200a0, 0x34420001, 0xaf8200a0, 0x24020080, +0xaf830124, 0xafa20010, 0xafa00014, 0x8f420014, +0x8c040208, 0x8c05020c, 0xafa20018, 0x8f420108, +0x3c060001, 0x24c63e84, 0x40f809, 0x24070004, +0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, +0x8ee201dc, 0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420120, 0xafa20010, 0x8f420128, 0x3c040001, -0x248431d0, 0xafa20014, 0x8f86011c, 0x8f8700a0, -0x3c050005, 0xc0029d3, 0x34a51300, 0x8f82011c, -0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0, -0x34420001, 0xaf8200a0, 0x24020080, 0xaf830124, -0xafa20010, 0xafa00014, 0x8f420014, 0x8c040208, -0x8c05020c, 0xafa20018, 0x8f420108, 0x3c060001, -0x24c63e14, 0x40f809, 0x24070004, 0x8f82011c, -0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc, -0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420120, -0xafa20010, 0x8f420128, 0x3c040001, 0x248431dc, -0xafa20014, 0x8f86011c, 0x8f8700a0, 0x3c050005, -0x34a51400, 0xc0029d3, 0x0, 0x8fbf0020, -0x3e00008, 0x27bd0028, 0x3c081000, 0x24070001, -0x3c060080, 0x3c050100, 0x8f820070, 0x481024, -0x1040fffd, 0x0, 0x8f820054, 0x24420005, -0xaf820078, 0x8c040234, 0x10800016, 0x1821, -0x3c020001, 0x571021, 0x8c4240e8, 0x24420005, -0x3c010001, 0x370821, 0xac2240e8, 0x3c020001, -0x571021, 0x8c4240e8, 0x44102b, 0x14400009, -0x0, 0x3c030080, 0x3c010001, 0x370821, -0xac2040e8, 0x3c010001, 0x370821, 0x1000000b, -0xa02740f0, 0x3c020001, 0x571021, 0x904240f0, -0x54400006, 0x661825, 0x3c020001, 0x571021, -0x904240f1, 0x54400001, 0x661825, 0x8c040230, -0x10800013, 0x0, 0x3c020001, 0x571021, -0x8c4240ec, 0x24420005, 0x3c010001, 0x370821, -0xac2240ec, 0x3c020001, 0x571021, 0x8c4240ec, -0x44102b, 0x14400006, 0x0, 0x3c010001, -0x370821, 0xac2040ec, 0x10000006, 0x651825, -0x3c020001, 0x571021, 0x904240f2, 0x54400001, -0x651825, 0x1060ffbc, 0x0, 0x8f420000, -0x10400007, 0x0, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x431025, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x1000ffa7, 0xaf80004c, -0x1000ffa5, 0xaf800048, 0x3e00008, 0x0, +0x24843200, 0xafa20014, 0x8f86011c, 0x8f8700a0, +0x3c050005, 0x34a51400, 0xc0029bb, 0x0, +0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3c081000, +0x24070001, 0x3c060080, 0x3c050100, 0x8f820070, +0x481024, 0x1040fffd, 0x0, 0x8f820054, +0x24420005, 0xaf820078, 0x8c040234, 0x10800016, +0x1821, 0x3c020001, 0x571021, 0x8c4240e8, +0x24420005, 0x3c010001, 0x370821, 0xac2240e8, +0x3c020001, 0x571021, 0x8c4240e8, 0x44102b, +0x14400009, 0x0, 0x3c030080, 0x3c010001, +0x370821, 0xac2040e8, 0x3c010001, 0x370821, +0x1000000b, 0xa02740f0, 0x3c020001, 0x571021, +0x904240f0, 0x54400006, 0x661825, 0x3c020001, +0x571021, 0x904240f1, 0x54400001, 0x661825, +0x8c040230, 0x10800013, 0x0, 0x3c020001, +0x571021, 0x8c4240ec, 0x24420005, 0x3c010001, +0x370821, 0xac2240ec, 0x3c020001, 0x571021, +0x8c4240ec, 0x44102b, 0x14400006, 0x0, +0x3c010001, 0x370821, 0xac2040ec, 0x10000006, +0x651825, 0x3c020001, 0x571021, 0x904240f2, +0x54400001, 0x651825, 0x1060ffbc, 0x0, +0x8f420000, 0x10400007, 0x0, 0xaf80004c, +0x8f82004c, 0x1040fffd, 0x0, 0x10000005, +0x0, 0xaf800048, 0x8f820048, 0x1040fffd, +0x0, 0x8f820060, 0x431025, 0xaf820060, +0x8f420000, 0x10400003, 0x0, 0x1000ffa7, +0xaf80004c, 0x1000ffa5, 0xaf800048, 0x3e00008, 0x0, 0x0, 0x0, 0x27bdffe0, 0xafbf001c, 0xafb00018, 0x8f860064, 0x30c20004, 0x10400025, 0x24040004, 0x8c020114, 0xaf420020, @@ -5479,8 +5488,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1000006b, 0xaf80004c, 0x10000069, 0xaf800048, 0x30c20001, 0x10400004, 0x24020001, 0xaf820064, 0x10000063, 0x0, 0x30c20002, 0x1440000b, -0x3c050003, 0x3c040001, 0x248432a4, 0x34a50500, -0x3821, 0xafa00010, 0xc0029d3, 0xafa00014, +0x3c050003, 0x3c040001, 0x248432c4, 0x34a50500, +0x3821, 0xafa00010, 0xc0029bb, 0xafa00014, 0x2402ffc0, 0x10000056, 0xaf820064, 0x8c10022c, 0x8c02010c, 0x12020047, 0x101080, 0x8c450300, 0x26020001, 0x3050003f, 0x24020003, 0xac10022c, @@ -5499,7 +5508,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0xaf800048, 0x8f820048, 0x1040fffd, 0x0, 0x8f820060, 0x34420100, 0xaf820060, 0x8f420000, 0x10400003, 0x0, 0x10000005, -0xaf80004c, 0x10000003, 0xaf800048, 0xc002033, +0xaf80004c, 0x10000003, 0xaf800048, 0xc00202b, 0xa02021, 0x8c02010c, 0x16020002, 0x24020002, 0xaf820064, 0x8f820064, 0x30420002, 0x14400004, 0x0, 0x8c02010c, 0x1602ffad, 0x0, @@ -5508,33 +5517,33 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x808021, 0x101602, 0x2442ffff, 0x304300ff, 0x2c620013, 0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044, 0xafb20040, 0x104001e6, 0xafb1003c, -0x31080, 0x3c010001, 0x220821, 0x8c2232e8, +0x31080, 0x3c010001, 0x220821, 0x8c223308, 0x400008, 0x0, 0x101302, 0x30440fff, 0x24020001, 0x10820005, 0x24020002, 0x1082000a, 0x2402fffe, 0x10000021, 0x3c050003, 0x8f430004, -0x3c020001, 0x8c423e40, 0xaf4401f0, 0xaf4401f4, +0x3c020001, 0x8c423eb0, 0xaf4401f0, 0xaf4401f4, 0x10000007, 0x34630001, 0x8f430004, 0xaf4401f0, -0xaf4401f4, 0x621824, 0x3c020001, 0x2442c254, +0xaf4401f4, 0x621824, 0x3c020001, 0x2442c1b0, 0x21100, 0x21182, 0xaf430004, 0x3c030800, 0x431025, 0x3c010000, 0xac224138, 0x8f840054, 0x41442, 0x41c82, 0x431021, 0x41cc2, 0x431023, 0x41d02, 0x431021, 0x41d42, 0x431023, 0x10000009, 0xaf4201f8, 0x3c040001, -0x248432b0, 0x34a51000, 0x2003021, 0x3821, -0xafa00010, 0xc0029d3, 0xafa00014, 0x8f420290, +0x248432d0, 0x34a51000, 0x2003021, 0x3821, +0xafa00010, 0xc0029bb, 0xafa00014, 0x8f420290, 0x24420001, 0xaf420290, 0x10000215, 0x8f420290, -0x27b00028, 0x2002021, 0x24050210, 0xc002a57, -0x24060008, 0xc0023a0, 0x2002021, 0x1000020c, +0x27b00028, 0x2002021, 0x24050210, 0xc002a3f, +0x24060008, 0xc002398, 0x2002021, 0x1000020c, 0x0, 0x8c06022c, 0x27a40028, 0x61880, 0x24c20001, 0x3046003f, 0x8c650300, 0x61080, 0x8c430300, 0x24c20001, 0x3042003f, 0xac02022c, -0xafa50028, 0xc0023a0, 0xafa3002c, 0x100001fc, +0xafa50028, 0xc002398, 0xafa3002c, 0x100001fc, 0x0, 0x27b00028, 0x2002021, 0x24050210, -0xc002a57, 0x24060008, 0xc0024df, 0x2002021, +0xc002a3f, 0x24060008, 0xc0024d7, 0x2002021, 0x100001f3, 0x0, 0x8c06022c, 0x27a40028, 0x61880, 0x24c20001, 0x3046003f, 0x8c650300, 0x61080, 0x8c430300, 0x24c20001, 0x3042003f, -0xac02022c, 0xafa50028, 0xc0024df, 0xafa3002c, +0xac02022c, 0xafa50028, 0xc0024d7, 0xafa3002c, 0x100001e3, 0x0, 0x101302, 0x30430fff, 0x24020001, 0x10620005, 0x24020002, 0x1062001e, 0x3c020002, 0x10000033, 0x3c050003, 0x3c030002, @@ -5550,8 +5559,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf82022c, 0x3c020001, 0x571021, 0x8c4238e0, 0xaf820230, 0x3c020001, 0x571021, 0x8c4238e4, 0xaf820234, 0x3c02fffd, 0x3442ffff, 0x10000009, -0x2c2b024, 0x3c040001, 0x248432bc, 0x34a51100, -0x2003021, 0x3821, 0xafa00010, 0xc0029d3, +0x2c2b024, 0x3c040001, 0x248432dc, 0x34a51100, +0x2003021, 0x3821, 0xafa00010, 0xc0029bb, 0xafa00014, 0x8f4202bc, 0x24420001, 0xaf4202bc, 0x1000019b, 0x8f4202bc, 0x101302, 0x30450fff, 0x24020001, 0x10a20005, 0x24020002, 0x10a2000d, @@ -5560,25 +5569,25 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x621824, 0x34630008, 0xaf830220, 0x10000012, 0xaf450288, 0x3484fff7, 0x3c03fffb, 0x8f820220, 0x3463ffff, 0x2c3b024, 0x441024, 0xaf820220, -0x10000009, 0xaf450288, 0x3c040001, 0x248432c8, +0x10000009, 0xaf450288, 0x3c040001, 0x248432e8, 0x34a51200, 0x2003021, 0x3821, 0xafa00010, -0xc0029d3, 0xafa00014, 0x8f4202ac, 0x24420001, +0xc0029bb, 0xafa00014, 0x8f4202ac, 0x24420001, 0xaf4202ac, 0x10000172, 0x8f4202ac, 0x27840208, -0x24050200, 0xc002a57, 0x24060008, 0x27440214, -0x24050200, 0xc002a57, 0x24060008, 0x8f4202b4, +0x24050200, 0xc002a3f, 0x24060008, 0x27440214, +0x24050200, 0xc002a3f, 0x24060008, 0x8f4202b4, 0x24420001, 0xaf4202b4, 0x10000165, 0x8f4202b4, 0x101302, 0x30430fff, 0x24020001, 0x10620011, 0x28620002, 0x50400005, 0x24020002, 0x10600007, 0x0, 0x10000017, 0x0, 0x1062000f, 0x0, 0x10000013, 0x0, 0x8c060248, -0x2021, 0xc004878, 0x24050004, 0x10000007, -0x0, 0x8c060248, 0x2021, 0xc004878, +0x2021, 0xc0047d4, 0x24050004, 0x10000007, +0x0, 0x8c060248, 0x2021, 0xc0047d4, 0x24050004, 0x10000010, 0x0, 0x8c06024c, -0x2021, 0xc004878, 0x24050001, 0x1000000a, -0x0, 0x3c040001, 0x248432d4, 0x3c050003, +0x2021, 0xc0047d4, 0x24050001, 0x1000000a, +0x0, 0x3c040001, 0x248432f4, 0x3c050003, 0x34a51300, 0x2003021, 0x3821, 0xafa00010, -0xc0029d3, 0xafa00014, 0x8f4202b0, 0x24420001, -0xaf4202b0, 0x10000136, 0x8f4202b0, 0xc0022b4, +0xc0029bb, 0xafa00014, 0x8f4202b0, 0x24420001, +0xaf4202b0, 0x10000136, 0x8f4202b0, 0xc0022ac, 0x0, 0x10000132, 0x0, 0x24020001, 0xa34205b6, 0x24100100, 0x8f440198, 0x8f45019c, 0xafb00010, 0xafa00014, 0x8f420014, 0xafa20018, @@ -5590,7 +5599,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27aa0020, 0x240200ff, 0x13c20002, 0xafaa0034, 0x27c30001, 0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, 0xaf42032c, -0x8f42032c, 0x8c020228, 0x3c040001, 0x2484326c, +0x8f42032c, 0x8c020228, 0x3c040001, 0x2484328c, 0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, @@ -5605,7 +5614,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x326200ff, 0x54400017, 0xaf520018, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa0034, 0xafa20010, 0x8f820124, 0x3c040001, -0x24843278, 0x3c050009, 0xafa20014, 0x8d460000, +0x24843298, 0x3c050009, 0xafa20014, 0x8d460000, 0x10000033, 0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, 0xaf4202f8, 0x8f4202f8, 0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, 0x247003e8, @@ -5617,26 +5626,26 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2c4203e9, 0x1440ffef, 0x0, 0x326200ff, 0x14400011, 0x0, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa0034, -0xafa20010, 0x8f820124, 0x3c040001, 0x24843280, +0xafa20010, 0x8f820124, 0x3c040001, 0x248432a0, 0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700, -0xc0029d3, 0x3c03821, 0x8f4202a0, 0x24420001, +0xc0029bb, 0x3c03821, 0x8f4202a0, 0x24420001, 0xaf4202a0, 0x8f4202a0, 0x8f4202e8, 0x24420001, 0xaf4202e8, 0x1000008a, 0x8f4202e8, 0x8c02025c, 0x27440214, 0xaf4201e0, 0x8c020260, 0x24050200, -0x24060008, 0xc002a57, 0xaf4201e8, 0x8f820220, +0x24060008, 0xc002a3f, 0xaf4201e8, 0x8f820220, 0x30420008, 0x14400002, 0x24020001, 0x24020002, 0xaf420288, 0x8f42029c, 0x24420001, 0xaf42029c, 0x10000077, 0x8f42029c, 0x3c0200ff, 0x3442ffff, 0x2021824, 0x32c20180, 0x14400006, 0x3402fffb, 0x43102b, 0x14400003, 0x0, 0x1000006c, -0xaf4300bc, 0x3c040001, 0x248432e0, 0x3c050003, +0xaf4300bc, 0x3c040001, 0x24843300, 0x3c050003, 0x34a51500, 0x2003021, 0x3821, 0xafa00010, -0xc0029d3, 0xafa00014, 0x3c020700, 0x34421000, +0xc0029bb, 0xafa00014, 0x3c020700, 0x34421000, 0x101e02, 0x621825, 0xafa30020, 0x8f510018, 0x240200ff, 0x12220002, 0x8021, 0x26300001, 0x8c020228, 0x1602000e, 0x1130c0, 0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, 0x8c020228, -0x3c040001, 0x24843254, 0x3c050009, 0xafa00014, +0x3c040001, 0x24843274, 0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440168, 0x8f45016c, @@ -5645,15 +5654,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f48010c, 0x24070008, 0xa32821, 0xa3482b, 0x822021, 0x100f809, 0x892021, 0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, 0x8f820124, -0x3c040001, 0x2484325c, 0x3c050009, 0xafa20014, +0x3c040001, 0x2484327c, 0x3c050009, 0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200, 0x8f440150, 0x8f450154, 0x8f43000c, 0xaf500018, 0x8f860120, 0x24020010, 0xafa20010, 0xafb00014, 0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, 0x14400010, 0x0, 0x8f420330, 0x24420001, 0xaf420330, 0x8f420330, 0x8f820120, 0xafa20010, 0x8f820124, -0x3c040001, 0x24843264, 0x3c050009, 0xafa20014, -0x8fa60020, 0x34a50300, 0xc0029d3, 0x2203821, +0x3c040001, 0x24843284, 0x3c050009, 0xafa20014, +0x8fa60020, 0x34a50300, 0xc0029bb, 0x2203821, 0x8f4202d0, 0x24420001, 0xaf4202d0, 0x8f4202d0, 0x8f4202e0, 0x24420001, 0xaf4202e0, 0x8f4202e0, 0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044, @@ -5673,21 +5682,21 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x431024, 0x34420004, 0xaf820200, 0x8f53034c, 0x8f550350, 0x8f5e0354, 0x8f470358, 0xafa70014, 0x8f4202c0, 0x274401b0, 0x24420001, 0xaf4202c0, -0x8f5002c0, 0x8f5101f4, 0x8f5201f0, 0xc002a40, +0x8f5002c0, 0x8f5101f4, 0x8f5201f0, 0xc002a28, 0x24050400, 0xaf53034c, 0xaf550350, 0xaf5e0354, 0x8fa70014, 0xaf470358, 0xaf5002c0, 0xaf5101f4, 0xaf5201f0, 0x8c02025c, 0x27440214, 0xaf4201e0, 0x8c020260, 0x24050200, 0x24060008, 0xaf4201e8, -0x24020006, 0xc002a57, 0xaf4201e4, 0x3c023b9a, +0x24020006, 0xc002a3f, 0xaf4201e4, 0x3c023b9a, 0x3442ca00, 0xaf4201ec, 0x240203e8, 0x24040002, 0x24030001, 0xaf420284, 0xaf440280, 0xaf43028c, 0x8f820220, 0x30420008, 0x10400004, 0x0, 0xaf430288, 0x10000003, 0x3021, 0xaf440288, -0x3021, 0x3c030001, 0x661821, 0x90633c80, +0x3021, 0x3c030001, 0x661821, 0x90633cf0, 0x3461021, 0x24c60001, 0xa043021c, 0x2cc2000f, 0x1440fff8, 0x3461821, 0x24c60001, 0x8f820040, 0x24040080, 0x24050080, 0x21702, 0x24420030, -0xa062021c, 0x3461021, 0xc002a40, 0xa040021c, +0xa062021c, 0x3461021, 0xc002a28, 0xa040021c, 0x8fa7001c, 0x30e20004, 0x14400006, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220, 0x8fa70024, 0x30e20004, 0x14400006, @@ -5711,7 +5720,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2c450001, 0xa01021, 0x14400009, 0x24840008, 0x86102b, 0x1440fff0, 0x1021, 0x304200ff, 0x14400030, 0x24020001, 0x1000002e, 0x1021, -0x1000fffa, 0x24020001, 0x2002021, 0xc00229a, +0x1000fffa, 0x24020001, 0x2002021, 0xc002292, 0x24050006, 0x3042007f, 0x218c0, 0x2e31021, 0x3c010001, 0x220821, 0x942230d0, 0x1040fff2, 0x2e31021, 0x3c060001, 0xc23021, 0x94c630d0, @@ -5726,7 +5735,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27bd0018, 0x3e00008, 0x0, 0x27bdffb0, 0x801021, 0xafb00030, 0x24500002, 0x2002021, 0x24050006, 0xafb10034, 0x408821, 0xafbf0048, -0xafbe0044, 0xafb50040, 0xafb3003c, 0xc00229a, +0xafbe0044, 0xafb50040, 0xafb3003c, 0xc002292, 0xafb20038, 0x3047007f, 0x710c0, 0x2e21021, 0x3c050001, 0xa22821, 0x94a530d0, 0x50a0001c, 0xa03021, 0x3c090001, 0x352934d2, 0x96280002, @@ -5739,15 +5748,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10c00014, 0x610c0, 0x571821, 0x3c010001, 0x230821, 0x8c2334d0, 0x571021, 0xafa30010, 0x3c010001, 0x220821, 0x8c2234d4, 0x3c040001, -0x248433f0, 0xafa20014, 0x8e260000, 0x8e270004, -0x3c050004, 0xc0029d3, 0x34a50400, 0x10000063, +0x24843414, 0xafa20014, 0x8e260000, 0x8e270004, +0x3c050004, 0xc0029bb, 0x34a50400, 0x10000063, 0x3c020800, 0x8f450100, 0x10a00006, 0x510c0, 0x2e21021, 0x3c010001, 0x220821, 0x942234d0, 0xaf420100, 0xa03021, 0x14c00011, 0x628c0, 0x710c0, 0x2e21021, 0xafa70010, 0x3c010001, -0x220821, 0x942230d0, 0x3c040001, 0x248433fc, +0x220821, 0x942230d0, 0x3c040001, 0x24843420, 0xafa20014, 0x8e260000, 0x8e270004, 0x3c050004, -0xc0029d3, 0x34a50500, 0x10000048, 0x3c020800, +0xc0029bb, 0x34a50500, 0x10000048, 0x3c020800, 0xb71821, 0x3c020001, 0x96040000, 0x344234d2, 0x621821, 0xa4640000, 0x8e020002, 0x720c0, 0xac620002, 0x2e41021, 0x3c030001, 0x621821, @@ -5770,7 +5779,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, -0x8c020228, 0x3c040001, 0x248433b8, 0x3c050009, +0x8c020228, 0x3c040001, 0x248433dc, 0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, @@ -5784,7 +5793,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff, 0x54400017, 0xaf520018, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, -0xafa20010, 0x8f820124, 0x3c040001, 0x248433c4, +0xafa20010, 0x8f820124, 0x3c040001, 0x248433e8, 0x3c050009, 0xafa20014, 0x8d460000, 0x10000033, 0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, 0xaf4202f8, 0x8f4202f8, 0x1000001c, 0x326200ff, @@ -5797,8 +5806,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1440ffef, 0x0, 0x326200ff, 0x14400011, 0x0, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x248433cc, 0x3c050009, -0xafa20014, 0x8d460000, 0x34a50700, 0xc0029d3, +0x8f820124, 0x3c040001, 0x248433f0, 0x3c050009, +0xafa20014, 0x8d460000, 0x34a50700, 0xc0029bb, 0x3c03821, 0x8f4202a4, 0x24420001, 0xaf4202a4, 0x8f4202a4, 0x8f4202e4, 0x24420001, 0xaf4202e4, 0x8f4202e4, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, @@ -5806,7 +5815,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3e00008, 0x27bd0050, 0x27bdffa0, 0x801021, 0xafb00040, 0x24500002, 0x2002021, 0x24050006, 0xafb10044, 0x408821, 0xafbf0058, 0xafbe0054, -0xafb50050, 0xafb3004c, 0xc00229a, 0xafb20048, +0xafb50050, 0xafb3004c, 0xc002292, 0xafb20048, 0x3048007f, 0x810c0, 0x2e21021, 0x3c060001, 0xc23021, 0x94c630d0, 0x10c0001c, 0x3821, 0x3c0a0001, 0x354a34d2, 0x96290002, 0x610c0, @@ -5818,8 +5827,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x94c634d0, 0x14c0ffea, 0x610c0, 0x14c00011, 0xafa70028, 0x810c0, 0x2e21021, 0xafa80010, 0x3c010001, 0x220821, 0x942230d0, 0x3c040001, -0x24843408, 0xafa20014, 0x8e260000, 0x8e270004, -0x3c050004, 0xc0029d3, 0x34a50900, 0x10000075, +0x2484342c, 0xafa20014, 0x8e260000, 0x8e270004, +0x3c050004, 0xc0029bb, 0x34a50900, 0x10000075, 0x3c020800, 0x10e0000c, 0x610c0, 0x2e21021, 0x3c030001, 0x621821, 0x946334d0, 0x710c0, 0x2e21021, 0x3c010001, 0x220821, 0xa42334d0, @@ -5854,7 +5863,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xafab0034, 0x27c30001, 0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, 0x8c020228, 0x3c040001, -0x248433b8, 0x3c050009, 0xafa00014, 0xafa20010, +0x248433dc, 0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, @@ -5868,7 +5877,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x326200ff, 0x54400017, 0xaf520018, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124, -0x3c040001, 0x248433c4, 0x3c050009, 0xafa20014, +0x3c040001, 0x248433e8, 0x3c050009, 0xafa20014, 0x8d660000, 0x10000033, 0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, 0xaf4202f8, 0x8f4202f8, 0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, @@ -5881,14 +5890,14 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x326200ff, 0x14400011, 0x0, 0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124, 0x3c040001, -0x248433cc, 0x3c050009, 0xafa20014, 0x8d660000, -0x34a50700, 0xc0029d3, 0x3c03821, 0x8f4202a8, +0x248433f0, 0x3c050009, 0xafa20014, 0x8d660000, +0x34a50700, 0xc0029bb, 0x3c03821, 0x8f4202a8, 0x24420001, 0xaf4202a8, 0x8f4202a8, 0x8f4202e4, 0x24420001, 0xaf4202e4, 0x8f4202e4, 0x8fbf0058, 0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060, 0x0, 0x0, 0x0, 0x27bdffe0, -0x27644000, 0xafbf0018, 0xc002a40, 0x24051000, +0x27644000, 0xafbf0018, 0xc002a28, 0x24051000, 0x3c030001, 0x34632cc0, 0x3c040001, 0x34842ec8, 0x24020020, 0xaf82011c, 0x2e31021, 0xaf800100, 0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114, @@ -5897,15 +5906,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2e31021, 0xaf4200f0, 0x2e41021, 0xaf4200f4, 0x2e41021, 0xaf4200f8, 0x3c020001, 0x571021, 0x904240f4, 0x1440001c, 0x3c050001, 0x8f82011c, -0x3c040001, 0x248434d0, 0x3c050001, 0x34420001, +0x3c040001, 0x248434f0, 0x3c050001, 0x34420001, 0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c, -0x34a50100, 0xc0029d3, 0x3821, 0x8c020218, +0x34a50100, 0xc0029bb, 0x3821, 0x8c020218, 0x30420040, 0x10400014, 0x0, 0x8f82011c, -0x3c040001, 0x248434dc, 0x3c050001, 0x34420004, +0x3c040001, 0x248434fc, 0x3c050001, 0x34420004, 0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c, -0x10000007, 0x34a50200, 0x3c040001, 0x248434e4, +0x10000007, 0x34a50200, 0x3c040001, 0x24843504, 0xafa00010, 0xafa00014, 0x8f86011c, 0x34a50300, -0xc0029d3, 0x3821, 0x8fbf0018, 0x3e00008, +0xc0029bb, 0x3821, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8fa90010, 0x8f83012c, 0x8faa0014, 0x8fab0018, 0x1060000a, 0x27624fe0, 0x14620002, 0x24680020, 0x27684800, 0x8f820128, 0x11020004, @@ -5926,79 +5935,75 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24820008, 0x3c020001, 0x34422ec8, 0x2e21021, 0x402021, 0x24020001, 0xaf4400f4, 0xac890000, 0xac820004, 0x24020001, 0x3e00008, 0x0, -0x3e00008, 0x0, 0x8fa90010, 0x8faa0014, -0x8f830120, 0x8fab0018, 0x27624fe0, 0x14620002, -0x24680020, 0x27684800, 0x8f820128, 0x1102000f, -0x24620016, 0xac640000, 0xac650004, 0xac660008, -0xa467000e, 0xac690018, 0xac6a001c, 0xac620014, -0xac6b0010, 0xaf880120, 0x8f4300fc, 0x24020001, -0x2463ffff, 0x10000006, 0xaf4300fc, 0x8f430324, -0x1021, 0x24630001, 0xaf430324, 0x8f430324, -0x3e00008, 0x0, 0x3e00008, 0x0, -0x8fa90010, 0x8f83010c, 0x8faa0014, 0x8fab0018, -0x1060000a, 0x276247e0, 0x14620002, 0x24680020, -0x27684000, 0x8f820108, 0x11020004, 0x0, -0x8f820104, 0x15020007, 0x0, 0x8f430328, -0x1021, 0x24630001, 0xaf430328, 0x10000035, -0x8f430328, 0xac640000, 0xac650004, 0xac660008, -0xa467000e, 0xac690018, 0xac6a001c, 0xac6b0010, -0xac620014, 0xaf880100, 0x8f4400ec, 0x8c820000, -0x30420006, 0x10400019, 0x31220006, 0x10400018, -0x3c020001, 0x8c830004, 0x2c620010, 0x10400013, -0x3c020001, 0x24630001, 0xac830004, 0x8f4300f0, -0x34422ec0, 0x2e21021, 0x54620004, 0x24620008, -0x3c020001, 0x34422cc0, 0x2e21021, 0x14440015, -0x24020001, 0x8f820108, 0x24420020, 0xaf820108, -0x8f820108, 0x1000000f, 0x24020001, 0x3c020001, -0x34422ec0, 0x2e21021, 0x54820004, 0x24820008, -0x3c020001, 0x34422cc0, 0x2e21021, 0x402021, -0x24020001, 0xaf4400ec, 0xac890000, 0xac820004, -0x24020001, 0x3e00008, 0x0, 0x3e00008, -0x0, 0x8fa30010, 0x8faa0014, 0x8f880100, -0x8fab0018, 0x276247e0, 0x15020002, 0x25090020, -0x27694000, 0x8f820108, 0x1122000d, 0x0, -0xad030018, 0x25030016, 0xad040000, 0xad050004, -0xad060008, 0xa507000e, 0xad0a001c, 0xad030014, -0xad0b0010, 0xaf890100, 0x10000006, 0x24020001, -0x8f430328, 0x1021, 0x24630001, 0xaf430328, -0x8f430328, 0x3e00008, 0x0, 0x3e00008, -0x0, 0x27bdffd8, 0x3c040001, 0x248434ec, -0x3c050001, 0xafbf0024, 0xafb20020, 0xafb1001c, -0xafb00018, 0x8f900104, 0x8f9100b0, 0x8f92011c, -0x34a52500, 0x8f820100, 0x2403021, 0x2203821, -0xafa20010, 0xc0029d3, 0xafb00014, 0x8e020008, -0xafa20010, 0x8e02000c, 0x3c040001, 0x248434f8, -0xafa20014, 0x8e060000, 0x8e070004, 0x3c050001, -0xc0029d3, 0x34a52510, 0x8e020018, 0xafa20010, -0x8e02001c, 0x3c040001, 0x24843504, 0xafa20014, -0x8e060010, 0x8e070014, 0x3c050001, 0xc0029d3, -0x34a52520, 0x3c030200, 0x2c31024, 0x1040000d, -0x2231024, 0x1040000b, 0x36420002, 0xaf82011c, -0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c, -0x8f420320, 0x24420001, 0xaf420320, 0x10000015, -0x8f420320, 0x3c040001, 0x24843510, 0x24020290, -0xafa20010, 0xafa00014, 0x8f860144, 0x3c070001, -0x24e73518, 0xc0029d3, 0x3405dead, 0x8f82011c, -0x34420002, 0xaf82011c, 0x8f820220, 0x34420004, -0xaf820220, 0x8f820140, 0x3c030001, 0x431025, -0xaf820140, 0x8fbf0024, 0x8fb20020, 0x8fb1001c, -0x8fb00018, 0x3e00008, 0x27bd0028, 0x27bdffd8, -0x3c040001, 0x24843540, 0x3c050001, 0xafbf0024, -0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900124, -0x8f9100a0, 0x8f92011c, 0x34a52600, 0x8f820120, -0x2403021, 0x2203821, 0xafa20010, 0xc0029d3, +0x3e00008, 0x0, 0x8fa90010, 0x8f83010c, +0x8faa0014, 0x8fab0018, 0x1060000a, 0x276247e0, +0x14620002, 0x24680020, 0x27684000, 0x8f820108, +0x11020004, 0x0, 0x8f820104, 0x15020007, +0x0, 0x8f430328, 0x1021, 0x24630001, +0xaf430328, 0x10000035, 0x8f430328, 0xac640000, +0xac650004, 0xac660008, 0xa467000e, 0xac690018, +0xac6a001c, 0xac6b0010, 0xac620014, 0xaf880100, +0x8f4400ec, 0x8c820000, 0x30420006, 0x10400019, +0x31220006, 0x10400018, 0x3c020001, 0x8c830004, +0x2c620010, 0x10400013, 0x3c020001, 0x24630001, +0xac830004, 0x8f4300f0, 0x34422ec0, 0x2e21021, +0x54620004, 0x24620008, 0x3c020001, 0x34422cc0, +0x2e21021, 0x14440015, 0x24020001, 0x8f820108, +0x24420020, 0xaf820108, 0x8f820108, 0x1000000f, +0x24020001, 0x3c020001, 0x34422ec0, 0x2e21021, +0x54820004, 0x24820008, 0x3c020001, 0x34422cc0, +0x2e21021, 0x402021, 0x24020001, 0xaf4400ec, +0xac890000, 0xac820004, 0x24020001, 0x3e00008, +0x0, 0x3e00008, 0x0, 0x27bdffd8, +0x3c040001, 0x2484350c, 0x3c050001, 0xafbf0024, +0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900104, +0x8f9100b0, 0x8f92011c, 0x34a52500, 0x8f820100, +0x2403021, 0x2203821, 0xafa20010, 0xc0029bb, 0xafb00014, 0x8e020008, 0xafa20010, 0x8e02000c, -0x3c040001, 0x2484354c, 0xafa20014, 0x8e060000, -0x8e070004, 0x3c050001, 0xc0029d3, 0x34a52610, +0x3c040001, 0x24843518, 0xafa20014, 0x8e060000, +0x8e070004, 0x3c050001, 0xc0029bb, 0x34a52510, 0x8e020018, 0xafa20010, 0x8e02001c, 0x3c040001, -0x24843558, 0xafa20014, 0x8e060010, 0x8e070014, -0x3c050001, 0xc0029d3, 0x34a52620, 0x3c030200, +0x24843524, 0xafa20014, 0x8e060010, 0x8e070014, +0x3c050001, 0xc0029bb, 0x34a52520, 0x3c027f00, +0x2221024, 0x3c030800, 0x54430016, 0x3c030200, +0x8f82009c, 0x3042ffff, 0x14400012, 0x3c030200, +0x3c040001, 0x24843530, 0x3c050002, 0x34a5f030, +0x3021, 0x3821, 0x36420002, 0xaf82011c, +0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c, +0xafa00010, 0xc0029bb, 0xafa00014, 0x10000024, +0x0, 0x2c31024, 0x1040000d, 0x2231024, +0x1040000b, 0x36420002, 0xaf82011c, 0x36220001, +0xaf8200b0, 0xaf900104, 0xaf92011c, 0x8f420320, +0x24420001, 0xaf420320, 0x10000015, 0x8f420320, +0x3c040001, 0x24843538, 0x240202a9, 0xafa20010, +0xafa00014, 0x8f860144, 0x3c070001, 0x24e73540, +0xc0029bb, 0x3405dead, 0x8f82011c, 0x34420002, +0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220, +0x8f820140, 0x3c030001, 0x431025, 0xaf820140, +0x8fbf0024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, +0x3e00008, 0x27bd0028, 0x27bdffd8, 0x3c040001, +0x24843568, 0x3c050001, 0xafbf0024, 0xafb20020, +0xafb1001c, 0xafb00018, 0x8f900124, 0x8f9100a0, +0x8f92011c, 0x34a52600, 0x8f820120, 0x2403021, +0x2203821, 0xafa20010, 0xc0029bb, 0xafb00014, +0x8e020008, 0xafa20010, 0x8e02000c, 0x3c040001, +0x24843574, 0xafa20014, 0x8e060000, 0x8e070004, +0x3c050001, 0xc0029bb, 0x34a52610, 0x8e020018, +0xafa20010, 0x8e02001c, 0x3c040001, 0x24843580, +0xafa20014, 0x8e060010, 0x8e070014, 0x3c050001, +0xc0029bb, 0x34a52620, 0x3c027f00, 0x2221024, +0x3c030800, 0x54430016, 0x3c030200, 0x8f8200ac, +0x3042ffff, 0x14400012, 0x3c030200, 0x3c040001, +0x2484358c, 0x3c050001, 0x34a5f030, 0x3021, +0x3821, 0x36420002, 0xaf82011c, 0x36220001, +0xaf8200a0, 0xaf900124, 0xaf92011c, 0xafa00010, +0xc0029bb, 0xafa00014, 0x10000024, 0x0, 0x2c31024, 0x1040000d, 0x2231024, 0x1040000b, 0x36420002, 0xaf82011c, 0x36220001, 0xaf8200a0, 0xaf900124, 0xaf92011c, 0x8f42031c, 0x24420001, 0xaf42031c, 0x10000015, 0x8f42031c, 0x3c040001, -0x24843510, 0x240202bc, 0xafa20010, 0xafa00014, -0x8f860144, 0x3c070001, 0x24e73518, 0xc0029d3, +0x24843538, 0x240202e2, 0xafa20010, 0xafa00014, +0x8f860144, 0x3c070001, 0x24e73540, 0xc0029bb, 0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220, 0x8f820140, 0x3c030001, 0x431025, 0xaf820140, 0x8fbf0024, @@ -6007,24 +6012,24 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2821, 0x6821, 0x4821, 0x7821, 0x7021, 0x8f880124, 0x8f870104, 0x1580002e, 0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120, -0x10460029, 0x0, 0x3c040001, 0x8c843e20, +0x10460029, 0x0, 0x3c040001, 0x8c843e90, 0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004, 0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014, 0x10000012, 0x24c60020, 0x10400017, 0x0, -0x3c040001, 0x8c843e20, 0x8d020000, 0x8d030004, +0x3c040001, 0x8c843e90, 0x8d020000, 0x8d030004, 0xac820000, 0xac830004, 0x8d020008, 0xac820008, 0x9502000e, 0xa482000e, 0x8d020010, 0x25060020, 0xac820010, 0x8d020014, 0x240c0001, 0xc01821, 0xac820014, 0x27624fe0, 0x43102b, 0x54400001, 0x27634800, 0x603021, 0x1540002f, 0x31620100, 0x11200014, 0x31628000, 0x8f820100, 0x1045002a, -0x31620100, 0x3c040001, 0x8c843e1c, 0x8ca20000, +0x31620100, 0x3c040001, 0x8c843e8c, 0x8ca20000, 0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010, 0x240a0001, 0xac820010, 0x8ca20014, 0x10000012, 0x24a50020, 0x10400018, 0x31620100, 0x3c040001, -0x8c843e1c, 0x8ce20000, 0x8ce30004, 0xac820000, +0x8c843e8c, 0x8ce20000, 0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010, 0x8ce20014, 0x240a0001, 0xa01821, 0xac820014, @@ -6033,7 +6038,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x11a00009, 0x31a20800, 0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124, 0x8f880124, 0x6821, 0x11800011, 0x31621000, -0x3c040001, 0x8c843e20, 0x8c820000, 0x8c830004, +0x3c040001, 0x8c843e90, 0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000, @@ -6042,7 +6047,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x3c020002, 0x1221024, 0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104, 0x8f870104, 0x4821, 0x1140ff70, 0x0, -0x3c040001, 0x8c843e1c, 0x8c820000, 0x8c830004, +0x3c040001, 0x8c843e8c, 0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c, 0x8c820010, 0x5021, 0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014, @@ -6051,11 +6056,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x7821, 0x7021, 0x8f880124, 0x8f870104, 0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014, 0x31220800, 0x8f820120, 0x10460029, 0x0, -0x3c040001, 0x8c843e20, 0x8cc20000, 0x8cc30004, +0x3c040001, 0x8c843e90, 0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004, 0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014, 0x10000012, 0x24c60020, -0x10400017, 0x0, 0x3c040001, 0x8c843e20, +0x10400017, 0x0, 0x3c040001, 0x8c843e90, 0x8d020000, 0x8d030004, 0xac820000, 0xac830004, 0x8d020008, 0xac820008, 0x9502000e, 0xa482000e, 0x8d020010, 0x25060020, 0xac820010, 0x8d020014, @@ -6063,11 +6068,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x43102b, 0x54400001, 0x27634800, 0x603021, 0x1560002f, 0x31220100, 0x11400014, 0x31228000, 0x8f820100, 0x1045002a, 0x31220100, 0x3c040001, -0x8c843e1c, 0x8ca20000, 0x8ca30004, 0xac820000, +0x8c843e8c, 0x8ca20000, 0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010, 0x240b0001, 0xac820010, 0x8ca20014, 0x10000012, 0x24a50020, 0x10400018, -0x31220100, 0x3c040001, 0x8c843e1c, 0x8ce20000, +0x31220100, 0x3c040001, 0x8c843e8c, 0x8ce20000, 0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001, @@ -6076,7 +6081,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x5440001d, 0x31221000, 0x11a00009, 0x31a20800, 0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124, 0x8f880124, 0x6821, -0x11800011, 0x31221000, 0x3c040001, 0x8c843e20, +0x11800011, 0x31221000, 0x3c040001, 0x8c843e90, 0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010, @@ -6085,7 +6090,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024, 0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104, 0x8f870104, 0x5021, -0x11600010, 0x0, 0x3c040001, 0x8c843e1c, +0x11600010, 0x0, 0x3c040001, 0x8c843e8c, 0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c, 0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010, @@ -6114,37 +6119,37 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f420000, 0x10400003, 0x0, 0x1000ff05, 0xaf80004c, 0x1000ff03, 0xaf800048, 0x3e00008, 0x0, 0x0, 0x0, 0x3c020001, -0x8c423ca8, 0x27bdffe8, 0xafbf0014, 0x14400012, -0xafb00010, 0x3c100001, 0x26103ec0, 0x2002021, -0xc002a40, 0x24052000, 0x26021fe0, 0x3c010001, -0xac223e28, 0x3c010001, 0xac223e24, 0xac020250, +0x8c423d18, 0x27bdffe8, 0xafbf0014, 0x14400012, +0xafb00010, 0x3c100001, 0x26103f30, 0x2002021, +0xc002a28, 0x24052000, 0x26021fe0, 0x3c010001, +0xac223e98, 0x3c010001, 0xac223e94, 0xac020250, 0x24022000, 0xac100254, 0xac020258, 0x24020001, -0x3c010001, 0xac223ca8, 0x8fbf0014, 0x8fb00010, -0x3e00008, 0x27bd0018, 0x3c090001, 0x8d293e28, +0x3c010001, 0xac223d18, 0x8fbf0014, 0x8fb00010, +0x3e00008, 0x27bd0018, 0x3c090001, 0x8d293e98, 0x8c820000, 0x8fa30010, 0x8fa80014, 0xad220000, 0x8c820004, 0xad250008, 0xad220004, 0x8f820054, 0xad260010, 0xad270014, 0xad230018, 0xad28001c, -0xad22000c, 0x2529ffe0, 0x3c020001, 0x24423ec0, +0xad22000c, 0x2529ffe0, 0x3c020001, 0x24423f30, 0x122102b, 0x10400003, 0x0, 0x3c090001, -0x8d293e24, 0x3c020001, 0x8c423c90, 0xad220000, -0x3c020001, 0x8c423c90, 0x3c010001, 0xac293e28, +0x8d293e94, 0x3c020001, 0x8c423d00, 0xad220000, +0x3c020001, 0x8c423d00, 0x3c010001, 0xac293e98, 0xad220004, 0xac090250, 0x3e00008, 0x0, -0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e103e28, -0x3c020001, 0x8c423c90, 0xafb10014, 0x808821, +0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e103e98, +0x3c020001, 0x8c423d00, 0xafb10014, 0x808821, 0xafbe0024, 0x8fbe0040, 0x8fa40048, 0xafb20018, 0xa09021, 0xafbf0028, 0xafb50020, 0xafb3001c, -0xae020000, 0x3c020001, 0x8c423c90, 0xc09821, +0xae020000, 0x3c020001, 0x8c423d00, 0xc09821, 0xe0a821, 0x10800006, 0xae020004, 0x26050008, -0xc002a4b, 0x24060018, 0x10000005, 0x2610ffe0, -0x26040008, 0xc002a40, 0x24050018, 0x2610ffe0, -0x3c030001, 0x24633ec0, 0x203102b, 0x10400003, -0x0, 0x3c100001, 0x8e103e24, 0x8e220000, +0xc002a33, 0x24060018, 0x10000005, 0x2610ffe0, +0x26040008, 0xc002a28, 0x24050018, 0x2610ffe0, +0x3c030001, 0x24633f30, 0x203102b, 0x10400003, +0x0, 0x3c100001, 0x8e103e94, 0x8e220000, 0xae020000, 0x8e220004, 0xae120008, 0xae020004, 0x8f820054, 0xae130010, 0xae150014, 0xae1e0018, 0x8fa80044, 0xae08001c, 0xae02000c, 0x2610ffe0, 0x203102b, 0x10400003, 0x0, 0x3c100001, -0x8e103e24, 0x3c020001, 0x8c423c90, 0xae020000, -0x3c020001, 0x8c423c90, 0x3c010001, 0xac303e28, +0x8e103e94, 0x3c020001, 0x8c423d00, 0xae020000, +0x3c020001, 0x8c423d00, 0x3c010001, 0xac303e98, 0xae020004, 0xac100250, 0x8fbf0028, 0x8fbe0024, 0x8fb50020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0030, 0x851821, @@ -6186,7 +6191,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27bdffc0, 0x32c20020, 0xafbf0038, 0xafb30034, 0xafb20030, 0xafb1002c, 0x10400004, 0xafb00028, 0x8f530028, 0x10000002, 0x0, 0x8f530020, -0x8f420030, 0x105300e4, 0x21100, 0x8f43001c, +0x8f420030, 0x105300eb, 0x21100, 0x8f43001c, 0x628021, 0x8e040000, 0x8e050004, 0x96120008, 0x8f420090, 0x9611000a, 0x3246ffff, 0x46102a, 0x10400017, 0x0, 0x8f8200d8, 0x8f430098, @@ -6194,9 +6199,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x2842fff9, 0x10400005, 0x0, 0x8f420090, 0x8f430138, 0x431021, 0xaf420090, 0x8f420090, 0x46102a, 0x10400006, 0x0, 0x8f420338, -0x24420001, 0xaf420338, 0x100000da, 0x8f420338, +0x24420001, 0xaf420338, 0x100000e1, 0x8f420338, 0x8f8200fc, 0x14400006, 0x32c20008, 0x8f420334, -0x24420001, 0xaf420334, 0x100000d2, 0x8f420334, +0x24420001, 0xaf420334, 0x100000d9, 0x8f420334, 0x5040000c, 0xaf4000ac, 0x934205b3, 0x10400008, 0x32220200, 0x10400006, 0x3c034000, 0x9602000e, 0xaf4300ac, 0x21400, 0x10000002, 0xaf4200b0, @@ -6205,7 +6210,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x24020004, 0xafa20010, 0x8f420030, 0xafa20014, 0x8f420010, 0x3c030002, 0x431025, 0xafa20018, 0x8f460098, 0x8f420108, 0x40f809, 0x0, -0x104000b0, 0x0, 0x8f42009c, 0x8f430094, +0x104000b7, 0x0, 0x8f42009c, 0x8f430094, 0x2421021, 0xaf42009c, 0xae03000c, 0x8f4200ac, 0x10400008, 0x3c034000, 0x8f420094, 0x431025, 0xafa20020, 0x8f42009c, 0x8f4300b0, 0x10000004, @@ -6232,123 +6237,124 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f420090, 0x8f430094, 0x862024, 0x441023, 0x65182b, 0x14600005, 0xaf420090, 0x8f420094, 0x8f430138, 0x431023, 0xaf420094, 0x8f420094, -0x10000023, 0xaf40009c, 0x3247ffff, 0x10e00021, -0x0, 0x14400002, 0x24020010, 0x24020002, +0x10000023, 0xaf40009c, 0x3247ffff, 0x50e00022, +0x32c20020, 0x14400002, 0x24020010, 0x24020002, 0xafa20010, 0x8f420030, 0xafa20014, 0x8f420010, 0xafa20018, 0x8f460098, 0x8f420108, 0x40f809, -0x0, 0x10400033, 0x3245ffff, 0x8f420098, +0x0, 0x1040003a, 0x3245ffff, 0x8f420098, 0x8f430090, 0x8f460130, 0x451021, 0xaf420098, 0x8f42009c, 0x8f440098, 0xa34005b3, 0x651823, 0xaf430090, 0x451021, 0x86202b, 0x14800005, 0xaf42009c, 0x8f420098, 0x8f430138, 0x431023, -0xaf420098, 0x8f420030, 0x8f430040, 0x24420001, -0x2463ffff, 0x431024, 0xaf420030, 0x8f420030, -0x14530018, 0x0, 0x8f420000, 0x10400007, -0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd, -0x0, 0x10000005, 0x0, 0xaf800048, -0x8f820048, 0x1040fffd, 0x0, 0x8f820060, -0x2403fff7, 0x431024, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x10000002, 0xaf80004c, -0xaf800048, 0x8fbf0038, 0x8fb30034, 0x8fb20030, -0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0040, -0x3e00008, 0x0, 0x27bdffd0, 0x32c20020, -0xafbf002c, 0xafb20028, 0xafb10024, 0x10400004, -0xafb00020, 0x8f520028, 0x10000002, 0x0, -0x8f520020, 0x8f420030, 0x105200b5, 0x21100, -0x8f43001c, 0x628021, 0x8e040000, 0x8e050004, -0x96110008, 0x8f420090, 0x9607000a, 0x3226ffff, -0x46102a, 0x10400017, 0x0, 0x8f8200d8, -0x8f430098, 0x431023, 0x2442ff80, 0xaf420090, -0x8f420090, 0x2842ff81, 0x10400005, 0x0, -0x8f420090, 0x8f430138, 0x431021, 0xaf420090, -0x8f420090, 0x46102a, 0x10400006, 0x0, -0x8f420338, 0x24420001, 0xaf420338, 0x100000ab, -0x8f420338, 0x8f8600fc, 0x10c0000c, 0x0, -0x8f8200f4, 0x2403fff8, 0x431024, 0x461023, -0x218c3, 0x50600001, 0x24030100, 0x8f42008c, -0x43102b, 0x14400006, 0x712c2, 0x8f420334, -0x24420001, 0xaf420334, 0x10000098, 0x8f420334, -0x934305b3, 0x1060000f, 0x30460001, 0x8f420010, -0x34480400, 0x32c20008, 0x10400008, 0x30e20200, -0x10400006, 0x3c034000, 0x9602000e, 0xaf4300ac, -0x21400, 0x10000004, 0xaf4200b0, 0x10000002, -0xaf4000ac, 0x8f480010, 0x30e20004, 0x10400045, -0x3227ffff, 0x8f4900ac, 0x11200005, 0x30c200ff, -0x14400006, 0x24020040, 0x10000004, 0x24020008, -0x14400002, 0x24020020, 0x24020004, 0xafa20010, -0x8f430030, 0x11200004, 0xafa30014, 0x8f4200b0, -0x621025, 0xafa20014, 0x3c020002, 0x1021025, -0xafa20018, 0x8f460098, 0x8f420108, 0x40f809, -0x0, 0x10400069, 0x3224ffff, 0x8f42008c, -0x8f430094, 0x24420001, 0xaf42008c, 0x24020001, -0xae03000c, 0xa34205b3, 0x8f420098, 0x2406fff8, -0x8f450130, 0x441021, 0x24420007, 0x461024, -0x24840007, 0xaf420094, 0x8f420090, 0x8f430094, -0x862024, 0x441023, 0x65182b, 0x14600005, -0xaf420090, 0x8f420094, 0x8f430138, 0x431023, -0xaf420094, 0x8f430094, 0x8f420134, 0x43102b, -0x10400009, 0x0, 0x8f430130, 0x8f440094, -0x8f420090, 0x8f45012c, 0x641823, 0x431023, -0xaf420090, 0xaf450094, 0x8f420094, 0x1000001f, -0xaf420098, 0x10e0001d, 0x30c200ff, 0x14400002, -0x24020010, 0x24020002, 0xafa20010, 0x8f420030, -0xafa80018, 0xafa20014, 0x8f460098, 0x8f420108, -0x40f809, 0x0, 0x10400030, 0x3225ffff, -0x8f420098, 0x8f440130, 0x451021, 0xaf420098, -0x8f420090, 0x8f430098, 0xa34005b3, 0x451023, -0x64182b, 0x14600005, 0xaf420090, 0x8f420098, -0x8f430138, 0x431023, 0xaf420098, 0x8f420030, -0x8f430040, 0x24420001, 0x2463ffff, 0x431024, -0xaf420030, 0x8f420030, 0x14520018, 0x0, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x2403fff7, 0x431024, -0xaf820060, 0x8f420000, 0x10400003, 0x0, -0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf002c, -0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, -0x27bd0030, 0x3e00008, 0x0, 0x27bdffd8, -0x3c020001, 0x34422ec0, 0xafbf0020, 0x8f4300f0, -0x8f840108, 0x2e21021, 0x54620004, 0x24620008, -0x3c020001, 0x34422cc0, 0x2e21021, 0x401821, -0xaf4300f0, 0xac600000, 0x8f4200ec, 0x8c660004, -0x14620004, 0x3c020001, 0x24820020, 0x1000000f, -0xaf820108, 0x8f4300f0, 0x34422ec0, 0x2e21021, -0x54620004, 0x24620008, 0x3c020001, 0x34422cc0, -0x2e21021, 0x401821, 0x8c620004, 0x21140, -0x821021, 0xaf820108, 0xac600000, 0x8c850018, -0x30a20036, 0x1040006c, 0x30a20001, 0x8c82001c, -0x8f430040, 0x8f440034, 0x24420001, 0x2463ffff, -0x431024, 0x862021, 0xaf42002c, 0x30a20030, -0x14400006, 0xaf440034, 0x8f420034, 0x8c03023c, -0x43102b, 0x144000c9, 0x0, 0x32c20010, -0x10400028, 0x24070008, 0x8f440160, 0x8f450164, -0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020080, -0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x14400011, 0x24020001, -0x3c010001, 0x370821, 0xa02240f1, 0x8f820124, -0xafa20010, 0x8f820128, 0x3c040001, 0x24843800, -0xafa20014, 0x8f46002c, 0x8f870120, 0x3c050009, -0xc0029d3, 0x34a51100, 0x10000036, 0x0, -0x8f4202f0, 0x8f43002c, 0x24420001, 0xaf4202f0, -0x8f4202f0, 0x24020001, 0xa34205b2, 0x10000026, -0xaf430038, 0x8f440160, 0x8f450164, 0x8f43002c, -0x8f48000c, 0x8f860120, 0x24020020, 0xafa20010, +0xaf420098, 0x32c20020, 0x10400005, 0x0, +0x8f420348, 0x2442ffff, 0xaf420348, 0x8f420348, +0x8f420030, 0x8f430040, 0x24420001, 0x2463ffff, +0x431024, 0xaf420030, 0x8f420030, 0x14530018, +0x0, 0x8f420000, 0x10400007, 0x0, +0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, +0x10000005, 0x0, 0xaf800048, 0x8f820048, +0x1040fffd, 0x0, 0x8f820060, 0x2403fff7, +0x431024, 0xaf820060, 0x8f420000, 0x10400003, +0x0, 0x10000002, 0xaf80004c, 0xaf800048, +0x8fbf0038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, +0x8fb00028, 0x3e00008, 0x27bd0040, 0x3e00008, +0x0, 0x27bdffd0, 0x32c20020, 0xafbf002c, +0xafb20028, 0xafb10024, 0x10400004, 0xafb00020, +0x8f520028, 0x10000002, 0x0, 0x8f520020, +0x8f420030, 0x105200b5, 0x21100, 0x8f43001c, +0x628021, 0x8e040000, 0x8e050004, 0x96110008, +0x8f420090, 0x9607000a, 0x3226ffff, 0x46102a, +0x10400017, 0x0, 0x8f8200d8, 0x8f430098, +0x431023, 0x2442ff80, 0xaf420090, 0x8f420090, +0x2842ff81, 0x10400005, 0x0, 0x8f420090, +0x8f430138, 0x431021, 0xaf420090, 0x8f420090, +0x46102a, 0x10400006, 0x0, 0x8f420338, +0x24420001, 0xaf420338, 0x100000ab, 0x8f420338, +0x8f8600fc, 0x10c0000c, 0x0, 0x8f8200f4, +0x2403fff8, 0x431024, 0x461023, 0x218c3, +0x50600001, 0x24030100, 0x8f42008c, 0x43102b, +0x14400006, 0x712c2, 0x8f420334, 0x24420001, +0xaf420334, 0x10000098, 0x8f420334, 0x934305b3, +0x1060000f, 0x30460001, 0x8f420010, 0x34480400, +0x32c20008, 0x10400008, 0x30e20200, 0x10400006, +0x3c034000, 0x9602000e, 0xaf4300ac, 0x21400, +0x10000004, 0xaf4200b0, 0x10000002, 0xaf4000ac, +0x8f480010, 0x30e20004, 0x10400045, 0x3227ffff, +0x8f4900ac, 0x11200005, 0x30c200ff, 0x14400006, +0x24020040, 0x10000004, 0x24020008, 0x14400002, +0x24020020, 0x24020004, 0xafa20010, 0x8f430030, +0x11200004, 0xafa30014, 0x8f4200b0, 0x621025, +0xafa20014, 0x3c020002, 0x1021025, 0xafa20018, +0x8f460098, 0x8f420108, 0x40f809, 0x0, +0x10400069, 0x3224ffff, 0x8f42008c, 0x8f430094, +0x24420001, 0xaf42008c, 0x24020001, 0xae03000c, +0xa34205b3, 0x8f420098, 0x2406fff8, 0x8f450130, +0x441021, 0x24420007, 0x461024, 0x24840007, +0xaf420094, 0x8f420090, 0x8f430094, 0x862024, +0x441023, 0x65182b, 0x14600005, 0xaf420090, +0x8f420094, 0x8f430138, 0x431023, 0xaf420094, +0x8f430094, 0x8f420134, 0x43102b, 0x10400009, +0x0, 0x8f430130, 0x8f440094, 0x8f420090, +0x8f45012c, 0x641823, 0x431023, 0xaf420090, +0xaf450094, 0x8f420094, 0x1000001f, 0xaf420098, +0x10e0001d, 0x30c200ff, 0x14400002, 0x24020010, +0x24020002, 0xafa20010, 0x8f420030, 0xafa80018, +0xafa20014, 0x8f460098, 0x8f420108, 0x40f809, +0x0, 0x10400030, 0x3225ffff, 0x8f420098, +0x8f440130, 0x451021, 0xaf420098, 0x8f420090, +0x8f430098, 0xa34005b3, 0x451023, 0x64182b, +0x14600005, 0xaf420090, 0x8f420098, 0x8f430138, +0x431023, 0xaf420098, 0x8f420030, 0x8f430040, +0x24420001, 0x2463ffff, 0x431024, 0xaf420030, +0x8f420030, 0x14520018, 0x0, 0x8f420000, +0x10400007, 0x0, 0xaf80004c, 0x8f82004c, +0x1040fffd, 0x0, 0x10000005, 0x0, +0xaf800048, 0x8f820048, 0x1040fffd, 0x0, +0x8f820060, 0x2403fff7, 0x431024, 0xaf820060, +0x8f420000, 0x10400003, 0x0, 0x10000002, +0xaf80004c, 0xaf800048, 0x8fbf002c, 0x8fb20028, +0x8fb10024, 0x8fb00020, 0x3e00008, 0x27bd0030, +0x3e00008, 0x0, 0x27bdffd8, 0x3c020001, +0x34422ec0, 0xafbf0020, 0x8f4300f0, 0x8f840108, +0x2e21021, 0x54620004, 0x24620008, 0x3c020001, +0x34422cc0, 0x2e21021, 0x401821, 0xaf4300f0, +0xac600000, 0x8f4200ec, 0x8c660004, 0x14620004, +0x3c020001, 0x24820020, 0x1000000f, 0xaf820108, +0x8f4300f0, 0x34422ec0, 0x2e21021, 0x54620004, +0x24620008, 0x3c020001, 0x34422cc0, 0x2e21021, +0x401821, 0x8c620004, 0x21140, 0x821021, +0xaf820108, 0xac600000, 0x8c850018, 0x30a20036, +0x1040006c, 0x30a20001, 0x8c82001c, 0x8f430040, +0x8f440034, 0x24420001, 0x2463ffff, 0x431024, +0x862021, 0xaf42002c, 0x30a20030, 0x14400006, +0xaf440034, 0x8f420034, 0x8c03023c, 0x43102b, +0x144000c6, 0x0, 0x32c20010, 0x10400028, +0x24070008, 0x8f440160, 0x8f450164, 0x8f43002c, +0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, -0x370821, 0xa02240f0, 0x8f820124, 0xafa20010, -0x8f820128, 0x3c040001, 0x248437f4, 0xafa20014, -0x8f46002c, 0x8f870120, 0x3c050009, 0xc0029d3, -0x34a50900, 0x1000000f, 0x0, 0x8f4202f0, -0x24420001, 0xaf4202f0, 0x8f4202f0, 0x8f42002c, -0xa34005b2, 0xaf420038, 0x3c010001, 0x370821, -0xa02040f1, 0x3c010001, 0x370821, 0xa02040f0, -0xaf400034, 0x8f420304, 0x24420001, 0xaf420304, -0x1000006e, 0x8f420304, 0x10400025, 0x30a27000, -0x8c85001c, 0x8f420028, 0xa22023, 0x4810003, -0x0, 0x8f420040, 0x822021, 0x8f420348, -0x8f430000, 0x441021, 0xaf420348, 0x8f42035c, -0xaf450028, 0x441021, 0x10600007, 0xaf42035c, +0x370821, 0xa02240f1, 0x8f820124, 0xafa20010, +0x8f820128, 0x3c040001, 0x24843844, 0xafa20014, +0x8f46002c, 0x8f870120, 0x3c050009, 0xc0029bb, +0x34a51100, 0x10000036, 0x0, 0x8f4202f0, +0x8f43002c, 0x24420001, 0xaf4202f0, 0x8f4202f0, +0x24020001, 0xa34205b2, 0x10000026, 0xaf430038, +0x8f440160, 0x8f450164, 0x8f43002c, 0x8f48000c, +0x8f860120, 0x24020020, 0xafa20010, 0xafa30014, +0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, +0x14400011, 0x24020001, 0x3c010001, 0x370821, +0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128, +0x3c040001, 0x24843838, 0xafa20014, 0x8f46002c, +0x8f870120, 0x3c050009, 0xc0029bb, 0x34a50900, +0x1000000f, 0x0, 0x8f4202f0, 0x24420001, +0xaf4202f0, 0x8f4202f0, 0x8f42002c, 0xa34005b2, +0xaf420038, 0x3c010001, 0x370821, 0xa02040f1, +0x3c010001, 0x370821, 0xa02040f0, 0xaf400034, +0x8f420304, 0x24420001, 0xaf420304, 0x1000006b, +0x8f420304, 0x10400022, 0x30a27000, 0x8c85001c, +0x8f420028, 0xa22023, 0x4810003, 0x0, +0x8f420040, 0x822021, 0x8f420348, 0x8f430000, +0xaf450028, 0x441021, 0x10600007, 0xaf420348, 0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd, 0x0, 0x8f820060, 0x34420008, @@ -6367,7 +6373,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x441021, 0xaf420358, 0x3c020800, 0x2c21024, 0x5040001a, 0x36940040, 0x10000018, 0x0, 0x30a20100, 0x10400015, 0x0, 0x3c020001, -0x8c423c54, 0x1040000c, 0x0, 0x274301b0, +0x8c423cc4, 0x1040000c, 0x0, 0x274301b0, 0x24650400, 0x65102b, 0x10400007, 0x26e40028, 0x8c820000, 0xac620000, 0x24630004, 0x65102b, 0x1440fffb, 0x24840004, 0x8f4202cc, 0xa34005b6, @@ -6376,7 +6382,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x27bdffa8, 0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044, 0xafb20040, 0xafb1003c, 0xafb00038, 0x8f910108, 0x26220020, 0xaf820108, 0x8e320018, -0xa821, 0x32420024, 0x104001b1, 0xf021, +0xa821, 0x32420024, 0x104001b7, 0xf021, 0x8e26001c, 0x8f42001c, 0x61900, 0x431021, 0x8c50000c, 0x9603000c, 0x962d0016, 0x9453000a, 0x2c6205dd, 0x10400015, 0x2821, 0x32c20040, @@ -6400,8 +6406,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x431021, 0x904c0009, 0x318900ff, 0x39230006, 0x3182b, 0x39220011, 0x2102b, 0x621824, 0x1060000c, 0x3c050006, 0x8f4200a4, 0x3c040001, -0x24843810, 0xafa20010, 0x8f4200a0, 0x34a54600, -0x1203821, 0xc0029d3, 0xafa20014, 0x1000004e, +0x24843854, 0xafa20010, 0x8f4200a0, 0x34a54600, +0x1203821, 0xc0029bb, 0xafa20014, 0x1000004e, 0x0, 0x32c20004, 0x14400013, 0x2821, 0x316200ff, 0x14400004, 0x0, 0x95020002, 0x1000000d, 0x4a2823, 0x9505000c, 0x9502000e, @@ -6429,7 +6435,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f4200b4, 0x24430001, 0x210c0, 0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001, 0x220821, 0xac2338e8, 0x3c010001, 0x220821, -0xac2438ec, 0x100000a5, 0xaf40009c, 0x10400064, +0xac2438ec, 0x100000a5, 0x32c20020, 0x10400064, 0x0, 0x8f4200b4, 0x24430001, 0x210c0, 0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001, 0x220821, 0xac2338e8, 0x3c010001, @@ -6463,41 +6469,44 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf450264, 0x92020000, 0x30420001, 0x1440000c, 0x2402ffff, 0x8f420268, 0x8f43026c, 0x24630001, 0x2c640001, 0x441021, 0xaf420268, 0xaf43026c, -0x8f420268, 0x8f43026c, 0x1000001c, 0xaf40009c, +0x8f420268, 0x8f43026c, 0x1000001c, 0x32c20020, 0x8e030000, 0x1462000f, 0x3402ffff, 0x96030004, 0x1462000c, 0x0, 0x8f420278, 0x8f43027c, 0x24630001, 0x2c640001, 0x441021, 0xaf420278, 0xaf43027c, 0x8f420278, 0x8f43027c, 0x1000000b, -0xaf40009c, 0x8f420270, 0x8f430274, 0x24630001, +0x32c20020, 0x8f420270, 0x8f430274, 0x24630001, 0x2c640001, 0x441021, 0xaf420270, 0xaf430274, -0x8f420270, 0x8f430274, 0xaf40009c, 0x8e22001c, +0x8f420270, 0x8f430274, 0x32c20020, 0x10400005, +0xaf40009c, 0x8f420348, 0x2442ffff, 0xaf420348, +0x8f420348, 0x8e22001c, 0x8f430040, 0x24420001, +0x2463ffff, 0x431024, 0xaf42002c, 0x32420060, +0x14400008, 0x32c20010, 0x8f420034, 0x24420001, +0xaf420034, 0x8c03023c, 0x43102b, 0x14400114, +0x32c20010, 0x10400018, 0x24070008, 0x8f440160, +0x8f450164, 0x8f43002c, 0x8f48000c, 0x8f860120, +0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, +0x8f42010c, 0x40f809, 0x24c6001c, 0x10400047, +0x24020001, 0x8f4202f0, 0x8f43002c, 0x24420001, +0xaf4202f0, 0x8f4202f0, 0x24020001, 0xa34205b2, +0x1000007c, 0xaf430038, 0x8f440160, 0x8f450164, +0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020, +0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, +0x40f809, 0x24c6001c, 0x10400057, 0x24020001, +0x10000065, 0x0, 0x32420012, 0x10400075, +0x32420001, 0x9622000e, 0x8f43009c, 0x621821, +0x32c20020, 0x10400005, 0xaf43009c, 0x8f420348, +0x2442ffff, 0xaf420348, 0x8f420348, 0x8e22001c, 0x8f430040, 0x24420001, 0x2463ffff, 0x431024, -0xaf42002c, 0x32420060, 0x14400008, 0x32c20010, +0xaf42002c, 0x32420010, 0x14400008, 0x32c20010, 0x8f420034, 0x24420001, 0xaf420034, 0x8c03023c, -0x43102b, 0x14400111, 0x32c20010, 0x10400018, -0x24070008, 0x8f440160, 0x8f450164, 0x8f43002c, -0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010, -0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, -0x24c6001c, 0x10400041, 0x24020001, 0x8f4202f0, -0x8f43002c, 0x24420001, 0xaf4202f0, 0x8f4202f0, -0x24020001, 0xa34205b2, 0x10000076, 0xaf430038, -0x8f440160, 0x8f450164, 0x8f43002c, 0x8f48000c, -0x8f860120, 0x24020020, 0xafa20010, 0xafa30014, -0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x10400051, 0x24020001, 0x1000005f, 0x0, -0x32420012, 0x1040006f, 0x32420001, 0x9623000e, -0x8f42009c, 0x431021, 0xaf42009c, 0x8e23001c, -0x8f420040, 0x24630001, 0x2442ffff, 0x621824, -0x32420010, 0x14400008, 0xaf43002c, 0x8f420034, -0x24420001, 0xaf420034, 0x8c03023c, 0x43102b, -0x144000d2, 0x0, 0x32c20010, 0x10400028, +0x43102b, 0x144000ce, 0x32c20010, 0x10400028, 0x24070008, 0x8f440160, 0x8f450164, 0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, 0x370821, 0xa02240f1, 0x8f820124, 0xafa20010, -0x8f820128, 0x3c040001, 0x24843800, 0xafa20014, -0x8f46002c, 0x8f870120, 0x3c050009, 0xc0029d3, +0x8f820128, 0x3c040001, 0x24843844, 0xafa20014, +0x8f46002c, 0x8f870120, 0x3c050009, 0xc0029bb, 0x34a51100, 0x10000036, 0x0, 0x8f4202f0, 0x8f43002c, 0x24420001, 0xaf4202f0, 0x8f4202f0, 0x24020001, 0xa34205b2, 0x10000026, 0xaf430038, @@ -6506,479 +6515,450 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, 0x370821, 0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128, -0x3c040001, 0x248437f4, 0xafa20014, 0x8f46002c, -0x8f870120, 0x3c050009, 0xc0029d3, 0x34a50900, +0x3c040001, 0x24843838, 0xafa20014, 0x8f46002c, +0x8f870120, 0x3c050009, 0xc0029bb, 0x34a50900, 0x1000000f, 0x0, 0x8f4202f0, 0x24420001, 0xaf4202f0, 0x8f4202f0, 0x8f42002c, 0xa34005b2, 0xaf420038, 0x3c010001, 0x370821, 0xa02040f1, 0x3c010001, 0x370821, 0xa02040f0, 0xaf400034, -0x8f420304, 0x24420001, 0xaf420304, 0x10000077, -0x8f420304, 0x10400025, 0x32427000, 0x8e25001c, +0x8f420304, 0x24420001, 0xaf420304, 0x10000074, +0x8f420304, 0x10400022, 0x32427000, 0x8e25001c, 0x8f420028, 0xa22023, 0x4810003, 0x0, 0x8f420040, 0x822021, 0x8f420348, 0x8f430000, -0x441021, 0xaf420348, 0x8f42035c, 0xaf450028, -0x441021, 0x10600007, 0xaf42035c, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x34420008, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x10000053, -0xaf80004c, 0x10000051, 0xaf800048, 0x1040002f, -0x32421000, 0x1040000c, 0x32424000, 0x8e23001c, -0x8f420050, 0x622023, 0x4820001, 0x24840200, -0x8f42034c, 0x441021, 0xaf42034c, 0x8f420358, -0x1000001a, 0xaf430050, 0x1040000c, 0x32c28000, -0x8e23001c, 0x8f420070, 0x622023, 0x4820001, -0x24840400, 0x8f420354, 0x441021, 0xaf420354, -0x8f420358, 0x1000000d, 0xaf430070, 0x1040000e, -0x3c020800, 0x8e23001c, 0x8f420060, 0x622023, -0x4820001, 0x24840100, 0x8f420350, 0x441021, -0xaf420350, 0x8f420358, 0xaf430060, 0x441021, -0xaf420358, 0x3c020800, 0x2c21024, 0x50400023, -0x36940040, 0x10000021, 0x0, 0x32420048, -0x10400007, 0x24150001, 0x8e22001c, 0x3c03ffff, -0x43f024, 0x3042ffff, 0x1000fd81, 0xae22001c, -0x32420100, 0x10400015, 0x0, 0x3c020001, -0x8c423c54, 0x1040000c, 0x0, 0x274301b0, -0x24650400, 0x65102b, 0x10400007, 0x26e40028, -0x8c820000, 0xac620000, 0x24630004, 0x65102b, -0x1440fffb, 0x24840004, 0x8f4202cc, 0xa34005b6, -0x24420001, 0xaf4202cc, 0x8f4202cc, 0x8fbf0050, -0x8fbe004c, 0x8fb50048, 0x8fb30044, 0x8fb20040, -0x8fb1003c, 0x8fb00038, 0x3e00008, 0x27bd0058, -0x3e00008, 0x0, 0x0, 0x8f8600e4, -0x8f8200e0, 0x2403fff8, 0x431024, 0x10c20007, -0x803821, 0x8cc20000, 0x8cc30004, 0xace20000, -0xace30004, 0x10000002, 0x24020001, 0x1021, -0x3e00008, 0x0, 0x3e00008, 0x0, -0x8f8300e4, 0x27623ff8, 0x14620002, 0x24620008, -0x27623000, 0x401821, 0xaf8300e8, 0xaf8300e4, -0x3e00008, 0x0, 0x3e00008, 0x0, -0x8f8400e0, 0x8f8800c4, 0x8f8300e8, 0x2402fff8, -0x823824, 0xe32023, 0x2c821000, 0x50400001, -0x24841000, 0x420c2, 0x801821, 0x8f440248, -0x8f45024c, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xaf440248, 0xaf45024c, -0x8f8300c8, 0x8f42013c, 0x1032023, 0x82102b, -0x14400004, 0x801821, 0x8f42013c, 0x822021, -0x801821, 0x8f440240, 0x8f450244, 0x1021, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0xaf440240, 0xaf450244, 0xaf8800c8, 0xaf8700e4, -0xaf8700e8, 0x3e00008, 0x0, 0x27bdff30, -0x240a0001, 0xafbf00c8, 0xafbe00c4, 0xafb500c0, -0xafb300bc, 0xafb200b8, 0xafb100b4, 0xafb000b0, -0xa3a00097, 0xafa00044, 0xafaa005c, 0x934205b5, -0xa7a0008e, 0x1040000a, 0xa7a00086, 0x8f4b00c4, -0xafab0064, 0x8f4a00c0, 0xafaa006c, 0x8f4b00cc, -0xafab0074, 0x8f4a00c8, 0x10000125, 0xafaa007c, -0x8f420114, 0x40f809, 0x27a40020, 0x304200ff, -0x1040033b, 0x0, 0x8fab0024, 0x8faa0020, -0x3162ffff, 0x2442fffc, 0xafa2006c, 0x3c020006, -0x2c21024, 0xafab007c, 0x14400015, 0xafaa0064, -0x91420000, 0x30420001, 0x10400011, 0x2402ffff, -0x8d430000, 0x14620004, 0x3402ffff, 0x95430004, -0x1062000b, 0x0, 0xc002343, 0x8fa40064, -0x304200ff, 0x14400006, 0x0, 0x8f420118, -0x40f809, 0x0, 0x1000031d, 0x0, -0x8fa20024, 0x3c03ffbf, 0x3463ffff, 0x431024, -0x3c03ffff, 0x431824, 0x14600003, 0xafa20024, -0x10000040, 0x1821, 0x3c020080, 0x621024, -0x10400007, 0x0, 0x8f42037c, 0x24420001, -0xaf42037c, 0x8f42037c, 0x10000036, 0x24030001, -0x8f420200, 0x24420001, 0xaf420200, 0x8f420200, -0x3c020001, 0x621024, 0x10400006, 0x3c020002, -0x8f4201b4, 0x24420001, 0xaf4201b4, 0x8f4201b4, -0x3c020002, 0x621024, 0x10400006, 0x3c020004, -0x8f42036c, 0x24420001, 0xaf42036c, 0x8f42036c, -0x3c020004, 0x621024, 0x10400006, 0x3c020008, -0x8f420370, 0x24420001, 0xaf420370, 0x8f420370, -0x3c020008, 0x621024, 0x10400006, 0x3c020010, -0x8f420374, 0x24420001, 0xaf420374, 0x8f420374, -0x3c020010, 0x621024, 0x10400006, 0x3c020020, -0x8f4201b0, 0x24420001, 0xaf4201b0, 0x8f4201b0, -0x3c020020, 0x621024, 0x10400006, 0x24030001, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x24030001, 0x8c020260, 0x8fab006c, 0x4b102b, -0x10400014, 0x307000ff, 0x8f4201d8, 0x24420001, -0xaf4201d8, 0x8f4201d8, 0x8faa007c, 0x8f8200e0, -0x354a0100, 0xafaa007c, 0xafa20010, 0x8f8200e4, -0x24100001, 0x3c040001, 0x248438d0, 0xafa20014, -0x8fa60020, 0x8fa70024, 0x3c050007, 0xc0029d3, -0x34a50800, 0x12000010, 0x3c020080, 0x2c21024, -0x1440000e, 0x32c20400, 0x8fab007c, 0x3c020080, -0x34420100, 0x1621024, 0x10400005, 0x0, -0x8f4201fc, 0x24420001, 0xaf4201fc, 0x8f4201fc, -0x100002a0, 0x8fa3006c, 0x32c20400, 0x10400015, -0x34028100, 0x8faa0064, 0x9543000c, 0x14620012, -0x3c020100, 0x240b0200, 0xa7ab008e, 0x9542000e, -0x8d430008, 0x8d440004, 0x8d450000, 0x8faa006c, -0x8fab0064, 0x254afffc, 0xafaa006c, 0xa7a20086, -0xad63000c, 0xad640008, 0xad650004, 0x256b0004, -0xafab0064, 0x3c020100, 0x2c21024, 0x10400004, -0x0, 0x8faa006c, 0x254a0004, 0xafaa006c, -0x8f4200bc, 0x5040000a, 0xafa00074, 0x8fab006c, -0x4b102b, 0x50400006, 0xafa00074, 0x8f4200bc, -0x1621023, 0xafa20074, 0x8f4a00bc, 0xafaa006c, -0x8f420080, 0x8fab006c, 0x4b102b, 0x10400056, -0x32c28000, 0x1040005e, 0x240a0003, 0x32c21000, -0x1040005b, 0xafaa005c, 0x10000058, 0x240b0004, -0x8f420340, 0x2403ffbf, 0x283a024, 0x24420001, -0xaf420340, 0x1000023f, 0x8f420340, 0x2c2b025, -0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001, -0x24843900, 0x26620001, 0xafa20014, 0xafa30010, -0x8f860120, 0x8f870124, 0x3c050007, 0xc0029d3, -0x34a52250, 0x1000022f, 0x0, 0x2c2b025, -0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001, -0x24843900, 0x24020002, 0xafa20014, 0xafa30010, -0x8f860120, 0x8f870124, 0x3c050007, 0xc0029d3, -0x34a52450, 0x1000021f, 0x0, 0x8ea20000, -0x8ea30004, 0x3c040001, 0x24843918, 0xafb00010, -0xafbe0014, 0x8ea70018, 0x34a52800, 0xc0029d3, -0x603021, 0x10000213, 0x0, 0xa6b1000a, -0x8f820124, 0x3c040001, 0x24843920, 0xafbe0014, -0xafa20010, 0x8f460044, 0x8f870120, 0x3c050007, -0xc0029d3, 0x34a53000, 0x10000206, 0x0, -0xa6b1000a, 0xa6b2000e, 0x8f820124, 0x3c040001, -0x2484392c, 0xafbe0014, 0xafa20010, 0x8f460044, -0x8f870120, 0x3c050007, 0xc0029d3, 0x34a53200, -0x100001f8, 0x0, 0x8f420084, 0x8faa006c, -0x4a102b, 0x14400007, 0x3c020001, 0x2c21024, -0x10400004, 0x0, 0x240b0002, 0xafab005c, -0x8faa006c, 0x1140020b, 0x27ab0020, 0xafab00a4, -0x3c0a001f, 0x354affff, 0xafaa009c, 0x8fab005c, -0x240a0001, 0x156a0021, 0x24020002, 0x8f430054, -0x8f420050, 0x1062000b, 0x274b0054, 0x8f5e0054, -0x3403ecc0, 0xafab004c, 0x27c20001, 0x304201ff, -0xafa20054, 0x1e1140, 0x431021, 0x1000006b, +0xaf450028, 0x441021, 0x10600007, 0xaf420348, +0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, +0x10000005, 0x0, 0xaf800048, 0x8f820048, +0x1040fffd, 0x0, 0x8f820060, 0x34420008, +0xaf820060, 0x8f420000, 0x10400003, 0x0, +0x10000053, 0xaf80004c, 0x10000051, 0xaf800048, +0x1040002f, 0x32421000, 0x1040000c, 0x32424000, +0x8e23001c, 0x8f420050, 0x622023, 0x4820001, +0x24840200, 0x8f42034c, 0x441021, 0xaf42034c, +0x8f420358, 0x1000001a, 0xaf430050, 0x1040000c, +0x32c28000, 0x8e23001c, 0x8f420070, 0x622023, +0x4820001, 0x24840400, 0x8f420354, 0x441021, +0xaf420354, 0x8f420358, 0x1000000d, 0xaf430070, +0x1040000e, 0x3c020800, 0x8e23001c, 0x8f420060, +0x622023, 0x4820001, 0x24840100, 0x8f420350, +0x441021, 0xaf420350, 0x8f420358, 0xaf430060, +0x441021, 0xaf420358, 0x3c020800, 0x2c21024, +0x50400023, 0x36940040, 0x10000021, 0x0, +0x32420048, 0x10400007, 0x24150001, 0x8e22001c, +0x3c03ffff, 0x43f024, 0x3042ffff, 0x1000fd78, +0xae22001c, 0x32420100, 0x10400015, 0x0, +0x3c020001, 0x8c423cc4, 0x1040000c, 0x0, +0x274301b0, 0x24650400, 0x65102b, 0x10400007, +0x26e40028, 0x8c820000, 0xac620000, 0x24630004, +0x65102b, 0x1440fffb, 0x24840004, 0x8f4202cc, +0xa34005b6, 0x24420001, 0xaf4202cc, 0x8f4202cc, +0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044, +0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008, +0x27bd0058, 0x3e00008, 0x0, 0x8f8400e0, +0x8f8800c4, 0x8f8300e8, 0x2402fff8, 0x823824, +0xe32023, 0x2c821000, 0x50400001, 0x24841000, +0x420c2, 0x801821, 0x8f440248, 0x8f45024c, +0x1021, 0xa32821, 0xa3302b, 0x822021, +0x862021, 0xaf440248, 0xaf45024c, 0x8f8300c8, +0x8f42013c, 0x1032023, 0x82102b, 0x14400004, +0x801821, 0x8f42013c, 0x822021, 0x801821, +0x8f440240, 0x8f450244, 0x1021, 0xa32821, +0xa3302b, 0x822021, 0x862021, 0xaf440240, +0xaf450244, 0xaf8800c8, 0xaf8700e4, 0xaf8700e8, +0x3e00008, 0x0, 0x27bdff30, 0x240a0001, +0xafbf00c8, 0xafbe00c4, 0xafb500c0, 0xafb300bc, +0xafb200b8, 0xafb100b4, 0xafb000b0, 0xa3a00097, +0xafa00044, 0xafaa005c, 0x934205b5, 0xa7a0008e, +0x1040000a, 0xa7a00086, 0x8f4b00c4, 0xafab0064, +0x8f4a00c0, 0xafaa006c, 0x8f4b00cc, 0xafab0074, +0x8f4a00c8, 0x10000129, 0xafaa007c, 0x8f420114, +0x40f809, 0x0, 0x403021, 0x10c0033f, +0x0, 0x8cc20000, 0x8cc30004, 0xafa20020, +0xafa30024, 0x8fab0024, 0x8faa0020, 0x3162ffff, +0x2442fffc, 0xafa2006c, 0x3c020006, 0x2c21024, +0xafab007c, 0x14400015, 0xafaa0064, 0x91420000, +0x30420001, 0x10400011, 0x2402ffff, 0x8d430000, +0x14620004, 0x3402ffff, 0x95430004, 0x1062000b, +0x0, 0xc00233b, 0x8fa40064, 0x304200ff, +0x14400006, 0x0, 0x8f420118, 0x40f809, +0x0, 0x1000031d, 0x0, 0x8fa20024, +0x3c03ffbf, 0x3463ffff, 0x431024, 0x3c03ffff, +0x431824, 0x14600003, 0xafa20024, 0x10000040, +0x1821, 0x3c020080, 0x621024, 0x10400007, +0x0, 0x8f42037c, 0x24420001, 0xaf42037c, +0x8f42037c, 0x10000036, 0x24030001, 0x8f420200, +0x24420001, 0xaf420200, 0x8f420200, 0x3c020001, +0x621024, 0x10400006, 0x3c020002, 0x8f4201b4, +0x24420001, 0xaf4201b4, 0x8f4201b4, 0x3c020002, +0x621024, 0x10400006, 0x3c020004, 0x8f42036c, +0x24420001, 0xaf42036c, 0x8f42036c, 0x3c020004, +0x621024, 0x10400006, 0x3c020008, 0x8f420370, +0x24420001, 0xaf420370, 0x8f420370, 0x3c020008, +0x621024, 0x10400006, 0x3c020010, 0x8f420374, +0x24420001, 0xaf420374, 0x8f420374, 0x3c020010, +0x621024, 0x10400006, 0x3c020020, 0x8f4201b0, +0x24420001, 0xaf4201b0, 0x8f4201b0, 0x3c020020, +0x621024, 0x10400006, 0x24030001, 0x8f420378, +0x24420001, 0xaf420378, 0x8f420378, 0x24030001, +0x8c020260, 0x8fab006c, 0x4b102b, 0x10400014, +0x307000ff, 0x8f4201d8, 0x24420001, 0xaf4201d8, +0x8f4201d8, 0x8faa007c, 0x8f8200e0, 0x354a0100, +0xafaa007c, 0xafa20010, 0x8f8200e4, 0x24100001, +0x3c040001, 0x24843914, 0xafa20014, 0x8fa60020, +0x8fa70024, 0x3c050007, 0xc0029bb, 0x34a50800, +0x12000010, 0x3c020080, 0x2c21024, 0x1440000e, +0x32c20400, 0x8fab007c, 0x3c020080, 0x34420100, +0x1621024, 0x10400005, 0x0, 0x8f4201fc, +0x24420001, 0xaf4201fc, 0x8f4201fc, 0x100002a0, +0x8fa3006c, 0x32c20400, 0x10400015, 0x34028100, +0x8faa0064, 0x9543000c, 0x14620012, 0x3c020100, +0x240b0200, 0xa7ab008e, 0x9542000e, 0x8d430008, +0x8d440004, 0x8d450000, 0x8faa006c, 0x8fab0064, +0x254afffc, 0xafaa006c, 0xa7a20086, 0xad63000c, +0xad640008, 0xad650004, 0x256b0004, 0xafab0064, +0x3c020100, 0x2c21024, 0x10400004, 0x0, +0x8faa006c, 0x254a0004, 0xafaa006c, 0x8f4200bc, +0x5040000a, 0xafa00074, 0x8fab006c, 0x4b102b, +0x50400006, 0xafa00074, 0x8f4200bc, 0x1621023, +0xafa20074, 0x8f4a00bc, 0xafaa006c, 0x8f420080, +0x8fab006c, 0x4b102b, 0x10400056, 0x32c28000, +0x1040005e, 0x240a0003, 0x32c21000, 0x1040005b, +0xafaa005c, 0x10000058, 0x240b0004, 0x8f420340, +0x2403ffbf, 0x283a024, 0x24420001, 0xaf420340, +0x1000023f, 0x8f420340, 0x2c2b025, 0x2402ffbf, +0x282a024, 0x8f830128, 0x3c040001, 0x24843944, +0x26620001, 0xafa20014, 0xafa30010, 0x8f860120, +0x8f870124, 0x3c050007, 0xc0029bb, 0x34a52250, +0x1000022f, 0x0, 0x2c2b025, 0x2402ffbf, +0x282a024, 0x8f830128, 0x3c040001, 0x24843944, +0x24020002, 0xafa20014, 0xafa30010, 0x8f860120, +0x8f870124, 0x3c050007, 0xc0029bb, 0x34a52450, +0x1000021f, 0x0, 0x8ea20000, 0x8ea30004, +0x3c040001, 0x2484395c, 0xafb00010, 0xafbe0014, +0x8ea70018, 0x34a52800, 0xc0029bb, 0x603021, +0x10000213, 0x0, 0xa6b1000a, 0x8f820124, +0x3c040001, 0x24843964, 0xafbe0014, 0xafa20010, +0x8f460044, 0x8f870120, 0x3c050007, 0xc0029bb, +0x34a53000, 0x10000206, 0x0, 0xa6b1000a, +0xa6b2000e, 0x8f820124, 0x3c040001, 0x24843970, +0xafbe0014, 0xafa20010, 0x8f460044, 0x8f870120, +0x3c050007, 0xc0029bb, 0x34a53200, 0x100001f8, +0x0, 0x8f420084, 0x8faa006c, 0x4a102b, +0x14400007, 0x3c020001, 0x2c21024, 0x10400004, +0x0, 0x240b0002, 0xafab005c, 0x8faa006c, +0x1140020b, 0x27ab0020, 0xafab00a4, 0x3c0a001f, +0x354affff, 0xafaa009c, 0x8fab005c, 0x240a0001, +0x156a0021, 0x24020002, 0x8f430054, 0x8f420050, +0x1062000b, 0x274b0054, 0x8f5e0054, 0x3403ecc0, +0xafab004c, 0x27c20001, 0x304201ff, 0xafa20054, +0x1e1140, 0x431021, 0x1000006b, 0x2e2a821, +0x8f420044, 0x8faa006c, 0x3c040001, 0x24843920, +0xafaa0014, 0xafa20010, 0x8f460054, 0x8f470050, +0x3c050007, 0xc0029bb, 0x34a51300, 0x8f430340, +0x2402ffbf, 0x282a024, 0x24630001, 0xaf430340, +0x100001c3, 0x8f420340, 0x1562001d, 0x0, +0x8f430074, 0x8f420070, 0x1062000a, 0x274a0074, +0x8f5e0074, 0xafaa004c, 0x27c20001, 0x304203ff, +0xafa20054, 0x1e1140, 0x24426cc0, 0x1000004a, +0x2e2a821, 0x8f420044, 0x8fab006c, 0x3c040001, +0x2484392c, 0x3c050007, 0xafab0014, 0xafa20010, +0x8f460074, 0x8f470070, 0x34a51500, 0x240a0001, +0xc0029bb, 0xafaa005c, 0x1000ffc3, 0x0, +0x8f430064, 0x8f420060, 0x1062001a, 0x274b0064, +0x8f5e0064, 0x8faa005c, 0xafab004c, 0x27c20001, +0x304200ff, 0xafa20054, 0x24020004, 0x1542000e, +0x1e1140, 0x1e1180, 0x24420cc0, 0x2e21021, +0xafa20044, 0x9442002a, 0x8fab0044, 0x8faa006c, +0x4a102b, 0x10400024, 0x25750020, 0x240b0001, +0x10000021, 0xa3ab0097, 0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044, 0x8faa006c, 0x3c040001, -0x248438dc, 0xafaa0014, 0xafa20010, 0x8f460054, -0x8f470050, 0x3c050007, 0xc0029d3, 0x34a51300, -0x8f430340, 0x2402ffbf, 0x282a024, 0x24630001, -0xaf430340, 0x100001c3, 0x8f420340, 0x1562001d, -0x0, 0x8f430074, 0x8f420070, 0x1062000a, -0x274a0074, 0x8f5e0074, 0xafaa004c, 0x27c20001, -0x304203ff, 0xafa20054, 0x1e1140, 0x24426cc0, -0x1000004a, 0x2e2a821, 0x8f420044, 0x8fab006c, -0x3c040001, 0x248438e8, 0x3c050007, 0xafab0014, -0xafa20010, 0x8f460074, 0x8f470070, 0x34a51500, -0x240a0001, 0xc0029d3, 0xafaa005c, 0x1000ffc3, -0x0, 0x8f430064, 0x8f420060, 0x1062001a, -0x274b0064, 0x8f5e0064, 0x8faa005c, 0xafab004c, -0x27c20001, 0x304200ff, 0xafa20054, 0x24020004, -0x1542000e, 0x1e1140, 0x1e1180, 0x24420cc0, -0x2e21021, 0xafa20044, 0x9442002a, 0x8fab0044, -0x8faa006c, 0x4a102b, 0x10400024, 0x25750020, -0x240b0001, 0x10000021, 0xa3ab0097, 0x24424cc0, -0x1000001e, 0x2e2a821, 0x8f420044, 0x8faa006c, -0x3c040001, 0x248438f4, 0xafaa0014, 0xafa20010, -0x8f460064, 0x8f470060, 0x3c050007, 0xc0029d3, -0x34a51800, 0x3c020008, 0x2c21024, 0x1440ff34, -0x0, 0x8f420360, 0x240b0001, 0xafab005c, -0x24420001, 0xaf420360, 0x1000ff90, 0x8f420360, -0x27a30036, 0x131040, 0x621821, 0x94620000, -0x441021, 0x10000020, 0xa4620000, 0x8faa0064, -0xaeaa0018, 0x93a20097, 0x10400072, 0x9821, -0x8fab0044, 0x8fa4006c, 0x8fa300a4, 0x25620020, -0xafa20028, 0x25620008, 0xafa20030, 0x25620010, -0xafab002c, 0xafa20034, 0x9562002a, 0xa7a20038, -0x95620018, 0xa7a2003a, 0x9562001a, 0xa7a2003c, -0x9562001c, 0xa7a2003e, 0x94620018, 0x24630002, -0x822023, 0x1880ffde, 0x26730001, 0x2e620004, -0x1440fff9, 0x0, 0x8f4200fc, 0x26650001, -0xa2102a, 0x1440002b, 0x24030001, 0x8f83012c, -0x10600023, 0x0, 0x8f820124, 0x431023, -0x22143, 0x58800001, 0x24840040, 0x8f820128, -0x431023, 0x21943, 0x58600001, 0x24630040, -0x64102a, 0x54400001, 0x602021, 0xaf4400fc, -0x8f4200fc, 0xa2102a, 0x10400011, 0x24030001, -0x10000015, 0x306200ff, 0x8faa0064, 0x96070018, -0xafaa0010, 0x8e220008, 0x3c040001, 0x2484390c, -0x8c430004, 0x8c420000, 0x34a52400, 0x2403021, -0xc0029d3, 0xafa30014, 0x1000002b, 0x0, -0x8f420324, 0x1821, 0x24420001, 0xaf420324, -0x8f420324, 0x306200ff, 0x5040fedc, 0x3c020800, -0x12600021, 0x9021, 0x8fb100a4, 0x2208021, -0x8e220008, 0x96070018, 0x8fa60064, 0x8c440000, -0x8c450004, 0x240b0001, 0xafab0010, 0xafbe0014, -0x8f420008, 0xafa20018, 0x8f42010c, 0x40f809, -0x0, 0x1040ffd8, 0x3c050007, 0x96020018, -0x8faa0064, 0x8fab009c, 0x1425021, 0x16a102b, -0x10400004, 0xafaa0064, 0x8f42013c, 0x1425023, -0xafaa0064, 0x26100002, 0x26520001, 0x253102b, -0x1440ffe3, 0x26310004, 0x8fb0006c, 0x10000036, -0x97b10038, 0x8f4200fc, 0x24050002, 0xa2102a, -0x1440001b, 0x24030001, 0x8f83012c, 0x10600013, +0x24843938, 0xafaa0014, 0xafa20010, 0x8f460064, +0x8f470060, 0x3c050007, 0xc0029bb, 0x34a51800, +0x3c020008, 0x2c21024, 0x1440ff34, 0x0, +0x8f420360, 0x240b0001, 0xafab005c, 0x24420001, +0xaf420360, 0x1000ff90, 0x8f420360, 0x27a30036, +0x131040, 0x621821, 0x94620000, 0x441021, +0x10000020, 0xa4620000, 0x8faa0064, 0xaeaa0018, +0x93a20097, 0x10400072, 0x9821, 0x8fab0044, +0x8fa4006c, 0x8fa300a4, 0x25620020, 0xafa20028, +0x25620008, 0xafa20030, 0x25620010, 0xafab002c, +0xafa20034, 0x9562002a, 0xa7a20038, 0x95620018, +0xa7a2003a, 0x9562001a, 0xa7a2003c, 0x9562001c, +0xa7a2003e, 0x94620018, 0x24630002, 0x822023, +0x1880ffde, 0x26730001, 0x2e620004, 0x1440fff9, +0x0, 0x8f4200fc, 0x26650001, 0xa2102a, +0x1440002b, 0x24030001, 0x8f83012c, 0x10600023, 0x0, 0x8f820124, 0x431023, 0x22143, 0x58800001, 0x24840040, 0x8f820128, 0x431023, 0x21943, 0x58600001, 0x24630040, 0x64102a, 0x54400001, 0x602021, 0xaf4400fc, 0x8f4200fc, -0xa2102a, 0x14400006, 0x24030001, 0x8f420324, +0xa2102a, 0x10400011, 0x24030001, 0x10000015, +0x306200ff, 0x8faa0064, 0x96070018, 0xafaa0010, +0x8e220008, 0x3c040001, 0x24843950, 0x8c430004, +0x8c420000, 0x34a52400, 0x2403021, 0xc0029bb, +0xafa30014, 0x1000002b, 0x0, 0x8f420324, 0x1821, 0x24420001, 0xaf420324, 0x8f420324, -0x306200ff, 0x1040fea5, 0x3c020800, 0x96b1000a, -0x8fb0006c, 0x3223ffff, 0x70102b, 0x54400001, -0x608021, 0x8ea40000, 0x8ea50004, 0x240a0001, -0xafaa0010, 0xafbe0014, 0x8f420008, 0x8fa60064, -0xafa20018, 0x8f42010c, 0x40f809, 0x2003821, -0x1040fea2, 0x3c050007, 0x96a3000e, 0x97ab008e, -0x11600007, 0x609021, 0x934205b5, 0x14400004, -0x0, 0x97aa0086, 0x6b1825, 0xa6aa0016, -0x8fab007c, 0x3c02ffff, 0x1621024, 0x10400003, -0xb1402, 0x34630400, 0xa6a20014, 0x8faa006c, -0x560a0072, 0xa6a3000e, 0x34620004, 0xa6a2000e, -0x8fab0074, 0x14b1021, 0xa6a2000a, 0x8f430044, +0x306200ff, 0x5040fedc, 0x3c020800, 0x12600021, +0x9021, 0x8fb100a4, 0x2208021, 0x8e220008, +0x96070018, 0x8fa60064, 0x8c440000, 0x8c450004, +0x240b0001, 0xafab0010, 0xafbe0014, 0x8f420008, +0xafa20018, 0x8f42010c, 0x40f809, 0x0, +0x1040ffd8, 0x3c050007, 0x96020018, 0x8faa0064, +0x8fab009c, 0x1425021, 0x16a102b, 0x10400004, +0xafaa0064, 0x8f42013c, 0x1425023, 0xafaa0064, +0x26100002, 0x26520001, 0x253102b, 0x1440ffe3, +0x26310004, 0x8fb0006c, 0x10000036, 0x97b10038, +0x8f4200fc, 0x24050002, 0xa2102a, 0x1440001b, +0x24030001, 0x8f83012c, 0x10600013, 0x0, +0x8f820124, 0x431023, 0x22143, 0x58800001, +0x24840040, 0x8f820128, 0x431023, 0x21943, +0x58600001, 0x24630040, 0x64102a, 0x54400001, +0x602021, 0xaf4400fc, 0x8f4200fc, 0xa2102a, +0x14400006, 0x24030001, 0x8f420324, 0x1821, +0x24420001, 0xaf420324, 0x8f420324, 0x306200ff, +0x1040fea5, 0x3c020800, 0x96b1000a, 0x8fb0006c, +0x3223ffff, 0x70102b, 0x54400001, 0x608021, +0x8ea40000, 0x8ea50004, 0x240a0001, 0xafaa0010, +0xafbe0014, 0x8f420008, 0x8fa60064, 0xafa20018, +0x8f42010c, 0x40f809, 0x2003821, 0x1040fea2, +0x3c050007, 0x96a3000e, 0x97ab008e, 0x11600007, +0x609021, 0x934205b5, 0x14400004, 0x0, +0x97aa0086, 0x6b1825, 0xa6aa0016, 0x8fab007c, +0x3c02ffff, 0x1621024, 0x10400003, 0xb1402, +0x34630400, 0xa6a20014, 0x8faa006c, 0x560a0072, +0xa6a3000e, 0x34620004, 0xa6a2000e, 0x8fab0074, +0x14b1021, 0xa6a2000a, 0x8f430044, 0x8f440190, +0x8f450194, 0x34028000, 0xafa20010, 0x8f420044, +0x2a03021, 0x24070020, 0xafa20014, 0x8f42000c, +0x31940, 0x604821, 0xafa20018, 0x8f42010c, +0x4021, 0xa92821, 0xa9182b, 0x882021, +0x40f809, 0x832021, 0x5040fe7f, 0xa6b2000e, +0x8f420358, 0xafa0006c, 0xa34005b5, 0x2442ffff, +0xaf420358, 0x8faa005c, 0x240b0001, 0x8f420358, +0x154b0006, 0x24020002, 0x8f42034c, 0x2442ffff, +0xaf42034c, 0x1000000c, 0x8f42034c, 0x15420006, +0x0, 0x8f420354, 0x2442ffff, 0xaf420354, +0x10000005, 0x8f420354, 0x8f420350, 0x2442ffff, +0xaf420350, 0x8f420350, 0x8faa0054, 0x8fab004c, +0xad6a0000, 0x8f420044, 0x8f440088, 0x8f430078, +0x24420001, 0x441024, 0x24630001, 0xaf420044, +0xaf430078, 0x8c020240, 0x62182b, 0x14600065, +0x24070008, 0x8f440158, 0x8f45015c, 0x8f430044, +0x8f48000c, 0x8f860120, 0x24020040, 0xafa20010, +0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, +0x24c6001c, 0x14400011, 0x240b0001, 0x3c010001, +0x370821, 0xa02b40f2, 0x8f820124, 0xafa20010, +0x8f820128, 0x3c040001, 0x2484390c, 0xafa20014, +0x8f460044, 0x8f870120, 0x3c050009, 0xc0029bb, +0x34a51300, 0x1000000b, 0x0, 0x8f4202f4, +0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8f420044, +0xaf42007c, 0x3c010001, 0x370821, 0xa02040f2, +0xaf400078, 0x8f420308, 0x24420001, 0xaf420308, +0x10000038, 0x8f420308, 0xa6b0000a, 0x8f430044, 0x8f440190, 0x8f450194, 0x34028000, 0xafa20010, 0x8f420044, 0x2a03021, 0x24070020, 0xafa20014, 0x8f42000c, 0x31940, 0x604821, 0xafa20018, 0x8f42010c, 0x4021, 0xa92821, 0xa9182b, -0x882021, 0x40f809, 0x832021, 0x5040fe7f, -0xa6b2000e, 0x8f420358, 0xafa0006c, 0xa34005b5, -0x2442ffff, 0xaf420358, 0x8faa005c, 0x240b0001, -0x8f420358, 0x154b0006, 0x24020002, 0x8f42034c, -0x2442ffff, 0xaf42034c, 0x1000000c, 0x8f42034c, -0x15420006, 0x0, 0x8f420354, 0x2442ffff, -0xaf420354, 0x10000005, 0x8f420354, 0x8f420350, -0x2442ffff, 0xaf420350, 0x8f420350, 0x8faa0054, -0x8fab004c, 0xad6a0000, 0x8f420044, 0x8f440088, -0x8f430078, 0x24420001, 0x441024, 0x24630001, -0xaf420044, 0xaf430078, 0x8c020240, 0x62182b, -0x14600065, 0x24070008, 0x8f440158, 0x8f45015c, -0x8f430044, 0x8f48000c, 0x8f860120, 0x24020040, -0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x14400011, 0x240b0001, -0x3c010001, 0x370821, 0xa02b40f2, 0x8f820124, -0xafa20010, 0x8f820128, 0x3c040001, 0x248438c8, -0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009, -0xc0029d3, 0x34a51300, 0x1000000b, 0x0, -0x8f4202f4, 0x24420001, 0xaf4202f4, 0x8f4202f4, -0x8f420044, 0xaf42007c, 0x3c010001, 0x370821, -0xa02040f2, 0xaf400078, 0x8f420308, 0x24420001, -0xaf420308, 0x10000038, 0x8f420308, 0xa6b0000a, -0x8f430044, 0x8f440190, 0x8f450194, 0x34028000, -0xafa20010, 0x8f420044, 0x2a03021, 0x24070020, -0xafa20014, 0x8f42000c, 0x31940, 0x604821, -0xafa20018, 0x8f42010c, 0x4021, 0xa92821, -0xa9182b, 0x882021, 0x40f809, 0x832021, -0x1040fe1f, 0x240a0001, 0xa34a05b5, 0x8fab006c, -0x8faa0064, 0x1705823, 0xafab006c, 0x8fab009c, -0x1505021, 0x16a102b, 0x10400004, 0xafaa0064, -0x8f42013c, 0x1425023, 0xafaa0064, 0x8f420358, -0x2442ffff, 0xaf420358, 0x8f420358, 0x8f42034c, -0x2442ffff, 0xaf42034c, 0x8fab0054, 0x8faa004c, -0x8f42034c, 0xad4b0000, 0x8f420044, 0x8f440088, -0x8f430078, 0x24420001, 0x441024, 0x24630001, -0xaf420044, 0xaf430078, 0x8faa006c, 0x1540fe1b, -0x0, 0x8fab006c, 0x1160001e, 0x0, -0x934205b5, 0x10400009, 0x0, 0x8faa0064, -0xaf4a00c4, 0xaf4b00c0, 0x8fab007c, 0xaf4b00c8, -0x8faa0074, 0x1000000e, 0xaf4a00cc, 0x97ab008e, -0x1160000b, 0x34038100, 0x8fa20020, 0x8c46000c, -0xa443000c, 0x97aa0086, 0x8c440004, 0x8c450008, -0xa44a000e, 0xac440000, 0xac450004, 0xac460008, -0x8f42033c, 0x24420001, 0xaf42033c, 0x10000010, -0x8f42033c, 0x8fab007c, 0x3164ffff, 0x2484fffc, -0x801821, 0x8f440240, 0x8f450244, 0x8f460118, -0x1021, 0xa32821, 0xa3382b, 0x822021, -0x872021, 0xaf440240, 0xc0f809, 0xaf450244, -0x8fbf00c8, 0x8fbe00c4, 0x8fb500c0, 0x8fb300bc, -0x8fb200b8, 0x8fb100b4, 0x8fb000b0, 0x3e00008, -0x27bd00d0, 0x3e00008, 0x0, 0x27bdff38, -0x240b0001, 0xafbf00c0, 0xafbe00bc, 0xafb500b8, -0xafb300b4, 0xafb200b0, 0xafb100ac, 0xafb000a8, -0xa3a00087, 0xafa00044, 0xafab005c, 0x934205b5, -0xa7a00076, 0x10400007, 0xa7a0007e, 0x8f4c00c0, -0xafac0064, 0x8f4b00c8, 0x8f5e00c4, 0x10000129, -0xafab006c, 0x8f420114, 0x40f809, 0x27a40020, -0x304200ff, 0x1040029c, 0x0, 0x8fac0024, -0x8fbe0020, 0x3182ffff, 0x2442fffc, 0xafa20064, -0x3c020006, 0x2c21024, 0x14400015, 0xafac006c, -0x93c20000, 0x30420001, 0x10400011, 0x2402ffff, -0x8fc30000, 0x14620004, 0x3402ffff, 0x97c30004, -0x1062000b, 0x0, 0xc002343, 0x3c02021, -0x304200ff, 0x14400006, 0x0, 0x8f420118, -0x40f809, 0x0, 0x1000027f, 0x0, -0x8fa20024, 0x3c03ffbf, 0x3463ffff, 0x431024, -0x3c03ffff, 0x431824, 0x14600003, 0xafa20024, -0x10000040, 0x8021, 0x3c020080, 0x621024, -0x10400007, 0x0, 0x8f42037c, 0x24420001, -0xaf42037c, 0x8f42037c, 0x10000036, 0x24100001, -0x8f420200, 0x24420001, 0xaf420200, 0x8f420200, -0x3c020001, 0x621024, 0x10400006, 0x3c020002, -0x8f4201b4, 0x24420001, 0xaf4201b4, 0x8f4201b4, -0x3c020002, 0x621024, 0x10400006, 0x3c020004, -0x8f42036c, 0x24420001, 0xaf42036c, 0x8f42036c, -0x3c020004, 0x621024, 0x10400006, 0x3c020008, -0x8f420370, 0x24420001, 0xaf420370, 0x8f420370, -0x3c020008, 0x621024, 0x10400006, 0x3c020010, -0x8f420374, 0x24420001, 0xaf420374, 0x8f420374, -0x3c020010, 0x621024, 0x10400006, 0x3c020020, -0x8f4201b0, 0x24420001, 0xaf4201b0, 0x8f4201b0, -0x3c020020, 0x621024, 0x10400006, 0x24100001, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x24100001, 0x8c020260, 0x8fab0064, 0x4b102b, -0x10400015, 0x320200ff, 0x8f4201d8, 0x24420001, -0xaf4201d8, 0x8f4201d8, 0x8fac006c, 0x8f8200e0, -0x358c0100, 0xafac006c, 0xafa20010, 0x8f8200e4, -0x24100001, 0x3c040001, 0x248438d0, 0xafa20014, -0x8fa60020, 0x8fa70024, 0x3c050007, 0xc0029d3, -0x34a53600, 0x320200ff, 0x10400010, 0x3c020080, -0x2c21024, 0x1440000e, 0x32c20400, 0x8fab006c, -0x3c020080, 0x34420100, 0x1621024, 0x10400005, -0x0, 0x8f4201fc, 0x24420001, 0xaf4201fc, -0x8f4201fc, 0x10000201, 0x8fa30064, 0x32c20400, -0x10400012, 0x34028100, 0x97c3000c, 0x1462000f, -0x0, 0x240c0200, 0xa7ac0076, 0x97c2000e, -0x8fc30008, 0x8fc40004, 0x8fab0064, 0x8fc50000, -0x256bfffc, 0xafab0064, 0xa7a2007e, 0xafc3000c, -0xafc40008, 0xafc50004, 0x27de0004, 0x8fa70064, -0x320200ff, 0x14400031, 0x3c020100, 0x97c3000c, -0x2c6205dd, 0x10400015, 0x2821, 0x32c20800, -0x10400015, 0x24020800, 0x97c30014, 0x14620012, -0x3402aaaa, 0x97c3000e, 0x14620007, 0x2021, -0x97c30010, 0x24020300, 0x14620004, 0x801021, -0x97c20012, 0x2c440001, 0x801021, 0x54400006, -0x24050016, 0x10000004, 0x0, 0x24020800, -0x50620001, 0x2405000e, 0x10a00013, 0x3c52021, -0x24830009, 0x3c02001f, 0x3442ffff, 0x43102b, -0x10400003, 0x0, 0x8f42013c, 0x621823, -0x90620000, 0x38430006, 0x2c630001, 0x38420011, -0x2c420001, 0x621825, 0x10600004, 0x3c020100, -0x94820002, 0x453821, 0x3c020100, 0x2c21024, -0x5040000e, 0xafa70064, 0x8fac0064, 0x10ec0008, -0x3c050007, 0x3c040001, 0x24843938, 0x8fa60064, -0x34a54000, 0xafa00010, 0xc0029d3, 0xafa00014, -0x8fab0064, 0x256b0004, 0xafab0064, 0x8f420080, -0x8fac0064, 0x4c102b, 0x1040002c, 0x32c28000, -0x10400034, 0x240b0003, 0x32c21000, 0x10400031, -0xafab005c, 0x1000002e, 0x240c0004, 0x8f420340, -0x2403ffbf, 0x283a024, 0x24420001, 0xaf420340, -0x10000175, 0x8f420340, 0x3c020800, 0x2c2b025, -0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001, -0x24843900, 0x26620001, 0xafa20014, 0xafa30010, -0x8f860120, 0x8f870124, 0x3c050007, 0xc0029d3, -0x34a55300, 0x10000164, 0x0, 0x8ea20000, -0x8ea30004, 0x3c040001, 0x24843918, 0xafb00010, -0xafb20014, 0x8ea70018, 0x34a55900, 0xc0029d3, -0x603021, 0x10000158, 0x0, 0x8f420084, -0x8fab0064, 0x4b102b, 0x14400007, 0x3c020001, -0x2c21024, 0x10400004, 0x0, 0x240c0002, -0xafac005c, 0x8fab0064, 0x11600168, 0x27ac0020, -0xafac008c, 0x8fab005c, 0x240c0001, 0x556c0021, -0x240c0002, 0x8f430054, 0x8f420050, 0x1062000b, -0x274b0054, 0x8f520054, 0x3403ecc0, 0xafab004c, -0x26420001, 0x304201ff, 0xafa20054, 0x121140, -0x431021, 0x1000006b, 0x2e2a821, 0x8f420044, -0x8fac0064, 0x3c040001, 0x248438dc, 0xafac0014, -0xafa20010, 0x8f460054, 0x8f470050, 0x3c050007, -0xc0029d3, 0x34a54300, 0x8f430340, 0x2402ffbf, -0x282a024, 0x24630001, 0xaf430340, 0x10000126, -0x8f420340, 0x156c001d, 0x0, 0x8f430074, -0x8f420070, 0x1062000a, 0x274b0074, 0x8f520074, -0xafab004c, 0x26420001, 0x304203ff, 0xafa20054, -0x121140, 0x24426cc0, 0x1000004a, 0x2e2a821, -0x8f420044, 0x8fac0064, 0x3c040001, 0x248438e8, -0x3c050007, 0xafac0014, 0xafa20010, 0x8f460074, -0x8f470070, 0x34a54500, 0x240b0001, 0xc0029d3, -0xafab005c, 0x1000ffc3, 0x0, 0x8f430064, -0x8f420060, 0x1062001a, 0x274c0064, 0x8f520064, -0x8fab005c, 0xafac004c, 0x26420001, 0x304200ff, -0xafa20054, 0x24020004, 0x1562000e, 0x121140, -0x121180, 0x24420cc0, 0x2e21021, 0xafa20044, -0x9442002a, 0x8fac0044, 0x8fab0064, 0x4b102b, -0x10400024, 0x25950020, 0x240c0001, 0x10000021, -0xa3ac0087, 0x24424cc0, 0x1000001e, 0x2e2a821, -0x8f420044, 0x8fab0064, 0x3c040001, 0x248438f4, -0xafab0014, 0xafa20010, 0x8f460064, 0x8f470060, -0x3c050007, 0xc0029d3, 0x34a54800, 0x3c020008, -0x2c21024, 0x1440ff61, 0x0, 0x8f420360, -0x240c0001, 0xafac005c, 0x24420001, 0xaf420360, -0x1000ff90, 0x8f420360, 0x27a30036, 0x131040, -0x621821, 0x94620000, 0x441021, 0x1000001f, -0xa4620000, 0xaebe0018, 0x93a20087, 0x10400086, -0x9821, 0x8fab0044, 0x8fa40064, 0x8fa3008c, -0x25620020, 0xafa20028, 0x25620008, 0xafa20030, -0x25620010, 0xafab002c, 0xafa20034, 0x9562002a, -0xa7a20038, 0x95620018, 0xa7a2003a, 0x9562001a, -0xa7a2003c, 0x9562001c, 0xa7a2003e, 0x94620018, -0x24630002, 0x822023, 0x1880ffdf, 0x26730001, -0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc, -0x262102a, 0x14400030, 0x24030001, 0x8f83012c, -0x10600028, 0x0, 0x8f820124, 0x431023, -0x22143, 0x58800001, 0x24840040, 0x8f820128, -0x431023, 0x21943, 0x58600001, 0x24630040, -0x64102a, 0x54400001, 0x602021, 0xaf4400fc, -0x8f4200fc, 0x262102a, 0x10400016, 0x24030001, -0x1000001a, 0x306200ff, 0x8fac008c, 0x111040, -0x4c1021, 0x94470018, 0x111080, 0x4c1021, -0xafbe0010, 0x8c420008, 0x3c040001, 0x2484390c, -0x3c050007, 0x8c430004, 0x8c420000, 0x34a55500, -0x2203021, 0xc0029d3, 0xafa30014, 0x1000003b, -0x0, 0x8f420324, 0x1821, 0x24420001, -0xaf420324, 0x8f420324, 0x306200ff, 0x1040ff06, -0x8821, 0x8f430008, 0x2402fbff, 0x621824, -0x605021, 0x1260002d, 0xaf430008, 0x2669ffff, -0x8fb0008c, 0x3c0b4000, 0x24b4025, 0x2009021, -0x8e420008, 0x96070018, 0x8c440000, 0x8c450004, -0x56290004, 0x240b0001, 0x240c0002, 0x10000002, -0xafac0010, 0xafab0010, 0x16200004, 0xafa80014, -0x8f420008, 0x10000002, 0xafa20018, 0xafaa0018, -0x8f42010c, 0x3c03021, 0xafa80098, 0xafa9009c, -0x40f809, 0xafaa00a0, 0x8fa80098, 0x8fa9009c, -0x8faa00a0, 0x1040ffc0, 0x3c02001f, 0x96030018, -0x3442ffff, 0x3c3f021, 0x5e102b, 0x10400003, -0x26100002, 0x8f42013c, 0x3c2f023, 0x26310001, -0x233102b, 0x1440ffda, 0x26520004, 0x8fb00064, -0x1000001a, 0x0, 0x96a3000a, 0x8fb00064, -0x70102b, 0x54400001, 0x608021, 0x8ea40000, -0x8ea50004, 0x8fab005c, 0x240c0002, 0xafac0010, -0x934305b5, 0xb1700, 0x10600003, 0x2423025, -0x3c020800, 0xc23025, 0xafa60014, 0x8f420008, -0xafa20018, 0x8f42010c, 0x3c03021, 0x40f809, -0x2003821, 0x1040fec9, 0x3c050007, 0x97ac0076, -0x11800007, 0x96a3000e, 0x934205b5, 0x14400004, -0x0, 0x97ab007e, 0x6c1825, 0xa6ab0016, -0x8fac006c, 0x3c02ffff, 0x1821024, 0x10400003, -0xc1402, 0x34630400, 0xa6a20014, 0xa6b0000a, -0x8fab0064, 0x560b0006, 0x3d0f021, 0x34620004, -0xafa00064, 0xa6a2000e, 0x1000000d, 0xa34005b5, -0x8fac0064, 0x3c02001f, 0x3442ffff, 0x5e102b, -0x1906023, 0xafac0064, 0xa6a3000e, 0x240b0001, -0x10400003, 0xa34b05b5, 0x8f42013c, 0x3c2f023, -0x8fab0054, 0x8fac004c, 0xad8b0000, 0x8fac0064, -0x1580feb8, 0x0, 0x8fab0064, 0x1160001b, -0x0, 0x934205b5, 0x10400006, 0x0, -0xaf5e00c4, 0xaf4b00c0, 0x8fac006c, 0x1000000e, -0xaf4c00c8, 0x97ab0076, 0x1160000b, 0x34038100, -0x8fa20020, 0x8c46000c, 0xa443000c, 0x97ac007e, -0x8c440004, 0x8c450008, 0xa44c000e, 0xac440000, -0xac450004, 0xac460008, 0x8f42033c, 0x24420001, -0xaf42033c, 0x10000010, 0x8f42033c, 0x8fab006c, -0x3164ffff, 0x2484fffc, 0x801821, 0x8f440240, -0x8f450244, 0x8f460118, 0x1021, 0xa32821, -0xa3382b, 0x822021, 0x872021, 0xaf440240, -0xc0f809, 0xaf450244, 0x8fbf00c0, 0x8fbe00bc, -0x8fb500b8, 0x8fb300b4, 0x8fb200b0, 0x8fb100ac, -0x8fb000a8, 0x3e00008, 0x27bd00c8, 0x3e00008, -0x0, 0x27bdffd8, 0xafbf0024, 0xafb00020, -0x8f43004c, 0x8f420048, 0x10620034, 0x0, -0x8f430048, 0x8f42004c, 0x622023, 0x4820001, -0x24840200, 0x8f430054, 0x8f42004c, 0x43102b, -0x14400004, 0x24020200, 0x8f43004c, 0x10000005, -0x431023, 0x8f420054, 0x8f43004c, 0x431023, -0x2442ffff, 0x405021, 0x8a102a, 0x54400001, -0x805021, 0x8f49004c, 0x8f48004c, 0x8f440178, -0x8f45017c, 0x8f46004c, 0x24071000, 0xafa70010, -0x84140, 0x1001821, 0x12a4821, 0x313001ff, -0xafb00014, 0x8f470014, 0x1021, 0x63140, -0xafa70018, 0xa32821, 0xa3382b, 0x822021, -0x872021, 0x3402ecc0, 0xc23021, 0x8f420108, -0x2e63021, 0x40f809, 0xa3940, 0x54400001, -0xaf50004c, 0x8f43004c, 0x8f420048, 0x14620018, -0x0, 0x8f420000, 0x10400007, 0x0, -0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, -0x10000005, 0x0, 0xaf800048, 0x8f820048, -0x1040fffd, 0x0, 0x8f820060, 0x2403fdff, -0x431024, 0xaf820060, 0x8f420000, 0x10400003, -0x0, 0x10000002, 0xaf80004c, 0xaf800048, -0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028, +0x882021, 0x40f809, 0x832021, 0x1040fe1f, +0x240a0001, 0xa34a05b5, 0x8fab006c, 0x8faa0064, +0x1705823, 0xafab006c, 0x8fab009c, 0x1505021, +0x16a102b, 0x10400004, 0xafaa0064, 0x8f42013c, +0x1425023, 0xafaa0064, 0x8f420358, 0x2442ffff, +0xaf420358, 0x8f420358, 0x8f42034c, 0x2442ffff, +0xaf42034c, 0x8fab0054, 0x8faa004c, 0x8f42034c, +0xad4b0000, 0x8f420044, 0x8f440088, 0x8f430078, +0x24420001, 0x441024, 0x24630001, 0xaf420044, +0xaf430078, 0x8faa006c, 0x1540fe1b, 0x0, +0x8fab006c, 0x1160001e, 0x0, 0x934205b5, +0x10400009, 0x0, 0x8faa0064, 0xaf4a00c4, +0xaf4b00c0, 0x8fab007c, 0xaf4b00c8, 0x8faa0074, +0x1000000e, 0xaf4a00cc, 0x97ab008e, 0x1160000b, +0x34038100, 0x8fa20020, 0x8c46000c, 0xa443000c, +0x97aa0086, 0x8c440004, 0x8c450008, 0xa44a000e, +0xac440000, 0xac450004, 0xac460008, 0x8f42033c, +0x24420001, 0xaf42033c, 0x10000010, 0x8f42033c, +0x8fab007c, 0x3164ffff, 0x2484fffc, 0x801821, +0x8f440240, 0x8f450244, 0x8f460118, 0x1021, +0xa32821, 0xa3382b, 0x822021, 0x872021, +0xaf440240, 0xc0f809, 0xaf450244, 0x8fbf00c8, +0x8fbe00c4, 0x8fb500c0, 0x8fb300bc, 0x8fb200b8, +0x8fb100b4, 0x8fb000b0, 0x3e00008, 0x27bd00d0, +0x3e00008, 0x0, 0x27bdff38, 0x240b0001, +0xafbf00c0, 0xafbe00bc, 0xafb500b8, 0xafb300b4, +0xafb200b0, 0xafb100ac, 0xafb000a8, 0xa3a00087, +0xafa00044, 0xafab005c, 0x934205b5, 0xa7a00076, +0x10400007, 0xa7a0007e, 0x8f4c00c0, 0xafac0064, +0x8f4b00c8, 0x8f5e00c4, 0x1000012d, 0xafab006c, +0x8f420114, 0x40f809, 0x0, 0x403021, +0x10c0029e, 0x0, 0x8cc20000, 0x8cc30004, +0xafa20020, 0xafa30024, 0x8fac0024, 0x8fbe0020, +0x3182ffff, 0x2442fffc, 0xafa20064, 0x3c020006, +0x2c21024, 0x14400015, 0xafac006c, 0x93c20000, +0x30420001, 0x10400011, 0x2402ffff, 0x8fc30000, +0x14620004, 0x3402ffff, 0x97c30004, 0x1062000b, +0x0, 0xc00233b, 0x3c02021, 0x304200ff, +0x14400006, 0x0, 0x8f420118, 0x40f809, +0x0, 0x1000027d, 0x0, 0x8fa20024, +0x3c03ffbf, 0x3463ffff, 0x431024, 0x3c03ffff, +0x431824, 0x14600003, 0xafa20024, 0x10000040, +0x8021, 0x3c020080, 0x621024, 0x10400007, +0x0, 0x8f42037c, 0x24420001, 0xaf42037c, +0x8f42037c, 0x10000036, 0x24100001, 0x8f420200, +0x24420001, 0xaf420200, 0x8f420200, 0x3c020001, +0x621024, 0x10400006, 0x3c020002, 0x8f4201b4, +0x24420001, 0xaf4201b4, 0x8f4201b4, 0x3c020002, +0x621024, 0x10400006, 0x3c020004, 0x8f42036c, +0x24420001, 0xaf42036c, 0x8f42036c, 0x3c020004, +0x621024, 0x10400006, 0x3c020008, 0x8f420370, +0x24420001, 0xaf420370, 0x8f420370, 0x3c020008, +0x621024, 0x10400006, 0x3c020010, 0x8f420374, +0x24420001, 0xaf420374, 0x8f420374, 0x3c020010, +0x621024, 0x10400006, 0x3c020020, 0x8f4201b0, +0x24420001, 0xaf4201b0, 0x8f4201b0, 0x3c020020, +0x621024, 0x10400006, 0x24100001, 0x8f420378, +0x24420001, 0xaf420378, 0x8f420378, 0x24100001, +0x8c020260, 0x8fab0064, 0x4b102b, 0x10400015, +0x320200ff, 0x8f4201d8, 0x24420001, 0xaf4201d8, +0x8f4201d8, 0x8fac006c, 0x8f8200e0, 0x358c0100, +0xafac006c, 0xafa20010, 0x8f8200e4, 0x24100001, +0x3c040001, 0x24843914, 0xafa20014, 0x8fa60020, +0x8fa70024, 0x3c050007, 0xc0029bb, 0x34a53600, +0x320200ff, 0x10400010, 0x3c020080, 0x2c21024, +0x1440000e, 0x32c20400, 0x8fab006c, 0x3c020080, +0x34420100, 0x1621024, 0x10400005, 0x0, +0x8f4201fc, 0x24420001, 0xaf4201fc, 0x8f4201fc, +0x100001ff, 0x8fa30064, 0x32c20400, 0x10400012, +0x34028100, 0x97c3000c, 0x1462000f, 0x0, +0x240c0200, 0xa7ac0076, 0x97c2000e, 0x8fc30008, +0x8fc40004, 0x8fab0064, 0x8fc50000, 0x256bfffc, +0xafab0064, 0xa7a2007e, 0xafc3000c, 0xafc40008, +0xafc50004, 0x27de0004, 0x8fa70064, 0x320200ff, +0x14400031, 0x3c020100, 0x97c3000c, 0x2c6205dd, +0x10400015, 0x2821, 0x32c20800, 0x10400015, +0x24020800, 0x97c30014, 0x14620012, 0x3402aaaa, +0x97c3000e, 0x14620007, 0x2021, 0x97c30010, +0x24020300, 0x14620004, 0x801021, 0x97c20012, +0x2c440001, 0x801021, 0x54400006, 0x24050016, +0x10000004, 0x0, 0x24020800, 0x50620001, +0x2405000e, 0x10a00013, 0x3c52021, 0x24830009, +0x3c02001f, 0x3442ffff, 0x43102b, 0x10400003, +0x0, 0x8f42013c, 0x621823, 0x90620000, +0x38430006, 0x2c630001, 0x38420011, 0x2c420001, +0x621825, 0x10600004, 0x3c020100, 0x94820002, +0x453821, 0x3c020100, 0x2c21024, 0x5040000e, +0xafa70064, 0x8fac0064, 0x10ec0008, 0x3c050007, +0x3c040001, 0x2484397c, 0x8fa60064, 0x34a54000, +0xafa00010, 0xc0029bb, 0xafa00014, 0x8fab0064, +0x256b0004, 0xafab0064, 0x8f420080, 0x8fac0064, +0x4c102b, 0x1040002c, 0x32c28000, 0x10400034, +0x240b0003, 0x32c21000, 0x10400031, 0xafab005c, +0x1000002e, 0x240c0004, 0x8f420340, 0x2403ffbf, +0x283a024, 0x24420001, 0xaf420340, 0x10000173, +0x8f420340, 0x3c020800, 0x2c2b025, 0x2402ffbf, +0x282a024, 0x8f830128, 0x3c040001, 0x24843944, +0x26620001, 0xafa20014, 0xafa30010, 0x8f860120, +0x8f870124, 0x3c050007, 0xc0029bb, 0x34a55300, +0x10000162, 0x0, 0x8ea20000, 0x8ea30004, +0x3c040001, 0x2484395c, 0xafb00010, 0xafb10014, +0x8ea70018, 0x34a55900, 0xc0029bb, 0x603021, +0x10000156, 0x0, 0x8f420084, 0x8fab0064, +0x4b102b, 0x14400007, 0x3c020001, 0x2c21024, +0x10400004, 0x0, 0x240c0002, 0xafac005c, +0x8fab0064, 0x11600166, 0x27ac0020, 0xafac008c, +0x8fab005c, 0x240c0001, 0x556c0021, 0x240c0002, +0x8f430054, 0x8f420050, 0x1062000b, 0x274b0054, +0x8f510054, 0x3403ecc0, 0xafab004c, 0x26220001, +0x304201ff, 0xafa20054, 0x111140, 0x431021, +0x1000006b, 0x2e2a821, 0x8f420044, 0x8fac0064, +0x3c040001, 0x24843920, 0xafac0014, 0xafa20010, +0x8f460054, 0x8f470050, 0x3c050007, 0xc0029bb, +0x34a54300, 0x8f430340, 0x2402ffbf, 0x282a024, +0x24630001, 0xaf430340, 0x10000124, 0x8f420340, +0x156c001d, 0x0, 0x8f430074, 0x8f420070, +0x1062000a, 0x274b0074, 0x8f510074, 0xafab004c, +0x26220001, 0x304203ff, 0xafa20054, 0x111140, +0x24426cc0, 0x1000004a, 0x2e2a821, 0x8f420044, +0x8fac0064, 0x3c040001, 0x2484392c, 0x3c050007, +0xafac0014, 0xafa20010, 0x8f460074, 0x8f470070, +0x34a54500, 0x240b0001, 0xc0029bb, 0xafab005c, +0x1000ffc3, 0x0, 0x8f430064, 0x8f420060, +0x1062001a, 0x274c0064, 0x8f510064, 0x8fab005c, +0xafac004c, 0x26220001, 0x304200ff, 0xafa20054, +0x24020004, 0x1562000e, 0x111140, 0x111180, +0x24420cc0, 0x2e21021, 0xafa20044, 0x9442002a, +0x8fac0044, 0x8fab0064, 0x4b102b, 0x10400024, +0x25950020, 0x240c0001, 0x10000021, 0xa3ac0087, +0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044, +0x8fab0064, 0x3c040001, 0x24843938, 0xafab0014, +0xafa20010, 0x8f460064, 0x8f470060, 0x3c050007, +0xc0029bb, 0x34a54800, 0x3c020008, 0x2c21024, +0x1440ff61, 0x0, 0x8f420360, 0x240c0001, +0xafac005c, 0x24420001, 0xaf420360, 0x1000ff90, +0x8f420360, 0x27a30036, 0x131040, 0x621821, +0x94620000, 0x441021, 0x1000001f, 0xa4620000, +0xaebe0018, 0x93a20087, 0x10400084, 0x9821, +0x8fab0044, 0x8fa40064, 0x8fa3008c, 0x25620020, +0xafa20028, 0x25620008, 0xafa20030, 0x25620010, +0xafab002c, 0xafa20034, 0x9562002a, 0xa7a20038, +0x95620018, 0xa7a2003a, 0x9562001a, 0xa7a2003c, +0x9562001c, 0xa7a2003e, 0x94620018, 0x24630002, +0x822023, 0x1880ffdf, 0x26730001, 0x2e620004, +0x1440fff9, 0x0, 0x8f4200fc, 0x262102a, +0x14400030, 0x24030001, 0x8f83012c, 0x10600028, +0x0, 0x8f820124, 0x431023, 0x22143, +0x58800001, 0x24840040, 0x8f820128, 0x431023, +0x21943, 0x58600001, 0x24630040, 0x64102a, +0x54400001, 0x602021, 0xaf4400fc, 0x8f4200fc, +0x262102a, 0x10400016, 0x24030001, 0x1000001a, +0x306200ff, 0x8fac008c, 0x101040, 0x4c1021, +0x94470018, 0x101080, 0x4c1021, 0xafbe0010, +0x8c420008, 0x3c040001, 0x24843950, 0x3c050007, +0x8c430004, 0x8c420000, 0x34a55500, 0x2003021, +0xc0029bb, 0xafa30014, 0x10000039, 0x0, +0x8f420324, 0x1821, 0x24420001, 0xaf420324, +0x8f420324, 0x306200ff, 0x1040ff06, 0x8021, +0x8f430008, 0x2402fbff, 0x1260002d, 0x625024, +0x3c0b4000, 0x22b4025, 0x8fb1008c, 0x2669ffff, +0x2209021, 0x8e420008, 0x96270018, 0x8c440000, +0x8c450004, 0x56090004, 0x240b0001, 0x240c0002, +0x10000002, 0xafac0010, 0xafab0010, 0x16000004, +0xafa80014, 0x8f420008, 0x10000002, 0xafa20018, +0xafaa0018, 0x8f42010c, 0x3c03021, 0xafa80098, +0xafa9009c, 0x40f809, 0xafaa00a0, 0x8fa80098, +0x8fa9009c, 0x8faa00a0, 0x1040ffc2, 0x3c02001f, +0x96230018, 0x3442ffff, 0x3c3f021, 0x5e102b, +0x10400003, 0x26310002, 0x8f42013c, 0x3c2f023, +0x26100001, 0x213102b, 0x1440ffda, 0x26520004, +0x8fb00064, 0x1000001a, 0x0, 0x96a3000a, +0x8fb00064, 0x70102b, 0x54400001, 0x608021, +0x8ea40000, 0x8ea50004, 0x8fab005c, 0x240c0002, +0xafac0010, 0x934305b5, 0xb1700, 0x10600003, +0x2223025, 0x3c020800, 0xc23025, 0xafa60014, +0x8f420008, 0xafa20018, 0x8f42010c, 0x3c03021, +0x40f809, 0x2003821, 0x1040fecb, 0x3c050007, +0x97ac0076, 0x11800007, 0x96a3000e, 0x934205b5, +0x14400004, 0x0, 0x97ab007e, 0x6c1825, +0xa6ab0016, 0x8fac006c, 0x3c02ffff, 0x1821024, +0x10400003, 0xc1402, 0x34630400, 0xa6a20014, +0xa6b0000a, 0x8fab0064, 0x560b0006, 0x3d0f021, +0x34620004, 0xafa00064, 0xa6a2000e, 0x1000000d, +0xa34005b5, 0x8fac0064, 0x3c02001f, 0x3442ffff, +0x5e102b, 0x1906023, 0xafac0064, 0xa6a3000e, +0x240b0001, 0x10400003, 0xa34b05b5, 0x8f42013c, +0x3c2f023, 0x8fab0054, 0x8fac004c, 0xad8b0000, +0x8fac0064, 0x1580feba, 0x0, 0x8fab0064, +0x1160001b, 0x0, 0x934205b5, 0x10400006, +0x0, 0xaf5e00c4, 0xaf4b00c0, 0x8fac006c, +0x1000000e, 0xaf4c00c8, 0x97ab0076, 0x1160000b, +0x34038100, 0x8fa20020, 0x8c46000c, 0xa443000c, +0x97ac007e, 0x8c440004, 0x8c450008, 0xa44c000e, +0xac440000, 0xac450004, 0xac460008, 0x8f42033c, +0x24420001, 0xaf42033c, 0x10000010, 0x8f42033c, +0x8fab006c, 0x3164ffff, 0x2484fffc, 0x801821, +0x8f440240, 0x8f450244, 0x8f460118, 0x1021, +0xa32821, 0xa3382b, 0x822021, 0x872021, +0xaf440240, 0xc0f809, 0xaf450244, 0x8fbf00c0, +0x8fbe00bc, 0x8fb500b8, 0x8fb300b4, 0x8fb200b0, +0x8fb100ac, 0x8fb000a8, 0x3e00008, 0x27bd00c8, 0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024, 0xafb00020, 0x8f43005c, 0x8f420058, 0x10620049, 0x0, 0x8f430058, 0x8f42005c, 0x622023, @@ -7051,23 +7031,23 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8f4202fc, 0x8f820044, 0x34420004, 0xaf820044, 0x8f4202f8, 0x24420001, 0xaf4202f8, 0x8f4202f8, 0x3e00008, 0x0, 0x3e00008, 0x0, -0x27bdffa0, 0xafbf0058, 0xafbe0054, 0xafb50050, -0xafb3004c, 0xafb20048, 0xafb10044, 0xafb00040, +0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb50058, +0xafb30054, 0xafb20050, 0xafb1004c, 0xafb00048, 0x8f4200fc, 0x24420001, 0xaf4200fc, 0x8f880128, 0x25020020, 0xaf820128, 0x8d030018, 0x30620070, 0x1040002e, 0x30620020, 0x10400004, 0x3c020010, 0x2c21024, 0x1040000d, 0x0, 0x30620040, 0x10400004, 0x3c020020, 0x2c21024, 0x10400007, -0x0, 0x30620010, 0x10400193, 0x3c020040, -0x2c21024, 0x14400190, 0x0, 0x8f820040, +0x0, 0x30620010, 0x104001a6, 0x3c020040, +0x2c21024, 0x144001a3, 0x0, 0x8f820040, 0x30420001, 0x14400008, 0x2021, 0x8c030104, 0x24020001, 0x50620005, 0x24040001, 0x8c020264, 0x10400003, 0x801021, 0x24040001, 0x801021, 0x10400006, 0x0, 0x8f4202fc, 0x24420001, -0xaf4202fc, 0x1000017c, 0x8f4202fc, 0x8f820044, +0xaf4202fc, 0x1000018f, 0x8f4202fc, 0x8f820044, 0x34420004, 0xaf820044, 0x8f4202f8, 0x24420001, -0xaf4202f8, 0x10000174, 0x8f4202f8, 0x30620002, -0x10400135, 0x3c020800, 0x8d0a001c, 0x1422024, +0xaf4202f8, 0x10000187, 0x8f4202f8, 0x30620002, +0x10400148, 0x3c020800, 0x8d0a001c, 0x1422024, 0xafaa0024, 0xa5702, 0xafaa0034, 0x8faa0024, 0x314affff, 0xafaa0024, 0x950a0016, 0xafaa002c, 0x8faa0034, 0x24020001, 0x15420007, 0x24020002, @@ -7078,248 +7058,238 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x8faa0024, 0xa1140, 0x24424cc0, 0x10000005, 0x2e2a821, 0x8faa0024, 0xa1180, 0x571021, 0x24550ce0, 0x96a2000e, 0x305efffc, 0x30420400, -0x144000c5, 0x8821, 0x10800004, 0x24091000, -0x97b1002e, 0x100000c1, 0x0, 0x8eb30018, -0x9663000c, 0x2c6205dd, 0x10400015, 0x2021, -0x32c20800, 0x10400015, 0x24020800, 0x96630014, -0x14620012, 0x3402aaaa, 0x9663000e, 0x14620007, -0x2821, 0x96630010, 0x24020300, 0x14620004, -0xa01021, 0x96620012, 0x2c450001, 0xa01021, -0x54400006, 0x24040016, 0x10000004, 0x0, -0x24020800, 0x50620001, 0x2404000e, 0x108000a2, -0x2649021, 0x92420000, 0x3042000f, 0x28080, -0x32c20100, 0x1040001e, 0x2501821, 0x3c020020, -0x43102b, 0x1440000e, 0x2402021, 0x2821, -0x94820000, 0x24840002, 0xa22821, 0x83102b, -0x1440fffb, 0x30a2ffff, 0x51c02, 0x622821, -0x51c02, 0x30a2ffff, 0x10000009, 0x622821, -0x8f47013c, 0x8f420110, 0x102842, 0x3c060020, -0x40f809, 0xafa80038, 0x3045ffff, 0x8fa80038, -0x50a00001, 0x3405ffff, 0x10000002, 0x37de0002, -0x2821, 0x32c20080, 0x1040007b, 0xa6a50010, -0x26430009, 0x3c02001f, 0x3442ffff, 0x43102b, -0x10400003, 0x0, 0x8f42013c, 0x621823, -0x90660000, 0x30c200ff, 0x38430006, 0x2c630001, -0x38420011, 0x2c420001, 0x621825, 0x1060006b, -0x24091000, 0x8821, 0x2602021, 0x94820000, -0x24840002, 0x2228821, 0x92102b, 0x1440fffb, -0x111c02, 0x3222ffff, 0x628821, 0x111c02, -0x3222ffff, 0x628821, 0x32c20200, 0x10400003, -0x26440006, 0x1000003e, 0x8021, 0x3c05001f, -0x34a5ffff, 0xa4102b, 0x10400003, 0x0, -0x8f42013c, 0x822023, 0x94820000, 0x30421fff, -0x10400004, 0x2644000c, 0x96420002, 0x10000030, -0x508023, 0x96420002, 0x26430014, 0x508023, -0x3c020020, 0x43102b, 0x1440000a, 0xd08021, -0x9642000c, 0x2028021, 0x9642000e, 0x96430010, -0x96440012, 0x2028021, 0x2038021, 0x10000020, -0x2048021, 0xa4102b, 0x10400003, 0x0, -0x8f42013c, 0x822023, 0x94820000, 0x24840002, -0x2028021, 0xa4102b, 0x10400003, 0x0, -0x8f42013c, 0x822023, 0x94820000, 0x24840002, -0x2028021, 0xa4102b, 0x10400003, 0x0, -0x8f42013c, 0x822023, 0x94820000, 0x24840002, -0x2028021, 0xa4102b, 0x10400003, 0x0, -0x8f42013c, 0x822023, 0x94820000, 0x2028021, -0x3c020100, 0x2c21024, 0x1040000c, 0x33c20004, -0x1040000a, 0x0, 0x9504000e, 0x2642021, -0xc003cc8, 0x2484fffc, 0x3042ffff, 0x2228821, -0x111c02, 0x3222ffff, 0x628821, 0x8faa002c, -0x1518823, 0x111402, 0x2228821, 0x2308821, -0x111402, 0x2228821, 0x3231ffff, 0x52200001, -0x3411ffff, 0x37de0001, 0x24091000, 0x33c20004, -0xa6b10012, 0x10400002, 0xa6be000e, 0x34098000, -0x8f480044, 0x8f440190, 0x8f450194, 0xafa90010, -0x8f490044, 0x84140, 0x1001821, 0xafa90014, -0x8f48000c, 0x2a03021, 0x24070020, 0xafa80018, -0x8f48010c, 0x1021, 0xa32821, 0xa3482b, -0x822021, 0x100f809, 0x892021, 0x1440000c, -0x0, 0x8f820128, 0x8faa0024, 0x3c040001, -0x24843944, 0xafaa0014, 0xafa20010, 0x8f860124, -0x8f870120, 0x3c050007, 0xc0029d3, 0x34a59920, -0x8f420358, 0x2442ffff, 0xaf420358, 0x8f420044, -0x8f430088, 0x24420001, 0x431024, 0xaf420044, -0x8faa0034, 0x8f440358, 0x24020001, 0x15420006, -0x24020002, 0x8f42034c, 0x2442ffff, 0xaf42034c, -0x10000049, 0x8f42034c, 0x15420006, 0x0, -0x8f420354, 0x2442ffff, 0xaf420354, 0x10000042, -0x8f420354, 0x8f420350, 0x2442ffff, 0xaf420350, -0x1000003d, 0x8f420350, 0x30621000, 0x10400005, -0x30628000, 0x8f420078, 0x24420001, 0x10000036, -0xaf420078, 0x10400034, 0x0, 0x8f420078, -0x24420001, 0xaf420078, 0x8c030240, 0x43102b, -0x1440002d, 0x24070008, 0x8f440158, 0x8f45015c, -0x8f430044, 0x8f48000c, 0x8f860120, 0x24020040, -0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x14400011, 0x24020001, -0x3c010001, 0x370821, 0xa02240f2, 0x8f820124, -0xafa20010, 0x8f820128, 0x3c040001, 0x248438c8, -0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009, -0xc0029d3, 0x34a51300, 0x1000000b, 0x0, -0x8f4202f4, 0x24420001, 0xaf4202f4, 0x8f4202f4, -0x8f420044, 0xaf42007c, 0x3c010001, 0x370821, -0xa02040f2, 0xaf400078, 0x8f420308, 0x24420001, -0xaf420308, 0x8f420308, 0x8fbf0058, 0x8fbe0054, -0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044, -0x8fb00040, 0x3e00008, 0x27bd0060, 0x3e00008, +0x144000d8, 0x8821, 0x10800004, 0x24091000, +0x97b1002e, 0x100000d4, 0x0, 0x8eb30018, +0x966a000c, 0xa7aa003e, 0x97a3003e, 0x2c6205dd, +0x10400015, 0x2021, 0x32c20800, 0x10400015, +0x24020800, 0x96630014, 0x14620012, 0x3402aaaa, +0x9663000e, 0x14620007, 0x2821, 0x96630010, +0x24020300, 0x14620004, 0xa01021, 0x96620012, +0x2c450001, 0xa01021, 0x54400006, 0x24040016, +0x10000004, 0x0, 0x24020800, 0x50620001, +0x2404000e, 0x108000b3, 0x2649021, 0x92420000, +0x3042000f, 0x28080, 0x32c20100, 0x1040001e, +0x2501821, 0x3c020020, 0x43102b, 0x1440000e, +0x2402021, 0x2821, 0x94820000, 0x24840002, +0xa22821, 0x83102b, 0x1440fffb, 0x30a2ffff, +0x51c02, 0x622821, 0x51c02, 0x30a2ffff, +0x10000009, 0x622821, 0x8f47013c, 0x8f420110, +0x102842, 0x3c060020, 0x40f809, 0xafa80040, +0x3045ffff, 0x8fa80040, 0x50a00001, 0x3405ffff, +0x10000002, 0x37de0002, 0x2821, 0x32c20080, +0x1040008c, 0xa6a50010, 0x26430009, 0x3c02001f, +0x3442ffff, 0x43102b, 0x10400003, 0x0, +0x8f42013c, 0x621823, 0x90660000, 0x30c200ff, +0x38430006, 0x2c630001, 0x38420011, 0x2c420001, +0x621825, 0x1060007b, 0x24020800, 0x8821, +0x97a3003e, 0x1462000f, 0x2602021, 0x96710000, +0x96620002, 0x96630004, 0x96640006, 0x2228821, +0x2238821, 0x2248821, 0x96620008, 0x9663000a, +0x9664000c, 0x2228821, 0x2238821, 0x10000007, +0x2248821, 0x94820000, 0x24840002, 0x2228821, +0x92102b, 0x1440fffb, 0x0, 0x111c02, +0x3222ffff, 0x628821, 0x111c02, 0x3222ffff, +0x628821, 0x32c20200, 0x10400003, 0x26440006, +0x1000003e, 0x8021, 0x3c05001f, 0x34a5ffff, +0xa4102b, 0x10400003, 0x0, 0x8f42013c, +0x822023, 0x94820000, 0x30421fff, 0x10400004, +0x2644000c, 0x96420002, 0x10000030, 0x508023, +0x96420002, 0x26430014, 0x508023, 0x3c020020, +0x43102b, 0x1440000a, 0xd08021, 0x9642000c, +0x2028021, 0x9642000e, 0x96430010, 0x96440012, +0x2028021, 0x2038021, 0x10000020, 0x2048021, +0xa4102b, 0x10400003, 0x0, 0x8f42013c, +0x822023, 0x94820000, 0x24840002, 0x2028021, +0xa4102b, 0x10400003, 0x0, 0x8f42013c, +0x822023, 0x94820000, 0x24840002, 0x2028021, +0xa4102b, 0x10400003, 0x0, 0x8f42013c, +0x822023, 0x94820000, 0x24840002, 0x2028021, +0xa4102b, 0x10400003, 0x0, 0x8f42013c, +0x822023, 0x94820000, 0x2028021, 0x3c020100, +0x2c21024, 0x1040000c, 0x33c20004, 0x1040000a, +0x0, 0x9504000e, 0x2642021, 0xc003c24, +0x2484fffc, 0x3042ffff, 0x2228821, 0x111c02, +0x3222ffff, 0x628821, 0x8faa002c, 0x1518823, +0x111402, 0x2228821, 0x2308821, 0x111402, +0x2228821, 0x3231ffff, 0x52200001, 0x3411ffff, +0x37de0001, 0x24091000, 0x33c20004, 0xa6b10012, +0x10400002, 0xa6be000e, 0x34098000, 0x8f480044, +0x8f440190, 0x8f450194, 0xafa90010, 0x8f490044, +0x84140, 0x1001821, 0xafa90014, 0x8f48000c, +0x2a03021, 0x24070020, 0xafa80018, 0x8f48010c, +0x1021, 0xa32821, 0xa3482b, 0x822021, +0x100f809, 0x892021, 0x1440000c, 0x0, +0x8f820128, 0x8faa0024, 0x3c040001, 0x24843988, +0xafaa0014, 0xafa20010, 0x8f860124, 0x8f870120, +0x3c050007, 0xc0029bb, 0x34a59920, 0x8f420358, +0x2442ffff, 0xaf420358, 0x8f420044, 0x8f430088, +0x24420001, 0x431024, 0xaf420044, 0x8faa0034, +0x8f440358, 0x24020001, 0x15420006, 0x24020002, +0x8f42034c, 0x2442ffff, 0xaf42034c, 0x10000049, +0x8f42034c, 0x15420006, 0x0, 0x8f420354, +0x2442ffff, 0xaf420354, 0x10000042, 0x8f420354, +0x8f420350, 0x2442ffff, 0xaf420350, 0x1000003d, +0x8f420350, 0x30621000, 0x10400005, 0x30628000, +0x8f420078, 0x24420001, 0x10000036, 0xaf420078, +0x10400034, 0x0, 0x8f420078, 0x24420001, +0xaf420078, 0x8c030240, 0x43102b, 0x1440002d, +0x24070008, 0x8f440158, 0x8f45015c, 0x8f430044, +0x8f48000c, 0x8f860120, 0x24020040, 0xafa20010, +0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, +0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, +0x370821, 0xa02240f2, 0x8f820124, 0xafa20010, +0x8f820128, 0x3c040001, 0x2484390c, 0xafa20014, +0x8f460044, 0x8f870120, 0x3c050009, 0xc0029bb, +0x34a51300, 0x1000000b, 0x0, 0x8f4202f4, +0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8f420044, +0xaf42007c, 0x3c010001, 0x370821, 0xa02040f2, +0xaf400078, 0x8f420308, 0x24420001, 0xaf420308, +0x8f420308, 0x8fbf0060, 0x8fbe005c, 0x8fb50058, +0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, +0x3e00008, 0x27bd0068, 0x3e00008, 0x0, 0x0, 0x0, 0x0, 0x8f420130, 0xaf8200c0, 0x8f420130, 0xaf8200c4, 0x8f420130, 0xaf8200c8, 0x8f42012c, 0xaf8200d0, 0x8f42012c, 0xaf8200d4, 0x8f42012c, 0x3e00008, 0xaf8200d8, 0x27bdffe0, 0x27840208, 0x24050200, 0xafbf0018, -0xc002a57, 0x24060008, 0x8c020204, 0xc003dee, +0xc002a3f, 0x24060008, 0x8c020204, 0xc003d4a, 0xaf820210, 0x2021, 0x8c060248, 0x24020004, -0x3c010001, 0xac223d18, 0xc004878, 0x24050004, -0x3c020001, 0x8c423d14, 0x30420001, 0x10400007, -0x24020001, 0x3c010001, 0xac223d18, 0x2021, -0x24050001, 0xc004878, 0x3c06601b, 0x3c040001, -0x24843a00, 0x8f420144, 0x8f430148, 0x3c050008, +0x3c010001, 0xac223d88, 0xc0047d4, 0x24050004, +0x3c020001, 0x8c423d84, 0x30420001, 0x10400007, +0x24020001, 0x3c010001, 0xac223d88, 0x2021, +0x24050001, 0xc0047d4, 0x3c06601b, 0x3c040001, +0x24843a50, 0x8f420144, 0x8f430148, 0x3c050008, 0x8f46014c, 0x21640, 0x31940, 0x34630403, 0x431025, 0x633c0, 0x461025, 0xaf82021c, 0xafa00010, 0xafa00014, 0x8f86021c, 0x34a50200, -0xc0029d3, 0x3821, 0x3c010001, 0xac203d10, -0x3c010001, 0xac203d28, 0x8fbf0018, 0x3e00008, +0xc0029bb, 0x3821, 0x3c010001, 0xac203d80, +0x3c010001, 0xac203d98, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0, 0x3c050008, 0x34a50300, 0xafbf0018, 0xafa00010, 0xafa00014, 0x8f860200, -0x3c040001, 0x24843a0c, 0xc0029d3, 0x3821, +0x3c040001, 0x24843a5c, 0xc0029bb, 0x3821, 0x8f420400, 0x24420001, 0xaf420400, 0x8f420400, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c, 0xafb00018, 0x8f420394, 0x24420001, 0xaf420394, 0x8f420394, 0x8f900220, -0x8f4303a8, 0x3c020001, 0x8c423d28, 0x3c040001, -0x24843a18, 0x3c050008, 0xafa20014, 0xafa30010, -0x8f4703ac, 0x34a50400, 0xc0029d3, 0x2003021, -0x3c024000, 0x2021024, 0x104000e1, 0x3c040100, -0x8f4203ac, 0x24420001, 0xaf4203ac, 0x8f4203ac, -0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, -0x34420004, 0xaf820220, 0x8f8200e0, 0x8f8300c4, -0x3c02001f, 0x3442ffff, 0x24690008, 0x49102b, -0x10400003, 0x0, 0x8f42013c, 0x1224823, -0x8f8700c8, 0x8f840120, 0x8f830124, 0x10000005, -0x5821, 0x8f42012c, 0x62102b, 0x50400001, -0x27634800, 0x1083000d, 0x316200ff, 0x8c620018, -0x2442ffff, 0x2c420002, 0x5040fff6, 0x24630020, -0x8f4203c0, 0x240b0001, 0x24420001, 0xaf4203c0, -0x8f4203c0, 0x8c670008, 0x316200ff, 0x14400078, -0x0, 0x934205b5, 0x14400075, 0x0, -0x8f8500e4, 0x8f8200e0, 0x2403fff8, 0x433024, -0xc51023, 0x218c3, 0x4620001, 0x24630100, -0x8f8a00c4, 0x10600005, 0x24020001, 0x10620009, -0x0, 0x10000021, 0x0, 0x8f4203b0, -0x1403821, 0x24420001, 0xaf4203b0, 0x10000060, +0x8f8200e0, 0xafa20010, 0x8f8200e4, 0xafa20014, +0x8f8600c4, 0x8f8700c8, 0x3c040001, 0x24843a68, +0xc0029bb, 0x2002821, 0x3c044000, 0x2041024, +0x504000ae, 0x3c040100, 0x8f4203ac, 0x24420001, +0xaf4203ac, 0x8f4203ac, 0x8f8700c4, 0x8f8300c8, +0x8f42013c, 0x671823, 0x43102b, 0x10400003, +0x0, 0x8f42013c, 0x621821, 0x10600005, +0x0, 0x8f420140, 0x43102b, 0x10400007, +0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, +0x431024, 0x100000cc, 0x441025, 0x8f820220, +0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004, +0xaf820220, 0x8f8600c8, 0x8f840120, 0x8f830124, +0x10000005, 0x2821, 0x14620002, 0x24620020, +0x27624800, 0x401821, 0x1064000c, 0x30a200ff, +0x8c620018, 0x30420003, 0x1040fff7, 0x27624fe0, +0x8f4203c0, 0x24050001, 0x24420001, 0xaf4203c0, +0x8f4203c0, 0x8c660008, 0x30a200ff, 0x14400058, +0x0, 0x934205b5, 0x14400055, 0x0, +0x8f8700c4, 0x8f8800e0, 0x8f8400e4, 0x2402fff8, +0x1024024, 0x1041023, 0x218c3, 0x4620001, +0x24630200, 0x10600005, 0x24020001, 0x10620009, +0x0, 0x1000001f, 0x0, 0x8f4203b0, +0xe03021, 0x24420001, 0xaf4203b0, 0x10000040, 0x8f4203b0, 0x8f4203b4, 0x24420001, 0xaf4203b4, -0x8ca70000, 0x8f42013c, 0x8f4303b4, 0x1471823, +0x8c860000, 0x8f42013c, 0x8f4303b4, 0xe61823, 0x43102b, 0x10400004, 0x2c62233f, 0x8f42013c, -0x621821, 0x2c62233f, 0x14400051, 0x3c020100, -0xaca20004, 0x8f8200e8, 0x24420008, 0xaf8200e8, -0x8f8200e8, 0x8f8200e4, 0x1403821, 0x24420008, -0xaf8200e4, 0x10000046, 0x8f8200e4, 0x8f4203b8, -0x24420001, 0xaf4203b8, 0x8ca80000, 0x8f42013c, -0x8f4303b8, 0x1092023, 0x44102b, 0x10400003, -0x0, 0x8f42013c, 0x822021, 0x8f420140, -0x44102b, 0x10400003, 0x3c030100, 0x10000034, -0x1003821, 0x8ca20004, 0x431025, 0xaca20004, -0x8f8200e4, 0x24450008, 0xaf8500e4, 0x8f8500e4, -0x10a60025, 0x3c080100, 0x8f4201fc, 0x24420001, -0xaf4201fc, 0x8ca20004, 0x8f4301fc, 0x481024, -0x1440000e, 0x0, 0x8ca30000, 0x8f42013c, -0x692023, 0x44102b, 0x10400003, 0x0, -0x8f42013c, 0x822021, 0x8f420140, 0x44102b, -0x10400006, 0x0, 0x603821, 0x8f420140, -0x44102b, 0x1440000a, 0x0, 0x8ca20004, -0x481025, 0xaca20004, 0x8f8200e4, 0x24450008, -0xaf8500e4, 0x8f8500e4, 0x14a6ffdf, 0x0, -0x14a60005, 0x0, 0x1403821, 0xaf8600e4, -0x10000003, 0xaf8600e8, 0xaf8500e4, 0xaf8500e8, -0x8f8300c8, 0x8f42013c, 0x692023, 0x44102b, -0x10400003, 0x0, 0x8f42013c, 0x822021, -0x8f420140, 0x82102b, 0x50400008, 0x5821, -0x8f42013c, 0xe92023, 0x44102b, 0x10400003, -0x0, 0x8f42013c, 0x822021, 0x8f420140, -0x82102b, 0x10400006, 0x316200ff, 0x1440001b, -0x3c02fdff, 0x934205b5, 0x14400018, 0x3c02fdff, -0xaf8700c8, 0x8f8400c8, 0x8f8300c4, 0x8f42013c, -0x832023, 0x44102b, 0x10400003, 0x0, -0x8f42013c, 0x822021, 0x8f420140, 0x2c830001, -0x44102b, 0x431025, 0x50400008, 0x3c02fdff, -0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, -0x3c034000, 0x10000046, 0x431025, 0x3442ffff, -0x8f4303bc, 0x282a024, 0x24020001, 0xa34205b1, -0x24630001, 0xaf4303bc, 0x1000003e, 0x8f4203bc, -0x2041024, 0x10400013, 0x3c110200, 0x8f420398, -0x24420001, 0xaf420398, 0x8f420398, 0x8f820220, -0x3c0308ff, 0x3463ffff, 0x431024, 0x441025, -0xaf820220, 0x3c020004, 0x2021024, 0x14400005, -0x3c110200, 0xc003bad, 0x0, 0x10000029, -0x0, 0x2111024, 0x50400008, 0x3c110400, -0x8f42039c, 0x24420001, 0xaf42039c, 0xc003bad, -0x8f42039c, 0x10000019, 0x0, 0x2111024, -0x1040001c, 0x0, 0x8f830224, 0x24021402, -0x14620009, 0x3c050008, 0x3c040001, 0x24843a24, -0xafa00010, 0xafa00014, 0x8f860224, 0x34a50500, -0xc0029d3, 0x3821, 0x8f4203a0, 0x24420001, -0xaf4203a0, 0x8f4203a0, 0x8f820220, 0x2002021, -0x34420002, 0xc004610, 0xaf820220, 0x8f820220, -0x3c0308ff, 0x3463ffff, 0x431024, 0x511025, -0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x3e00008, 0x0, -0x3c020001, 0x8c423d28, 0x27bdffb0, 0xafbf0048, -0xafbe0044, 0xafb50040, 0xafb3003c, 0xafb20038, -0xafb10034, 0x1040000f, 0xafb00030, 0x3c040001, -0x24843a30, 0x3c050008, 0xafa00010, 0xafa00014, -0x8f860220, 0x34a50600, 0x24020001, 0x3c010001, -0xac203d28, 0x3c010001, 0xac223d1c, 0xc0029d3, -0x3821, 0x3c037fff, 0x8c020268, 0x3463ffff, -0x3c04fdff, 0x431024, 0xac020268, 0x8f420004, -0x3484ffff, 0x30420002, 0x10400092, 0x284a024, -0x3c040600, 0x34842000, 0x8f420004, 0x2821, -0x2403fffd, 0x431024, 0xaf420004, 0xafa40020, -0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, -0xafaa002c, 0x27c50001, 0x8c020228, 0xa09021, -0x1642000e, 0x1e38c0, 0x8f42032c, 0x24420001, -0xaf42032c, 0x8f42032c, 0x8c020228, 0x3c040001, -0x248439c8, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006d, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, +0x621821, 0x2c62233f, 0x14400031, 0x0, +0x8f4201fc, 0x24420001, 0xaf4201fc, 0x8f4201fc, +0xe03021, 0x24820008, 0xaf8200e4, 0x10000028, +0xaf8200e8, 0x8f4203b8, 0x24420001, 0xaf4203b8, +0x8f4203b8, 0x8c850000, 0x8f42013c, 0xa71823, +0x43102b, 0x10400003, 0x0, 0x8f42013c, +0x621821, 0x8f420140, 0x43102b, 0x5440000a, +0xa03021, 0x8f4201fc, 0x24420001, 0xaf4201fc, +0x8f4201fc, 0x24820008, 0xaf8200e4, 0x8f8400e4, +0x1488ffec, 0xaf8400e8, 0x1488000d, 0x27623000, +0x14820002, 0x2482fff8, 0x27623ff8, 0x94430006, +0x3c02001f, 0x3442ffff, 0xc33021, 0x46102b, +0x10400003, 0x0, 0x8f42013c, 0xc23023, +0xaf8600c8, 0x8f8300c4, 0x8f42013c, 0xc31823, +0x43102b, 0x10400003, 0x0, 0x8f42013c, +0x621821, 0x10600005, 0x0, 0x8f420140, +0x43102b, 0x50400008, 0x3c02fdff, 0x8f820220, +0x3c0308ff, 0x3463fffb, 0x431024, 0x3c034000, +0x10000041, 0x431025, 0x3442ffff, 0x8f4303bc, +0x282a024, 0x24020001, 0xa34205b1, 0x24630001, +0xaf4303bc, 0x10000039, 0x8f4203bc, 0x2041024, +0x1040000e, 0x3c110200, 0x8f420398, 0x24420001, +0xaf420398, 0x8f420398, 0x8f820220, 0x3c0308ff, +0x3463ffff, 0x431024, 0x441025, 0xc003b0b, +0xaf820220, 0x10000029, 0x0, 0x2111024, +0x50400008, 0x3c110400, 0x8f42039c, 0x24420001, +0xaf42039c, 0xc003b0b, 0x8f42039c, 0x10000019, +0x0, 0x2111024, 0x1040001c, 0x0, +0x8f830224, 0x24021402, 0x14620009, 0x3c050008, +0x3c040001, 0x24843a74, 0xafa00010, 0xafa00014, +0x8f860224, 0x34a50500, 0xc0029bb, 0x3821, +0x8f4203a0, 0x24420001, 0xaf4203a0, 0x8f4203a0, +0x8f820220, 0x2002021, 0x34420002, 0xc00456c, +0xaf820220, 0x8f820220, 0x3c0308ff, 0x3463ffff, +0x431024, 0x511025, 0xaf820220, 0x8fbf0020, +0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028, +0x3e00008, 0x0, 0x3c020001, 0x8c423d98, +0x27bdffb0, 0xafbf0048, 0xafbe0044, 0xafb50040, +0xafb3003c, 0xafb20038, 0xafb10034, 0x1040000f, +0xafb00030, 0x3c040001, 0x24843a80, 0x3c050008, +0xafa00010, 0xafa00014, 0x8f860220, 0x34a50600, +0x24020001, 0x3c010001, 0xac203d98, 0x3c010001, +0xac223d8c, 0xc0029bb, 0x3821, 0x3c037fff, +0x8c020268, 0x3463ffff, 0x3c04fdff, 0x431024, +0xac020268, 0x8f420004, 0x3484ffff, 0x30420002, +0x10400092, 0x284a024, 0x3c040600, 0x34842000, +0x8f420004, 0x2821, 0x2403fffd, 0x431024, +0xaf420004, 0xafa40020, 0x8f5e0018, 0x27aa0020, +0x240200ff, 0x13c20002, 0xafaa002c, 0x27c50001, +0x8c020228, 0xa09021, 0x1642000e, 0x1e38c0, +0x8f42032c, 0x24420001, 0xaf42032c, 0x8f42032c, +0x8c020228, 0x3c040001, 0x24843a18, 0x3c050009, +0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d, +0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, +0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, +0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b, +0x9821, 0xe08821, 0x263504c0, 0x8f440168, +0x8f45016c, 0x2201821, 0x240a0004, 0xafaa0010, +0xafb20014, 0x8f48000c, 0x1021, 0x2f53021, +0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, +0xa3482b, 0x822021, 0x100f809, 0x892021, +0x54400006, 0x24130001, 0x8f820054, 0x2021023, +0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff, +0x54400017, 0xaf520018, 0x8f420368, 0x24420001, +0xaf420368, 0x8f420368, 0x8f820120, 0x8faa002c, +0xafa20010, 0x8f820124, 0x3c040001, 0x24843a24, +0x3c050009, 0xafa20014, 0x8d460000, 0x10000035, +0x34a50600, 0x8f4202f8, 0x24130001, 0x24420001, +0xaf4202f8, 0x8f4202f8, 0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440168, 0x8f45016c, 0x2201821, -0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, -0x8f420368, 0x24420001, 0xaf420368, 0x8f420368, -0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124, -0x3c040001, 0x248439d4, 0x3c050009, 0xafa20014, -0x8d460000, 0x10000035, 0x34a50600, 0x8f4202f8, -0x24130001, 0x24420001, 0xaf4202f8, 0x8f4202f8, -0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400016, -0x9821, 0x3c150020, 0x24110010, 0x8f42000c, -0x8f440150, 0x8f450154, 0x8f860120, 0xafb10010, -0xafb20014, 0x551025, 0xafa20018, 0x8f42010c, -0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3, -0x0, 0x8f820054, 0x2021023, 0x2c4203e9, -0x1440ffee, 0x0, 0x326200ff, 0x14400011, -0x0, 0x8f420368, 0x24420001, 0xaf420368, -0x8f420368, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x248439dc, 0x3c050009, -0xafa20014, 0x8d460000, 0x34a50700, 0xc0029d3, -0x3c03821, 0x8f4202dc, 0x24420001, 0xaf4202dc, -0x8f4202dc, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, -0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, -0x3e00008, 0x27bd0050, 0x3c020001, 0x8c423d28, -0x27bdffe0, 0x1440000d, 0xafbf0018, 0x3c040001, -0x24843a3c, 0x3c050008, 0xafa00010, 0xafa00014, -0x8f860220, 0x34a50700, 0x24020001, 0x3c010001, -0xac223d28, 0xc0029d3, 0x3821, 0x3c020004, -0x2c21024, 0x10400008, 0x2021, 0x8f820220, -0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008, -0xaf820220, 0x2021, 0xc004981, 0x24050004, -0xac020268, 0x8fbf0018, 0x3e00008, 0x27bd0020, -0x0, 0x0, 0x0, 0x86102b, +0x2c4203e9, 0x10400016, 0x9821, 0x3c150020, +0x24110010, 0x8f42000c, 0x8f440150, 0x8f450154, +0x8f860120, 0xafb10010, 0xafb20014, 0x551025, +0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, +0x24c6001c, 0x1440ffe3, 0x0, 0x8f820054, +0x2021023, 0x2c4203e9, 0x1440ffee, 0x0, +0x326200ff, 0x14400011, 0x0, 0x8f420368, +0x24420001, 0xaf420368, 0x8f420368, 0x8f820120, +0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001, +0x24843a2c, 0x3c050009, 0xafa20014, 0x8d460000, +0x34a50700, 0xc0029bb, 0x3c03821, 0x8f4202dc, +0x24420001, 0xaf4202dc, 0x8f4202dc, 0x8fbf0048, +0x8fbe0044, 0x8fb50040, 0x8fb3003c, 0x8fb20038, +0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050, +0x3c020001, 0x8c423d98, 0x27bdffe0, 0x1440000d, +0xafbf0018, 0x3c040001, 0x24843a8c, 0x3c050008, +0xafa00010, 0xafa00014, 0x8f860220, 0x34a50700, +0x24020001, 0x3c010001, 0xac223d98, 0xc0029bb, +0x3821, 0x3c020004, 0x2c21024, 0x10400008, +0x2021, 0x8f820220, 0x3c0308ff, 0x3463ffff, +0x431024, 0x34420008, 0xaf820220, 0x2021, +0xc0048dd, 0x24050004, 0xac020268, 0x8fbf0018, +0x3e00008, 0x27bd0020, 0x0, 0x86102b, 0x50400001, 0x872023, 0xc41023, 0x24843, 0x125102b, 0x1040001b, 0x91040, 0x824021, 0x88102b, 0x10400007, 0x1821, 0x94820000, @@ -7359,7 +7329,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x90a20000, 0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x41c02, 0x3082ffff, 0x622021, 0x3e00008, 0x3082ffff, 0x0, 0x8f820220, -0x34420002, 0xaf820220, 0x3c020001, 0x8c425f28, +0x34420002, 0xaf820220, 0x3c020001, 0x8c425f98, 0x30424000, 0x10400054, 0x24040001, 0x8f820200, 0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd, 0x621824, 0xaf830200, 0xaf840204, 0x8f830054, @@ -7406,501 +7376,501 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x43102b, 0x14400006, 0x3c026000, 0x3c024000, 0x10620008, 0x24020800, 0x10000008, 0x0, 0x10620004, 0x24020800, 0x10000004, 0x0, -0x24020700, 0x3c010001, 0xac223d2c, 0x3e00008, +0x24020700, 0x3c010001, 0xac223d9c, 0x3e00008, 0x0, 0x27bdffc8, 0xafbf0034, 0xafb20030, -0xafb1002c, 0xafb00028, 0x3c010001, 0xc0045ed, -0xac203d14, 0x24040001, 0x2821, 0x27a60020, -0x34028000, 0xc00420a, 0xa7a20020, 0x8f830054, +0xafb1002c, 0xafb00028, 0x3c010001, 0xc004549, +0xac203d84, 0x24040001, 0x2821, 0x27a60020, +0x34028000, 0xc004166, 0xa7a20020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, -0x24050001, 0xc0041c8, 0x27a60020, 0x8f830054, +0x24050001, 0xc004124, 0x27a60020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, -0x24050001, 0xc0041c8, 0x27a60020, 0x8f830054, +0x24050001, 0xc004124, 0x27a60020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, -0x24050002, 0xc0041c8, 0x27a60018, 0x8f830054, +0x24050002, 0xc004124, 0x27a60018, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, -0x24050003, 0xc0041c8, 0x27a6001a, 0x97a20020, -0x10400029, 0x24020001, 0x3c020001, 0x8c423d14, -0x97a30018, 0x34420001, 0x3c010001, 0xac223d14, -0x24020015, 0x14620009, 0x0, 0x97a2001a, -0x3843f423, 0x2c630001, 0x3842f430, 0x2c420001, -0x621825, 0x14600018, 0x24020003, 0x97a30018, -0x24027810, 0x14620014, 0x24020002, 0x97a3001a, -0x24020001, 0x14620010, 0x24020002, 0x1000000e, -0x24020004, 0x3c020001, 0x8c423d14, 0x34420008, -0x3c010001, 0xac223d14, 0x10000058, 0x24020004, -0x3c020001, 0x8c423d14, 0x34420004, 0x3c010001, -0x100000a9, 0xac223d14, 0x3c010001, 0xac223e70, -0x24020e00, 0xaf820238, 0x8f840054, 0x8f820054, -0x24030008, 0x3c010001, 0xac233d18, 0x10000002, -0x248401f4, 0x8f820054, 0x821023, 0x2c4201f5, -0x1440fffc, 0x3c0200c8, 0x344201fb, 0xaf820238, -0x8f830054, 0x8f820054, 0x10000002, 0x246301f4, -0x8f820054, 0x621023, 0x2c4201f5, 0x1440fffc, -0x8021, 0x24120001, 0x24110009, 0xc0040e8, -0x0, 0x3c010001, 0xac323d30, 0xc004194, -0x0, 0x3c020001, 0x8c423d30, 0x1451fffb, -0x3c0200c8, 0x344201f6, 0xaf820238, 0x8f830054, -0x8f820054, 0x10000002, 0x2463000a, 0x8f820054, -0x621023, 0x2c42000b, 0x1440fffc, 0x0, +0x24050003, 0xc004124, 0x27a6001a, 0x97a20020, +0x1040002a, 0x24020001, 0x3c020001, 0x8c423d84, +0x97a30018, 0x34420001, 0x3c010001, 0xac223d84, +0x24020015, 0x1462000a, 0x0, 0x97a2001a, +0x3042fff0, 0x3843f420, 0x2c630001, 0x3842f430, +0x2c420001, 0x621825, 0x14600018, 0x24020003, +0x97a30018, 0x24027810, 0x14620014, 0x24020002, +0x97a2001a, 0x3042fff0, 0x14400010, 0x24020002, +0x1000000e, 0x24020004, 0x3c020001, 0x8c423d84, +0x34420008, 0x3c010001, 0xac223d84, 0x10000058, +0x24020004, 0x3c020001, 0x8c423d84, 0x34420004, +0x3c010001, 0x100000a9, 0xac223d84, 0x3c010001, +0xac223ee0, 0x24020e00, 0xaf820238, 0x8f840054, +0x8f820054, 0x24030008, 0x3c010001, 0xac233d88, +0x10000002, 0x248401f4, 0x8f820054, 0x821023, +0x2c4201f5, 0x1440fffc, 0x3c0200c8, 0x344201fb, +0xaf820238, 0x8f830054, 0x8f820054, 0x10000002, +0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5, +0x1440fffc, 0x8021, 0x24120001, 0x24110009, +0xc004045, 0x0, 0x3c010001, 0xac323da0, +0xc0040f2, 0x0, 0x3c020001, 0x8c423da0, +0x1451fffb, 0x3c0200c8, 0x344201f6, 0xaf820238, +0x8f830054, 0x8f820054, 0x10000002, 0x2463000a, +0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc, +0x0, 0x8f820220, 0x24040001, 0x34420002, +0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd, +0x621824, 0xaf830200, 0xaf840204, 0x8f830054, +0x8f820054, 0x10000002, 0x24630001, 0x8f820054, +0x621023, 0x2c420002, 0x1440fffc, 0x0, +0x8f820224, 0x14440005, 0x34028000, 0x42040, +0xa4102b, 0x1040fff0, 0x34028000, 0x1082ffa6, +0x26100001, 0x2e020014, 0x1440ffcd, 0x24020004, +0x3c010001, 0xac223d88, 0x8021, 0x24120009, +0x3c11ffff, 0x36313f7f, 0xc004045, 0x0, +0x24020001, 0x3c010001, 0xac223da0, 0xc0040f2, +0x0, 0x3c020001, 0x8c423da0, 0x1452fffb, +0x0, 0x8f820044, 0x511024, 0x34425080, +0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, +0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, +0x1440fffc, 0x0, 0x8f820044, 0x511024, +0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054, +0x10000002, 0x2463000a, 0x8f820054, 0x621023, +0x2c42000b, 0x1440fffc, 0x0, 0x8f820220, +0x3c03f700, 0x431025, 0xaf820220, 0x8f830054, +0x8f820054, 0x10000002, 0x24630064, 0x8f820054, +0x621023, 0x2c420065, 0x1440fffc, 0x0, 0x8f820220, 0x24040001, 0x34420002, 0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd, 0x621824, 0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820224, 0x14440005, 0x34028000, 0x42040, 0xa4102b, -0x1040fff0, 0x34028000, 0x1082ffa6, 0x26100001, -0x2e020014, 0x1440ffcd, 0x24020004, 0x3c010001, -0xac223d18, 0x8021, 0x24120009, 0x3c11ffff, -0x36313f7f, 0xc0040e8, 0x0, 0x24020001, -0x3c010001, 0xac223d30, 0xc004194, 0x0, -0x3c020001, 0x8c423d30, 0x1452fffb, 0x0, -0x8f820044, 0x511024, 0x34425080, 0xaf820044, -0x8f830054, 0x8f820054, 0x10000002, 0x2463000a, -0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc, -0x0, 0x8f820044, 0x511024, 0x3442f080, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, -0x1440fffc, 0x0, 0x8f820220, 0x3c03f700, -0x431025, 0xaf820220, 0x8f830054, 0x8f820054, -0x10000002, 0x24630064, 0x8f820054, 0x621023, -0x2c420065, 0x1440fffc, 0x0, 0x8f820220, -0x24040001, 0x34420002, 0xaf820220, 0x8f830200, -0x24057fff, 0x2402fffd, 0x621824, 0xaf830200, -0xaf840204, 0x8f830054, 0x8f820054, 0x10000002, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820224, 0x14440005, -0x34028000, 0x42040, 0xa4102b, 0x1040fff0, -0x34028000, 0x1082ff56, 0x26100001, 0x2e020064, -0x1440ffb0, 0x0, 0x3c020001, 0x8c423d14, -0x30420004, 0x14400007, 0x3c08fff0, 0x8f820044, -0x3c03ffff, 0x34633f7f, 0x431024, 0xaf820044, -0x3c08fff0, 0x3508bdc0, 0x8f830054, 0x97a60018, -0x3c070001, 0x8ce73e70, 0x3c040001, 0x24843b00, -0x24020001, 0x3c010001, 0xac223d1c, 0xafa60010, -0x3c060001, 0x8cc63d14, 0x97a2001a, 0x3c05000d, -0x34a50100, 0x3c010001, 0xac203d18, 0x681821, -0x3c010001, 0xac233e68, 0xc0029d3, 0xafa20014, -0x8fbf0034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, -0x3e00008, 0x27bd0038, 0x27bdffe8, 0x24070004, -0x3c040001, 0x8c843d18, 0x3021, 0x24020001, -0x1482000a, 0xafbf0010, 0x3c020001, 0x8c425f2c, -0x3c050004, 0x30428000, 0x1040000c, 0x34a593e0, -0x3c05000f, 0x10000009, 0x34a54240, 0x3c020001, -0x8c425f2c, 0x3c05000f, 0x30428000, 0x10400003, -0x34a54240, 0x3c05001e, 0x34a58480, 0x3c020001, -0x8c423e68, 0x8f830054, 0x451021, 0x431023, -0x45102b, 0x1440002e, 0x0, 0x3c020001, -0x8c423d20, 0x1440002a, 0x2cc20001, 0x7182b, -0x431024, 0x1040001d, 0x0, 0x3c090001, -0x8d293d14, 0x240b0001, 0x3c054000, 0x3c080001, -0x25085f2c, 0x250afffc, 0x42042, 0x14800002, -0x24e7ffff, 0x24040008, 0x891024, 0x5040000b, -0x2cc20001, 0x148b0004, 0x0, 0x8d020000, -0x10000003, 0x451024, 0x8d420000, 0x451024, -0x54400001, 0x24060001, 0x2cc20001, 0x7182b, -0x431024, 0x5440ffed, 0x42042, 0x3c010001, -0x10c00020, 0xac243d18, 0x8f830054, 0x24020001, -0x3c010001, 0xac223d1c, 0x3c010001, 0xac233e68, -0x3c020001, 0x8c423d1c, 0x10400004, 0x24020001, -0x3c010001, 0xac203d1c, 0xaee204b8, 0x8ee304b8, -0x24020008, 0x10620005, 0x24020001, 0xc003f91, -0x0, 0x1000000b, 0x0, 0x3c030001, -0x8c633d18, 0x10620007, 0x2402000e, 0x3c030001, -0x8c635ec0, 0x10620003, 0x0, 0xc004610, -0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018, -0x27bdffe0, 0x3c03fdff, 0x3c040001, 0x8c843d18, -0x3c020001, 0x8c423d38, 0x3463ffff, 0x283a024, -0x14820006, 0xafbf0018, 0x8ee304b8, 0x3c020001, -0x8c423d3c, 0x10620006, 0x0, 0x8ee204b8, -0x3c010001, 0xac243d38, 0x3c010001, 0xac223d3c, -0x3c030001, 0x8c633d18, 0x24020002, 0x1062013c, -0x2c620003, 0x10400005, 0x24020001, 0x1062000a, -0x0, 0x10000134, 0x0, 0x24020004, -0x1062006d, 0x24020008, 0x1062009f, 0x24020001, -0x1000012d, 0x0, 0x8ee204b8, 0x2443ffff, -0x2c620008, 0x1040012a, 0x31080, 0x3c010001, -0x220821, 0x8c223b18, 0x400008, 0x0, -0xc0040e8, 0x0, 0x3c020001, 0x8c423d24, -0x3c010001, 0xac203cb0, 0x104000d7, 0x24020002, -0xaee204b8, 0x3c010001, 0x10000119, 0xac203d24, -0xc00424b, 0x0, 0x3c030001, 0x8c633d40, -0x1000009e, 0x24020011, 0x3c050001, 0x8ca53d18, -0x3c060001, 0x8cc65f2c, 0xc004878, 0x2021, -0x24020005, 0x3c010001, 0xac203d24, 0x10000108, -0xaee204b8, 0x3c040001, 0x24843b0c, 0x3c05000f, -0x34a50100, 0x3021, 0x3821, 0xafa00010, -0xc0029d3, 0xafa00014, 0x100000fd, 0x0, -0x8f820220, 0x3c03f700, 0x431025, 0x100000a4, -0xaf820220, 0x8f820220, 0x3c030004, 0x431024, -0x144000ae, 0x24020007, 0x8f830054, 0x3c020001, -0x8c423e60, 0x2463d8f0, 0x431023, 0x2c422710, -0x144000eb, 0x24020001, 0x100000e7, 0x0, -0x3c050001, 0x8ca53d18, 0xc004981, 0x2021, -0xc004a4c, 0x2021, 0x3c030001, 0x8c635f24, -0x46100dd, 0x24020001, 0x3c020008, 0x621024, -0x10400006, 0x0, 0x8f820214, 0x3c03ffff, -0x431024, 0x10000005, 0x3442251f, 0x8f820214, -0x3c03ffff, 0x431024, 0x3442241f, 0xaf820214, -0x8f820220, 0x3c030200, 0x283a025, 0x34420002, -0xaf820220, 0x24020008, 0xc003c6b, 0xaee204b8, -0x100000c7, 0x0, 0x8ee204b8, 0x2443ffff, -0x2c620008, 0x104000c2, 0x31080, 0x3c010001, -0x220821, 0x8c223b38, 0x400008, 0x0, -0x3c020001, 0x8c425f28, 0x30424000, 0x10400004, -0x0, 0x8f820044, 0x10000006, 0x3442f080, -0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024, -0x3442a080, 0xaf820044, 0x8f830054, 0x1000005a, -0x24020004, 0xc003d2c, 0x0, 0x104000a6, -0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001, -0x8c843e58, 0x431024, 0x3442251f, 0xaf820214, -0x24020008, 0x10800005, 0xaee204b8, 0x3c020001, -0x8c423da4, 0x1040006d, 0x24020001, 0x8f820220, -0x3c030008, 0x431024, 0x10400073, 0x3c020200, -0x10000081, 0x0, 0x8ee204b8, 0x2443ffff, -0x2c620007, 0x1040008e, 0x31080, 0x3c010001, -0x220821, 0x8c223b58, 0x400008, 0x0, -0xc003bad, 0x0, 0x3c010001, 0xac203d1c, -0xaf800204, 0x3c010001, 0xc0040e8, 0xac205f10, -0x24020001, 0x3c010001, 0xac223d30, 0x24020002, -0x1000007b, 0xaee204b8, 0xc004194, 0x0, -0x3c030001, 0x8c633d30, 0x24020009, 0x14620074, -0x24020003, 0x10000072, 0xaee204b8, 0x3c020001, -0x8c425f28, 0x30424000, 0x10400003, 0x3c0200c8, -0x10000002, 0x344201f6, 0x344201fe, 0xaf820238, -0x8f830054, 0x10000014, 0x24020004, 0x8f830054, -0x3c020001, 0x8c423e60, 0x2463d8f0, 0x431023, -0x2c422710, 0x1440005e, 0x24020005, 0x1000005c, -0xaee204b8, 0x8f820220, 0x3c03f700, 0x431025, -0xaf820220, 0xaf800204, 0x3c010001, 0xac205f10, -0x8f830054, 0x24020006, 0xaee204b8, 0x3c010001, -0x1000004f, 0xac233e60, 0x8f830054, 0x3c020001, -0x8c423e60, 0x2463fff6, 0x431023, 0x2c42000a, -0x14400047, 0x0, 0x24020007, 0x10000044, -0xaee204b8, 0xc003d2c, 0x0, 0x1040003e, -0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001, -0x8c843e58, 0x431024, 0x3442251f, 0xaf820214, -0x24020008, 0x1080000f, 0xaee204b8, 0x3c020001, -0x8c423da4, 0x1440000b, 0x0, 0x8f820220, -0x34420002, 0xaf820220, 0x24020001, 0x3c010001, -0xac225ec0, 0xc004610, 0x8f840220, 0x10000016, -0x0, 0x8f820220, 0x3c030008, 0x431024, -0x14400011, 0x3c020200, 0x282a025, 0x2402000e, -0x3c010001, 0xac225ec0, 0xc004a4c, 0x2021, -0x8f820220, 0x34420002, 0xc003c6b, 0xaf820220, -0x3c050001, 0x8ca53d18, 0xc004981, 0x2021, -0x10000013, 0x0, 0x3c020001, 0x8c423da4, -0x1040000f, 0x0, 0x3c020001, 0x8c423da0, -0x2442ffff, 0x3c010001, 0xac223da0, 0x14400008, -0x24020002, 0x3c010001, 0xac203da4, 0x3c010001, -0x10000003, 0xac223da0, 0x3c010001, 0xac223d1c, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f820200, -0x8f820220, 0x8f820220, 0x34420004, 0xaf820220, -0x8f820200, 0x3c040001, 0x8c843d18, 0x34420004, -0xaf820200, 0x24020002, 0x1082003a, 0x2c820003, -0x10400005, 0x24020001, 0x1082000a, 0x3c03f0ff, -0x10000098, 0x0, 0x24020004, 0x10820059, -0x24020008, 0x1082006c, 0x3c02f0ff, 0x10000091, -0x0, 0x8f820050, 0x3463ffff, 0x3c05ffff, -0x34a53f7f, 0x431024, 0x3c030700, 0x431025, -0xaf820050, 0x24020e00, 0xaf840200, 0xaf840220, -0xaf820238, 0x8f820044, 0x3c030001, 0x8c633d08, -0x3c040001, 0x8c843e70, 0x451024, 0x34630022, -0xaf820044, 0x24020004, 0x1082000c, 0xaf830200, -0x3c020001, 0x8c423d2c, 0x3c030001, 0x8c633d10, -0x3c040001, 0x8c843d0c, 0x34428000, 0x621825, -0x641825, 0x1000006e, 0x34620002, 0x3c020001, -0x8c423d10, 0x3c030001, 0x8c633d2c, 0x3c040001, -0x8c843d0c, 0x431025, 0x441025, 0x10000064, -0x34420002, 0x8f830050, 0x3c02f0ff, 0x3442ffff, -0x3c040001, 0x8c843e58, 0x621824, 0x3c020d00, -0x621825, 0x24020001, 0xaf830050, 0xaf820200, -0xaf820220, 0x24020e00, 0x10800009, 0xaf820238, -0x3c020001, 0x8c423da4, 0x14400005, 0x3c033f00, -0x3c020001, 0x8c423d00, 0x10000005, 0x34630070, -0x3c020001, 0x8c423d00, 0x3c033f00, 0x34630072, -0x431025, 0xaf820200, 0x3c030001, 0x8c633d04, -0x3c04f700, 0x3c020001, 0x8c423d10, 0x3c050001, -0x8ca53d2c, 0x641825, 0x431025, 0x1000003c, -0x451025, 0x8f830050, 0x3c02f0ff, 0x3442ffff, -0x3c040001, 0x8c843e58, 0x621824, 0x3c020a00, -0x621825, 0x24020001, 0xaf830050, 0xaf820200, -0x1080001e, 0xaf820220, 0x3c020001, 0x8c423da4, -0x1440001a, 0x3c033f00, 0x3c020001, 0x8c423d00, -0x1000001a, 0x346300e0, 0x8f830050, 0x3c040001, -0x8c843e58, 0x3442ffff, 0x621824, 0x1080000f, -0xaf830050, 0x3c020001, 0x8c423da4, 0x1440000b, -0x3c043f00, 0x3c030001, 0x8c633d00, 0x348400e0, -0x24020001, 0xaf820200, 0xaf820220, 0x641825, -0xaf830200, 0x10000008, 0x3c05f700, 0x3c020001, -0x8c423d00, 0x3c033f00, 0x346300e2, 0x431025, -0xaf820200, 0x3c05f700, 0x34a58000, 0x3c030001, -0x8c633d04, 0x3c020001, 0x8c423d10, 0x3c040001, -0x8c843d2c, 0x651825, 0x431025, 0x441025, -0xaf820220, 0x3e00008, 0x0, 0x3c030001, -0x8c633d30, 0x3c020001, 0x8c423d34, 0x10620003, -0x24020002, 0x3c010001, 0xac233d34, 0x1062001d, -0x2c620003, 0x10400025, 0x24020001, 0x14620023, -0x24020004, 0x3c030001, 0x8c633d18, 0x10620006, -0x24020008, 0x1462000c, 0x3c0200c8, 0x344201fb, -0x10000009, 0xaf820238, 0x24020e01, 0xaf820238, +0x1040fff0, 0x34028000, 0x1082ff56, 0x26100001, +0x2e020064, 0x1440ffb0, 0x0, 0x3c020001, +0x8c423d84, 0x30420004, 0x14400007, 0x3c08fff0, 0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024, -0x34420080, 0xaf820044, 0x8f830054, 0x24020002, -0x3c010001, 0xac223d30, 0x3c010001, 0x1000000b, -0xac233e64, 0x8f830054, 0x3c020001, 0x8c423e64, -0x2463d8f0, 0x431023, 0x2c422710, 0x14400003, -0x24020009, 0x3c010001, 0xac223d30, 0x3e00008, -0x0, 0x0, 0x0, 0x27bdffd8, +0xaf820044, 0x3c08fff0, 0x3508bdc0, 0x8f830054, +0x97a60018, 0x3c070001, 0x8ce73ee0, 0x3c040001, +0x24843b60, 0x24020001, 0x3c010001, 0xac223d8c, +0xafa60010, 0x3c060001, 0x8cc63d84, 0x97a2001a, +0x3c05000d, 0x34a50100, 0x3c010001, 0xac203d88, +0x681821, 0x3c010001, 0xac233ed8, 0xc0029bb, +0xafa20014, 0x8fbf0034, 0x8fb20030, 0x8fb1002c, +0x8fb00028, 0x3e00008, 0x27bd0038, 0x27bdffe8, +0x24070004, 0x3c040001, 0x8c843d88, 0x3021, +0x24020001, 0x1482000a, 0xafbf0010, 0x3c020001, +0x8c425f9c, 0x3c050004, 0x30428000, 0x1040000c, +0x34a593e0, 0x3c05000f, 0x10000009, 0x34a54240, +0x3c020001, 0x8c425f9c, 0x3c05000f, 0x30428000, +0x10400003, 0x34a54240, 0x3c05001e, 0x34a58480, +0x3c020001, 0x8c423ed8, 0x8f830054, 0x451021, +0x431023, 0x45102b, 0x1440002e, 0x0, +0x3c020001, 0x8c423d90, 0x1440002a, 0x2cc20001, +0x7182b, 0x431024, 0x1040001d, 0x0, +0x3c090001, 0x8d293d84, 0x240b0001, 0x3c054000, +0x3c080001, 0x25085f9c, 0x250afffc, 0x42042, +0x14800002, 0x24e7ffff, 0x24040008, 0x891024, +0x5040000b, 0x2cc20001, 0x148b0004, 0x0, +0x8d020000, 0x10000003, 0x451024, 0x8d420000, +0x451024, 0x54400001, 0x24060001, 0x2cc20001, +0x7182b, 0x431024, 0x5440ffed, 0x42042, +0x3c010001, 0x10c00020, 0xac243d88, 0x8f830054, +0x24020001, 0x3c010001, 0xac223d8c, 0x3c010001, +0xac233ed8, 0x3c020001, 0x8c423d8c, 0x10400004, +0x24020001, 0x3c010001, 0xac203d8c, 0xaee204b8, +0x8ee304b8, 0x24020008, 0x10620005, 0x24020001, +0xc003eee, 0x0, 0x1000000b, 0x0, +0x3c030001, 0x8c633d88, 0x10620007, 0x2402000e, +0x3c030001, 0x8c635f30, 0x10620003, 0x0, +0xc00456c, 0x8f840220, 0x8fbf0010, 0x3e00008, +0x27bd0018, 0x27bdffe0, 0x3c03fdff, 0x3c040001, +0x8c843d88, 0x3c020001, 0x8c423da8, 0x3463ffff, +0x283a024, 0x14820006, 0xafbf0018, 0x8ee304b8, +0x3c020001, 0x8c423dac, 0x10620006, 0x0, +0x8ee204b8, 0x3c010001, 0xac243da8, 0x3c010001, +0xac223dac, 0x3c030001, 0x8c633d88, 0x24020002, +0x1062013c, 0x2c620003, 0x10400005, 0x24020001, +0x1062000a, 0x0, 0x10000134, 0x0, +0x24020004, 0x1062006d, 0x24020008, 0x1062009f, +0x24020001, 0x1000012d, 0x0, 0x8ee204b8, +0x2443ffff, 0x2c620008, 0x1040012a, 0x31080, +0x3c010001, 0x220821, 0x8c223b78, 0x400008, +0x0, 0xc004045, 0x0, 0x3c020001, +0x8c423d94, 0x3c010001, 0xac203d20, 0x104000d7, +0x24020002, 0xaee204b8, 0x3c010001, 0x10000119, +0xac203d94, 0xc0041a7, 0x0, 0x3c030001, +0x8c633db0, 0x1000009e, 0x24020011, 0x3c050001, +0x8ca53d88, 0x3c060001, 0x8cc65f9c, 0xc0047d4, +0x2021, 0x24020005, 0x3c010001, 0xac203d94, +0x10000108, 0xaee204b8, 0x3c040001, 0x24843b6c, +0x3c05000f, 0x34a50100, 0x3021, 0x3821, +0xafa00010, 0xc0029bb, 0xafa00014, 0x100000fd, +0x0, 0x8f820220, 0x3c03f700, 0x431025, +0x100000a4, 0xaf820220, 0x8f820220, 0x3c030004, +0x431024, 0x144000ae, 0x24020007, 0x8f830054, +0x3c020001, 0x8c423ed0, 0x2463d8f0, 0x431023, +0x2c422710, 0x144000eb, 0x24020001, 0x100000e7, +0x0, 0x3c050001, 0x8ca53d88, 0xc0048dd, +0x2021, 0xc0049a8, 0x2021, 0x3c030001, +0x8c635f94, 0x46100dd, 0x24020001, 0x3c020008, +0x621024, 0x10400006, 0x0, 0x8f820214, +0x3c03ffff, 0x431024, 0x10000005, 0x3442251f, +0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f, +0xaf820214, 0x8f820220, 0x3c030200, 0x283a025, +0x34420002, 0xaf820220, 0x24020008, 0xc003bc9, +0xaee204b8, 0x100000c7, 0x0, 0x8ee204b8, +0x2443ffff, 0x2c620008, 0x104000c2, 0x31080, +0x3c010001, 0x220821, 0x8c223b98, 0x400008, +0x0, 0x3c020001, 0x8c425f98, 0x30424000, +0x10400004, 0x0, 0x8f820044, 0x10000006, +0x3442f080, 0x8f820044, 0x3c03ffff, 0x34633f7f, +0x431024, 0x3442a080, 0xaf820044, 0x8f830054, +0x1000005a, 0x24020004, 0xc003c88, 0x0, +0x104000a6, 0x24020001, 0x8f820214, 0x3c03ffff, +0x3c040001, 0x8c843ec8, 0x431024, 0x3442251f, +0xaf820214, 0x24020008, 0x10800005, 0xaee204b8, +0x3c020001, 0x8c423e14, 0x1040006d, 0x24020001, +0x8f820220, 0x3c030008, 0x431024, 0x10400073, +0x3c020200, 0x10000081, 0x0, 0x8ee204b8, +0x2443ffff, 0x2c620007, 0x1040008e, 0x31080, +0x3c010001, 0x220821, 0x8c223bb8, 0x400008, +0x0, 0xc003b0b, 0x0, 0x3c010001, +0xac203d8c, 0xaf800204, 0x3c010001, 0xc004045, +0xac205f80, 0x24020001, 0x3c010001, 0xac223da0, +0x24020002, 0x1000007b, 0xaee204b8, 0xc0040f2, +0x0, 0x3c030001, 0x8c633da0, 0x24020009, +0x14620074, 0x24020003, 0x10000072, 0xaee204b8, +0x3c020001, 0x8c425f98, 0x30424000, 0x10400003, +0x3c0200c8, 0x10000002, 0x344201f6, 0x344201fe, +0xaf820238, 0x8f830054, 0x10000014, 0x24020004, +0x8f830054, 0x3c020001, 0x8c423ed0, 0x2463d8f0, +0x431023, 0x2c422710, 0x1440005e, 0x24020005, +0x1000005c, 0xaee204b8, 0x8f820220, 0x3c03f700, +0x431025, 0xaf820220, 0xaf800204, 0x3c010001, +0xac205f80, 0x8f830054, 0x24020006, 0xaee204b8, +0x3c010001, 0x1000004f, 0xac233ed0, 0x8f830054, +0x3c020001, 0x8c423ed0, 0x2463fff6, 0x431023, +0x2c42000a, 0x14400047, 0x0, 0x24020007, +0x10000044, 0xaee204b8, 0xc003c88, 0x0, +0x1040003e, 0x24020001, 0x8f820214, 0x3c03ffff, +0x3c040001, 0x8c843ec8, 0x431024, 0x3442251f, +0xaf820214, 0x24020008, 0x1080000f, 0xaee204b8, +0x3c020001, 0x8c423e14, 0x1440000b, 0x0, +0x8f820220, 0x34420002, 0xaf820220, 0x24020001, +0x3c010001, 0xac225f30, 0xc00456c, 0x8f840220, +0x10000016, 0x0, 0x8f820220, 0x3c030008, +0x431024, 0x14400011, 0x3c020200, 0x282a025, +0x2402000e, 0x3c010001, 0xac225f30, 0xc0049a8, +0x2021, 0x8f820220, 0x34420002, 0xc003bc9, +0xaf820220, 0x3c050001, 0x8ca53d88, 0xc0048dd, +0x2021, 0x10000013, 0x0, 0x3c020001, +0x8c423e14, 0x1040000f, 0x0, 0x3c020001, +0x8c423e10, 0x2442ffff, 0x3c010001, 0xac223e10, +0x14400008, 0x24020002, 0x3c010001, 0xac203e14, +0x3c010001, 0x10000003, 0xac223e10, 0x3c010001, +0xac223d8c, 0x8fbf0018, 0x3e00008, 0x27bd0020, +0x8f820200, 0x8f820220, 0x8f820220, 0x34420004, +0xaf820220, 0x8f820200, 0x3c060001, 0x8cc63d88, +0x34420004, 0xaf820200, 0x24020002, 0x10c2003b, +0x2cc20003, 0x10400005, 0x24020001, 0x10c2000a, +0x3c03f0ff, 0x10000099, 0x0, 0x24020004, +0x10c2005a, 0x24020008, 0x10c2006d, 0x3c02f0ff, +0x10000092, 0x0, 0x8f820050, 0x3463ffff, +0x3c05ffff, 0x3c040001, 0x8c843ee0, 0x431024, +0x3c030700, 0x431025, 0xaf820050, 0x24020e00, +0xaf860200, 0xaf860220, 0xaf820238, 0x8f820044, +0x3c030001, 0x8c633d78, 0x34a53f7f, 0x451024, +0x34630022, 0xaf820044, 0x24020004, 0xaf860238, +0x1082000c, 0xaf830200, 0x3c020001, 0x8c423d9c, +0x3c030001, 0x8c633d80, 0x3c040001, 0x8c843d7c, +0x34428000, 0x621825, 0x641825, 0x1000006e, +0x34620002, 0x3c020001, 0x8c423d80, 0x3c030001, +0x8c633d9c, 0x3c040001, 0x8c843d7c, 0x431025, +0x441025, 0x10000064, 0x34420002, 0x8f830050, +0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c843ec8, +0x621824, 0x3c020d00, 0x621825, 0x24020001, +0xaf830050, 0xaf820200, 0xaf820220, 0x24020e00, +0x10800009, 0xaf820238, 0x3c020001, 0x8c423e14, +0x14400005, 0x3c033f00, 0x3c020001, 0x8c423d70, +0x10000005, 0x34630070, 0x3c020001, 0x8c423d70, +0x3c033f00, 0x34630072, 0x431025, 0xaf820200, +0x3c030001, 0x8c633d74, 0x3c04f700, 0x3c020001, +0x8c423d80, 0x3c050001, 0x8ca53d9c, 0x641825, +0x431025, 0x1000003c, 0x451025, 0x8f830050, +0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c843ec8, +0x621824, 0x3c020a00, 0x621825, 0x24020001, +0xaf830050, 0xaf820200, 0x1080001e, 0xaf820220, +0x3c020001, 0x8c423e14, 0x1440001a, 0x3c033f00, +0x3c020001, 0x8c423d70, 0x1000001a, 0x346300e0, +0x8f830050, 0x3c040001, 0x8c843ec8, 0x3442ffff, +0x621824, 0x1080000f, 0xaf830050, 0x3c020001, +0x8c423e14, 0x1440000b, 0x3c043f00, 0x3c030001, +0x8c633d70, 0x348400e0, 0x24020001, 0xaf820200, +0xaf820220, 0x641825, 0xaf830200, 0x10000008, +0x3c05f700, 0x3c020001, 0x8c423d70, 0x3c033f00, +0x346300e2, 0x431025, 0xaf820200, 0x3c05f700, +0x34a58000, 0x3c030001, 0x8c633d74, 0x3c020001, +0x8c423d80, 0x3c040001, 0x8c843d9c, 0x651825, +0x431025, 0x441025, 0xaf820220, 0x3e00008, +0x0, 0x3c030001, 0x8c633da0, 0x3c020001, +0x8c423da4, 0x10620003, 0x24020002, 0x3c010001, +0xac233da4, 0x1062001d, 0x2c620003, 0x10400025, +0x24020001, 0x14620023, 0x24020004, 0x3c030001, +0x8c633d88, 0x10620006, 0x24020008, 0x1462000c, +0x3c0200c8, 0x344201fb, 0x10000009, 0xaf820238, +0x24020e01, 0xaf820238, 0x8f820044, 0x3c03ffff, +0x34633f7f, 0x431024, 0x34420080, 0xaf820044, +0x8f830054, 0x24020002, 0x3c010001, 0xac223da0, +0x3c010001, 0x1000000b, 0xac233ed4, 0x8f830054, +0x3c020001, 0x8c423ed4, 0x2463d8f0, 0x431023, +0x2c422710, 0x14400003, 0x24020009, 0x3c010001, +0xac223da0, 0x3e00008, 0x0, 0x27bdffd8, 0xafb20018, 0x809021, 0xafb3001c, 0xa09821, 0xafb10014, 0xc08821, 0xafb00010, 0x8021, -0xafbf0020, 0xa6200000, 0xc0045c7, 0x24040001, +0xafbf0020, 0xa6200000, 0xc004523, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc0045c7, 0x2021, 0xc0045c7, 0x24040001, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x2021, 0xc004523, 0x24040001, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x24100010, 0x2501024, 0x10400002, 0x2021, -0x24040001, 0xc0045c7, 0x108042, 0x1600fffa, +0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x2501024, 0x24100010, 0x2701024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fffa, 0x2701024, 0xc0045ed, 0x34108000, -0xc0045ed, 0x0, 0xc0045a7, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fffa, 0x2701024, 0xc004549, 0x34108000, +0xc004549, 0x0, 0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc0045ed, 0x0, 0x8fbf0020, 0x8fb3001c, +0xc004549, 0x0, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821, 0xafb20018, 0xa09021, 0xafb3001c, 0xc09821, -0xafb00010, 0x8021, 0xafbf0020, 0xc0045c7, +0xafb00010, 0x8021, 0xafbf0020, 0xc004523, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc0045c7, 0x2021, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0xc0045c7, +0x0, 0xc004523, 0x2021, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0xc004523, 0x24040001, 0x24100010, 0x2301024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, +0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x2301024, 0x24100010, 0x2501024, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, -0x108042, 0x1600fffa, 0x2501024, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004523, +0x108042, 0x1600fffa, 0x2501024, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96620000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc0045c7, 0x108042, 0x1600fff8, -0x0, 0xc0045ed, 0x0, 0x8fbf0020, +0x24040001, 0xc004523, 0x108042, 0x1600fff8, +0x0, 0xc004549, 0x0, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, -0x3e00008, 0x27bd0028, 0x3c030001, 0x8c633d40, -0x3c020001, 0x8c423d84, 0x27bdffd8, 0xafbf0020, +0x3e00008, 0x27bd0028, 0x3c030001, 0x8c633db0, +0x3c020001, 0x8c423df4, 0x27bdffd8, 0xafbf0020, 0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001, -0xac233d84, 0x2463ffff, 0x2c620013, 0x10400349, -0x31080, 0x3c010001, 0x220821, 0x8c223b80, -0x400008, 0x0, 0xc0045ed, 0x8021, -0x34028000, 0xa7a20010, 0x27b10010, 0xc0045c7, +0xac233df4, 0x2463ffff, 0x2c620013, 0x10400349, +0x31080, 0x3c010001, 0x220821, 0x8c223be0, +0x400008, 0x0, 0xc004549, 0x8021, +0x34028000, 0xa7a20010, 0x27b10010, 0xc004523, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc0045c7, 0x2021, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0xc0045c7, +0x0, 0xc004523, 0x2021, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0xc004523, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0xc0045c7, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fffa, 0x32020001, 0x24100010, 0xc004523, 0x2021, 0x108042, 0x1600fffc, 0x0, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x1000030e, 0x24020002, 0x27b10010, 0xa7a00010, -0x8021, 0xc0045c7, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc0045c7, -0x2021, 0xc0045c7, 0x24040001, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0x24100010, +0x8021, 0xc004523, 0x24040001, 0x26100001, +0x2e020020, 0x1440fffb, 0x0, 0xc004523, +0x2021, 0xc004523, 0x24040001, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0xc0045c7, 0x2021, 0x108042, -0x1600fffc, 0x0, 0xc0045ed, 0x34108000, -0xc0045ed, 0x0, 0xc0045a7, 0x0, +0xc004523, 0x108042, 0x1600fffa, 0x32020001, +0x24100010, 0xc004523, 0x2021, 0x108042, +0x1600fffc, 0x0, 0xc004549, 0x34108000, +0xc004549, 0x0, 0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc0045ed, 0x0, 0x97a20010, 0x30428000, +0xc004549, 0x0, 0x97a20010, 0x30428000, 0x144002dc, 0x24020003, 0x100002d8, 0x0, 0x24021200, 0xa7a20010, 0x27b10010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0xc0045c7, 0x2021, 0x108042, 0x1600fffc, -0x0, 0xc0045c7, 0x24040001, 0xc0045c7, +0xc004523, 0x2021, 0x108042, 0x1600fffc, +0x0, 0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, -0x108042, 0x1600fff8, 0x0, 0xc0045ed, +0x10400002, 0x2021, 0x24040001, 0xc004523, +0x108042, 0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x10000296, 0x24020004, -0x8f830054, 0x3c020001, 0x8c423e6c, 0x2463ff9c, +0x8f830054, 0x3c020001, 0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440029e, 0x24020002, -0x3c030001, 0x8c633e70, 0x10620297, 0x2c620003, +0x3c030001, 0x8c633ee0, 0x10620297, 0x2c620003, 0x14400296, 0x24020011, 0x24020003, 0x10620005, 0x24020004, 0x10620291, 0x2402000f, 0x1000028f, 0x24020011, 0x1000028d, 0x24020005, 0x24020014, -0xa7a20010, 0x27b10010, 0x8021, 0xc0045c7, +0xa7a20010, 0x27b10010, 0x8021, 0xc004523, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc0045c7, 0x2021, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0xc0045c7, +0x0, 0xc004523, 0x2021, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0xc004523, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, +0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020012, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, -0x108042, 0x1600fffa, 0x32020012, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004523, +0x108042, 0x1600fffa, 0x32020012, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc0045c7, 0x108042, 0x1600fff8, -0x0, 0xc0045ed, 0x0, 0x8f830054, +0x24040001, 0xc004523, 0x108042, 0x1600fff8, +0x0, 0xc004549, 0x0, 0x8f830054, 0x10000248, 0x24020006, 0x8f830054, 0x3c020001, -0x8c423e6c, 0x2463ff9c, 0x431023, 0x2c420064, +0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400250, 0x24020007, 0x1000024c, 0x0, 0x24020006, 0xa7a20010, 0x27b10010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020013, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020013, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x108042, 0x1600fffa, 0x32020013, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x10000207, 0x24020008, 0x8f830054, -0x3c020001, 0x8c423e6c, 0x2463ff9c, 0x431023, +0x3c020001, 0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440020f, 0x24020009, 0x1000020b, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x24040001, -0xc0045c7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x24040001, +0xc004523, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020018, -0xc0045ed, 0x34108000, 0xc0045ed, 0x0, -0xc0045a7, 0x0, 0x50400005, 0x108042, +0xc004523, 0x108042, 0x1600fffa, 0x32020018, +0xc004549, 0x34108000, 0xc004549, 0x0, +0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc0045ed, 0x8021, +0x1600fff7, 0x0, 0xc004549, 0x8021, 0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020018, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x108042, 0x1600fffa, 0x32020018, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x10000193, 0x2402000a, 0x8f830054, -0x3c020001, 0x8c423e6c, 0x2463ff9c, 0x431023, +0x3c020001, 0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440019b, 0x2402000b, 0x10000197, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x24040001, -0xc0045c7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x24040001, +0xc004523, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020017, -0xc0045ed, 0x34108000, 0xc0045ed, 0x0, -0xc0045a7, 0x0, 0x50400005, 0x108042, +0xc004523, 0x108042, 0x1600fffa, 0x32020017, +0xc004549, 0x34108000, 0xc004549, 0x0, +0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc0045ed, 0x8021, +0x1600fff7, 0x0, 0xc004549, 0x8021, 0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020017, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x108042, 0x1600fffa, 0x32020017, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x1000011f, 0x2402000c, 0x8f830054, -0x3c020001, 0x8c423e6c, 0x2463ff9c, 0x431023, +0x3c020001, 0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400127, 0x24020012, 0x10000123, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x24040001, -0xc0045c7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x24040001, +0xc004523, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020014, -0xc0045ed, 0x34108000, 0xc0045ed, 0x0, -0xc0045a7, 0x0, 0x50400005, 0x108042, +0xc004523, 0x108042, 0x1600fffa, 0x32020014, +0xc004549, 0x34108000, 0xc004549, 0x0, +0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc0045ed, 0x8021, +0x1600fff7, 0x0, 0xc004549, 0x8021, 0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020014, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x108042, 0x1600fffa, 0x32020014, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x100000ab, 0x24020013, 0x8f830054, -0x3c020001, 0x8c423e6c, 0x2463ff9c, 0x431023, +0x3c020001, 0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x144000b3, 0x2402000d, 0x100000af, 0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x24040001, -0xc0045c7, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x24040001, +0xc004523, 0x2021, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020018, -0xc0045ed, 0x34108000, 0xc0045ed, 0x0, -0xc0045a7, 0x0, 0x50400005, 0x108042, +0xc004523, 0x108042, 0x1600fffa, 0x32020018, +0xc004549, 0x34108000, 0xc004549, 0x0, +0xc004503, 0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc0045ed, 0x8021, +0x1600fff7, 0x0, 0xc004549, 0x8021, 0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010, -0xc0045c7, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, -0xc0045c7, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, +0xc004523, 0x24040001, 0x26100001, 0x2e020020, +0x1440fffb, 0x0, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0xc004523, 0x2021, +0xc004523, 0x24040001, 0x24100010, 0x32020001, +0x10400002, 0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc0045c7, 0x108042, 0x1600fffa, 0x32020018, -0xc0045c7, 0x24040001, 0xc0045c7, 0x2021, +0xc004523, 0x108042, 0x1600fffa, 0x32020018, +0xc004523, 0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, -0x1600fff8, 0x0, 0xc0045ed, 0x0, +0x2021, 0x24040001, 0xc004523, 0x108042, +0x1600fff8, 0x0, 0xc004549, 0x0, 0x8f830054, 0x10000037, 0x2402000e, 0x24020840, -0xa7a20010, 0x27b10010, 0x8021, 0xc0045c7, +0xa7a20010, 0x27b10010, 0x8021, 0xc004523, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc0045c7, 0x2021, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0xc0045c7, +0x0, 0xc004523, 0x2021, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0xc004523, 0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc0045c7, 0x108042, +0x2021, 0x24040001, 0xc004523, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020013, -0x10400002, 0x2021, 0x24040001, 0xc0045c7, -0x108042, 0x1600fffa, 0x32020013, 0xc0045c7, -0x24040001, 0xc0045c7, 0x2021, 0x34108000, +0x10400002, 0x2021, 0x24040001, 0xc004523, +0x108042, 0x1600fffa, 0x32020013, 0xc004523, +0x24040001, 0xc004523, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc0045c7, 0x108042, 0x1600fff8, -0x0, 0xc0045ed, 0x0, 0x8f830054, -0x24020010, 0x3c010001, 0xac223d40, 0x3c010001, -0x1000000c, 0xac233e6c, 0x8f830054, 0x3c020001, -0x8c423e6c, 0x2463ff9c, 0x431023, 0x2c420064, +0x24040001, 0xc004523, 0x108042, 0x1600fff8, +0x0, 0xc004549, 0x0, 0x8f830054, +0x24020010, 0x3c010001, 0xac223db0, 0x3c010001, +0x1000000c, 0xac233edc, 0x8f830054, 0x3c020001, +0x8c423edc, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400004, 0x0, 0x24020011, 0x3c010001, -0xac223d40, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, +0xac223db0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044, 0x3c030001, 0x431025, 0x3c030008, 0xaf820044, 0x8f840054, 0x8f820054, 0xa32824, 0x10000002, @@ -7929,136 +7899,136 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0x0, 0x0, 0x27bdffe8, 0xafbf0010, 0x8ee304b8, 0x24020008, 0x146201e0, -0x0, 0x3c020001, 0x8c423e58, 0x14400005, -0x0, 0xc003bad, 0x8f840224, 0x100001d8, +0x0, 0x3c020001, 0x8c423ec8, 0x14400005, +0x0, 0xc003b0b, 0x8f840224, 0x100001d8, 0x0, 0x8f820220, 0x3c030008, 0x431024, 0x10400026, 0x24020001, 0x8f840224, 0x8f820220, 0x3c030400, 0x431024, 0x10400006, 0x0, -0x3c010001, 0xac205ed0, 0x3c010001, 0x1000000b, -0xac205ef0, 0x3c030001, 0x24635ed0, 0x8c620000, +0x3c010001, 0xac205f40, 0x3c010001, 0x1000000b, +0xac205f60, 0x3c030001, 0x24635f40, 0x8c620000, 0x24420001, 0xac620000, 0x2c420002, 0x14400003, -0x24020001, 0x3c010001, 0xac225ef0, 0x3c020001, -0x8c425ef0, 0x10400006, 0x30820040, 0x10400004, -0x24020001, 0x3c010001, 0x10000003, 0xac225ef4, -0x3c010001, 0xac205ef4, 0x3c010001, 0xac245ecc, -0x3c010001, 0x1000000b, 0xac205f00, 0x3c010001, -0xac225f00, 0x3c010001, 0xac205ef0, 0x3c010001, -0xac205ed0, 0x3c010001, 0xac205ef4, 0x3c010001, -0xac205ecc, 0x3c030001, 0x8c635ec0, 0x3c020001, -0x8c425ec4, 0x50620004, 0x2463ffff, 0x3c010001, -0xac235ec4, 0x2463ffff, 0x2c62000e, 0x10400194, -0x31080, 0x3c010001, 0x220821, 0x8c223bd0, +0x24020001, 0x3c010001, 0xac225f60, 0x3c020001, +0x8c425f60, 0x10400006, 0x30820040, 0x10400004, +0x24020001, 0x3c010001, 0x10000003, 0xac225f64, +0x3c010001, 0xac205f64, 0x3c010001, 0xac245f3c, +0x3c010001, 0x1000000b, 0xac205f70, 0x3c010001, +0xac225f70, 0x3c010001, 0xac205f60, 0x3c010001, +0xac205f40, 0x3c010001, 0xac205f64, 0x3c010001, +0xac205f3c, 0x3c030001, 0x8c635f30, 0x3c020001, +0x8c425f34, 0x50620004, 0x2463ffff, 0x3c010001, +0xac235f34, 0x2463ffff, 0x2c62000e, 0x10400194, +0x31080, 0x3c010001, 0x220821, 0x8c223c30, 0x400008, 0x0, 0x24020002, 0x3c010001, -0xac205ef0, 0x3c010001, 0xac205ed0, 0x3c010001, -0xac205ecc, 0x3c010001, 0xac205ef4, 0x3c010001, -0xac205ee8, 0x3c010001, 0xac205ee0, 0xaf800224, -0x3c010001, 0xac225ec0, 0x3c020001, 0x8c425f00, -0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003bad, +0xac205f60, 0x3c010001, 0xac205f40, 0x3c010001, +0xac205f3c, 0x3c010001, 0xac205f64, 0x3c010001, +0xac205f58, 0x3c010001, 0xac205f50, 0xaf800224, +0x3c010001, 0xac225f30, 0x3c020001, 0x8c425f70, +0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003b0b, 0x282a024, 0xaf800204, 0x8f820200, 0x2403fffd, -0x431024, 0xaf820200, 0x3c010001, 0xac205f10, -0x8f830054, 0x3c020001, 0x8c425ee8, 0x24040001, -0x3c010001, 0xac245efc, 0x24420001, 0x3c010001, -0xac225ee8, 0x2c420004, 0x3c010001, 0xac235ee4, -0x14400006, 0x24020003, 0x3c010001, 0xac243d1c, -0x3c010001, 0x1000015e, 0xac205ee8, 0x3c010001, -0x1000015b, 0xac225ec0, 0x8f830054, 0x3c020001, -0x8c425ee4, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400003, 0x24020004, 0x3c010001, 0xac225ec0, -0x3c020001, 0x8c425f00, 0x14400021, 0x3c02fdff, +0x431024, 0xaf820200, 0x3c010001, 0xac205f80, +0x8f830054, 0x3c020001, 0x8c425f58, 0x24040001, +0x3c010001, 0xac245f6c, 0x24420001, 0x3c010001, +0xac225f58, 0x2c420004, 0x3c010001, 0xac235f54, +0x14400006, 0x24020003, 0x3c010001, 0xac243d8c, +0x3c010001, 0x1000015e, 0xac205f58, 0x3c010001, +0x1000015b, 0xac225f30, 0x8f830054, 0x3c020001, +0x8c425f54, 0x2463d8f0, 0x431023, 0x2c422710, +0x14400003, 0x24020004, 0x3c010001, 0xac225f30, +0x3c020001, 0x8c425f70, 0x14400021, 0x3c02fdff, 0x3442ffff, 0x1000014a, 0x282a024, 0x3c040001, -0x8c843e5c, 0x3c010001, 0xc0047f8, 0xac205ed8, -0x3c020001, 0x8c425f0c, 0xaf820204, 0x3c020001, -0x8c425f00, 0x14400012, 0x3c03fdff, 0x8f820204, +0x8c843ecc, 0x3c010001, 0xc004754, 0xac205f48, +0x3c020001, 0x8c425f7c, 0xaf820204, 0x3c020001, +0x8c425f70, 0x14400012, 0x3c03fdff, 0x8f820204, 0x3463ffff, 0x30420030, 0x1440012f, 0x283a024, -0x3c030001, 0x8c635f0c, 0x24020005, 0x3c010001, -0xac225ec0, 0x3c010001, 0x10000131, 0xac235f10, -0x3c020001, 0x8c425f00, 0x10400010, 0x3c02fdff, -0x3c020001, 0x8c423d9c, 0x24420001, 0x3c010001, -0xac223d9c, 0x2c420002, 0x14400125, 0x24020001, -0x3c010001, 0xac223da4, 0x3c010001, 0xac203d9c, -0x3c010001, 0x1000011e, 0xac223d1c, 0x3c030001, -0x8c635ef0, 0x3442ffff, 0x10600119, 0x282a024, -0x3c020001, 0x8c425ecc, 0x10400115, 0x0, -0x3c010001, 0xac225ef8, 0x24020003, 0x3c010001, -0xac225ed0, 0x100000b8, 0x24020006, 0x3c010001, -0xac205ed8, 0x8f820204, 0x34420040, 0xaf820204, -0x3c020001, 0x8c425f10, 0x24030007, 0x3c010001, -0xac235ec0, 0x34420040, 0x3c010001, 0xac225f10, -0x3c020001, 0x8c425ef0, 0x10400005, 0x0, -0x3c020001, 0x8c425ecc, 0x104000f0, 0x24020002, -0x3c050001, 0x24a55ed0, 0x8ca20000, 0x2c424e21, -0x104000ea, 0x24020002, 0x3c020001, 0x8c425ef4, -0x104000ef, 0x2404ffbf, 0x3c020001, 0x8c425ecc, -0x3c030001, 0x8c635ef8, 0x441024, 0x641824, +0x3c030001, 0x8c635f7c, 0x24020005, 0x3c010001, +0xac225f30, 0x3c010001, 0x10000131, 0xac235f80, +0x3c020001, 0x8c425f70, 0x10400010, 0x3c02fdff, +0x3c020001, 0x8c423e0c, 0x24420001, 0x3c010001, +0xac223e0c, 0x2c420002, 0x14400125, 0x24020001, +0x3c010001, 0xac223e14, 0x3c010001, 0xac203e0c, +0x3c010001, 0x1000011e, 0xac223d8c, 0x3c030001, +0x8c635f60, 0x3442ffff, 0x10600119, 0x282a024, +0x3c020001, 0x8c425f3c, 0x10400115, 0x0, +0x3c010001, 0xac225f68, 0x24020003, 0x3c010001, +0xac225f40, 0x100000b8, 0x24020006, 0x3c010001, +0xac205f48, 0x8f820204, 0x34420040, 0xaf820204, +0x3c020001, 0x8c425f80, 0x24030007, 0x3c010001, +0xac235f30, 0x34420040, 0x3c010001, 0xac225f80, +0x3c020001, 0x8c425f60, 0x10400005, 0x0, +0x3c020001, 0x8c425f3c, 0x104000f0, 0x24020002, +0x3c050001, 0x24a55f40, 0x8ca20000, 0x2c424e21, +0x104000ea, 0x24020002, 0x3c020001, 0x8c425f64, +0x104000ef, 0x2404ffbf, 0x3c020001, 0x8c425f3c, +0x3c030001, 0x8c635f68, 0x441024, 0x641824, 0x10430004, 0x24020001, 0x3c010001, 0x100000e4, -0xac225ec0, 0x24020003, 0xaca20000, 0x24020008, -0x3c010001, 0xac225ec0, 0x3c020001, 0x8c425efc, -0x1040000c, 0x24020001, 0x3c040001, 0xc004805, -0x8c845ecc, 0x3c020001, 0x8c425f18, 0x14400005, -0x24020001, 0x3c020001, 0x8c425f14, 0x10400006, -0x24020001, 0x3c010001, 0xac223d1c, 0x3c010001, -0x100000cb, 0xac205ee8, 0x3c020001, 0x8c425ee0, -0x3c030001, 0x8c635ecc, 0x2c420001, 0x210c0, -0x30630008, 0x3c010001, 0xac225ee0, 0x3c010001, -0xac235edc, 0x8f830054, 0x24020009, 0x3c010001, -0xac225ec0, 0x3c010001, 0x100000b9, 0xac235ee4, -0x8f830054, 0x3c020001, 0x8c425ee4, 0x2463d8f0, +0xac225f30, 0x24020003, 0xaca20000, 0x24020008, +0x3c010001, 0xac225f30, 0x3c020001, 0x8c425f6c, +0x1040000c, 0x24020001, 0x3c040001, 0xc004761, +0x8c845f3c, 0x3c020001, 0x8c425f88, 0x14400005, +0x24020001, 0x3c020001, 0x8c425f84, 0x10400006, +0x24020001, 0x3c010001, 0xac223d8c, 0x3c010001, +0x100000cb, 0xac205f58, 0x3c020001, 0x8c425f50, +0x3c030001, 0x8c635f3c, 0x2c420001, 0x210c0, +0x30630008, 0x3c010001, 0xac225f50, 0x3c010001, +0xac235f4c, 0x8f830054, 0x24020009, 0x3c010001, +0xac225f30, 0x3c010001, 0x100000b9, 0xac235f54, +0x8f830054, 0x3c020001, 0x8c425f54, 0x2463d8f0, 0x431023, 0x2c422710, 0x1440009f, 0x0, -0x3c020001, 0x8c425ef0, 0x10400005, 0x0, -0x3c020001, 0x8c425ecc, 0x104000a0, 0x24020002, -0x3c030001, 0x24635ed0, 0x8c620000, 0x2c424e21, -0x1040009a, 0x24020002, 0x3c020001, 0x8c425efc, -0x1040000e, 0x0, 0x3c020001, 0x8c425ecc, -0x3c010001, 0xac205efc, 0x30420080, 0x1040002f, +0x3c020001, 0x8c425f60, 0x10400005, 0x0, +0x3c020001, 0x8c425f3c, 0x104000a0, 0x24020002, +0x3c030001, 0x24635f40, 0x8c620000, 0x2c424e21, +0x1040009a, 0x24020002, 0x3c020001, 0x8c425f6c, +0x1040000e, 0x0, 0x3c020001, 0x8c425f3c, +0x3c010001, 0xac205f6c, 0x30420080, 0x1040002f, 0x2402000c, 0x8f820204, 0x30420080, 0x1440000c, 0x24020003, 0x10000029, 0x2402000c, 0x3c020001, -0x8c425ecc, 0x30420080, 0x14400005, 0x24020003, +0x8c425f3c, 0x30420080, 0x14400005, 0x24020003, 0x8f820204, 0x30420080, 0x1040001f, 0x24020003, -0xac620000, 0x2402000a, 0x3c010001, 0xac225ec0, -0x3c040001, 0x24845f08, 0x8c820000, 0x3c030001, -0x8c635ee0, 0x431025, 0xaf820204, 0x8c830000, -0x3c040001, 0x8c845ee0, 0x2402000b, 0x3c010001, -0xac225ec0, 0x641825, 0x3c010001, 0xac235f10, -0x3c050001, 0x24a55ed0, 0x8ca20000, 0x2c424e21, -0x10400066, 0x24020002, 0x3c020001, 0x8c425f00, +0xac620000, 0x2402000a, 0x3c010001, 0xac225f30, +0x3c040001, 0x24845f78, 0x8c820000, 0x3c030001, +0x8c635f50, 0x431025, 0xaf820204, 0x8c830000, +0x3c040001, 0x8c845f50, 0x2402000b, 0x3c010001, +0xac225f30, 0x641825, 0x3c010001, 0xac235f80, +0x3c050001, 0x24a55f40, 0x8ca20000, 0x2c424e21, +0x10400066, 0x24020002, 0x3c020001, 0x8c425f70, 0x10400005, 0x0, 0x2402000c, 0x3c010001, -0x10000067, 0xac225ec0, 0x3c020001, 0x8c425ef0, -0x10400063, 0x0, 0x3c040001, 0x8c845ecc, -0x10800055, 0x30820008, 0x3c030001, 0x8c635edc, -0x1062005b, 0x24020003, 0x3c010001, 0xac245ef8, +0x10000067, 0xac225f30, 0x3c020001, 0x8c425f60, +0x10400063, 0x0, 0x3c040001, 0x8c845f3c, +0x10800055, 0x30820008, 0x3c030001, 0x8c635f4c, +0x1062005b, 0x24020003, 0x3c010001, 0xac245f68, 0xaca20000, 0x24020006, 0x3c010001, 0x10000054, -0xac225ec0, 0x8f820200, 0x34420002, 0xaf820200, -0x8f830054, 0x2402000d, 0x3c010001, 0xac225ec0, -0x3c010001, 0xac235ee4, 0x8f830054, 0x3c020001, -0x8c425ee4, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400031, 0x0, 0x3c020001, 0x8c425f00, -0x10400020, 0x2402000e, 0x3c030001, 0x8c635f14, -0x3c010001, 0x14600015, 0xac225ec0, 0xc003c6b, -0x0, 0x3c050001, 0x8ca53d18, 0xc004981, -0x2021, 0x3c030001, 0x8c633d18, 0x24020004, -0x14620005, 0x2403fffb, 0x3c020001, 0x8c423d14, -0x10000003, 0x2403fff7, 0x3c020001, 0x8c423d14, -0x431024, 0x3c010001, 0xac223d14, 0x8f830224, -0x3c020200, 0x3c010001, 0xac235f1c, 0x10000020, -0x282a025, 0x3c020001, 0x8c425ef0, 0x10400005, -0x0, 0x3c020001, 0x8c425ecc, 0x1040000f, -0x24020002, 0x3c020001, 0x8c425ed0, 0x2c424e21, -0x1040000a, 0x24020002, 0x3c020001, 0x8c425ef0, -0x1040000f, 0x0, 0x3c020001, 0x8c425ecc, +0xac225f30, 0x8f820200, 0x34420002, 0xaf820200, +0x8f830054, 0x2402000d, 0x3c010001, 0xac225f30, +0x3c010001, 0xac235f54, 0x8f830054, 0x3c020001, +0x8c425f54, 0x2463d8f0, 0x431023, 0x2c422710, +0x14400031, 0x0, 0x3c020001, 0x8c425f70, +0x10400020, 0x2402000e, 0x3c030001, 0x8c635f84, +0x3c010001, 0x14600015, 0xac225f30, 0xc003bc9, +0x0, 0x3c050001, 0x8ca53d88, 0xc0048dd, +0x2021, 0x3c030001, 0x8c633d88, 0x24020004, +0x14620005, 0x2403fffb, 0x3c020001, 0x8c423d84, +0x10000003, 0x2403fff7, 0x3c020001, 0x8c423d84, +0x431024, 0x3c010001, 0xac223d84, 0x8f830224, +0x3c020200, 0x3c010001, 0xac235f8c, 0x10000020, +0x282a025, 0x3c020001, 0x8c425f60, 0x10400005, +0x0, 0x3c020001, 0x8c425f3c, 0x1040000f, +0x24020002, 0x3c020001, 0x8c425f40, 0x2c424e21, +0x1040000a, 0x24020002, 0x3c020001, 0x8c425f60, +0x1040000f, 0x0, 0x3c020001, 0x8c425f3c, 0x1440000b, 0x0, 0x24020002, 0x3c010001, -0x10000007, 0xac225ec0, 0x3c020001, 0x8c425ef0, -0x10400003, 0x0, 0xc003bad, 0x0, +0x10000007, 0xac225f30, 0x3c020001, 0x8c425f60, +0x10400003, 0x0, 0xc003b0b, 0x0, 0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, 0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030001, -0x24635f18, 0x8c620000, 0x10400005, 0x34422000, -0x3c010001, 0xac225f0c, 0x10000003, 0xac600000, -0x3c010001, 0xac245f0c, 0x3e00008, 0x0, +0x24635f88, 0x8c620000, 0x10400005, 0x34422000, +0x3c010001, 0xac225f7c, 0x10000003, 0xac600000, +0x3c010001, 0xac245f7c, 0x3e00008, 0x0, 0x27bdffe0, 0x30820030, 0xafbf0018, 0x3c010001, -0xac225f14, 0x14400067, 0x3c02ffff, 0x34421f0e, +0xac225f84, 0x14400067, 0x3c02ffff, 0x34421f0e, 0x821024, 0x14400061, 0x24020030, 0x30822000, 0x1040005d, 0x30838000, 0x31a02, 0x30820001, -0x21200, 0x3c040001, 0x8c843e5c, 0x621825, -0x331c2, 0x3c030001, 0x24633da8, 0x30828000, +0x21200, 0x3c040001, 0x8c843ecc, 0x621825, +0x331c2, 0x3c030001, 0x24633e18, 0x30828000, 0x21202, 0x30840001, 0x42200, 0x441025, 0x239c2, 0x61080, 0x431021, 0x471021, 0x90430000, 0x24020001, 0x10620025, 0x0, @@ -8066,86 +8036,86 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x1062002c, 0x3c05000f, 0x10000037, 0x0, 0x8f820200, 0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, -0xaf820220, 0x3c010001, 0xac205f34, 0x3c010001, -0x10000034, 0xac205f3c, 0x8f820200, 0x34420100, +0xaf820220, 0x3c010001, 0xac205fa4, 0x3c010001, +0x10000034, 0xac205fac, 0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, 0x24020100, 0x3c010001, -0xac225f34, 0x3c010001, 0x10000026, 0xac205f3c, +0xac225fa4, 0x3c010001, 0x10000026, 0xac205fac, 0x8f820200, 0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c030001, 0x431025, 0xaf820220, -0x3c010001, 0xac205f34, 0x3c010001, 0x10000019, -0xac235f3c, 0x8f820200, 0x34420100, 0xaf820200, +0x3c010001, 0xac205fa4, 0x3c010001, 0x10000019, +0xac235fac, 0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c030001, 0x431025, 0xaf820220, -0x24020100, 0x3c010001, 0xac225f34, 0x3c010001, -0x1000000c, 0xac235f3c, 0x34a5ffff, 0x3c040001, -0x24843c08, 0xafa30010, 0xc0029d3, 0xafa00014, +0x24020100, 0x3c010001, 0xac225fa4, 0x3c010001, +0x1000000c, 0xac235fac, 0x34a5ffff, 0x3c040001, +0x24843c68, 0xafa30010, 0xc0029bb, 0xafa00014, 0x10000004, 0x0, 0x24020030, 0x3c010001, -0xac225f18, 0x8fbf0018, 0x3e00008, 0x27bd0020, +0xac225f88, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x0, 0x0, 0x0, 0x27bdffc8, 0xafb10024, 0x808821, 0xafb3002c, 0xa09821, -0xafb00020, 0xc08021, 0x3c040001, 0x24843c20, -0x3c050009, 0x3c020001, 0x8c423d18, 0x34a59001, +0xafb00020, 0xc08021, 0x3c040001, 0x24843c80, +0x3c050009, 0x3c020001, 0x8c423d88, 0x34a59001, 0x2203021, 0x2603821, 0xafbf0030, 0xafb20028, -0xa7a0001a, 0xafb00014, 0xc0029d3, 0xafa20010, +0xa7a0001a, 0xafb00014, 0xc0029bb, 0xafa20010, 0x24020002, 0x126200eb, 0x2e620003, 0x10400005, 0x24020001, 0x1262000a, 0x3c02fffb, 0x100000e5, 0x0, 0x24020004, 0x1262006d, 0x24020008, 0x1262006c, 0x3c02ffec, 0x100000de, 0x0, 0x3442ffff, 0x2028024, 0x119140, 0x3c010001, -0x320821, 0xac305f2c, 0x3c024000, 0x2021024, +0x320821, 0xac305f9c, 0x3c024000, 0x2021024, 0x10400046, 0x1023c2, 0x30840030, 0x101382, -0x3042000c, 0x3c030001, 0x24633d44, 0x431021, +0x3042000c, 0x3c030001, 0x24633db4, 0x431021, 0x823821, 0x3c020020, 0x2021024, 0x10400006, -0x24020100, 0x3c010001, 0x320821, 0xac225f30, +0x24020100, 0x3c010001, 0x320821, 0xac225fa0, 0x10000005, 0x3c020080, 0x3c010001, 0x320821, -0xac205f30, 0x3c020080, 0x2021024, 0x10400006, +0xac205fa0, 0x3c020080, 0x2021024, 0x10400006, 0x111940, 0x3c020001, 0x3c010001, 0x230821, -0x10000005, 0xac225f38, 0x111140, 0x3c010001, -0x220821, 0xac205f38, 0x94e30000, 0x32024000, +0x10000005, 0xac225fa8, 0x111140, 0x3c010001, +0x220821, 0xac205fa8, 0x94e30000, 0x32024000, 0x10400003, 0xa7a30018, 0x34624000, 0xa7a20018, 0x24040001, 0x94e20002, 0x24050004, 0x24e60002, -0x34420001, 0xc00420a, 0xa4e20002, 0x24040001, -0x2821, 0xc00420a, 0x27a60018, 0x3c020001, -0x8c423d18, 0x24110001, 0x3c010001, 0xac313d24, -0x14530004, 0x32028000, 0xc003bad, 0x0, -0x32028000, 0x10400097, 0x0, 0xc003bad, -0x0, 0x24020002, 0x3c010001, 0xac313d1c, -0x3c010001, 0x1000008f, 0xac223d18, 0x24040001, -0x24050004, 0x27b0001a, 0xc00420a, 0x2003021, -0x24040001, 0x2821, 0xc00420a, 0x2003021, -0x3c020001, 0x521021, 0x8c425f24, 0x3c040001, -0x8c843d18, 0x3c03bfff, 0x3463ffff, 0x3c010001, -0xac333d24, 0x431024, 0x3c010001, 0x320821, -0x10930076, 0xac225f24, 0x10000076, 0x0, +0x34420001, 0xc004166, 0xa4e20002, 0x24040001, +0x2821, 0xc004166, 0x27a60018, 0x3c020001, +0x8c423d88, 0x24110001, 0x3c010001, 0xac313d94, +0x14530004, 0x32028000, 0xc003b0b, 0x0, +0x32028000, 0x10400097, 0x0, 0xc003b0b, +0x0, 0x24020002, 0x3c010001, 0xac313d8c, +0x3c010001, 0x1000008f, 0xac223d88, 0x24040001, +0x24050004, 0x27b0001a, 0xc004166, 0x2003021, +0x24040001, 0x2821, 0xc004166, 0x2003021, +0x3c020001, 0x521021, 0x8c425f94, 0x3c040001, +0x8c843d88, 0x3c03bfff, 0x3463ffff, 0x3c010001, +0xac333d94, 0x431024, 0x3c010001, 0x320821, +0x10930076, 0xac225f94, 0x10000076, 0x0, 0x3c02ffec, 0x3442ffff, 0x2028024, 0x3c020008, 0x2028025, 0x111140, 0x3c010001, 0x220821, -0xac305f28, 0x3c022000, 0x2021024, 0x10400009, -0x0, 0x3c020001, 0x8c423da4, 0x14400005, -0x24020001, 0x3c010001, 0xac223e58, 0x10000004, -0x3c024000, 0x3c010001, 0xac203e58, 0x3c024000, +0xac305f98, 0x3c022000, 0x2021024, 0x10400009, +0x0, 0x3c020001, 0x8c423e14, 0x14400005, +0x24020001, 0x3c010001, 0xac223ec8, 0x10000004, +0x3c024000, 0x3c010001, 0xac203ec8, 0x3c024000, 0x2021024, 0x1440001a, 0x0, 0x3c020001, -0x8c423e58, 0x10400005, 0x24022020, 0x3c010001, -0xac223e5c, 0x24020001, 0xaee204b8, 0x3c04bfff, -0x111940, 0x3c020001, 0x431021, 0x8c425f20, -0x3c050001, 0x8ca53d18, 0x3484ffff, 0x441024, -0x3c010001, 0x230821, 0xac225f20, 0x24020001, +0x8c423ec8, 0x10400005, 0x24022020, 0x3c010001, +0xac223ecc, 0x24020001, 0xaee204b8, 0x3c04bfff, +0x111940, 0x3c020001, 0x431021, 0x8c425f90, +0x3c050001, 0x8ca53d88, 0x3484ffff, 0x441024, +0x3c010001, 0x230821, 0xac225f90, 0x24020001, 0x10a20044, 0x0, 0x10000040, 0x0, -0x3c020001, 0x8c423e58, 0x1040001c, 0x24022000, -0x3c010001, 0xac223e5c, 0x3c0300a0, 0x2031024, +0x3c020001, 0x8c423ec8, 0x1040001c, 0x24022000, +0x3c010001, 0xac223ecc, 0x3c0300a0, 0x2031024, 0x14430005, 0x111140, 0x3402a000, 0x3c010001, -0x1000002d, 0xac223e5c, 0x3c030001, 0x621821, -0x8c635f28, 0x3c020020, 0x621024, 0x10400004, -0x24022001, 0x3c010001, 0x10000023, 0xac223e5c, +0x1000002d, 0xac223ecc, 0x3c030001, 0x621821, +0x8c635f98, 0x3c020020, 0x621024, 0x10400004, +0x24022001, 0x3c010001, 0x10000023, 0xac223ecc, 0x3c020080, 0x621024, 0x1040001f, 0x3402a001, -0x3c010001, 0x1000001c, 0xac223e5c, 0x3c020020, +0x3c010001, 0x1000001c, 0xac223ecc, 0x3c020020, 0x2021024, 0x10400007, 0x111940, 0x24020100, -0x3c010001, 0x230821, 0xac225f34, 0x10000006, +0x3c010001, 0x230821, 0xac225fa4, 0x10000006, 0x3c020080, 0x111140, 0x3c010001, 0x220821, -0xac205f34, 0x3c020080, 0x2021024, 0x10400006, +0xac205fa4, 0x3c020080, 0x2021024, 0x10400006, 0x111940, 0x3c020001, 0x3c010001, 0x230821, -0x10000005, 0xac225f3c, 0x111140, 0x3c010001, -0x220821, 0xac205f3c, 0x3c030001, 0x8c633d18, -0x24020001, 0x10620003, 0x0, 0xc003bad, +0x10000005, 0xac225fac, 0x111140, 0x3c010001, +0x220821, 0xac205fac, 0x3c030001, 0x8c633d88, +0x24020001, 0x10620003, 0x0, 0xc003b0b, 0x0, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, 0x27bd0038, 0x27bdffd0, 0xafb50028, 0x80a821, 0xafb20020, @@ -8155,95 +8125,95 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x10400005, 0x24020001, 0x10a2000a, 0x158140, 0x100000ae, 0x2201021, 0x24020004, 0x10a2005e, 0x24020008, 0x10a2005d, 0x152940, 0x100000a7, -0x2201021, 0x3c030001, 0x701821, 0x8c635f2c, +0x2201021, 0x3c030001, 0x701821, 0x8c635f9c, 0x3c024000, 0x621024, 0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff, 0x628824, 0x3c010001, -0x300821, 0xac315f24, 0x10000098, 0x2201021, -0x24050001, 0xc0041c8, 0x27a60010, 0x24040001, -0x24050001, 0xc0041c8, 0x27a60010, 0x97a20010, +0x300821, 0xac315f94, 0x10000098, 0x2201021, +0x24050001, 0xc004124, 0x27a60010, 0x24040001, +0x24050001, 0xc004124, 0x27a60010, 0x97a20010, 0x30420004, 0x10400034, 0x3c114000, 0x3c030001, -0x8c633e70, 0x24020003, 0x10620008, 0x2c620004, +0x8c633ee0, 0x24020003, 0x10620008, 0x2c620004, 0x14400029, 0x3c028000, 0x24020004, 0x10620014, 0x24040001, 0x10000024, 0x3c028000, 0x24040001, -0x24050011, 0x27b00012, 0xc0041c8, 0x2003021, -0x24040001, 0x24050011, 0xc0041c8, 0x2003021, +0x24050011, 0x27b00012, 0xc004124, 0x2003021, +0x24040001, 0x24050011, 0xc004124, 0x2003021, 0x97a30012, 0x30624000, 0x10400002, 0x3c130010, 0x3c130008, 0x3c120001, 0x10000010, 0x30628000, -0x24050014, 0x27b00012, 0xc0041c8, 0x2003021, -0x24040001, 0x24050014, 0xc0041c8, 0x2003021, +0x24050014, 0x27b00012, 0xc004124, 0x2003021, +0x24040001, 0x24050014, 0xc004124, 0x2003021, 0x97a30012, 0x30621000, 0x10400002, 0x3c130010, 0x3c130008, 0x3c120001, 0x30620800, 0x54400001, 0x3c120002, 0x3c028000, 0x2221025, 0x2531825, 0x10000007, 0x438825, 0x3c110001, 0x2308821, -0x8e315f2c, 0x3c027fff, 0x3442ffff, 0x2228824, -0x151140, 0x3c010001, 0x220821, 0xac315f24, +0x8e315f9c, 0x3c027fff, 0x3442ffff, 0x2228824, +0x151140, 0x3c010001, 0x220821, 0xac315f94, 0x1000004e, 0x2201021, 0x152940, 0x3c030001, -0x651821, 0x8c635f28, 0x3c024000, 0x621024, +0x651821, 0x8c635f98, 0x3c024000, 0x621024, 0x14400008, 0x3c027fff, 0x3442ffff, 0x628824, -0x3c010001, 0x250821, 0xac315f20, 0x1000003f, -0x2201021, 0x3c020001, 0x8c423d28, 0x10400033, -0x3c11c00c, 0x3c020001, 0x8c423da4, 0x3c04c00c, -0x34842000, 0x3c030001, 0x8c633e58, 0x2102b, +0x3c010001, 0x250821, 0xac315f90, 0x1000003f, +0x2201021, 0x3c020001, 0x8c423d98, 0x10400033, +0x3c11c00c, 0x3c020001, 0x8c423e14, 0x3c04c00c, +0x34842000, 0x3c030001, 0x8c633ec8, 0x2102b, 0x21023, 0x441024, 0x10600003, 0x518825, 0x3c022000, 0x2228825, 0x3c020001, 0x451021, -0x8c425f34, 0x10400003, 0x3c020020, 0x10000004, +0x8c425fa4, 0x10400003, 0x3c020020, 0x10000004, 0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x151140, 0x3c010001, 0x220821, 0x8c225f3c, +0x151140, 0x3c010001, 0x220821, 0x8c225fac, 0x10400003, 0x3c020080, 0x10000004, 0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c020001, -0x8c423d90, 0x10400002, 0x3c020800, 0x2228825, -0x3c020001, 0x8c423d94, 0x10400002, 0x3c020400, -0x2228825, 0x3c020001, 0x8c423d98, 0x10400006, +0x8c423e00, 0x10400002, 0x3c020800, 0x2228825, +0x3c020001, 0x8c423e04, 0x10400002, 0x3c020400, +0x2228825, 0x3c020001, 0x8c423e08, 0x10400006, 0x3c020100, 0x10000004, 0x2228825, 0x3c027fff, 0x3442ffff, 0x628824, 0x151140, 0x3c010001, -0x220821, 0xac315f20, 0x2201021, 0x8fbf002c, +0x220821, 0xac315f90, 0x2201021, 0x8fbf002c, 0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffe0, 0xafb20018, 0x809021, 0xafbf001c, 0xafb10014, -0xafb00010, 0x8f840200, 0x3c030001, 0x8c633d18, +0xafb00010, 0x8f840200, 0x3c030001, 0x8c633d88, 0x8f860220, 0x24020002, 0x106200a6, 0x2c620003, 0x10400005, 0x24020001, 0x1062000a, 0x121940, 0x100000a0, 0x0, 0x24020004, 0x10620053, 0x24020008, 0x10620052, 0x128940, 0x10000099, -0x0, 0x3c050001, 0xa32821, 0x8ca55f2c, -0x3c100001, 0x2038021, 0x8e105f24, 0x3c024000, +0x0, 0x3c050001, 0xa32821, 0x8ca55f9c, +0x3c100001, 0x2038021, 0x8e105f94, 0x3c024000, 0xa21024, 0x10400038, 0x3c020008, 0x2021024, 0x10400020, 0x34840002, 0x3c020001, 0x431021, -0x8c425f30, 0x10400005, 0x34840020, 0x34840100, +0x8c425fa0, 0x10400005, 0x34840020, 0x34840100, 0x3c020020, 0x10000006, 0x2028025, 0x2402feff, 0x822024, 0x3c02ffdf, 0x3442ffff, 0x2028024, -0x121140, 0x3c010001, 0x220821, 0x8c225f38, +0x121140, 0x3c010001, 0x220821, 0x8c225fa8, 0x10400005, 0x3c020001, 0xc23025, 0x3c020080, 0x10000016, 0x2028025, 0x3c02fffe, 0x3442ffff, 0xc23024, 0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2028024, 0x2402fedf, 0x822024, 0x3c02fffe, 0x3442ffff, 0xc23024, 0x3c02ff5f, 0x3442ffff, -0x2028024, 0x3c010001, 0x230821, 0xac205f30, -0x3c010001, 0x230821, 0xac205f38, 0xaf840200, +0x2028024, 0x3c010001, 0x230821, 0xac205fa0, +0x3c010001, 0x230821, 0xac205fa8, 0xaf840200, 0xaf860220, 0x8f820220, 0x34420002, 0xaf820220, 0x1000000a, 0x121140, 0x3c02bfff, 0x3442ffff, 0x8f830200, 0x2028024, 0x2402fffd, 0x621824, -0xc003bad, 0xaf830200, 0x121140, 0x3c010001, -0x220821, 0x1000004b, 0xac305f24, 0x128940, -0x3c050001, 0xb12821, 0x8ca55f28, 0x3c100001, -0x2118021, 0x8e105f20, 0x3c024000, 0xa21024, -0x14400010, 0x0, 0x3c020001, 0x8c423e58, +0xc003b0b, 0xaf830200, 0x121140, 0x3c010001, +0x220821, 0x1000004b, 0xac305f94, 0x128940, +0x3c050001, 0xb12821, 0x8ca55f98, 0x3c100001, +0x2118021, 0x8e105f90, 0x3c024000, 0xa21024, +0x14400010, 0x0, 0x3c020001, 0x8c423ec8, 0x14400005, 0x3c02bfff, 0x8f820200, 0x34420002, -0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc003bad, +0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc003b0b, 0x2028024, 0x3c010001, 0x310821, 0x10000031, -0xac305f20, 0x3c020001, 0x8c423e58, 0x10400005, -0x3c020020, 0x3c020001, 0x8c423da4, 0x10400025, +0xac305f90, 0x3c020001, 0x8c423ec8, 0x10400005, +0x3c020020, 0x3c020001, 0x8c423e14, 0x10400025, 0x3c020020, 0xa21024, 0x10400007, 0x34840020, -0x24020100, 0x3c010001, 0x310821, 0xac225f34, +0x24020100, 0x3c010001, 0x310821, 0xac225fa4, 0x10000006, 0x34840100, 0x3c010001, 0x310821, -0xac205f34, 0x2402feff, 0x822024, 0x3c020080, +0xac205fa4, 0x2402feff, 0x822024, 0x3c020080, 0xa21024, 0x10400007, 0x121940, 0x3c020001, -0x3c010001, 0x230821, 0xac225f3c, 0x10000008, +0x3c010001, 0x230821, 0xac225fac, 0x10000008, 0xc23025, 0x121140, 0x3c010001, 0x220821, -0xac205f3c, 0x3c02fffe, 0x3442ffff, 0xc23024, +0xac205fac, 0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200, 0xaf860220, 0x8f820220, 0x34420002, 0xaf820220, 0x121140, 0x3c010001, 0x220821, -0xac305f20, 0x8fbf001c, 0x8fb20018, 0x8fb10014, +0xac305f90, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020, 0x1821, 0x308400ff, 0x2405ffdf, 0x2406ffbf, 0x641007, 0x30420001, 0x10400004, 0x0, 0x8f820044, @@ -8251,15 +8221,58 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0xaf820044, 0x8f820044, 0x34420020, 0xaf820044, 0x8f820044, 0x451024, 0xaf820044, 0x24630001, 0x28620008, 0x5440ffee, 0x641007, 0x3e00008, +0x0, 0x0, 0x0, 0x8f8400c4, +0x8f8600e0, 0x8f8700e4, 0x2402fff8, 0xc22824, +0x10e5001a, 0x27623ff8, 0x14e20002, 0x24e80008, +0x27683000, 0x55050004, 0x8d0a0000, 0x30c20004, +0x14400012, 0x805021, 0x8ce90000, 0x8f42013c, +0x1494823, 0x49182b, 0x94eb0006, 0x10600002, +0x25630050, 0x494821, 0x123182b, 0x50400003, +0x8f4201fc, 0x3e00008, 0xe01021, 0xaf8800e8, +0x24420001, 0xaf4201fc, 0xaf8800e4, 0x3e00008, +0x1021, 0x3e00008, 0x0, 0x8f8300e4, +0x27623ff8, 0x10620004, 0x24620008, 0xaf8200e4, +0x3e00008, 0xaf8200e8, 0x27623000, 0xaf8200e4, +0x3e00008, 0xaf8200e8, 0x3e00008, 0x0, +0x27bdffd0, 0xafbf0028, 0x8f4c004c, 0x8f4d0048, +0xafb00024, 0x118d0026, 0x1ac4023, 0x8f490054, +0x5020001, 0x25080200, 0x189102b, 0x14400003, +0x24020200, 0x8004abe, 0x4c5023, 0x12c5023, +0x254affff, 0x10a102a, 0x54400001, 0x1005021, +0x14c8021, 0x321001ff, 0x8f45017c, 0x8f440178, +0xc1140, 0xa22821, 0x3406ecc0, 0xc23021, +0x2e63021, 0xa3940, 0x24031000, 0xafa30010, +0x8f430108, 0xafb00014, 0x8f420014, 0x60f809, +0xafa20018, 0x10400002, 0x8fbf0028, 0xaf50004c, +0x120d0003, 0x8fb00024, 0x3e00008, 0x27bd0030, +0xaf800048, 0x8f820048, 0x0, 0x1040fffc, +0x8f820060, 0x2403fdff, 0x431024, 0xaf820060, +0xaf800048, 0x3e00008, 0x27bd0030, 0x3e00008, +0x0, 0x0, 0x0, 0x8f880120, +0x27624fe0, 0x8f830128, 0x15020002, 0x25090020, +0x27694800, 0x11230012, 0x8fa20010, 0xad040000, +0xad050004, 0xad060008, 0xa507000e, 0x8fa30014, +0xad020018, 0x8fa20018, 0xad03001c, 0x25030016, +0xad020010, 0xad030014, 0xaf890120, 0x8f4300fc, +0x24020001, 0x2463ffff, 0x3e00008, 0xaf4300fc, +0x8f430324, 0x1021, 0x24630001, 0x3e00008, +0xaf430324, 0x3e00008, 0x0, 0x8f880100, +0x276247e0, 0x8f830108, 0x15020002, 0x25090020, +0x27694000, 0x1123000f, 0x8fa20010, 0xad040000, +0xad050004, 0xad060008, 0xa507000e, 0x8fa30014, +0xad020018, 0x8fa20018, 0xad03001c, 0x25030016, +0xad020010, 0xad030014, 0xaf890100, 0x3e00008, +0x24020001, 0x8f430328, 0x1021, 0x24630001, +0x3e00008, 0xaf430328, 0x3e00008, 0x0, 0x0, 0x0, 0x0, 0x0 }; u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x66776d61, 0x696e2e63, 0x2c762031, 0x2e312e32, -0x2e343520, 0x31393939, 0x2f30312f, 0x32342030, -0x303a3130, 0x3a353520, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x65767452, 0x6e674600, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f6677, 0x6d61696e, 0x2e632c76, 0x20312e31, +0x2e322e34, 0x35203139, 0x39392f30, 0x312f3234, +0x2030303a, 0x31303a35, 0x35207368, 0x75616e67, +0x20457870, 0x20240000, 0x65767452, 0x6e674600, 0x51657674, 0x46000000, 0x51657674, 0x505f4600, 0x4d657674, 0x526e6746, 0x0, 0x4d516576, 0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, @@ -8326,27 +8339,27 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x5f646573, 0x63720000, 0x2b685f68, 0x665f7469, 0x6d657200, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x74696d65, 0x722e632c, 0x7620312e, 0x312e322e, -0x33352031, 0x3939392f, 0x30312f32, 0x37203139, -0x3a30393a, 0x35302068, 0x61796573, 0x20457870, -0x20240000, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x542d446d, 0x61526432, 0x0, -0x542d446d, 0x61526431, 0x0, 0x542d446d, -0x61526442, 0x0, 0x542d446d, 0x61577232, -0x0, 0x542d446d, 0x61577231, 0x0, -0x542d446d, 0x61577242, 0x0, 0x0, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f7469, 0x6d65722e, 0x632c7620, 0x312e312e, +0x322e3335, 0x20313939, 0x392f3031, 0x2f323720, +0x31393a30, 0x393a3530, 0x20686179, 0x65732045, +0x78702024, 0x0, 0x65767452, 0x6e674600, +0x51657674, 0x46000000, 0x51657674, 0x505f4600, +0x4d657674, 0x526e6746, 0x0, 0x4d516576, +0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, +0x6e495f46, 0x0, 0x5173436f, 0x6e734600, +0x51725072, 0x6f644600, 0x542d446d, 0x61526432, +0x0, 0x542d446d, 0x61526431, 0x0, +0x542d446d, 0x61526442, 0x0, 0x542d446d, +0x61577232, 0x0, 0x542d446d, 0x61577231, +0x0, 0x542d446d, 0x61577242, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x636f6d6d, 0x616e642e, 0x632c7620, 0x312e312e, -0x322e3238, 0x20313939, 0x392f3031, 0x2f323020, -0x31393a34, 0x393a3439, 0x20736875, 0x616e6720, -0x45787020, 0x24000000, 0x65767452, 0x6e674600, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f636f, 0x6d6d616e, 0x642e632c, 0x7620312e, +0x312e322e, 0x32382031, 0x3939392f, 0x30312f32, +0x30203139, 0x3a34393a, 0x34392073, 0x6875616e, +0x67204578, 0x70202400, 0x65767452, 0x6e674600, 0x51657674, 0x46000000, 0x51657674, 0x505f4600, 0x4d657674, 0x526e6746, 0x0, 0x4d516576, 0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, @@ -8355,33 +8368,33 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x0, 0x3f636d64, 0x48737453, 0x0, 0x3f636d64, 0x4d634d64, 0x0, 0x3f636d64, 0x50726f6d, 0x0, 0x3f636d64, 0x4c696e6b, -0x0, 0x3f636d64, 0x45727200, 0x811c, -0x8898, 0x8898, 0x8820, 0x85c4, -0x886c, 0x8898, 0x81f4, 0x8258, -0x83dc, 0x84b4, 0x8480, 0x8898, -0x82bc, 0x8570, 0x8898, 0x8580, -0x8218, 0x827c, 0x0, 0x0, +0x0, 0x3f636d64, 0x45727200, 0x80fc, +0x8878, 0x8878, 0x8800, 0x85a4, +0x884c, 0x8878, 0x81d4, 0x8238, +0x83bc, 0x8494, 0x8460, 0x8878, +0x829c, 0x8550, 0x8878, 0x8560, +0x81f8, 0x825c, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x6d636173, 0x742e632c, 0x7620312e, 0x312e322e, -0x38203139, 0x39382f31, 0x322f3038, 0x2030323a, -0x33363a33, 0x36207368, 0x75616e67, 0x20457870, -0x20240000, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x6164644d, 0x63447570, 0x0, -0x6164644d, 0x6346756c, 0x0, 0x64656c4d, -0x634e6f45, 0x0, 0x0, 0x0, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f6d63, 0x6173742e, 0x632c7620, 0x312e312e, +0x322e3820, 0x31393938, 0x2f31322f, 0x30382030, +0x323a3336, 0x3a333620, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x65767452, 0x6e674600, +0x51657674, 0x46000000, 0x51657674, 0x505f4600, +0x4d657674, 0x526e6746, 0x0, 0x4d516576, +0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, +0x6e495f46, 0x0, 0x5173436f, 0x6e734600, +0x51725072, 0x6f644600, 0x6164644d, 0x63447570, +0x0, 0x6164644d, 0x6346756c, 0x0, +0x64656c4d, 0x634e6f45, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x646d612e, 0x632c7620, 0x312e312e, 0x322e3234, -0x20313939, 0x382f3132, 0x2f323120, 0x30303a33, -0x333a3039, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x65767452, 0x6e674600, 0x51657674, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f646d, 0x612e632c, 0x7620312e, 0x312e322e, +0x32342031, 0x3939382f, 0x31322f32, 0x31203030, +0x3a33333a, 0x30392073, 0x6875616e, 0x67204578, +0x70202400, 0x65767452, 0x6e674600, 0x51657674, 0x46000000, 0x51657674, 0x505f4600, 0x4d657674, 0x526e6746, 0x0, 0x4d516576, 0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, @@ -8390,81 +8403,84 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x31446d61, 0x4f6e0000, 0x7377446d, 0x614f6e00, 0x2372446d, 0x6141544e, 0x0, 0x72446d61, 0x41544e30, 0x0, 0x72446d61, 0x41544e31, -0x0, 0x2a50414e, 0x49432a00, 0x2e2e2f2e, -0x2e2f2e2e, 0x2f2e2e2f, 0x2e2e2f73, 0x72632f6e, -0x69632f66, 0x77322f63, 0x6f6d6d6f, 0x6e2f646d, -0x612e6300, 0x2377446d, 0x6141544e, 0x0, -0x77446d61, 0x41544e30, 0x0, 0x77446d61, -0x41544e31, 0x0, 0x0, 0x0, +0x0, 0x72446d61, 0x34476200, 0x2a50414e, +0x49432a00, 0x2e2e2f2e, 0x2e2f2e2e, 0x2f2e2e2f, +0x2e2e2f73, 0x72632f6e, 0x69632f66, 0x77322f63, +0x6f6d6d6f, 0x6e2f646d, 0x612e6300, 0x2377446d, +0x6141544e, 0x0, 0x77446d61, 0x41544e30, +0x0, 0x77446d61, 0x41544e31, 0x0, +0x77446d61, 0x34476200, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x74726163, 0x652e632c, 0x7620312e, 0x312e322e, -0x35203139, 0x39382f30, 0x392f3330, 0x2031383a, -0x35303a32, 0x38207368, 0x75616e67, 0x20457870, -0x20240000, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x64617461, 0x2e632c76, 0x20312e31, 0x2e322e31, -0x32203139, 0x39392f30, 0x312f3230, 0x2031393a, -0x34393a35, 0x31207368, 0x75616e67, 0x20457870, -0x20240000, 0x46575f56, 0x45525349, 0x4f4e3a20, -0x2331204d, 0x6f6e2046, 0x65622031, 0x2031373a, -0x30313a30, 0x36205053, 0x54203139, 0x39390000, -0x46575f43, 0x4f4d5049, 0x4c455f54, 0x494d453a, -0x2031373a, 0x30313a30, 0x36000000, 0x46575f43, -0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263, -0x73000000, 0x46575f43, 0x4f4d5049, 0x4c455f48, -0x4f53543a, 0x20636f6d, 0x70757465, 0x0, -0x46575f43, 0x4f4d5049, 0x4c455f44, 0x4f4d4149, -0x4e3a2065, 0x6e672e61, 0x6374656f, 0x6e2e636f, -0x6d000000, 0x46575f43, 0x4f4d5049, 0x4c45523a, -0x20676363, 0x20766572, 0x73696f6e, 0x20322e37, -0x2e320000, 0x0, 0x12030303, 0x0, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f7472, 0x6163652e, 0x632c7620, 0x312e312e, +0x322e3520, 0x31393938, 0x2f30392f, 0x33302031, +0x383a3530, 0x3a323820, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x6d656d2e, 0x632c7620, 0x312e312e, 0x322e3520, -0x31393938, 0x2f30392f, 0x33302031, 0x383a3530, -0x3a303820, 0x73687561, 0x6e672045, 0x78702024, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f6461, 0x74612e63, 0x2c762031, 0x2e312e32, +0x2e313220, 0x31393939, 0x2f30312f, 0x32302031, +0x393a3439, 0x3a353120, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x46575f56, 0x45525349, +0x4f4e3a20, 0x23312054, 0x68752041, 0x75672031, +0x32203135, 0x3a35323a, 0x32392050, 0x44542031, +0x39393900, 0x46575f43, 0x4f4d5049, 0x4c455f54, +0x494d453a, 0x2031353a, 0x35323a32, 0x39000000, +0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064, +0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049, +0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465, +0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44, +0x4f4d4149, 0x4e3a2065, 0x6e672e61, 0x6374656f, +0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049, +0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e, +0x20322e37, 0x2e320000, 0x0, 0x12030303, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x73656e64, 0x2e632c76, 0x20312e31, 0x2e322e34, -0x34203139, 0x39382f31, 0x322f3231, 0x2030303a, -0x33333a31, 0x38207368, 0x75616e67, 0x20457870, -0x20240000, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x69736e74, 0x54637055, 0x0, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f6d65, 0x6d2e632c, 0x7620312e, 0x312e322e, +0x35203139, 0x39382f30, 0x392f3330, 0x2031383a, +0x35303a30, 0x38207368, 0x75616e67, 0x20457870, +0x20240000, 0x24486561, 0x6465723a, 0x202f7072, +0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f7365, 0x6e642e63, 0x2c762031, 0x2e312e32, +0x2e343420, 0x31393938, 0x2f31322f, 0x32312030, +0x303a3333, 0x3a313820, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x65767452, 0x6e674600, +0x51657674, 0x46000000, 0x51657674, 0x505f4600, +0x4d657674, 0x526e6746, 0x0, 0x4d516576, +0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, +0x6e495f46, 0x0, 0x5173436f, 0x6e734600, +0x51725072, 0x6f644600, 0x69736e74, 0x54637055, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x72656376, 0x2e632c76, 0x20312e31, 0x2e322e35, -0x33203139, 0x39392f30, 0x312f3136, 0x2030323a, -0x35353a34, 0x33207368, 0x75616e67, 0x20457870, -0x20240000, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x72784672, 0x6d324c67, 0x0, -0x72784e6f, 0x53744264, 0x0, 0x72784e6f, -0x4d694264, 0x0, 0x72784e6f, 0x4a6d4264, -0x0, 0x7278436b, 0x446d6146, 0x0, -0x72785144, 0x6d457846, 0x0, 0x72785144, -0x6d614600, 0x72785144, 0x4c426446, 0x0, -0x72785144, 0x6d426446, 0x0, 0x72784372, -0x63506164, 0x0, 0x72536d51, 0x446d6146, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f7265, 0x63762e63, 0x2c762031, 0x2e312e32, +0x2e353320, 0x31393939, 0x2f30312f, 0x31362030, +0x323a3535, 0x3a343320, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x65767452, 0x6e674600, +0x51657674, 0x46000000, 0x51657674, 0x505f4600, +0x4d657674, 0x526e6746, 0x0, 0x4d516576, +0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, +0x6e495f46, 0x0, 0x5173436f, 0x6e734600, +0x51725072, 0x6f644600, 0x72784672, 0x6d324c67, +0x0, 0x72784e6f, 0x53744264, 0x0, +0x72784e6f, 0x4d694264, 0x0, 0x72784e6f, +0x4a6d4264, 0x0, 0x7278436b, 0x446d6146, +0x0, 0x72785144, 0x6d457846, 0x0, +0x72785144, 0x6d614600, 0x72785144, 0x4c426446, +0x0, 0x72785144, 0x6d426446, 0x0, +0x72784372, 0x63506164, 0x0, 0x72536d51, +0x446d6146, 0x0, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x6d61632e, 0x632c7620, 0x312e312e, 0x322e3232, -0x20313939, 0x382f3132, 0x2f303820, 0x30323a33, -0x363a3330, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x65767452, 0x6e674600, 0x51657674, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f6d61, 0x632e632c, 0x7620312e, 0x312e322e, +0x32322031, 0x3939382f, 0x31322f30, 0x38203032, +0x3a33363a, 0x33302073, 0x6875616e, 0x67204578, +0x70202400, 0x65767452, 0x6e674600, 0x51657674, 0x46000000, 0x51657674, 0x505f4600, 0x4d657674, 0x526e6746, 0x0, 0x4d516576, 0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, @@ -8476,32 +8492,33 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x6c696e6b, 0x55500000, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, -0x636b7375, 0x6d2e632c, 0x7620312e, 0x312e322e, -0x39203139, 0x39392f30, 0x312f3134, 0x2030303a, -0x30333a34, 0x38207368, 0x75616e67, 0x20457870, -0x20240000, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x50726f62, 0x65506879, 0x0, -0x6c6e6b41, 0x53535254, 0x0, 0xff04, -0xff34, 0xff4c, 0xff78, 0xffa4, -0xffb8, 0xfff4, 0x10394, 0x10174, -0x101ac, 0x100a4, 0x10200, 0x10228, -0x1025c, 0x100e8, 0x10394, 0x10174, -0x101ac, 0x101d0, 0x10200, 0x10228, -0x1025c, 0x10288, 0x0, 0x0, -0x0, 0x1097c, 0x10a4c, 0x10b24, -0x10bf4, 0x10c50, 0x10d2c, 0x10d54, -0x10e30, 0x10e58, 0x11000, 0x11028, -0x111d0, 0x113c8, 0x1165c, 0x11570, -0x1165c, 0x11688, 0x111f8, 0x113a0, -0x0, 0x1198c, 0x119cc, 0x11a5c, -0x11aa0, 0x11b04, 0x11b90, 0x11bc4, -0x11c4c, 0x11ce4, 0x11db4, 0x11df4, -0x11e78, 0x11e9c, 0x11fac, 0x646f4261, +0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, +0x6e2f636b, 0x73756d2e, 0x632c7620, 0x312e312e, +0x322e3920, 0x31393939, 0x2f30312f, 0x31342030, +0x303a3033, 0x3a343820, 0x73687561, 0x6e672045, +0x78702024, 0x0, 0x65767452, 0x6e674600, +0x51657674, 0x46000000, 0x51657674, 0x505f4600, +0x4d657674, 0x526e6746, 0x0, 0x4d516576, +0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, +0x6e495f46, 0x0, 0x5173436f, 0x6e734600, +0x51725072, 0x6f644600, 0x0, 0x0, +0x0, 0x50726f62, 0x65506879, 0x0, +0x6c6e6b41, 0x53535254, 0x0, 0xfc78, +0xfca8, 0xfcc0, 0xfcec, 0xfd18, +0xfd2c, 0xfd68, 0x10108, 0xfee8, +0xff20, 0xfe18, 0xff74, 0xff9c, +0xffd0, 0xfe5c, 0x10108, 0xfee8, +0xff20, 0xff44, 0xff74, 0xff9c, +0xffd0, 0xfffc, 0x0, 0x0, +0x0, 0x106ec, 0x107bc, 0x10894, +0x10964, 0x109c0, 0x10a9c, 0x10ac4, +0x10ba0, 0x10bc8, 0x10d70, 0x10d98, +0x10f40, 0x11138, 0x113cc, 0x112e0, +0x113cc, 0x113f8, 0x10f68, 0x11110, +0x0, 0x116fc, 0x1173c, 0x117cc, +0x11810, 0x11874, 0x11900, 0x11934, +0x119bc, 0x11a54, 0x11b24, 0x11b64, +0x11be8, 0x11c0c, 0x11d1c, 0x646f4261, 0x73655067, 0x0, 0x0, 0x0, 0x0, 0x73746d61, 0x634c4e4b, 0x0, 0x0, 0x0 }; diff --git a/drivers/net/am79c961a.c b/drivers/net/am79c961a.c index 4e0f00318..cfb48ca03 100644 --- a/drivers/net/am79c961a.c +++ b/drivers/net/am79c961a.c @@ -36,7 +36,7 @@ static unsigned int net_debug = NET_DEBUG; static void -am79c961_setmulticastlist (struct device *dev); +am79c961_setmulticastlist (struct net_device *dev); static char *version = "am79c961 ethernet driver (c) 1995 R.M.King v0.00\n"; @@ -69,7 +69,7 @@ write_ireg (unsigned long base, unsigned int reg, unsigned short val) " : : "r" ((val) & 0xffff), "r" (0xe0000000 + ((off) << 1))); static inline void -am_writebuffer(struct device *dev, unsigned int offset, unsigned char *buf, unsigned int length) +am_writebuffer(struct net_device *dev, unsigned int offset, unsigned char *buf, unsigned int length) { offset = 0xe0000000 + (offset << 1); length = (length + 1) & ~1; @@ -115,7 +115,7 @@ read_rreg (unsigned int base_addr, unsigned int reg) } static inline unsigned short -am_readword (struct device *dev, unsigned long off) +am_readword (struct net_device *dev, unsigned long off) { unsigned long address = 0xe0000000 + (off << 1); unsigned short val; @@ -127,7 +127,7 @@ am_readword (struct device *dev, unsigned long off) } static inline void -am_readbuffer(struct device *dev, unsigned int offset, unsigned char *buf, unsigned int length) +am_readbuffer(struct net_device *dev, unsigned int offset, unsigned char *buf, unsigned int length) { offset = 0xe0000000 + (offset << 1); length = (length + 1) & ~1; @@ -168,7 +168,7 @@ am_readbuffer(struct device *dev, unsigned int offset, unsigned char *buf, unsig } static int -am79c961_ramtest(struct device *dev, unsigned int val) +am79c961_ramtest(struct net_device *dev, unsigned int val) { unsigned char *buffer = kmalloc (65536, GFP_KERNEL); int i, error = 0, errorcount = 0; @@ -196,7 +196,7 @@ am79c961_ramtest(struct device *dev, unsigned int val) } static void -am79c961_init_for_open(struct device *dev) +am79c961_init_for_open(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; unsigned long hdr_addr, first_free_addr; @@ -264,7 +264,7 @@ am79c961_init_for_open(struct device *dev) } static int -am79c961_init(struct device *dev) +am79c961_init(struct net_device *dev) { unsigned long flags; @@ -286,7 +286,7 @@ am79c961_init(struct device *dev) * This is the real probe routine. */ static int -am79c961_probe1(struct device *dev) +am79c961_probe1(struct net_device *dev) { static unsigned version_printed = 0; struct dev_priv *priv; @@ -351,7 +351,7 @@ am79c961_probe1(struct device *dev) } int -am79c961_probe(struct device *dev) +am79c961_probe(struct net_device *dev) { static int initialised = 0; @@ -374,7 +374,7 @@ am79c961_probe(struct device *dev) * there is non-reboot way to recover if something goes wrong. */ static int -am79c961_open(struct device *dev) +am79c961_open(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -397,7 +397,7 @@ am79c961_open(struct device *dev) * The inverse routine to am79c961_open(). */ static int -am79c961_close(struct device *dev) +am79c961_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -414,7 +414,7 @@ am79c961_close(struct device *dev) * Get the current statistics. This may be called with the card open or * closed. */ -static struct enet_statistics *am79c961_getstats (struct device *dev) +static struct enet_statistics *am79c961_getstats (struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; return &priv->stats; @@ -426,7 +426,7 @@ static struct enet_statistics *am79c961_getstats (struct device *dev) * We don't attempt any packet filtering. The card may have a SEEQ 8004 * in which does not have the other ethernet address registers present... */ -static void am79c961_setmulticastlist (struct device *dev) +static void am79c961_setmulticastlist (struct net_device *dev) { unsigned long flags; int i; @@ -446,7 +446,7 @@ static void am79c961_setmulticastlist (struct device *dev) * Transmit a packet */ static int -am79c961_sendpacket(struct sk_buff *skb, struct device *dev) +am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -494,7 +494,7 @@ again: static void am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct dev_priv *priv = (struct dev_priv *)dev->priv; unsigned int status; @@ -527,7 +527,7 @@ am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs) * If we have a good packet(s), get it/them out of the buffers. */ static void -am79c961_rx(struct device *dev, struct dev_priv *priv) +am79c961_rx(struct net_device *dev, struct dev_priv *priv) { unsigned long hdraddr; unsigned long pktaddr; @@ -589,7 +589,7 @@ am79c961_rx(struct device *dev, struct dev_priv *priv) * Update stats for the transmitted packet */ static void -am79c961_tx(struct device *dev, struct dev_priv *priv) +am79c961_tx(struct net_device *dev, struct dev_priv *priv) { do { unsigned long hdraddr; diff --git a/drivers/net/am79c961a.h b/drivers/net/am79c961a.h index 4c15f8a8a..24bcd24fa 100644 --- a/drivers/net/am79c961a.h +++ b/drivers/net/am79c961a.h @@ -114,15 +114,15 @@ struct dev_priv { unsigned long txhdr; }; -extern int am79c961_probe (struct device *dev); -static int am79c961_probe1 (struct device *dev); -static int am79c961_open (struct device *dev); -static int am79c961_sendpacket (struct sk_buff *skb, struct device *dev); +extern int am79c961_probe (struct net_device *dev); +static int am79c961_probe1 (struct net_device *dev); +static int am79c961_open (struct net_device *dev); +static int am79c961_sendpacket (struct sk_buff *skb, struct net_device *dev); static void am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static void am79c961_rx (struct device *dev, struct dev_priv *priv); -static void am79c961_tx (struct device *dev, struct dev_priv *priv); -static int am79c961_close (struct device *dev); -static struct enet_statistics *am79c961_getstats (struct device *dev); -static void am79c961_setmulticastlist (struct device *dev); +static void am79c961_rx (struct net_device *dev, struct dev_priv *priv); +static void am79c961_tx (struct net_device *dev, struct dev_priv *priv); +static int am79c961_close (struct net_device *dev); +static struct enet_statistics *am79c961_getstats (struct net_device *dev); +static void am79c961_setmulticastlist (struct net_device *dev); #endif diff --git a/drivers/net/apne.c b/drivers/net/apne.c index 28ac93605..33da607fe 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -74,18 +74,18 @@ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -int apne_probe(struct device *dev); -static int apne_probe1(struct device *dev, int ioaddr); +int apne_probe(struct net_device *dev); +static int apne_probe1(struct net_device *dev, int ioaddr); -static int apne_open(struct device *dev); -static int apne_close(struct device *dev); +static int apne_open(struct net_device *dev); +static int apne_close(struct net_device *dev); -static void apne_reset_8390(struct device *dev); -static void apne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void apne_reset_8390(struct net_device *dev); +static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void apne_block_input(struct device *dev, int count, +static void apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void apne_block_output(struct device *dev, const int count, +static void apne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -121,7 +121,7 @@ static const char *version = static int apne_owned = 0; /* signal if card already owned */ -int __init apne_probe(struct device *dev) +int __init apne_probe(struct net_device *dev) { #ifndef MANUAL_CONFIG char tuple[8]; @@ -161,7 +161,7 @@ int __init apne_probe(struct device *dev) } -static int __init apne_probe1(struct device *dev, int ioaddr) +static int __init apne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; @@ -294,7 +294,8 @@ static int __init apne_probe1(struct device *dev, int ioaddr) dev->base_addr = ioaddr; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, apne_interrupt, 0, "apne Ethernet", dev)) + if (request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, + "apne Ethernet", dev)) return -EAGAIN; @@ -337,7 +338,7 @@ static int __init apne_probe1(struct device *dev, int ioaddr) } static int -apne_open(struct device *dev) +apne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; @@ -345,7 +346,7 @@ apne_open(struct device *dev) } static int -apne_close(struct device *dev) +apne_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -357,7 +358,7 @@ apne_close(struct device *dev) /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ static void -apne_reset_8390(struct device *dev) +apne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -384,7 +385,7 @@ apne_reset_8390(struct device *dev) the start of a page, so we optimize accordingly. */ static void -apne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -433,7 +434,7 @@ apne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) the packet out through the "remote DMA" dataport using writeb. */ static void -apne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; char *buf = skb->data; @@ -475,7 +476,7 @@ apne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_of } static void -apne_block_output(struct device *dev, int count, +apne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -560,7 +561,7 @@ static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs) #ifdef MODULE static char devicename[9] = {0, }; -static struct device apne_dev = +static struct net_device apne_dev = { devicename, 0, 0, 0, 0, diff --git a/drivers/net/arc-rimi.c b/drivers/net/arc-rimi.c index c0c8161ae..f9f434891 100644 --- a/drivers/net/arc-rimi.c +++ b/drivers/net/arc-rimi.c @@ -74,15 +74,15 @@ /* Internal function declarations */ -static int arcrimi_probe(struct device *dev); -static void arcrimi_rx(struct device *dev,int recbuf); -static int arcrimi_found(struct device *dev,int ioaddr,int airq,u_long shmem); -static void arcrimi_inthandler (struct device *dev); -static int arcrimi_reset (struct device *dev, int reset_delay); -static void arcrimi_setmask (struct device *dev, u_char mask); -static void arcrimi_command (struct device *dev, u_char command); -static u_char arcrimi_status (struct device *dev); -static void arcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arcrimi_probe(struct net_device *dev); +static void arcrimi_rx(struct net_device *dev,int recbuf); +static int arcrimi_found(struct net_device *dev,int ioaddr,int airq,u_long shmem); +static void arcrimi_inthandler (struct net_device *dev); +static int arcrimi_reset (struct net_device *dev, int reset_delay); +static void arcrimi_setmask (struct net_device *dev, u_char mask); +static void arcrimi_command (struct net_device *dev, u_char command); +static u_char arcrimi_status (struct net_device *dev); +static void arcrimi_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arcrimi_openclose(int open); @@ -101,7 +101,7 @@ MODULE_PARM(device, "s"); MODULE_PARM (node, "i"); #else void __init arcrimi_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -140,7 +140,7 @@ static const char *version = * them. In fact, we can't even get their node ID automatically. So, we * need to be passed a specific shmem address, IRQ, and node ID. */ -int __init arcrimi_probe(struct device *dev) +int __init arcrimi_probe(struct net_device *dev) { BUGLVL(D_NORMAL) printk(version); BUGMSG(D_NORMAL,"Given: node %02Xh, shmem %lXh, irq %d\n", @@ -164,10 +164,10 @@ int __init arcrimi_probe(struct device *dev) } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arcrimi_found(struct device *dev,int node,int airq, u_long shmem) +int __init arcrimi_found(struct net_device *dev,int node,int airq, u_long shmem) { struct arcnet_local *lp; u_long first_mirror,last_mirror; @@ -275,7 +275,7 @@ int __init arcrimi_found(struct device *dev,int node,int airq, u_long shmem) * * However, it does make sure the card is in a defined state. */ -int arcrimi_reset(struct device *dev,int reset_delay) +int arcrimi_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->mem_start + 0x800; @@ -333,21 +333,21 @@ static void arcrimi_openclose(int open) MOD_DEC_USE_COUNT; } -static void arcrimi_setmask(struct device *dev, u_char mask) +static void arcrimi_setmask(struct net_device *dev, u_char mask) { int ioaddr=dev->mem_start+0x800; AINTMASK(mask); } -static u_char arcrimi_status(struct device *dev) +static u_char arcrimi_status(struct net_device *dev) { int ioaddr=dev->mem_start+0x800; return ARCSTATUS; } -static void arcrimi_command(struct device *dev, u_char cmd) +static void arcrimi_command(struct net_device *dev, u_char cmd) { int ioaddr=dev->mem_start+0x800; @@ -359,7 +359,7 @@ static void arcrimi_command(struct device *dev, u_char cmd) * by the card. */ static void -arcrimi_inthandler(struct device *dev) +arcrimi_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->mem_start+0x800, status, boguscount = 3, didsomething; @@ -578,7 +578,7 @@ arcrimi_inthandler(struct device *dev) */ static void -arcrimi_rx(struct device *dev,int recbuf) +arcrimi_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->mem_start+0x800; @@ -636,7 +636,7 @@ arcrimi_rx(struct device *dev,int recbuf) * by arcnet_go_tx. */ static void -arcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arcrimi_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -734,7 +734,7 @@ arcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, #ifdef MODULE static char devicename[9] = ""; -static struct device thiscard = { +static struct net_device thiscard = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ @@ -744,7 +744,7 @@ static struct device thiscard = { int init_module(void) { - struct device *dev=&thiscard; + struct net_device *dev=&thiscard; if (device) strcpy(dev->name,device); else arcnet_makename(dev->name); @@ -771,7 +771,7 @@ int init_module(void) void cleanup_module(void) { - struct device *dev=&thiscard; + struct net_device *dev=&thiscard; int ioaddr=dev->mem_start; if (dev->start) (*dev->stop)(dev); @@ -799,7 +799,7 @@ void cleanup_module(void) void __init arcrimi_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index 5e61ca6bc..d8bddd665 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -242,16 +242,16 @@ void arcnet_init(void); static int init_module(void); #ifdef CONFIG_ARCNET_COM90xx extern char com90xx_explicit; -extern int arc90xx_probe(struct device *dev); +extern int arc90xx_probe(struct net_device *dev); #endif #endif -void arcnet_tx_done(struct device *dev, struct arcnet_local *lp); +void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp); void arcnet_use_count (int open); -void arcnet_setup(struct device *dev); +void arcnet_setup(struct net_device *dev); void arcnet_makename(char *device); -void arcnetA_continue_tx(struct device *dev); -int arcnet_go_tx(struct device *dev,int enable_irq); +void arcnetA_continue_tx(struct net_device *dev); +int arcnet_go_tx(struct net_device *dev,int enable_irq); void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs); void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr); @@ -266,7 +266,7 @@ EXPORT_SYMBOL(arcnet_interrupt); EXPORT_SYMBOL(arcnet_rx); #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct device *dev,struct sk_buff *skb, +void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb, char *desc); EXPORT_SYMBOL(arcnet_dump_skb); #else @@ -274,7 +274,7 @@ EXPORT_SYMBOL(arcnet_dump_skb); #endif #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext, +void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext, char *desc); EXPORT_SYMBOL(arcnet_dump_packet); #else @@ -283,41 +283,41 @@ EXPORT_SYMBOL(arcnet_dump_packet); /* Internal function prototypes */ -static int arcnet_open(struct device *dev); -static int arcnet_close(struct device *dev); -static int arcnetA_header(struct sk_buff *skb,struct device *dev, +static int arcnet_open(struct net_device *dev); +static int arcnet_close(struct net_device *dev); +static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len); static int arcnetA_rebuild_header(struct sk_buff *skb); -static int arcnet_send_packet_bad(struct sk_buff *skb,struct device *dev); -static int arcnetA_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetA_rx(struct device *dev,u_char *buf, +static int arcnet_send_packet_bad(struct sk_buff *skb,struct net_device *dev); +static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetA_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr); -static struct net_device_stats *arcnet_get_stats(struct device *dev); +static struct net_device_stats *arcnet_get_stats(struct net_device *dev); static unsigned short arcnetA_type_trans(struct sk_buff *skb, - struct device *dev); + struct net_device *dev); #ifdef CONFIG_ARCNET_ETH /* functions specific to Ethernet-Encap */ -static int arcnetE_init(struct device *dev); -static int arcnetE_open_close(struct device *dev); -static int arcnetE_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetE_rx(struct device *dev,u_char *arcsoft, +static int arcnetE_init(struct net_device *dev); +static int arcnetE_open_close(struct net_device *dev); +static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, int length,u_char saddr, u_char daddr); #endif #ifdef CONFIG_ARCNET_1051 /* functions specific to RFC1051 */ -static int arcnetS_init(struct device *dev); -static int arcnetS_open_close(struct device *dev); -static int arcnetS_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetS_rx(struct device *dev,u_char *buf, +static int arcnetS_init(struct net_device *dev); +static int arcnetS_open_close(struct net_device *dev); +static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetS_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr); -static int arcnetS_header(struct sk_buff *skb,struct device *dev, +static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len); static int arcnetS_rebuild_header(struct sk_buff *skb); -static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev); +static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev); #endif @@ -330,7 +330,7 @@ static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev) /* Dump the contents of an sk_buff */ #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc) +void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb,char *desc) { int i; long flags; @@ -353,7 +353,7 @@ void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc) /* Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc) +void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext,char *desc) { int i; long flags; @@ -373,7 +373,7 @@ void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc) #endif -/* Setup a struct device for ARCnet. This should really be in net_init.c +/* Setup a struct net_device for ARCnet. This should really be in net_init.c * but since there are three different ARCnet devices ANYWAY... <gargle> * * Actually, the whole idea of having all this kernel-dependent stuff (ie. @@ -382,7 +382,7 @@ void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc) * Intelligent defaults?! Nah. */ -void arcnet_setup(struct device *dev) +void arcnet_setup(struct net_device *dev) { dev_init_buffers(dev); @@ -421,7 +421,7 @@ void arcnet_setup(struct device *dev) * there is non-reboot way to recover if something goes wrong. */ static int -arcnet_open(struct device *dev) +arcnet_open(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -453,10 +453,10 @@ arcnet_open(struct device *dev) #ifdef CONFIG_ARCNET_ETH /* Initialize the ethernet-encap protocol driver */ - lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL); + lp->edev=(struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL); if (lp->edev == NULL) return -ENOMEM; - memcpy(lp->edev,dev,sizeof(struct device)); + memcpy(lp->edev,dev,sizeof(struct net_device)); lp->edev->type=ARPHRD_ETHER; lp->edev->name=(char *)kmalloc(10,GFP_KERNEL); if (lp->edev->name == NULL) { @@ -471,15 +471,15 @@ arcnet_open(struct device *dev) #ifdef CONFIG_ARCNET_1051 /* Initialize the RFC1051-encap protocol driver */ - lp->sdev=(struct device *)kmalloc(sizeof(struct device)+10,GFP_KERNEL); - if(lp->sdev = NULL) + lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); + if(lp->sdev == NULL) { if(lp->edev) kfree(lp->edev); lp->edev=NULL; return -ENOMEM; } - memcpy(lp->sdev,dev,sizeof(struct device)); + memcpy(lp->sdev,dev,sizeof(struct net_device)); lp->sdev->name=(char *)(lp+1); sprintf(lp->sdev->name,"%ss",dev->name); lp->sdev->init=arcnetS_init; @@ -513,7 +513,7 @@ arcnet_open(struct device *dev) /* The inverse routine to arcnet_open - shuts down the card. */ static int -arcnet_close(struct device *dev) +arcnet_close(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -591,7 +591,7 @@ arcnet_close(struct device *dev) /* Generic error checking routine for arcnet??_send_packet */ static int -arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev) +arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -709,7 +709,7 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev) /* Called by the kernel in order to transmit a packet. */ static int -arcnetA_send_packet(struct sk_buff *skb, struct device *dev) +arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,oldmask=0; @@ -832,7 +832,7 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev) * arcnetAS_prepare_tx to load the next segment into the card. This function * does NOT automatically call arcnet_go_tx. */ -void arcnetA_continue_tx(struct device *dev) +void arcnetA_continue_tx(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int maxsegsize=XMTU-4; @@ -885,7 +885,7 @@ void arcnetA_continue_tx(struct device *dev) * to the card; TXFREEflag is always OR'ed into the memory variable either * way. */ -int arcnet_go_tx(struct device *dev,int enable_irq) +int arcnet_go_tx(struct net_device *dev,int enable_irq) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; @@ -934,7 +934,7 @@ int arcnet_go_tx(struct device *dev,int enable_irq) void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct arcnet_local *lp; if (dev==NULL) @@ -994,7 +994,7 @@ arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) } -void arcnet_tx_done(struct device *dev, struct arcnet_local *lp) +void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) { if (dev->tbusy) { @@ -1026,7 +1026,7 @@ void arcnet_tx_done(struct device *dev, struct arcnet_local *lp) void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr) { - struct device *dev=lp->adev; + struct net_device *dev=lp->adev; BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n", saddr,daddr,length); @@ -1080,7 +1080,7 @@ void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr /* Packet receiver for "standard" RFC1201-style packets */ static void -arcnetA_rx(struct device *dev,u_char *buf, +arcnetA_rx(struct net_device *dev,u_char *buf, int length, u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1361,7 +1361,7 @@ arcnetA_rx(struct device *dev,u_char *buf, * closed. */ -static struct net_device_stats *arcnet_get_stats(struct device *dev) +static struct net_device_stats *arcnet_get_stats(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1374,7 +1374,7 @@ static struct net_device_stats *arcnet_get_stats(struct device *dev) * saddr=NULL means use device source address (always will anyway) * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetA_header(struct sk_buff *skb,struct device *dev, +static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len) { struct ClientData *head = (struct ClientData *) @@ -1450,7 +1450,7 @@ static int arcnetA_header(struct sk_buff *skb,struct device *dev, static int arcnetA_rebuild_header(struct sk_buff *skb) { struct ClientData *head = (struct ClientData *)skb->data; - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); #ifdef CONFIG_INET int status; @@ -1493,7 +1493,7 @@ static int arcnetA_rebuild_header(struct sk_buff *skb) * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev) +static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device *dev) { struct ClientData *head; struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); @@ -1541,7 +1541,7 @@ static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev) /* Initialize the arc0e device. */ -static int arcnetE_init(struct device *dev) +static int arcnetE_init(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1560,7 +1560,7 @@ static int arcnetE_init(struct device *dev) /* Bring up/down the arc0e device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */ -static int arcnetE_open_close(struct device *dev) +static int arcnetE_open_close(struct net_device *dev) { return 0; } @@ -1569,7 +1569,7 @@ static int arcnetE_open_close(struct device *dev) /* Called by the kernel in order to transmit an ethernet-type packet. */ static int -arcnetE_send_packet(struct sk_buff *skb, struct device *dev) +arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,oldmask=0; @@ -1655,7 +1655,7 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev) /* Packet receiver for ethernet-encap packets. */ static void -arcnetE_rx(struct device *dev,u_char *arcsoft, +arcnetE_rx(struct net_device *dev,u_char *arcsoft, int length,u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1695,7 +1695,7 @@ arcnetE_rx(struct device *dev,u_char *arcsoft, /* Initialize the arc0s device. */ -static int arcnetS_init(struct device *dev) +static int arcnetS_init(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1719,7 +1719,7 @@ static int arcnetS_init(struct device *dev) /* Bring up/down the arc0s device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */ -static int arcnetS_open_close(struct device *dev) +static int arcnetS_open_close(struct net_device *dev) { return 0; } @@ -1728,7 +1728,7 @@ static int arcnetS_open_close(struct device *dev) /* Called by the kernel in order to transmit an RFC1051-type packet. */ static int -arcnetS_send_packet(struct sk_buff *skb, struct device *dev) +arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,length; @@ -1791,7 +1791,7 @@ arcnetS_send_packet(struct sk_buff *skb, struct device *dev) /* Packet receiver for RFC1051 packets; */ static void -arcnetS_rx(struct device *dev,u_char *buf, +arcnetS_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1837,7 +1837,7 @@ arcnetS_rx(struct device *dev,u_char *buf, * saddr=NULL means use device source address (always will anyway) * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetS_header(struct sk_buff *skb,struct device *dev, +static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len) { struct S_ClientData *head = (struct S_ClientData *) @@ -1895,7 +1895,7 @@ static int arcnetS_header(struct sk_buff *skb,struct device *dev, */ static int arcnetS_rebuild_header(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; struct S_ClientData *head = (struct S_ClientData *)skb->data; struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); @@ -1929,7 +1929,7 @@ static int arcnetS_rebuild_header(struct sk_buff *skb) * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev) +unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) { struct S_ClientData *head; struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); @@ -1993,7 +1993,7 @@ void arcnet_use_count(int open) { } -struct device arcnet_devs[MAX_ARCNET_DEVS]; +struct net_device arcnet_devs[MAX_ARCNET_DEVS]; int arcnet_num_devs=0; char arcnet_dev_names[MAX_ARCNET_DEVS][10]; @@ -2079,7 +2079,7 @@ static int __init init_module(void) void arcnet_makename(char *device) { - struct device *dev; + struct net_device *dev; int arcnum; arcnum = 0; diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index e08455cf8..75bff9f36 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -1,8 +1,7 @@ /* * Amiga Linux/m68k Ariadne Ethernet Driver * - * © Copyright 1995 by Geert Uytterhoeven - * (Geert.Uytterhoeven@cs.kuleuven.ac.be) + * © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org) * Peter De Schrijver * (Peter.DeSchrijver@linux.cc.kuleuven.ac.be) * @@ -123,15 +122,15 @@ struct lancedata { }; -static int ariadne_open(struct device *dev); -static void ariadne_init_ring(struct device *dev); -static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev); -static int ariadne_rx(struct device *dev); +static int ariadne_open(struct net_device *dev); +static void ariadne_init_ring(struct net_device *dev); +static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ariadne_rx(struct net_device *dev); static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp); -static int ariadne_close(struct device *dev); -static struct net_device_stats *ariadne_get_stats(struct device *dev); +static int ariadne_close(struct net_device *dev); +static struct net_device_stats *ariadne_get_stats(struct net_device *dev); #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif @@ -146,7 +145,7 @@ static void memcpyw(u_short *dest, u_short *src, int len) } -int __init ariadne_probe(struct device *dev) +int __init ariadne_probe(struct net_device *dev) { unsigned int key; const struct ConfigDev *cd; @@ -193,7 +192,7 @@ int __init ariadne_probe(struct device *dev) } -static int ariadne_open(struct device *dev) +static int ariadne_open(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -293,7 +292,7 @@ static int ariadne_open(struct device *dev) dev->interrupt = 0; dev->start = 1; - if (request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, 0, + if (request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, SA_SHIRQ, "Ariadne Ethernet", dev)) return(-EAGAIN); @@ -306,7 +305,7 @@ static int ariadne_open(struct device *dev) } -static void ariadne_init_ring(struct device *dev) +static void ariadne_init_ring(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -353,7 +352,7 @@ static void ariadne_init_ring(struct device *dev) } -static int ariadne_close(struct device *dev) +static int ariadne_close(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -385,7 +384,7 @@ static int ariadne_close(struct device *dev) static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct ariadne_private *priv; struct AriadneBoard *board; int csr0, boguscnt = 10; @@ -400,8 +399,8 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp) board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */ - if (!(board->Lance.RDP & INTR)) /* Check if any interrupt has been - return; generated by the board. */ + if (!(board->Lance.RDP & INTR)) /* Check if any interrupt has been */ + return; /* generated by the board. */ if (dev->interrupt) printk("%s: Re-entering the interrupt handler.\n", dev->name); @@ -542,7 +541,7 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp) } -static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev) +static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -692,7 +691,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev) } -static int ariadne_rx(struct device *dev) +static int ariadne_rx(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; int entry = priv->cur_rx % RX_RING_SIZE; @@ -780,7 +779,7 @@ static int ariadne_rx(struct device *dev) } -static struct net_device_stats *ariadne_get_stats(struct device *dev) +static struct net_device_stats *ariadne_get_stats(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -805,7 +804,7 @@ static struct net_device_stats *ariadne_get_stats(struct device *dev) num_addrs > 0 Multicast mode, receive normal and MC packets, and do best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -842,7 +841,7 @@ static void set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device ariadne_dev = +static struct net_device ariadne_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h index 796bbcba4..2ba188134 100644 --- a/drivers/net/ariadne.h +++ b/drivers/net/ariadne.h @@ -1,8 +1,7 @@ /* * Amiga Linux/m68k Ariadne Ethernet Driver * - * © Copyright 1995 by Geert Uytterhoeven - * (Geert.Uytterhoeven@cs.kuleuven.ac.be) + * © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org) * Peter De Schrijver * (Peter.DeSchrijver@linux.cc.kuleuven.ac.be) * diff --git a/drivers/net/ariadne2.c b/drivers/net/ariadne2.c index fc02ecbb5..10edf1e79 100644 --- a/drivers/net/ariadne2.c +++ b/drivers/net/ariadne2.c @@ -65,23 +65,23 @@ #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) -int ariadne2_probe(struct device *dev); -static int ariadne2_init(struct device *dev, unsigned int key, +int ariadne2_probe(struct net_device *dev); +static int ariadne2_init(struct net_device *dev, unsigned int key, unsigned long board); -static int ariadne2_open(struct device *dev); -static int ariadne2_close(struct device *dev); +static int ariadne2_open(struct net_device *dev); +static int ariadne2_close(struct net_device *dev); -static void ariadne2_reset_8390(struct device *dev); -static void ariadne2_get_8390_hdr(struct device *dev, +static void ariadne2_reset_8390(struct net_device *dev); +static void ariadne2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ariadne2_block_input(struct device *dev, int count, +static void ariadne2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ariadne2_block_output(struct device *dev, const int count, +static void ariadne2_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -int __init ariadne2_probe(struct device *dev) +int __init ariadne2_probe(struct net_device *dev) { unsigned int key; const struct ConfigDev *cd; @@ -100,7 +100,7 @@ int __init ariadne2_probe(struct device *dev) return -ENODEV; } -static int __init ariadne2_init(struct device *dev, unsigned int key, +static int __init ariadne2_init(struct net_device *dev, unsigned int key, unsigned long board) { int i; @@ -177,10 +177,11 @@ static int __init ariadne2_init(struct device *dev, unsigned int key, name = "NE2000"; dev->base_addr = ioaddr; + dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, 0, "AriadNE2 Ethernet", - dev)) + if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, + "AriadNE2 Ethernet", dev)) return -EAGAIN; /* Allocate dev->priv and fill in 8390 specific dev fields. */ @@ -191,7 +192,9 @@ static int __init ariadne2_init(struct device *dev, unsigned int key, ((struct ei_device *)dev->priv)->priv = key; for(i = 0; i < ETHER_ADDR_LEN; i++) { +#ifdef DEBUG printk(" %2.2x", SA_prom[i]); +#endif dev->dev_addr[i] = SA_prom[i]; } @@ -218,14 +221,14 @@ static int __init ariadne2_init(struct device *dev, unsigned int key, return 0; } -static int ariadne2_open(struct device *dev) +static int ariadne2_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ariadne2_close(struct device *dev) +static int ariadne2_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -236,7 +239,7 @@ static int ariadne2_close(struct device *dev) /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ariadne2_reset_8390(struct device *dev) +static void ariadne2_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -261,7 +264,7 @@ static void ariadne2_reset_8390(struct device *dev) we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ariadne2_get_8390_hdr(struct device *dev, +static void ariadne2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -301,7 +304,7 @@ static void ariadne2_get_8390_hdr(struct device *dev, The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using writeb. */ -static void ariadne2_block_input(struct device *dev, int count, +static void ariadne2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; @@ -335,7 +338,7 @@ static void ariadne2_block_input(struct device *dev, int count, ei_status.dmaing &= ~0x01; } -static void ariadne2_block_output(struct device *dev, int count, +static void ariadne2_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { @@ -392,7 +395,7 @@ static void ariadne2_block_output(struct device *dev, int count, #ifdef MODULE static char devicename[9] = { 0, }; -static struct device ariadne2_dev = +static struct net_device ariadne2_dev = { devicename, 0, 0, 0, 0, diff --git a/drivers/net/arlan-proc.c b/drivers/net/arlan-proc.c index 2d48479e0..83ac209e8 100644 --- a/drivers/net/arlan-proc.c +++ b/drivers/net/arlan-proc.c @@ -1,16 +1,17 @@ #include <linux/config.h> #include "arlan.h" +#include <linux/sysctl.h> + #ifdef CONFIG_PROC_FS -#include <linux/sysctl.h> #include <linux/version.h> -/* void enableReceive(struct device* dev); +/* void enableReceive(struct net_device* dev); */ -static int arlan_command(struct device * dev, int command); +static int arlan_command(struct net_device * dev, int command); #define ARLAN_STR_SIZE 0x2ff0 @@ -58,7 +59,7 @@ static int arlan_command(struct device * dev, int command); } -const char *arlan_diagnostic_info_string(struct device *dev) +const char *arlan_diagnostic_info_string(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -113,7 +114,7 @@ const char *arlan_diagnostic_info_string(struct device *dev) } }; -static const char *arlan_hardware_type_string(struct device *dev) +static const char *arlan_hardware_type_string(struct net_device *dev) { u_char hardwareType; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -186,7 +187,7 @@ static const char *arlan_hardware_type_string(struct device *dev) } } -static void arlan_print_diagnostic_info(struct device *dev) +static void arlan_print_diagnostic_info(struct net_device *dev) { int i; u_char diagnosticInfo; @@ -251,7 +252,7 @@ static void arlan_print_diagnostic_info(struct device *dev) /****************************** TEST MEMORY **************/ -static int arlan_hw_test_memory(struct device *dev) +static int arlan_hw_test_memory(struct net_device *dev) { u_char *ptr; int i; @@ -320,7 +321,7 @@ static int arlan_hw_test_memory(struct device *dev) } -static int arlan_setup_card_by_book(struct device *dev) +static int arlan_setup_card_by_book(struct net_device *dev) { u_char irqLevel, configuredStatusFlag; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -408,7 +409,7 @@ static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp, int i; int retv, pos, devnum; struct arlan_private *priva = NULL; - struct device *dev; + struct net_device *dev; pos = 0; if (write) { @@ -1001,6 +1002,12 @@ static ctl_table arlan_table[MAX_ARLANS + 1] = {0} }; #endif +#else + +static ctl_table arlan_table[MAX_ARLANS + 1] = +{ + {0} +}; #endif static int mmtu = 1234; diff --git a/drivers/net/arlan.c b/drivers/net/arlan.c index d8f9ee74f..5ccad60a9 100644 --- a/drivers/net/arlan.c +++ b/drivers/net/arlan.c @@ -10,7 +10,7 @@ static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee Oct'98, http://www.ylenurme.ee/~elmer/655/"; -struct device *arlan_device[MAX_ARLANS]; +struct net_device *arlan_device[MAX_ARLANS]; int last_arlan = 0; static int SID = SIDUNKNOWN; @@ -72,11 +72,9 @@ EXPORT_SYMBOL(last_arlan); // #warning kernel 2.1.110 tested #define myATOMIC_INIT(a,b) atomic_set(&(a),b) -#define __initfunctio(a) __initfunc(a) #else #define test_and_set_bit set_bit -#define __initfunctio(a) a #if LINUX_VERSION_CODE != 0x20024 // #warning kernel 2.0.36 tested #endif @@ -87,20 +85,20 @@ EXPORT_SYMBOL(last_arlan); struct arlan_conf_stru arlan_conf[MAX_ARLANS]; int arlans_found = 0; -static int arlan_probe_here(struct device *dev, int ioaddr); -static int arlan_open(struct device *dev); -static int arlan_tx(struct sk_buff *skb, struct device *dev); +static int arlan_probe_here(struct net_device *dev, int ioaddr); +static int arlan_open(struct net_device *dev); +static int arlan_tx(struct sk_buff *skb, struct net_device *dev); static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int arlan_close(struct device *dev); +static int arlan_close(struct net_device *dev); static struct enet_statistics * - arlan_statistics (struct device *dev); -static void arlan_set_multicast (struct device *dev); -static int arlan_hw_tx (struct device* dev, char *buf, int length ); -static int arlan_hw_config (struct device * dev); -static void arlan_tx_done_interrupt (struct device * dev, int status); -static void arlan_rx_interrupt (struct device * dev, u_char rxStatus, u_short, u_short); -static void arlan_process_interrupt (struct device * dev); -static int arlan_command(struct device * dev, int command); + arlan_statistics (struct net_device *dev); +static void arlan_set_multicast (struct net_device *dev); +static int arlan_hw_tx (struct net_device* dev, char *buf, int length ); +static int arlan_hw_config (struct net_device * dev); +static void arlan_tx_done_interrupt (struct net_device * dev, int status); +static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short); +static void arlan_process_interrupt (struct net_device * dev); +int arlan_command(struct net_device * dev, int command); EXPORT_SYMBOL(arlan_command); @@ -162,7 +160,7 @@ extern inline long long arlan_time(void) -extern inline int arlan_drop_tx(struct device *dev) +extern inline int arlan_drop_tx(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -189,7 +187,7 @@ extern inline int arlan_drop_tx(struct device *dev) }; -static int arlan_command(struct device *dev, int command_p) +int arlan_command(struct net_device *dev, int command_p) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -532,7 +530,7 @@ command_busy_end: }; -extern inline void arlan_command_process(struct device *dev) +extern inline void arlan_command_process(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -553,7 +551,7 @@ extern inline void arlan_command_process(struct device *dev) } -extern inline void arlan_retransmit_now(struct device *dev) +extern inline void arlan_retransmit_now(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -596,7 +594,7 @@ extern inline void arlan_retransmit_now(struct device *dev) static void arlan_registration_timer(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct arlan_private *priv = (struct arlan_private *) dev->priv; int lostTime = ((int) (jiffies - priv->registrationLastSeen)) * 1000 / HZ; @@ -696,7 +694,7 @@ static void arlan_registration_timer(unsigned long data) -static void arlan_print_registers(struct device *dev, int line) +static void arlan_print_registers(struct net_device *dev, int line) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -722,7 +720,7 @@ static void arlan_print_registers(struct device *dev, int line) } -static int arlan_hw_tx(struct device *dev, char *buf, int length) +static int arlan_hw_tx(struct net_device *dev, char *buf, int length) { int i; @@ -827,7 +825,7 @@ static int arlan_hw_tx(struct device *dev, char *buf, int length) } -static int arlan_hw_config(struct device *dev) +static int arlan_hw_config(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -909,7 +907,7 @@ static int arlan_hw_config(struct device *dev) } -static int arlan_read_card_configuration(struct device *dev) +static int arlan_read_card_configuration(struct net_device *dev) { u_char tlx415; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -1034,7 +1032,7 @@ static int lastFoundAt = 0xbe000; * verifies that the correct device exists and functions. */ -__initfunctio(static int arlan_check_fingerprint(int memaddr)) +static int __init arlan_check_fingerprint(int memaddr) { static char probeText[] = "TELESYSTEM SLW INC. ARLAN \0"; char tempBuf[49]; @@ -1056,7 +1054,7 @@ __initfunctio(static int arlan_check_fingerprint(int memaddr)) } -__initfunctio(int arlan_probe_everywhere(struct device *dev)) +int __init arlan_probe_everywhere(struct net_device *dev) { int m; int probed = 0; @@ -1094,7 +1092,7 @@ __initfunctio(int arlan_probe_everywhere(struct device *dev)) return ENODEV; } -__initfunctio(int arlan_find_devices(void)) +int __init arlan_find_devices(void) { int m; int found = 0; @@ -1113,7 +1111,7 @@ __initfunctio(int arlan_find_devices(void)) } -static int arlan_change_mtu(struct device *dev, int new_mtu) +static int arlan_change_mtu(struct net_device *dev, int new_mtu) { struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1134,7 +1132,7 @@ static int arlan_change_mtu(struct device *dev, int new_mtu) return 0; } -static int arlan_mac_addr(struct device *dev, void *p) +static int arlan_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; @@ -1153,11 +1151,11 @@ static int arlan_mac_addr(struct device *dev, void *p) -__initfunctio(static int - arlan_allocate_device(int num, struct device *devs)) +static int __init + arlan_allocate_device(int num, struct net_device *devs) { - struct device *dev; + struct net_device *dev; ARLAN_DEBUG_ENTRY("arlan_allocate_device"); @@ -1214,7 +1212,7 @@ __initfunctio(static int } -__initfunctio(int arlan_probe_here(struct device *dev, int memaddr)) +int __init arlan_probe_here(struct net_device *dev, int memaddr) { volatile struct arlan_shmem *arlan; @@ -1249,7 +1247,7 @@ __initfunctio(int arlan_probe_here(struct device *dev, int memaddr)) -static int arlan_open(struct device *dev) +static int arlan_open(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; @@ -1291,7 +1289,7 @@ static int arlan_open(struct device *dev) priv->command_lock = 0; add_timer(&priv->timer); - init_mutex(&priv->card_lock); + init_MUTEX(&priv->card_lock); myATOMIC_INIT(priv->card_users, 1); /* damn 2.0.33 */ priv->registrationLostCount = 0; priv->registrationLastSeen = jiffies; @@ -1323,7 +1321,7 @@ static int arlan_open(struct device *dev) -static int arlan_tx(struct sk_buff *skb, struct device *dev) +static int arlan_tx(struct sk_buff *skb, struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1399,7 +1397,7 @@ bad_end: } -extern inline int DoNotReTransmitCrap(struct device *dev) +extern inline int DoNotReTransmitCrap(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1409,7 +1407,7 @@ extern inline int DoNotReTransmitCrap(struct device *dev) } -extern inline int DoNotWaitReTransmitCrap(struct device *dev) +extern inline int DoNotWaitReTransmitCrap(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1418,7 +1416,7 @@ extern inline int DoNotWaitReTransmitCrap(struct device *dev) return 0; } -extern inline void arlan_queue_retransmit(struct device *dev) +extern inline void arlan_queue_retransmit(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1433,7 +1431,7 @@ extern inline void arlan_queue_retransmit(struct device *dev) ARLAN_DEBUG_EXIT("arlan_queue_retransmit"); }; -extern inline void RetryOrFail(struct device *dev) +extern inline void RetryOrFail(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1454,7 +1452,7 @@ extern inline void RetryOrFail(struct device *dev) } -static void arlan_tx_done_interrupt(struct device *dev, int status) +static void arlan_tx_done_interrupt(struct net_device *dev, int status) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1596,7 +1594,7 @@ static void arlan_tx_done_interrupt(struct device *dev, int status) } -static void arlan_rx_interrupt(struct device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len) +static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len) { char *skbtmp; int i = 0; @@ -1749,7 +1747,7 @@ static void arlan_rx_interrupt(struct device *dev, u_char rxStatus, u_short rxOf ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); } -static void arlan_process_interrupt(struct device *dev) +static void arlan_process_interrupt(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; @@ -1859,7 +1857,7 @@ end_int_process: static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; u_char rxStatus = READSHMB(arlan->rxStatus); @@ -1883,7 +1881,7 @@ static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs) } -static int arlan_close(struct device *dev) +static int arlan_close(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; @@ -1929,7 +1927,7 @@ static long alignLong(volatile u_char * ptr) * This may be called with the card open or closed. */ -static struct enet_statistics *arlan_statistics(struct device *dev) +static struct enet_statistics *arlan_statistics(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -1959,7 +1957,7 @@ static struct enet_statistics *arlan_statistics(struct device *dev) } -static void arlan_set_multicast(struct device *dev) +static void arlan_set_multicast(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1992,7 +1990,7 @@ static void arlan_set_multicast(struct device *dev) } -__initfunctio(int arlan_probe(struct device *dev)) +int __init arlan_probe(struct net_device *dev) { printk("Arlan driver %s\n", arlan_version); diff --git a/drivers/net/arlan.h b/drivers/net/arlan.h index 7074335ea..869c8bebd 100644 --- a/drivers/net/arlan.h +++ b/drivers/net/arlan.h @@ -45,7 +45,7 @@ extern int init_arlan_proc(void); #endif -extern struct device *arlan_device[MAX_ARLANS]; +extern struct net_device *arlan_device[MAX_ARLANS]; static int arlan_debug; static char * siteName; static int arlan_entry_debug; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 9ba40dd13..a028b159e 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -150,17 +150,17 @@ struct net_local { #define AT1700_IO_EXTENT 32 /* Index to functions, as function prototypes. */ -extern int at1700_probe(struct device *dev); +extern int at1700_probe(struct net_device *dev); -static int at1700_probe1(struct device *dev, int ioaddr); +static int at1700_probe1(struct net_device *dev, int ioaddr); static int read_eeprom(int ioaddr, int location); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct enet_statistics *net_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct enet_statistics *net_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); #ifdef CONFIG_MCA @@ -192,7 +192,7 @@ struct netdev_entry at1700_drv = {"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list}; #else -int at1700_probe(struct device *dev) +int at1700_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -221,7 +221,7 @@ int at1700_probe(struct device *dev) that can be done is checking a few bits and then diving right into an EEPROM read. */ -int at1700_probe1(struct device *dev, int ioaddr) +int at1700_probe1(struct net_device *dev, int ioaddr) { char fmv_irqmap[4] = {3, 7, 10, 15}; char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; @@ -498,7 +498,7 @@ static int read_eeprom(int ioaddr, int location) -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -535,7 +535,7 @@ static int net_open(struct device *dev) } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -615,7 +615,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -681,7 +681,7 @@ net_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -762,7 +762,7 @@ net_rx(struct device *dev) } /* The inverse routine to net_open(). */ -static int net_close(struct device *dev) +static int net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -794,7 +794,7 @@ static int net_close(struct device *dev) There are no on-chip counters, so this function is trivial. */ static struct enet_statistics * -net_get_stats(struct device *dev) +net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -826,7 +826,7 @@ static inline unsigned ether_crc_le(int length, unsigned char *data) } static void -set_rx_mode(struct device *dev) +set_rx_mode(struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -875,7 +875,7 @@ set_rx_mode(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_at1700 = { +static struct net_device dev_at1700 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c index 8fb48eeb4..cb8b20918 100644 --- a/drivers/net/atari_bionet.c +++ b/drivers/net/atari_bionet.c @@ -115,7 +115,7 @@ static char *version = #include <asm/atari_stdma.h> -extern struct device *init_etherdev(struct device *dev, int sizeof_private); +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private); /* use 0 for production, 1 for verification, >2 for debug */ @@ -149,13 +149,13 @@ unsigned char *phys_nic_packet; /* Index to functions, as function prototypes. */ -extern int bionet_probe(struct device *dev); +extern int bionet_probe(struct net_device *dev); -static int bionet_open(struct device *dev); -static int bionet_send_packet(struct sk_buff *skb, struct device *dev); -static void bionet_poll_rx(struct device *); -static int bionet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); +static int bionet_open(struct net_device *dev); +static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev); +static void bionet_poll_rx(struct net_device *); +static int bionet_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); static void bionet_tick(unsigned long); static struct timer_list bionet_timer = { NULL, NULL, 0, 0, bionet_tick }; @@ -325,7 +325,7 @@ end: /* Check for a network adaptor of this type, and return '0' if one exists. */ int __init -bionet_probe(struct device *dev){ +bionet_probe(struct net_device *dev){ unsigned char station_addr[6]; static unsigned version_printed = 0; static int no_more_found = 0; /* avoid "Probing for..." printed 4 times */ @@ -404,7 +404,7 @@ bionet_probe(struct device *dev){ there is non-reboot way to recover if something goes wrong. */ static int -bionet_open(struct device *dev) { +bionet_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) @@ -430,7 +430,7 @@ bionet_open(struct device *dev) { } static int -bionet_send_packet(struct sk_buff *skb, struct device *dev) { +bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -446,7 +446,7 @@ bionet_send_packet(struct sk_buff *skb, struct device *dev) { } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned long buf = VTOP(skb->data); + unsigned long buf = virt_to_phys(skb->data); int stat; stdma_lock(bionet_intr, NULL); @@ -497,7 +497,7 @@ bionet_send_packet(struct sk_buff *skb, struct device *dev) { /* We have a good packet(s), get it/them out of the buffers. */ static void -bionet_poll_rx(struct device *dev) { +bionet_poll_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount = 10; int pkt_len, status; @@ -599,7 +599,7 @@ bionet_poll_rx(struct device *dev) { */ static void bionet_tick(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct net_local *lp = (struct net_local *)dev->priv; if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 ) @@ -614,7 +614,7 @@ bionet_tick(unsigned long data) { /* The inverse routine to bionet_open(). */ static int -bionet_close(struct device *dev) { +bionet_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) @@ -636,7 +636,7 @@ bionet_close(struct device *dev) { /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -646,7 +646,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) #ifdef MODULE static char bio_name[16]; -static struct device bio_dev = +static struct net_device bio_dev = { bio_name, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c index 83cd0f665..38effe36d 100644 --- a/drivers/net/atari_pamsnet.c +++ b/drivers/net/atari_pamsnet.c @@ -111,7 +111,7 @@ static char *version = #undef READ #undef WRITE -extern struct device *init_etherdev(struct device *dev, int sizeof_private); +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private); /* use 0 for production, 1 for verification, >2 for debug */ @@ -157,13 +157,13 @@ static int send_1_5 (int lun, unsigned char *command, int dma); static int get_status (void); static int calc_received (void *start_address); -extern int pamsnet_probe(struct device *dev); +extern int pamsnet_probe(struct net_device *dev); -static int pamsnet_open(struct device *dev); -static int pamsnet_send_packet(struct sk_buff *skb, struct device *dev); -static void pamsnet_poll_rx(struct device *); -static int pamsnet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); +static int pamsnet_open(struct net_device *dev); +static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev); +static void pamsnet_poll_rx(struct net_device *); +static int pamsnet_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); static void pamsnet_tick(unsigned long); static void pamsnet_intr(int irq, void *data, struct pt_regs *fp); @@ -439,7 +439,7 @@ inquiry (target, buffer) unsigned char *buffer; { int ret = -1; - unsigned char *vbuffer = (unsigned char *)PTOV(buffer); + unsigned char *vbuffer = phys_to_virt((unsigned long)buffer); unsigned char cmd_buffer[5]; if (send_first(target, INQUIRY)) @@ -487,7 +487,7 @@ static HADDR !acsi_wait_for_IRQ(TIMEOUTDMA) || get_status()) goto bad; - ret = (HADDR *)PTOV(&(((DMAHWADDR *)buffer)->hwaddr)); + ret = phys_to_virt(&(((DMAHWADDR *)buffer)->hwaddr)); dma_cache_maintenance((unsigned long)buffer, 512, 0); bad: return (ret); @@ -563,7 +563,7 @@ bad: extern int __init pamsnet_probe (dev) - struct device *dev; + struct net_device *dev; { int i; HADDR *hwaddr; @@ -661,7 +661,7 @@ pamsnet_probe (dev) there is non-reboot way to recover if something goes wrong. */ static int -pamsnet_open(struct device *dev) { +pamsnet_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (pamsnet_debug > 0) @@ -691,7 +691,7 @@ pamsnet_open(struct device *dev) { } static int -pamsnet_send_packet(struct sk_buff *skb, struct device *dev) { +pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -707,7 +707,7 @@ pamsnet_send_packet(struct sk_buff *skb, struct device *dev) { } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned long buf = VTOP(skb->data); + unsigned long buf = virt_to_phys(skb->data); int stat; stdma_lock(pamsnet_intr, NULL); @@ -738,7 +738,7 @@ pamsnet_send_packet(struct sk_buff *skb, struct device *dev) { /* We have a good packet(s), get it/them out of the buffers. */ static void -pamsnet_poll_rx(struct device *dev) { +pamsnet_poll_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount; int pkt_len; @@ -813,7 +813,7 @@ pamsnet_poll_rx(struct device *dev) { */ static void pamsnet_tick(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct net_local *lp = (struct net_local *)dev->priv; if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 ) @@ -828,7 +828,7 @@ pamsnet_tick(unsigned long data) { /* The inverse routine to pamsnet_open(). */ static int -pamsnet_close(struct device *dev) { +pamsnet_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (pamsnet_debug > 0) @@ -855,7 +855,7 @@ pamsnet_close(struct device *dev) { /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -865,7 +865,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device pam_dev = +static struct net_device pam_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index de439cb27..fa41fd3b7 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -339,17 +339,17 @@ struct lance_addr { static int addr_accessible( volatile void *regp, int wordflag, int writeflag ); -static unsigned long lance_probe1( struct device *dev, struct lance_addr +static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); -static int lance_open( struct device *dev ); -static void lance_init_ring( struct device *dev ); -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ); +static int lance_open( struct net_device *dev ); +static void lance_init_ring( struct net_device *dev ); +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); -static int lance_rx( struct device *dev ); -static int lance_close( struct device *dev ); -static struct net_device_stats *lance_get_stats( struct device *dev ); -static void set_multicast_list( struct device *dev ); -static int lance_set_mac_address( struct device *dev, void *addr ); +static int lance_rx( struct net_device *dev ); +static int lance_close( struct net_device *dev ); +static struct net_device_stats *lance_get_stats( struct net_device *dev ); +static void set_multicast_list( struct net_device *dev ); +static int lance_set_mac_address( struct net_device *dev, void *addr ); /************************* End of Prototypes **************************/ @@ -370,7 +370,7 @@ void *slow_memcpy( void *dst, const void *src, size_t len ) } -int __init atarilance_probe( struct device *dev ) +int __init atarilance_probe( struct net_device *dev ) { int i; static int found = 0; @@ -443,7 +443,7 @@ static int __init addr_accessible( volatile void *regp, int wordflag, int writef } -static unsigned long __init lance_probe1( struct device *dev, +static unsigned long __init lance_probe1( struct net_device *dev, struct lance_addr *init_rec ) { volatile unsigned short *memaddr = @@ -623,7 +623,7 @@ static unsigned long __init lance_probe1( struct device *dev, } -static int lance_open( struct device *dev ) +static int lance_open( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -667,7 +667,7 @@ static int lance_open( struct device *dev ) /* Initialize the LANCE Rx and Tx rings. */ -static void lance_init_ring( struct device *dev ) +static void lance_init_ring( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -713,7 +713,7 @@ static void lance_init_ring( struct device *dev ) } -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -844,7 +844,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; struct lance_ioreg *IO; int csr0, boguscnt = 10; @@ -952,7 +952,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) } -static int lance_rx( struct device *dev ) +static int lance_rx( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1045,7 +1045,7 @@ static int lance_rx( struct device *dev ) } -static int lance_close( struct device *dev ) +static int lance_close( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1067,7 +1067,7 @@ static int lance_close( struct device *dev ) } -static struct net_device_stats *lance_get_stats( struct device *dev ) +static struct net_device_stats *lance_get_stats( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1082,7 +1082,7 @@ static struct net_device_stats *lance_get_stats( struct device *dev ) best-effort filtering. */ -static void set_multicast_list( struct device *dev ) +static void set_multicast_list( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1124,7 +1124,7 @@ static void set_multicast_list( struct device *dev ) /* This is needed for old RieblCards and possible for new RieblCards */ -static int lance_set_mac_address( struct device *dev, void *addr ) +static int lance_set_mac_address( struct net_device *dev, void *addr ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct sockaddr *saddr = addr; @@ -1154,7 +1154,7 @@ static int lance_set_mac_address( struct device *dev, void *addr ) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device atarilance_dev = +static struct net_device atarilance_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 4cfed8d92..45da37261 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -120,28 +120,28 @@ static unsigned int net_debug = NET_DEBUG; #ifdef TIMED_CHECKER #include <linux/timer.h> static void atp_timed_checker(unsigned long ignored); -static struct device *atp_timed_dev; +static struct net_device *atp_timed_dev; static struct timer_list atp_timer = {NULL, NULL, 0, 0, atp_timed_checker}; #endif /* Index to functions, as function prototypes. */ -extern int atp_probe(struct device *dev); +extern int atp_probe(struct net_device *dev); -static int atp_probe1(struct device *dev, short ioaddr); -static void get_node_ID(struct device *dev); +static int atp_probe1(struct net_device *dev, short ioaddr); +static void get_node_ID(struct net_device *dev); static unsigned short eeprom_op(short ioaddr, unsigned int cmd); -static int net_open(struct device *dev); -static void hardware_init(struct device *dev); +static int net_open(struct net_device *dev); +static void hardware_init(struct net_device *dev); static void write_packet(short ioaddr, int length, unsigned char *packet, int mode); static void trigger_send(short ioaddr, int length); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); +static void net_rx(struct net_device *dev); static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Check for a network adapter of this type, and return '0' iff one exists. @@ -151,7 +151,7 @@ static void set_multicast_list(struct device *dev); (detachable devices only). */ int __init -atp_init(struct device *dev) +atp_init(struct net_device *dev) { int *port, ports[] = {0x378, 0x278, 0x3bc, 0}; int base_addr = dev->base_addr; @@ -173,7 +173,7 @@ atp_init(struct device *dev) return ENODEV; } -static int __init atp_probe1(struct device *dev, short ioaddr) +static int __init atp_probe1(struct net_device *dev, short ioaddr) { int saved_ctrl_reg, status; @@ -184,7 +184,7 @@ static int __init atp_probe1(struct device *dev, short ioaddr) /* IRQEN=0, SLCTB=high INITB=high, AUTOFDB=high, STBB=high. */ outb(0x04, ioaddr + PAR_CONTROL); write_reg_high(ioaddr, CMR1, CMR1h_RESET); - eeprom_delay(2048); + udelay(100); status = read_nibble(ioaddr, CMR1); if ((status & 0x78) != 0x08) { @@ -259,7 +259,7 @@ static int __init atp_probe1(struct device *dev, short ioaddr) } /* Read the station address PROM, usually a word-wide EEPROM. */ -static void __init get_node_ID(struct device *dev) +static void __init get_node_ID(struct net_device *dev) { short ioaddr = dev->base_addr; int sa_offset = 0; @@ -299,12 +299,12 @@ static unsigned short __init eeprom_op(short ioaddr, unsigned int cmd) while (--num_bits >= 0) { char outval = test_bit(num_bits, &cmd) ? EE_DATA_WRITE : 0; write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW); - eeprom_delay(5); + udelay(5); write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH); eedata_out <<= 1; if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ) eedata_out++; - eeprom_delay(5); + udelay(5); } write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS); return eedata_out; @@ -321,7 +321,7 @@ static unsigned short __init eeprom_op(short ioaddr, unsigned int cmd) This is an attachable device: if there is no dev->priv entry then it wasn't probed for at boot-time, and we need to probe for it again. */ -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { /* The interrupt line is turned off (tri-stated) when the device isn't in @@ -338,7 +338,7 @@ static int net_open(struct device *dev) /* This routine resets the hardware. We initialize everything, assuming that the hardware may have been temporarily detached. */ -static void hardware_init(struct device *dev) +static void hardware_init(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -412,7 +412,7 @@ static void write_packet(short ioaddr, int length, unsigned char *packet, int da } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -477,7 +477,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 20; static int num_tx_since_rx = 0; @@ -634,7 +634,7 @@ static void atp_timed_checker(unsigned long ignored) #endif /* We have a good packet(s), get it/them out of the buffers. */ -static void net_rx(struct device *dev) +static void net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -713,7 +713,7 @@ static void read_block(short ioaddr, int length, unsigned char *p, int data_mode /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -737,7 +737,7 @@ net_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -747,7 +747,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) * Set or clear the multicast filter for this adapter. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; diff --git a/drivers/net/atp.h b/drivers/net/atp.h index 2a64697e9..8a74d4451 100644 --- a/drivers/net/atp.h +++ b/drivers/net/atp.h @@ -261,10 +261,6 @@ extern inline void write_word_mode0(short ioaddr, unsigned short value) #define EE_DATA_WRITE 0x01 /* EEPROM chip data in. */ #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ -/* Delay between EEPROM clock transitions. */ -#define eeprom_delay(ticks) \ -do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) - /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD(offset) (((5 << 6) + (offset)) << 17) #define EE_READ(offset) (((6 << 6) + (offset)) << 17) diff --git a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c index f08007e6d..eeb6b77c5 100644 --- a/drivers/net/bagetlance.c +++ b/drivers/net/bagetlance.c @@ -329,17 +329,17 @@ struct lance_addr { static int addr_accessible( volatile void *regp, int wordflag, int writeflag ); -static unsigned long lance_probe1( struct device *dev, struct lance_addr +static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); -static int lance_open( struct device *dev ); -static void lance_init_ring( struct device *dev ); -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ); +static int lance_open( struct net_device *dev ); +static void lance_init_ring( struct net_device *dev ); +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); -static int lance_rx( struct device *dev ); -static int lance_close( struct device *dev ); -static struct net_device_stats *lance_get_stats( struct device *dev ); -static void set_multicast_list( struct device *dev ); -static int lance_set_mac_address( struct device *dev, void *addr ); +static int lance_rx( struct net_device *dev ); +static int lance_close( struct net_device *dev ); +static struct net_device_stats *lance_get_stats( struct net_device *dev ); +static void set_multicast_list( struct net_device *dev ); +static int lance_set_mac_address( struct net_device *dev, void *addr ); /************************* End of Prototypes **************************/ @@ -469,7 +469,7 @@ void *slow_memcpy( void *dst, const void *src, size_t len ) } -__initfunc(int bagetlance_probe( struct device *dev )) +int __init bagetlance_probe( struct net_device *dev ) { int i; static int found = 0; @@ -493,9 +493,9 @@ __initfunc(int bagetlance_probe( struct device *dev )) /* Derived from hwreg_present() in vme/config.c: */ -__initfunc(static int addr_accessible( volatile void *regp, - int wordflag, - int writeflag )) +static int __init addr_accessible( volatile void *regp, + int wordflag, + int writeflag ) { /* We have a fine function to do it */ extern int try_read(unsigned long, int); @@ -508,8 +508,8 @@ __initfunc(static int addr_accessible( volatile void *regp, #define IRQ_TYPE_PRIO SA_INTERRUPT #define IRQ_SOURCE_TO_VECTOR(x) (x) -__initfunc(static unsigned long lance_probe1( struct device *dev, - struct lance_addr *init_rec )) +static unsigned long __init lance_probe1( struct net_device *dev, + struct lance_addr *init_rec ) { volatile unsigned short *memaddr = (volatile unsigned short *)init_rec->memaddr; @@ -723,7 +723,7 @@ __initfunc(static unsigned long lance_probe1( struct device *dev, } -static int lance_open( struct device *dev ) +static int lance_open( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -767,7 +767,7 @@ static int lance_open( struct device *dev ) /* Initialize the LANCE Rx and Tx rings. */ -static void lance_init_ring( struct device *dev ) +static void lance_init_ring( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -823,7 +823,7 @@ static void lance_init_ring( struct device *dev ) } -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -962,7 +962,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; struct lance_ioreg *IO; int csr0, boguscnt = 10; @@ -1082,7 +1082,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) } -static int lance_rx( struct device *dev ) +static int lance_rx( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1205,7 +1205,7 @@ static int lance_rx( struct device *dev ) } -static int lance_close( struct device *dev ) +static int lance_close( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1227,7 +1227,7 @@ static int lance_close( struct device *dev ) } -static struct net_device_stats *lance_get_stats( struct device *dev ) +static struct net_device_stats *lance_get_stats( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1242,7 +1242,7 @@ static struct net_device_stats *lance_get_stats( struct device *dev ) best-effort filtering. */ -static void set_multicast_list( struct device *dev ) +static void set_multicast_list( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1284,7 +1284,7 @@ static void set_multicast_list( struct device *dev ) /* This is needed for old RieblCards and possible for new RieblCards */ -static int lance_set_mac_address( struct device *dev, void *addr ) +static int lance_set_mac_address( struct net_device *dev, void *addr ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct sockaddr *saddr = addr; @@ -1326,7 +1326,7 @@ static int lance_set_mac_address( struct device *dev, void *addr ) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device bagetlance_dev = +static struct net_device bagetlance_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index f9be725cd..f3d3bcc01 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -19,6 +19,11 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/feature.h> +#ifdef CONFIG_PMAC_PBOOK +#include <linux/adb.h> +#include <linux/pmu.h> +#include <asm/irq.h> +#endif #include "bmac.h" #define trunc_page(x) ((void *)(((unsigned long)(x)) & ~((unsigned long)(PAGE_SIZE - 1)))) @@ -114,9 +119,16 @@ bmac_reg_entry_t reg_entries[N_REG_ENTRIES] = { {"RXCV", RXCV} }; -struct device *bmac_devs = NULL; +struct net_device *bmac_devs = NULL; static int is_bmac_plus; +#ifdef CONFIG_PMAC_PBOOK +int bmac_sleep_notify(struct pmu_sleep_notifier *self, int when); +static struct pmu_sleep_notifier bmac_sleep_notifier = { + bmac_sleep_notify, SLEEP_LEVEL_NET, +}; +#endif + #if 0 /* * If we can't get a skbuff when we need it, we use this area for DMA. @@ -135,25 +147,25 @@ static unsigned char dummy_buf[RX_BUFLEN]; + sizeof(struct sk_buff_head)) static unsigned char bitrev(unsigned char b); -static int bmac_open(struct device *dev); -static int bmac_close(struct device *dev); -static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *bmac_stats(struct device *dev); -static void bmac_set_multicast(struct device *dev); -static int bmac_reset_and_enable(struct device *dev, int enable); -static void bmac_start_chip(struct device *dev); -static int bmac_init_chip(struct device *dev); -static void bmac_init_registers(struct device *dev); -static void bmac_reset_chip(struct device *dev); -static int bmac_set_address(struct device *dev, void *addr); +static int bmac_open(struct net_device *dev); +static int bmac_close(struct net_device *dev); +static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *bmac_stats(struct net_device *dev); +static void bmac_set_multicast(struct net_device *dev); +static int bmac_reset_and_enable(struct net_device *dev, int enable); +static void bmac_start_chip(struct net_device *dev); +static int bmac_init_chip(struct net_device *dev); +static void bmac_init_registers(struct net_device *dev); +static void bmac_reset_chip(struct net_device *dev); +static int bmac_set_address(struct net_device *dev, void *addr); static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs); static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); -static void bmac_set_timeout(struct device *dev); +static void bmac_set_timeout(struct net_device *dev); static void bmac_tx_timeout(unsigned long data); static int bmac_proc_info ( char *buffer, char **start, off_t offset, int length, int dummy); -static int bmac_output(struct sk_buff *skb, struct device *dev); -static void bmac_start(struct device *dev); +static int bmac_output(struct sk_buff *skb, struct net_device *dev); +static void bmac_start(struct net_device *dev); #define DBDMA_SET(x) ( ((x) | (x) << 16) ) #define DBDMA_CLEAR(x) ( (x) << 16) @@ -214,20 +226,20 @@ dbdma_setcmd(volatile struct dbdma_cmd *cp, } static __inline__ -void bmwrite(struct device *dev, unsigned long reg_offset, unsigned data ) +void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data ) { out_le16((void *)dev->base_addr + reg_offset, data); } static __inline__ -volatile unsigned short bmread(struct device *dev, unsigned long reg_offset ) +volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset ) { return in_le16((void *)dev->base_addr + reg_offset); } static void -bmac_reset_chip(struct device *dev) +bmac_reset_chip(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -244,10 +256,10 @@ bmac_reset_chip(struct device *dev) udelay(10000); } -#define MIFDELAY udelay(500) +#define MIFDELAY udelay(10) static unsigned int -bmac_mif_readbits(struct device *dev, int nb) +bmac_mif_readbits(struct net_device *dev, int nb) { unsigned int val = 0; @@ -267,7 +279,7 @@ bmac_mif_readbits(struct device *dev, int nb) } static void -bmac_mif_writebits(struct device *dev, unsigned int val, int nb) +bmac_mif_writebits(struct net_device *dev, unsigned int val, int nb) { int b; @@ -281,7 +293,7 @@ bmac_mif_writebits(struct device *dev, unsigned int val, int nb) } static unsigned int -bmac_mif_read(struct device *dev, unsigned int addr) +bmac_mif_read(struct net_device *dev, unsigned int addr) { unsigned int val; @@ -297,12 +309,11 @@ bmac_mif_read(struct device *dev, unsigned int addr) val = bmac_mif_readbits(dev, 17); bmwrite(dev, MIFCSR, 4); MIFDELAY; - /* printk(KERN_DEBUG "bmac_mif_read(%x) -> %x\n", addr, val); */ return val; } static void -bmac_mif_write(struct device *dev, unsigned int addr, unsigned int val) +bmac_mif_write(struct net_device *dev, unsigned int addr, unsigned int val) { bmwrite(dev, MIFCSR, 4); MIFDELAY; @@ -315,7 +326,7 @@ bmac_mif_write(struct device *dev, unsigned int addr, unsigned int val) } static void -bmac_init_registers(struct device *dev) +bmac_init_registers(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile unsigned short regValue; @@ -396,13 +407,13 @@ bmac_init_registers(struct device *dev) #if 0 static void -bmac_disable_interrupts(struct device *dev) +bmac_disable_interrupts(struct net_device *dev) { bmwrite(dev, INTDISABLE, DisableAll); } static void -bmac_enable_interrupts(struct device *dev) +bmac_enable_interrupts(struct net_device *dev) { bmwrite(dev, INTDISABLE, EnableNormal); } @@ -410,7 +421,7 @@ bmac_enable_interrupts(struct device *dev) static void -bmac_start_chip(struct device *dev) +bmac_start_chip(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -428,27 +439,79 @@ bmac_start_chip(struct device *dev) udelay(20000); } -static int -bmac_init_chip(struct device *dev) +static void +bmac_init_phy(struct net_device *dev) { - if (is_bmac_plus && bmac_mif_read(dev, 2) == 0x7810) { - if (bmac_mif_read(dev, 4) == 0xa1) { - bmac_mif_write(dev, 0, 0x1000); - } else { - bmac_mif_write(dev, 4, 0xa1); + unsigned int addr; + + printk(KERN_DEBUG "phy registers:"); + for (addr = 0; addr < 32; ++addr) { + if ((addr & 7) == 0) + printk("\n" KERN_DEBUG); + printk(" %.4x", bmac_mif_read(dev, addr)); + } + printk("\n"); + if (is_bmac_plus) { + unsigned int capable, ctrl; + + ctrl = bmac_mif_read(dev, 0); + capable = ((bmac_mif_read(dev, 1) & 0xf800) >> 6) | 1; + if (bmac_mif_read(dev, 4) != capable + || (ctrl & 0x1000) == 0) { + bmac_mif_write(dev, 4, capable); bmac_mif_write(dev, 0, 0x1200); - } -#if 0 - /* XXX debugging */ - bmac_mif_read(dev, 0); - bmac_mif_read(dev, 4); -#endif + } else + bmac_mif_write(dev, 0, 0x1000); } +} + +static int +bmac_init_chip(struct net_device *dev) +{ + bmac_init_phy(dev); bmac_init_registers(dev); return 1; } -static int bmac_set_address(struct device *dev, void *addr) +#ifdef CONFIG_PMAC_PBOOK +int +bmac_sleep_notify(struct pmu_sleep_notifier *self, int when) +{ + struct bmac_data *bp; + + if (bmac_devs == 0) + return PBOOK_SLEEP_OK; + + bp = (struct bmac_data *) bmac_devs->priv; + + switch (when) { + case PBOOK_SLEEP_REQUEST: + break; + case PBOOK_SLEEP_REJECT: + break; + case PBOOK_SLEEP_NOW: + /* prolly should wait for dma to finish & turn off the chip */ + disable_irq(bmac_devs->irq); + disable_irq(bp->tx_dma_intr); + disable_irq(bp->rx_dma_intr); + feature_set(bp->node, FEATURE_BMac_reset); + udelay(10000); + feature_clear(bp->node, FEATURE_BMac_IO_enable); + udelay(10000); + break; + case PBOOK_WAKE: + /* see if this is enough */ + bmac_reset_and_enable(bmac_devs, 1); + enable_irq(bmac_devs->irq); + enable_irq(bp->tx_dma_intr); + enable_irq(bp->rx_dma_intr); + break; + } + return PBOOK_SLEEP_OK; +} +#endif + +static int bmac_set_address(struct net_device *dev, void *addr) { unsigned char *p = addr; unsigned short *pWord16; @@ -472,7 +535,7 @@ static int bmac_set_address(struct device *dev, void *addr) return 0; } -static inline void bmac_set_timeout(struct device *dev) +static inline void bmac_set_timeout(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; unsigned long flags; @@ -580,7 +643,7 @@ bmac_init_rx_ring(struct bmac_data *bp) } -static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev) +static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *td = bp->tx_dma; @@ -616,7 +679,7 @@ static int rxintcount = 0; static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_cmd *cp; @@ -684,7 +747,7 @@ static int txintcount = 0; static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_cmd *cp; int stat; @@ -730,7 +793,7 @@ static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) bmac_start(dev); } -static struct net_device_stats *bmac_stats(struct device *dev) +static struct net_device_stats *bmac_stats(struct net_device *dev) { struct bmac_data *p = (struct bmac_data *) dev->priv; @@ -833,7 +896,7 @@ bmac_removehash(struct bmac_data *bp, unsigned char *addr) */ static void -bmac_rx_off(struct device *dev) +bmac_rx_off(struct net_device *dev) { unsigned short rx_cfg; @@ -846,7 +909,7 @@ bmac_rx_off(struct device *dev) } unsigned short -bmac_rx_on(struct device *dev, int hash_enable, int promisc_enable) +bmac_rx_on(struct net_device *dev, int hash_enable, int promisc_enable) { unsigned short rx_cfg; @@ -864,7 +927,7 @@ bmac_rx_on(struct device *dev, int hash_enable, int promisc_enable) } static void -bmac_update_hash_table_mask(struct device *dev, struct bmac_data *bp) +bmac_update_hash_table_mask(struct net_device *dev, struct bmac_data *bp) { bmwrite(dev, BHASH3, bp->hash_table_mask[0]); /* bits 15 - 0 */ bmwrite(dev, BHASH2, bp->hash_table_mask[1]); /* bits 31 - 16 */ @@ -874,7 +937,7 @@ bmac_update_hash_table_mask(struct device *dev, struct bmac_data *bp) #if 0 static void -bmac_add_multi(struct device *dev, +bmac_add_multi(struct net_device *dev, struct bmac_data *bp, unsigned char *addr) { /* XXDEBUG(("bmac: enter bmac_add_multi\n")); */ @@ -886,7 +949,7 @@ bmac_add_multi(struct device *dev, } static void -bmac_remove_multi(struct device *dev, +bmac_remove_multi(struct net_device *dev, struct bmac_data *bp, unsigned char *addr) { bmac_removehash(bp, addr); @@ -902,7 +965,7 @@ bmac_remove_multi(struct device *dev, num_addrs > 0 Multicast mode, receive normal and MC packets, and do best-effort filtering. */ -static void bmac_set_multicast(struct device *dev) +static void bmac_set_multicast(struct net_device *dev) { struct dev_mc_list *dmi; struct bmac_data *bp = (struct bmac_data *) dev->priv; @@ -946,7 +1009,7 @@ static void bmac_set_multicast(struct device *dev) #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void bmac_set_multicast(struct device *dev) +static void bmac_set_multicast(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; char *addrs; @@ -1014,7 +1077,7 @@ static int miscintcount = 0; static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *)dev->priv; unsigned int status = bmread(dev, STATUS); if (miscintcount++ < 10) { @@ -1052,7 +1115,7 @@ static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) #define EnetAddressOffset 20 static unsigned char -bmac_clock_out_bit(struct device *dev) +bmac_clock_out_bit(struct net_device *dev) { unsigned short data; unsigned short val; @@ -1071,7 +1134,7 @@ bmac_clock_out_bit(struct device *dev) } static void -bmac_clock_in_bit(struct device *dev, unsigned int val) +bmac_clock_in_bit(struct net_device *dev, unsigned int val) { unsigned short data; @@ -1089,7 +1152,7 @@ bmac_clock_in_bit(struct device *dev, unsigned int val) } static void -reset_and_select_srom(struct device *dev) +reset_and_select_srom(struct net_device *dev) { /* first reset */ bmwrite(dev, SROMCSR, 0); @@ -1102,7 +1165,7 @@ reset_and_select_srom(struct device *dev) } static unsigned short -read_srom(struct device *dev, unsigned int addr, unsigned int addr_len) +read_srom(struct net_device *dev, unsigned int addr, unsigned int addr_len) { unsigned short data, val; int i; @@ -1131,7 +1194,7 @@ read_srom(struct device *dev, unsigned int addr, unsigned int addr_len) */ static int -bmac_verify_checksum(struct device *dev) +bmac_verify_checksum(struct net_device *dev) { unsigned short data, storedCS; @@ -1144,7 +1207,7 @@ bmac_verify_checksum(struct device *dev) static void -bmac_get_station_address(struct device *dev, unsigned char *ea) +bmac_get_station_address(struct net_device *dev, unsigned char *ea) { int i; unsigned short data; @@ -1158,7 +1221,7 @@ bmac_get_station_address(struct device *dev, unsigned char *ea) } } -static int bmac_reset_and_enable(struct device *dev, int enable) +static int bmac_reset_and_enable(struct net_device *dev, int enable) { struct bmac_data *bp = dev->priv; unsigned long flags; @@ -1191,7 +1254,7 @@ static int bmac_reset_and_enable(struct device *dev, int enable) } int -bmac_probe(struct device *dev) +bmac_probe(struct net_device *dev) { int j, rev; struct bmac_data *bp; @@ -1213,7 +1276,12 @@ bmac_probe(struct device *dev) if (bmacs == NULL) return -ENODEV; next_bmac = bmacs->next; - bmac_devs = dev; /* KLUDGE!! */ + if (bmac_devs == 0) { + bmac_devs = dev; /* KLUDGE!! */ +#ifdef CONFIG_PMAC_PBOOK + pmu_register_sleep_notifier(&bmac_sleep_notifier); +#endif + } if (bmacs->n_addrs != 3 || bmacs->n_intrs != 3) { printk(KERN_ERR "can't use BMAC %s: expect 3 addrs and 3 intrs\n", @@ -1322,7 +1390,7 @@ bmac_probe(struct device *dev) return 0; } -static int bmac_open(struct device *dev) +static int bmac_open(struct net_device *dev) { /* XXDEBUG(("bmac: enter open\n")); */ /* reset the chip */ @@ -1330,10 +1398,11 @@ static int bmac_open(struct device *dev) dev->flags |= IFF_UP | IFF_RUNNING; + MOD_INC_USE_COUNT; return 0; } -static int bmac_close(struct device *dev) +static int bmac_close(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -1375,11 +1444,13 @@ static int bmac_close(struct device *dev) bp->reset_and_enabled = 0; XXDEBUG(("bmac: all bufs freed\n")); + MOD_DEC_USE_COUNT; + return 0; } static void -bmac_start(struct device *dev) +bmac_start(struct net_device *dev) { struct bmac_data *bp = dev->priv; int i; @@ -1399,7 +1470,7 @@ bmac_start(struct device *dev) } static int -bmac_output(struct sk_buff *skb, struct device *dev) +bmac_output(struct sk_buff *skb, struct net_device *dev) { struct bmac_data *bp = dev->priv; skb_queue_tail(bp->queue, skb); @@ -1409,7 +1480,7 @@ bmac_output(struct sk_buff *skb, struct device *dev) static void bmac_tx_timeout(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *td = bp->tx_dma; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -1546,15 +1617,24 @@ int init_module(void) res = bmac_probe(NULL); return res; } + void cleanup_module(void) { - struct bmac_data *bp = (struct bmac_data *) bmac_devs->priv; + struct bmac_data *bp; + + if (bmac_devs == 0) + return; + + bp = (struct bmac_data *) bmac_devs->priv; unregister_netdev(bmac_devs); free_irq(bmac_devs->irq, bmac_misc_intr); free_irq(bp->tx_dma_intr, bmac_txdma_intr); free_irq(bp->rx_dma_intr, bmac_rxdma_intr); +#ifdef CONFIG_PMAC_PBOOK + pmu_unregister_sleep_notifier(&bmac_sleep_notifier); +#endif kfree(bmac_devs); bmac_devs = NULL; } diff --git a/drivers/net/com20020.c b/drivers/net/com20020.c index afadea838..0f3bd0210 100644 --- a/drivers/net/com20020.c +++ b/drivers/net/com20020.c @@ -58,23 +58,23 @@ /* Internal function declarations */ -static int arc20020_probe(struct device *dev); -static void arc20020_rx(struct device *dev,int recbuf); -static int arc20020_found(struct device *dev,int ioaddr,int airq); -static void arc20020_inthandler (struct device *dev); -static int arc20020_reset (struct device *dev, int reset_delay); -static void arc20020_setmask (struct device *dev, u_char mask); -static void arc20020_command (struct device *dev, u_char command); -static u_char arc20020_status (struct device *dev); -static void arc20020_en_dis_able_TX (struct device *dev, int enable); -static void arc20020_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arc20020_probe(struct net_device *dev); +static void arc20020_rx(struct net_device *dev,int recbuf); +static int arc20020_found(struct net_device *dev,int ioaddr,int airq); +static void arc20020_inthandler (struct net_device *dev); +static int arc20020_reset (struct net_device *dev, int reset_delay); +static void arc20020_setmask (struct net_device *dev, u_char mask); +static void arc20020_command (struct net_device *dev, u_char command); +static u_char arc20020_status (struct net_device *dev); +static void arc20020_en_dis_able_TX (struct net_device *dev, int enable); +static void arc20020_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arc20020_openclose(int open); -static void arc20020_set_mc_list(struct device *dev); -static u_char get_buffer_byte (struct device *dev, unsigned offset); -static void put_buffer_byte (struct device *dev, unsigned offset, u_char datum); -static void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); -static void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); +static void arc20020_set_mc_list(struct net_device *dev); +static u_char get_buffer_byte (struct net_device *dev, unsigned offset); +static void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum); +static void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); +static void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); /* Module parameters */ @@ -97,7 +97,7 @@ MODULE_PARM(backplane,"i"); MODULE_PARM(clock,"i"); #else void __init com20020_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -155,7 +155,7 @@ static char *clockrates[]={"2.5 Mb/s","1.25Mb/s","625 Kb/s","312.5 Kb/s", * * ****************************************************************************/ -u_char get_buffer_byte (struct device *dev, unsigned offset) +u_char get_buffer_byte (struct net_device *dev, unsigned offset) { int ioaddr=dev->base_addr; @@ -165,7 +165,7 @@ u_char get_buffer_byte (struct device *dev, unsigned offset) return inb(_MEMDATA); } -void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) +void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum) { int ioaddr=dev->base_addr; @@ -179,7 +179,7 @@ void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) #undef ONE_AT_A_TIME_TX #undef ONE_AT_A_TIME_RX -void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -194,7 +194,7 @@ void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, cha #endif } -void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -224,7 +224,7 @@ static const char *version = * it's where we were told it was, and even autoirq */ -int __init arc20020_probe(struct device *dev) +int __init arc20020_probe(struct net_device *dev) { int ioaddr=dev->base_addr,status,delayval; unsigned long airqmask; @@ -324,10 +324,10 @@ int __init arc20020_probe(struct device *dev) } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arc20020_found(struct device *dev,int ioaddr,int airq) +int __init arc20020_found(struct net_device *dev,int ioaddr,int airq) { struct arcnet_local *lp; @@ -444,7 +444,7 @@ int __init arc20020_found(struct device *dev,int ioaddr,int airq) * * However, it does make sure the card is in a defined state. */ -int arc20020_reset(struct device *dev,int reset_delay) +int arc20020_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->base_addr; @@ -515,7 +515,7 @@ int arc20020_reset(struct device *dev,int reset_delay) * FIX ME - do multicast stuff, not just promiscuous. */ static void -arc20020_set_mc_list(struct device *dev) +arc20020_set_mc_list(struct net_device *dev) { struct arcnet_local *lp=dev->priv; int ioaddr=dev->base_addr; @@ -550,7 +550,7 @@ static void arc20020_openclose(int open) } -static void arc20020_en_dis_able_TX(struct device *dev, int enable) +static void arc20020_en_dis_able_TX(struct net_device *dev, int enable) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -560,7 +560,7 @@ static void arc20020_en_dis_able_TX(struct device *dev, int enable) } -static void arc20020_setmask(struct device *dev, u_char mask) +static void arc20020_setmask(struct net_device *dev, u_char mask) { short ioaddr=dev->base_addr; @@ -568,7 +568,7 @@ static void arc20020_setmask(struct device *dev, u_char mask) } -static u_char arc20020_status(struct device *dev) +static u_char arc20020_status(struct net_device *dev) { short ioaddr=dev->base_addr; @@ -576,7 +576,7 @@ static u_char arc20020_status(struct device *dev) } -static void arc20020_command(struct device *dev, u_char cmd) +static void arc20020_command(struct net_device *dev, u_char cmd) { short ioaddr=dev->base_addr; @@ -588,7 +588,7 @@ static void arc20020_command(struct device *dev, u_char cmd) * by the card. */ static void -arc20020_inthandler(struct device *dev) +arc20020_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr, status, boguscount = 3, didsomething, @@ -828,7 +828,7 @@ arc20020_inthandler(struct device *dev) */ static void -arc20020_rx(struct device *dev,int recbuf) +arc20020_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -885,7 +885,7 @@ arc20020_rx(struct device *dev,int recbuf) * by arcnet_go_tx. */ static void -arc20020_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arc20020_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -957,19 +957,19 @@ arc20020_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, #ifdef MODULE -static struct device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +static struct net_device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; int init_module(void) { - struct device *dev; + struct net_device *dev; - cards[0]=dev=(struct device *)kmalloc(sizeof(struct device), GFP_KERNEL); + cards[0]=dev=(struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); dev->name=(char *)kmalloc(9, GFP_KERNEL); if (!dev->name) @@ -1006,7 +1006,7 @@ int init_module(void) void cleanup_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; int ioaddr=dev->base_addr; if (dev->start) (*dev->stop)(dev); @@ -1037,7 +1037,7 @@ void cleanup_module(void) void __init com20020_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff --git a/drivers/net/com90io.c b/drivers/net/com90io.c index 2e9ea0660..8c12c6325 100644 --- a/drivers/net/com90io.c +++ b/drivers/net/com90io.c @@ -58,22 +58,22 @@ /* Internal function declarations */ -static int arc90io_probe(struct device *dev); -static void arc90io_rx(struct device *dev,int recbuf); -static int arc90io_found(struct device *dev,int ioaddr,int airq); -static void arc90io_inthandler (struct device *dev); -static int arc90io_reset (struct device *dev, int reset_delay); -static void arc90io_setmask (struct device *dev, u_char mask); -static void arc90io_command (struct device *dev, u_char command); -static u_char arc90io_status (struct device *dev); -static void arc90io_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arc90io_probe(struct net_device *dev); +static void arc90io_rx(struct net_device *dev,int recbuf); +static int arc90io_found(struct net_device *dev,int ioaddr,int airq); +static void arc90io_inthandler (struct net_device *dev); +static int arc90io_reset (struct net_device *dev, int reset_delay); +static void arc90io_setmask (struct net_device *dev, u_char mask); +static void arc90io_command (struct net_device *dev, u_char command); +static u_char arc90io_status (struct net_device *dev); +static void arc90io_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arc90io_openclose(int open); -static u_char get_buffer_byte (struct device *dev, unsigned offset); -static void put_buffer_byte (struct device *dev, unsigned offset, u_char datum); -static void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); -static void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); +static u_char get_buffer_byte (struct net_device *dev, unsigned offset); +static void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum); +static void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); +static void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); /* Module parameters */ @@ -88,7 +88,7 @@ MODULE_PARM(irq, "i"); MODULE_PARM(device, "s"); #else void __init com90io_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -124,7 +124,7 @@ extern int arcnet_num_devs; * * ****************************************************************************/ -u_char get_buffer_byte (struct device *dev, unsigned offset) +u_char get_buffer_byte (struct net_device *dev, unsigned offset) { int ioaddr=dev->base_addr; @@ -134,7 +134,7 @@ u_char get_buffer_byte (struct device *dev, unsigned offset) return inb(_MEMDATA); } -void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) +void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum) { int ioaddr=dev->base_addr; @@ -148,7 +148,7 @@ void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) #undef ONE_AT_A_TIME_TX #undef ONE_AT_A_TIME_RX -void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -163,7 +163,7 @@ void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, cha #endif } -void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -193,7 +193,7 @@ static const char *version = * it's where we were told it was, and even autoirq */ -int __init arc90io_probe(struct device *dev) +int __init arc90io_probe(struct net_device *dev) { int ioaddr=dev->base_addr,status,delayval; unsigned long airqmask; @@ -284,10 +284,10 @@ int __init arc90io_probe(struct device *dev) } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arc90io_found(struct device *dev,int ioaddr,int airq) +int __init arc90io_found(struct net_device *dev,int ioaddr,int airq) { struct arcnet_local *lp; @@ -381,7 +381,7 @@ int __init arc90io_found(struct device *dev,int ioaddr,int airq) * * However, it does make sure the card is in a defined state. */ -int arc90io_reset(struct device *dev,int reset_delay) +int arc90io_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->base_addr; @@ -453,21 +453,21 @@ static void arc90io_openclose(int open) } -static void arc90io_setmask(struct device *dev, u_char mask) +static void arc90io_setmask(struct net_device *dev, u_char mask) { short ioaddr=dev->base_addr; AINTMASK(mask); } -static u_char arc90io_status(struct device *dev) +static u_char arc90io_status(struct net_device *dev) { short ioaddr=dev->base_addr; return ARCSTATUS; } -static void arc90io_command(struct device *dev, u_char cmd) +static void arc90io_command(struct net_device *dev, u_char cmd) { short ioaddr=dev->base_addr; @@ -479,7 +479,7 @@ static void arc90io_command(struct device *dev, u_char cmd) * by the card. */ static void -arc90io_inthandler(struct device *dev) +arc90io_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr, status, boguscount = 3, didsomething; @@ -711,7 +711,7 @@ arc90io_inthandler(struct device *dev) */ static void -arc90io_rx(struct device *dev,int recbuf) +arc90io_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -768,7 +768,7 @@ arc90io_rx(struct device *dev,int recbuf) * by arcnet_go_tx. */ static void -arc90io_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arc90io_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -840,19 +840,19 @@ arc90io_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, #ifdef MODULE -static struct device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +static struct net_device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; int init_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; - cards[0]=dev=(struct device *)kmalloc(sizeof(struct device), GFP_KERNEL); + cards[0]=dev=(struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); dev->name=(char *)kmalloc(9, GFP_KERNEL); if (!dev->name) @@ -881,7 +881,7 @@ int init_module(void) void cleanup_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; int ioaddr=dev->base_addr; if (dev->start) (*dev->stop)(dev); @@ -916,7 +916,7 @@ void cleanup_module(void) void __init com90io_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff --git a/drivers/net/com90xx.c b/drivers/net/com90xx.c index be4514fab..c07452f23 100644 --- a/drivers/net/com90xx.c +++ b/drivers/net/com90xx.c @@ -91,15 +91,15 @@ #ifdef MODULE static #endif -int arc90xx_probe(struct device *dev); -static void arc90xx_rx(struct device *dev, int recbuf); -static int arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more); -static void arc90xx_inthandler(struct device *dev); -static int arc90xx_reset(struct device *dev, int reset_delay); -static void arc90xx_setmask(struct device *dev, u_char mask); -static void arc90xx_command(struct device *dev, u_char command); -static u_char arc90xx_status(struct device *dev); -static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen, +int arc90xx_probe(struct net_device *dev); +static void arc90xx_rx(struct net_device *dev, int recbuf); +static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more); +static void arc90xx_inthandler(struct net_device *dev); +static int arc90xx_reset(struct net_device *dev, int reset_delay); +static void arc90xx_setmask(struct net_device *dev, u_char mask); +static void arc90xx_command(struct net_device *dev, u_char command); +static u_char arc90xx_status(struct net_device *dev); +static void arc90xx_prepare_tx(struct net_device *dev, u_char * hdr, int hdrlen, char *data, int length, int daddr, int exceptA, int offset); static void arc90xx_openclose(int open); @@ -120,7 +120,7 @@ MODULE_PARM(device, "s"); void __init com90xx_setup(char *str, int *ints); char __initdata com90xx_explicit = 0; -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -179,7 +179,7 @@ static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata = { 0 }; -int __init arc90xx_probe(struct device *dev) +int __init arc90xx_probe(struct net_device *dev) { static int init_once = 0; static int numports = sizeof(ports) / sizeof(ports[0]), numshmems = sizeof(shmems) / sizeof(shmems[0]); @@ -490,10 +490,10 @@ int __init arc90xx_probe(struct device *dev) return retval; } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -static int __init arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more) +static int __init arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more) { struct arcnet_local *lp; u_long first_mirror, last_mirror; @@ -623,7 +623,7 @@ static int __init arc90xx_found(struct device *dev, int ioaddr, int airq, u_long * * However, it does make sure the card is in a defined state. */ -int arc90xx_reset(struct device *dev, int reset_delay) +int arc90xx_reset(struct net_device *dev, int reset_delay) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; short ioaddr = dev->base_addr; @@ -690,7 +690,7 @@ static void arc90xx_openclose(int open) } -static void arc90xx_setmask(struct device *dev, u_char mask) +static void arc90xx_setmask(struct net_device *dev, u_char mask) { short ioaddr = dev->base_addr; @@ -698,7 +698,7 @@ static void arc90xx_setmask(struct device *dev, u_char mask) } -static u_char arc90xx_status(struct device *dev) +static u_char arc90xx_status(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -706,7 +706,7 @@ static u_char arc90xx_status(struct device *dev) } -static void arc90xx_command(struct device *dev, u_char cmd) +static void arc90xx_command(struct net_device *dev, u_char cmd) { short ioaddr = dev->base_addr; @@ -717,7 +717,7 @@ static void arc90xx_command(struct device *dev, u_char cmd) /* The actual interrupt handler routine - handle various IRQ's generated * by the card. */ -static void arc90xx_inthandler(struct device *dev) +static void arc90xx_inthandler(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int ioaddr = dev->base_addr, status, boguscount = 3, didsomething; @@ -909,7 +909,7 @@ static void arc90xx_inthandler(struct device *dev) * arcnet_rx routing to deal with it. */ -static void arc90xx_rx(struct device *dev, int recbuf) +static void arc90xx_rx(struct net_device *dev, int recbuf) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int ioaddr = dev->base_addr; @@ -962,7 +962,7 @@ static void arc90xx_rx(struct device *dev, int recbuf) /* Given an skb, copy a packet into the ARCnet buffers for later transmission * by arcnet_go_tx. */ -static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen, +static void arc90xx_prepare_tx(struct net_device *dev, u_char * hdr, int hdrlen, char *data, int length, int daddr, int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; @@ -1053,7 +1053,7 @@ static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen, #ifdef MODULE static char devicename[9] = ""; -static struct device thiscard = +static struct net_device thiscard = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, @@ -1064,7 +1064,7 @@ static struct device thiscard = int init_module(void) { - struct device *dev = &thiscard; + struct net_device *dev = &thiscard; if (device) strcpy(dev->name, device); else @@ -1090,7 +1090,7 @@ int init_module(void) void cleanup_module(void) { - struct device *dev = &thiscard; + struct net_device *dev = &thiscard; int ioaddr = dev->mem_start; if (dev->start) @@ -1123,7 +1123,7 @@ void cleanup_module(void) void __init com90xx_setup(char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { printk("com90xx: Too many ARCnet devices registered (max %d).\n", diff --git a/drivers/net/cops.c b/drivers/net/cops.c index 0d3469204..5f9c727a3 100644 --- a/drivers/net/cops.c +++ b/drivers/net/cops.c @@ -188,28 +188,28 @@ struct cops_local }; /* Index to functions, as function prototypes. */ -extern int cops_probe (struct device *dev); -static int cops_probe1 (struct device *dev, int ioaddr); +extern int cops_probe (struct net_device *dev); +static int cops_probe1 (struct net_device *dev, int ioaddr); static int cops_irq (int ioaddr, int board); -static int cops_open (struct device *dev); -static int cops_jumpstart (struct device *dev); -static void cops_reset (struct device *dev, int sleep); -static void cops_load (struct device *dev); -static int cops_nodeid (struct device *dev, int nodeid); +static int cops_open (struct net_device *dev); +static int cops_jumpstart (struct net_device *dev); +static void cops_reset (struct net_device *dev, int sleep); +static void cops_load (struct net_device *dev); +static int cops_nodeid (struct net_device *dev, int nodeid); static void cops_interrupt (int irq, void *dev_id, struct pt_regs *regs); static void cops_poll (unsigned long ltdev); -static void cops_rx (struct device *dev); -static int cops_send_packet (struct sk_buff *skb, struct device *dev); -static void set_multicast_list (struct device *dev); -static int cops_hard_header (struct sk_buff *skb, struct device *dev, +static void cops_rx (struct net_device *dev); +static int cops_send_packet (struct sk_buff *skb, struct net_device *dev); +static void set_multicast_list (struct net_device *dev); +static int cops_hard_header (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); -static int cops_ioctl (struct device *dev, struct ifreq *rq, int cmd); -static int cops_close (struct device *dev); -static struct enet_statistics *cops_get_stats (struct device *dev); +static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static int cops_close (struct net_device *dev); +static struct enet_statistics *cops_get_stats (struct net_device *dev); /* @@ -218,7 +218,7 @@ static struct enet_statistics *cops_get_stats (struct device *dev); * If dev->base_addr in [1..0x1ff], always return failure. * otherwise go with what we pass in. */ -int __init cops_probe(struct device *dev) +int __init cops_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -252,7 +252,7 @@ int __init cops_probe(struct device *dev) * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -static int __init cops_probe1(struct device *dev, int ioaddr) +static int __init cops_probe1(struct net_device *dev, int ioaddr) { struct cops_local *lp; static unsigned version_printed = 0; @@ -397,7 +397,7 @@ static int __init cops_irq (int ioaddr, int board) * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. */ -static int cops_open(struct device *dev) +static int cops_open(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -438,7 +438,7 @@ static int cops_open(struct device *dev) /* * This allows for a dynamic start/restart of the entire card. */ -static int cops_jumpstart(struct device *dev) +static int cops_jumpstart(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -472,7 +472,7 @@ static void tangent_wait_reset(int ioaddr) /* * Reset the LocalTalk board. */ -static void cops_reset(struct device *dev, int sleep) +static void cops_reset(struct net_device *dev, int sleep) { struct cops_local *lp = (struct cops_local *)dev->priv; int ioaddr=dev->base_addr; @@ -506,7 +506,7 @@ static void cops_reset(struct device *dev, int sleep) return; } -static void cops_load (struct device *dev) +static void cops_load (struct net_device *dev) { struct ifreq ifr; struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data; @@ -601,7 +601,7 @@ static void cops_load (struct device *dev) * address else we can specify 0 as the nodeid and the card * will autoprobe for a nodeid. */ -static int cops_nodeid (struct device *dev, int nodeid) +static int cops_nodeid (struct net_device *dev, int nodeid) { struct cops_local *lp = (struct cops_local *) dev->priv; int ioaddr = dev->base_addr; @@ -678,7 +678,7 @@ static void cops_poll(unsigned long ltdev) int ioaddr, status; int boguscount = 0; - struct device *dev = (struct device *)ltdev; + struct net_device *dev = (struct net_device *)ltdev; del_timer(&cops_timer); @@ -707,7 +707,7 @@ static void cops_poll(unsigned long ltdev) */ static void cops_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct cops_local *lp; int ioaddr, status; int boguscount = 0; @@ -754,7 +754,7 @@ static void cops_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* * We have a good packet(s), get it/them out of the buffers. */ -static void cops_rx(struct device *dev) +static void cops_rx(struct net_device *dev) { int pkt_len = 0; int rsp_type = 0; @@ -860,7 +860,7 @@ static void cops_rx(struct device *dev) /* * Make the card transmit a LocalTalk packet. */ -static int cops_send_packet(struct sk_buff *skb, struct device *dev) +static int cops_send_packet(struct sk_buff *skb, struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; int ioaddr = dev->base_addr; @@ -937,7 +937,7 @@ static int cops_send_packet(struct sk_buff *skb, struct device *dev) * Dummy function to keep the Appletalk layer happy. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(cops_debug >= 3) printk("%s: set_multicast_list executed\n", dev->name); @@ -947,7 +947,7 @@ static void set_multicast_list(struct device *dev) * Another Dummy function to keep the Appletalk layer happy. */ -static int cops_hard_header(struct sk_buff *skb, struct device *dev, +static int cops_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -960,7 +960,7 @@ static int cops_hard_header(struct sk_buff *skb, struct device *dev, * System ioctls for the COPS LocalTalk card. */ -static int cops_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct cops_local *lp = (struct cops_local *)dev->priv; struct sockaddr_at *sa=(struct sockaddr_at *)&ifr->ifr_addr; @@ -996,7 +996,7 @@ static int cops_ioctl(struct device *dev, struct ifreq *ifr, int cmd) * The inverse routine to cops_open(). */ -static int cops_close(struct device *dev) +static int cops_close(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -1019,7 +1019,7 @@ static int cops_close(struct device *dev) * Get the current statistics. * This may be called with the card open or closed. */ -static struct enet_statistics *cops_get_stats(struct device *dev) +static struct enet_statistics *cops_get_stats(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; return &lp->stats; @@ -1028,7 +1028,7 @@ static struct enet_statistics *cops_get_stats(struct device *dev) #ifdef MODULE static char lt_name[16]; -static struct device cops0_dev = +static struct net_device cops0_dev = { lt_name, /* device name */ 0, 0, 0, 0, diff --git a/drivers/net/cosa.c b/drivers/net/cosa.c index fdfa991b9..863cd4b59 100644 --- a/drivers/net/cosa.c +++ b/drivers/net/cosa.c @@ -1,10 +1,7 @@ -/* $Id: cosa.c,v 1.24 1999/05/28 17:28:34 kas Exp $ */ +/* $Id: cosa.c,v 1.26 1999/07/09 15:02:37 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz> - * - * 5/25/1999 : Marcelo Tosatti <marcelo@conectiva.com.br> - * fixed a deadlock in cosa_sppp_open * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -93,6 +90,7 @@ #include <linux/errno.h> #include <linux/ioport.h> #include <linux/netdevice.h> +#include <linux/spinlock.h> #undef COSA_SLOW_IO /* for testing purposes only */ #undef REALLY_SLOW_IO @@ -100,11 +98,17 @@ #include <asm/io.h> #include <asm/dma.h> #include <asm/byteorder.h> -#include <asm/spinlock.h> #include "syncppp.h" #include "cosa.h" +/* Linux version stuff */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) +typedef struct wait_queue *wait_queue_head_t; +#define DECLARE_WAITQUEUE(wait, current) \ + struct wait_queue wait = { current, NULL } +#endif + /* Maximum length of the identification string. */ #define COSA_MAX_ID_STRING 128 @@ -274,14 +278,14 @@ static int cosa_dma_able(struct channel_data *chan, char *buf, int data); /* SPPP/HDLC stuff */ static void sppp_channel_init(struct channel_data *chan); static void sppp_channel_delete(struct channel_data *chan); -static int cosa_sppp_open(struct device *d); -static int cosa_sppp_close(struct device *d); -static int cosa_sppp_tx(struct sk_buff *skb, struct device *d); +static int cosa_sppp_open(struct net_device *d); +static int cosa_sppp_close(struct net_device *d); +static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d); static char *sppp_setup_rx(struct channel_data *channel, int size); static int sppp_rx_done(struct channel_data *channel); static int sppp_tx_done(struct channel_data *channel, int size); -static int cosa_sppp_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *cosa_net_stats(struct device *dev); +static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *cosa_net_stats(struct net_device *dev); /* Character device */ static void chardev_channel_init(struct channel_data *chan); @@ -366,7 +370,7 @@ static int __init cosa_init(void) #endif { int i; - printk(KERN_INFO "cosa v1.04 (c) 1997-8 Jan Kasprzak <kas@fi.muni.cz>\n"); + printk(KERN_INFO "cosa v1.06 (c) 1997-8 Jan Kasprzak <kas@fi.muni.cz>\n"); #ifdef __SMP__ printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n"); #endif @@ -568,7 +572,7 @@ bad1: release_region(cosa->datareg,is_8bit(cosa)?2:4); static void sppp_channel_init(struct channel_data *chan) { - struct device *d; + struct net_device *d; sppp_attach(&chan->pppdev); d=&chan->pppdev.dev; d->name = chan->name; @@ -597,7 +601,7 @@ static void sppp_channel_delete(struct channel_data *chan) } -static int cosa_sppp_open(struct device *d) +static int cosa_sppp_open(struct net_device *d) { struct channel_data *chan = d->priv; int err, flags; @@ -633,7 +637,7 @@ static int cosa_sppp_open(struct device *d) return 0; } -static int cosa_sppp_tx(struct sk_buff *skb, struct device *dev) +static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) { struct channel_data *chan = dev->priv; @@ -665,7 +669,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct device *dev) return 0; } -static int cosa_sppp_close(struct device *d) +static int cosa_sppp_close(struct net_device *d) { struct channel_data *chan = d->priv; int flags; @@ -747,7 +751,7 @@ static int sppp_tx_done(struct channel_data *chan, int size) return 1; } -static struct net_device_stats *cosa_net_stats(struct device *dev) +static struct net_device_stats *cosa_net_stats(struct net_device *dev) { struct channel_data *chan = dev->priv; return &chan->stats; @@ -1166,7 +1170,7 @@ static int cosa_ioctl_common(struct cosa_data *cosa, return -ENOIOCTLCMD; } -static int cosa_sppp_ioctl(struct device *dev, struct ifreq *ifr, +static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int rv; @@ -1269,10 +1273,8 @@ static void put_driver_status(struct cosa_data *cosa) debug_status_out(cosa, 0); #endif } - cosa_putdata8(cosa, 0); cosa_putdata8(cosa, status); #ifdef DEBUG_IO - debug_data_cmd(cosa, 0); debug_data_cmd(cosa, status); #endif } @@ -1558,7 +1560,6 @@ static int get_wait_data(struct cosa_data *cosa) /* sleep if not ready to read */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); - current->state = TASK_RUNNING; } printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n", cosa_getstatus(cosa)); @@ -1586,7 +1587,6 @@ static int put_wait_data(struct cosa_data *cosa, int data) /* sleep if not ready to read */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); - current->state = TASK_RUNNING; #endif } printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n", @@ -1647,6 +1647,14 @@ static int puthexnumber(struct cosa_data *cosa, int number) * use the round-robin approach. The newer COSA firmwares have a simple * flow-control - in the status word has bits 2 and 3 set to 1 means that the * channel 0 or 1 doesn't want to receive data. + * + * It seems there is a bug in COSA firmware (need to trace it further): + * When the driver status says that the kernel has no more data for transmit + * (e.g. at the end of TX DMA) and then the kernel changes its mind + * (e.g. new packet is queued to hard_start_xmit()), the card issues + * the TX interrupt but does not mark the channel as ready-to-transmit. + * The fix seems to be to push the packet to COSA despite its request. + * We first try to obey the card's opinion, and then fall back to forced TX. */ static inline void tx_interrupt(struct cosa_data *cosa, int status) { @@ -1658,23 +1666,35 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) spin_lock_irqsave(&cosa->lock, flags); set_bit(TXBIT, &cosa->rxtx); if (!test_bit(IRQBIT, &cosa->rxtx)) { - /* flow control */ + /* flow control, see the comment above */ int i=0; - do { - if (i++ > cosa->nchannels) { - printk(KERN_WARNING - "%s: No channel wants data in TX IRQ\n", - cosa->name); - put_driver_status_nolock(cosa); - clear_bit(TXBIT, &cosa->rxtx); - spin_unlock_irqrestore(&cosa->lock, flags); - return; - } + if (!cosa->txbitmap) { + printk(KERN_WARNING "%s: No channel wants data " + "in TX IRQ. Expect DMA timeout.", + cosa->name); + put_driver_status_nolock(cosa); + clear_bit(TXBIT, &cosa->rxtx); + spin_unlock_irqrestore(&cosa->lock, flags); + return; + } + while(1) { cosa->txchan++; + i++; if (cosa->txchan >= cosa->nchannels) cosa->txchan = 0; - } while ((!(cosa->txbitmap & (1<<cosa->txchan))) - || status & (1<<(cosa->txchan+DRIVER_TXMAP_SHIFT))); + if (!(cosa->txbitmap & (1<<cosa->txchan))) + continue; + if (~status & (1 << (cosa->txchan+DRIVER_TXMAP_SHIFT))) + break; + /* in second pass, accept first ready-to-TX channel */ + if (i > cosa->nchannels) { + /* Can be safely ignored */ + printk(KERN_DEBUG "%s: Forcing TX " + "to not-ready channel %d\n", + cosa->name, cosa->txchan); + break; + } + } cosa->txsize = cosa->chan[cosa->txchan].txsize; if (cosa_dma_able(cosa->chan+cosa->txchan, @@ -1784,6 +1804,7 @@ static inline void rx_interrupt(struct cosa_data *cosa, int status) if (is_8bit(cosa)) { if (!test_bit(IRQBIT, &cosa->rxtx)) { set_bit(IRQBIT, &cosa->rxtx); + put_driver_status_nolock(cosa); cosa->rxsize = cosa_getdata8(cosa) <<8; #ifdef DEBUG_IO debug_data_in(cosa, cosa->rxsize >> 8); diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 3867c58d3..ac6ff986c 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -30,7 +30,7 @@ */ static char *version = -"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n"; +"cs89x0.c:v1.03 11/26/96 Russell Nelson <nelson@crynwr.com>\n"; /* ======================= configure the driver here ======================= */ @@ -113,20 +113,20 @@ struct net_local { /* Index to functions, as function prototypes. */ -extern int cs89x0_probe(struct device *dev); +extern int cs89x0_probe(struct net_device *dev); -static int cs89x0_probe1(struct device *dev, int ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int cs89x0_probe1(struct net_device *dev, int ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void set_multicast_list(struct device *dev); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void reset_chip(struct device *dev); -static int get_eeprom_data(struct device *dev, int off, int len, int *buffer); +static void set_multicast_list(struct net_device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void reset_chip(struct net_device *dev); +static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer); static int get_eeprom_cksum(int off, int len, int *buffer); -static int set_mac_address(struct device *dev, void *addr); +static int set_mac_address(struct net_device *dev, void *addr); /* Example routines you must write ;->. */ @@ -146,7 +146,7 @@ struct netdev_entry netcard_drv = {"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else int __init -cs89x0_probe(struct device *dev) +cs89x0_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -169,14 +169,14 @@ cs89x0_probe(struct device *dev) #endif static int inline -readreg(struct device *dev, int portno) +readreg(struct net_device *dev, int portno) { outw(portno, dev->base_addr + ADD_PORT); return inw(dev->base_addr + DATA_PORT); } static void inline -writereg(struct device *dev, int portno, int value) +writereg(struct net_device *dev, int portno, int value) { outw(portno, dev->base_addr + ADD_PORT); outw(value, dev->base_addr + DATA_PORT); @@ -184,19 +184,19 @@ writereg(struct device *dev, int portno, int value) static int inline -readword(struct device *dev, int portno) +readword(struct net_device *dev, int portno) { return inw(dev->base_addr + portno); } static void inline -writeword(struct device *dev, int portno, int value) +writeword(struct net_device *dev, int portno, int value) { outw(value, dev->base_addr + portno); } static int __init -wait_eeprom_ready(struct device *dev) +wait_eeprom_ready(struct net_device *dev) { int timeout = jiffies; /* check to see if the EEPROM is ready, a timeout is used - @@ -209,7 +209,7 @@ wait_eeprom_ready(struct device *dev) } static int __init -get_eeprom_data(struct device *dev, int off, int len, int *buffer) +get_eeprom_data(struct net_device *dev, int off, int len, int *buffer) { int i; @@ -244,7 +244,7 @@ get_eeprom_cksum(int off, int len, int *buffer) probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int __init cs89x0_probe1(struct device *dev, int ioaddr) +static int __init cs89x0_probe1(struct net_device *dev, int ioaddr) { struct net_local *lp; static unsigned version_printed = 0; @@ -306,7 +306,7 @@ static int __init cs89x0_probe1(struct device *dev, int ioaddr) else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { printk("\ncs89x0: EEPROM read failed, relying on command line.\n"); } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { - printk("\ncs89x0: EEPROM checksum bad, relyong on command line\n"); + printk("\ncs89x0: EEPROM checksum bad, relying on command line\n"); } else { /* get transmission control word but keep the autonegotiation bits */ if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; @@ -391,7 +391,7 @@ static int __init cs89x0_probe1(struct device *dev, int ioaddr) } void __init -reset_chip(struct device *dev) +reset_chip(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -421,7 +421,7 @@ reset_chip(struct device *dev) static void -control_dc_dc(struct device *dev, int on_not_off) +control_dc_dc(struct net_device *dev, int on_not_off) { struct net_local *lp = (struct net_local *)dev->priv; unsigned int selfcontrol; @@ -442,7 +442,7 @@ control_dc_dc(struct device *dev, int on_not_off) } static int -detect_tp(struct device *dev) +detect_tp(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int timenow = jiffies; @@ -487,7 +487,7 @@ detect_tp(struct device *dev) /* send a test packet - return true if carrier bits are ok */ static int -send_test_pkt(struct device *dev) +send_test_pkt(struct net_device *dev) { int ioaddr = dev->base_addr; char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, @@ -532,7 +532,7 @@ send_test_pkt(struct device *dev) static int -detect_aui(struct device *dev) +detect_aui(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -548,7 +548,7 @@ detect_aui(struct device *dev) } static int -detect_bnc(struct device *dev) +detect_bnc(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -565,7 +565,7 @@ detect_bnc(struct device *dev) static void -write_irq(struct device *dev, int chip_type, int irq) +write_irq(struct net_device *dev, int chip_type, int irq) { int i; @@ -591,7 +591,7 @@ write_irq(struct device *dev, int chip_type, int irq) there is non-reboot way to recover if something goes wrong. */ static int -net_open(struct device *dev) +net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int result = 0; @@ -728,7 +728,7 @@ net_open(struct device *dev) } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. @@ -787,7 +787,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) Handle the network interface interrupts. */ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -841,6 +841,13 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) lp->send_underrun++; if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381; else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL; + /* transmit cycle is done, although + frame wasn't transmitted - this + avoids having to wait for the upper + layers to timeout on us, in the + event of a tx underrun */ + dev->tbusy = 0; + mark_bh(NET_BH); /* Inform upper layers. */ } break; case ISQ_RX_MISS_EVENT: @@ -857,7 +864,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -904,7 +911,7 @@ net_rx(struct device *dev) /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { writereg(dev, PP_RxCFG, 0); @@ -926,7 +933,7 @@ net_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ static struct net_device_stats * -net_get_stats(struct device *dev) +net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -939,7 +946,7 @@ net_get_stats(struct device *dev) return &lp->stats; } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -964,7 +971,7 @@ static void set_multicast_list(struct device *dev) } -static int set_mac_address(struct device *dev, void *addr) +static int set_mac_address(struct net_device *dev, void *addr) { int i; if (dev->start) @@ -983,7 +990,7 @@ static int set_mac_address(struct device *dev, void *addr) #ifdef MODULE static char namespace[16] = ""; -static struct device dev_cs89x0 = { +static struct net_device dev_cs89x0 = { NULL, 0, 0, 0, 0, 0, 0, diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h index d988bdcd5..42776088f 100644 --- a/drivers/net/cs89x0.h +++ b/drivers/net/cs89x0.h @@ -319,8 +319,8 @@ #define TX_FRAME_PORT RX_FRAME_PORT #define TX_CMD_PORT 0x0004 #define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */ -#define TX_AFTER_381 0x0020 /* Tx packet after 381 bytes copied */ -#define TX_AFTER_ALL 0x0060 /* Tx packet after all bytes copied */ +#define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */ +#define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */ #define TX_LEN_PORT 0x0006 #define ISQ_PORT 0x0008 #define ADD_PORT 0x000A diff --git a/drivers/net/cycx_drv.c b/drivers/net/cycx_drv.c index 7f803c63d..1629bdcf0 100644 --- a/drivers/net/cycx_drv.c +++ b/drivers/net/cycx_drv.c @@ -57,7 +57,7 @@ #include <asm/io.h> /* for inb(), outb(), etc. */ #define MOD_VERSION 0 -#define MOD_RELEASE 1 +#define MOD_RELEASE 2 #ifdef MODULE MODULE_AUTHOR("Arnaldo Carvalho de Melo"); @@ -122,7 +122,6 @@ int init_module (void) { printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, copyright); - printk(KERN_INFO "version=0x%X\n", LINUX_VERSION_CODE); return 0; } /* Module 'remove' entry point. @@ -639,7 +638,6 @@ static void delay_cycx (int sec) know it all the contexts where this routine is used are interruptible... */ current->state = TASK_INTERRUPTIBLE; - current->counter = 0; /* make us low-priority */ schedule_timeout(sec*HZ); } diff --git a/drivers/net/cycx_main.c b/drivers/net/cycx_main.c index d0371c3a1..52a2abd04 100644 --- a/drivers/net/cycx_main.c +++ b/drivers/net/cycx_main.c @@ -13,12 +13,15 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/08/09 acme removed references to enable_tx_int +* use spinlocks instead of cli/sti in +* cyclomx_set_state * 1999/05/19 acme works directly linked into the kernel * init_waitqueue_head for 2.3.* kernel * 1999/05/18 acme major cleanup (polling not needed), etc -* Aug 28, 1998 Arnaldo minor cleanup (ioctls for firmware deleted) +* 1998/08/28 acme minor cleanup (ioctls for firmware deleted) * queue_task activated -* Aug 08, 1998 Arnaldo Initial version. +* 1998/08/08 acme Initial version. */ #include <linux/config.h> /* OS configuration options */ @@ -33,7 +36,7 @@ #include <linux/wanrouter.h> /* WAN router definitions */ #include <linux/cyclomx.h> /* cyclomx common user API definitions */ #include <asm/uaccess.h> /* kernel <-> user copy */ -#include <linux/init.h> /* __initfunc (when not using as a module) */ +#include <linux/init.h> /* __init (when not using as a module) */ #ifdef MODULE MODULE_AUTHOR("Arnaldo Carvalho de Melo"); @@ -43,7 +46,7 @@ MODULE_DESCRIPTION("Cyclades Sync Cards Driver."); /* Defines & Macros */ #define DRV_VERSION 0 /* version number */ -#define DRV_RELEASE 3 /* release (minor version) number */ +#define DRV_RELEASE 4 /* release (minor version) number */ #define MAX_CARDS 1 /* max number of adapters */ #ifndef CONFIG_CYCLOMX_CARDS /* configurable option */ @@ -92,7 +95,7 @@ static cycx_t *card_array = NULL; /* adapter data space */ #ifdef MODULE int init_module (void) #else -__initfunc(int cyclomx_init (void)) +int __init cyclomx_init (void) #endif { int cnt, err = 0; @@ -118,7 +121,6 @@ __initfunc(int cyclomx_init (void)) wandev->magic = ROUTER_MAGIC; wandev->name = card->devname; wandev->private = card; - wandev->enable_tx_int = 0; wandev->setup = &setup; wandev->shutdown = &shutdown; wandev->ioctl = &ioctl; @@ -239,7 +241,7 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf) /* Protocol-specific initialization */ switch (card->hw.fwid) { -#ifdef CONFIG_CYCLOMX_X25 +#ifdef CONFIG_CYCLOMX_X25 case CFID_X25_2X: err = cyx_init(card, conf); break; #endif default: @@ -254,7 +256,6 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf) return err; } - wandev->critical = 0; return 0; } @@ -280,7 +281,6 @@ static int shutdown (wan_device_t *wandev) cycx_down(&card->hw); printk(KERN_INFO "%s: irq %d being freed!\n", wandev->name,wandev->irq); free_irq(wandev->irq, card); - wandev->critical = 0; return 0; } @@ -306,7 +306,8 @@ static int ioctl (wan_device_t *wandev, unsigned cmd, unsigned long arg) static void cycx_isr (int irq, void *dev_id, struct pt_regs *regs) { #define card ((cycx_t*)dev_id) - if (!card || card->wandev.state == WAN_UNCONFIGURED) return; + if (!card || card->wandev.state == WAN_UNCONFIGURED) + return; if (card->in_isr) { printk(KERN_WARNING "%s: interrupt re-entrancy on IRQ %d!\n", @@ -314,7 +315,8 @@ static void cycx_isr (int irq, void *dev_id, struct pt_regs *regs) return; } - if (card->isr) card->isr(card); + if (card->isr) + card->isr(card); #undef card } @@ -345,9 +347,9 @@ void cyclomx_close (cycx_t *card) /* Set WAN device state. */ void cyclomx_set_state (cycx_t *card, int state) { - unsigned long flags; + unsigned long host_cpu_flags; - save_flags(flags); cli(); + spin_lock_irqsave(&card->lock, host_cpu_flags); if (card->wandev.state != state) { switch (state) { @@ -371,7 +373,7 @@ void cyclomx_set_state (cycx_t *card, int state) } card->state_tick = jiffies; - restore_flags(flags); + spin_unlock_irqrestore(&card->lock, host_cpu_flags); } /* End */ diff --git a/drivers/net/cycx_x25.c b/drivers/net/cycx_x25.c index d6fbe07c3..7e79943c0 100644 --- a/drivers/net/cycx_x25.c +++ b/drivers/net/cycx_x25.c @@ -11,6 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/08/10 acme serialized access to the card thru a spinlock +* in x25_exec +* 1999/08/09 acme removed per channel spinlocks +* removed references to enable_tx_int * 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated * if_send simplified * 1999/05/25 acme fixed t1, t2, t21 & t23 configuration @@ -70,11 +74,9 @@ /* Defines & Macros */ #define MAX_CMD_RETRY 5 #define X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */ -#define OUT_INTR 1 -#define IN_INTR 0 /* Data Structures */ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network interface to keep the rest of X.25 channel-specific data. */ typedef struct x25_channel { char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ @@ -84,7 +86,6 @@ typedef struct x25_channel { s16 lcn; /* logical channel number/conn.req.key*/ u8 link; struct timer_list timer; /* timer used for svc channel disc. */ - spinlock_t lock; u16 protocol; /* ethertype, 0 - multiplexed */ u8 svc; /* 0 - permanent, 1 - switched */ u8 state; /* channel state */ @@ -98,19 +99,19 @@ typedef struct x25_channel { /* Function Prototypes */ /* WAN link driver entry points. These are called by the WAN router module. */ static int update (wan_device_t *wandev), - new_if (wan_device_t *wandev, struct device *dev,wanif_conf_t *conf), - del_if (wan_device_t *wandev, struct device *dev); + new_if (wan_device_t *wandev, struct net_device *dev,wanif_conf_t *conf), + del_if (wan_device_t *wandev, struct net_device *dev); /* Network device interface */ -static int if_init (struct device *dev), - if_open (struct device *dev), - if_close (struct device *dev), - if_header (struct sk_buff *skb, struct device *dev, +static int if_init (struct net_device *dev), + if_open (struct net_device *dev), + if_close (struct net_device *dev), + if_header (struct sk_buff *skb, struct net_device *dev, u16 type, void *daddr, void *saddr, unsigned len), if_rebuild_hdr (struct sk_buff *skb), - if_send (struct sk_buff *skb, struct device *dev); + if_send (struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats * if_stats (struct device *dev); +static struct net_device_stats * if_stats (struct net_device *dev); /* Interrupt handlers */ static void cyx_isr (cycx_t *card), @@ -132,22 +133,22 @@ static int x25_configure (cycx_t *card, TX25Config *conf), x25_disconnect_response (cycx_t *card, u8 link, u8 lcn); /* Miscellaneous functions */ -static int chan_connect (struct device *dev), - chan_send (struct device *dev, struct sk_buff *skb); +static int chan_connect (struct net_device *dev), + chan_send (struct net_device *dev, struct sk_buff *skb); -static void set_chan_state (struct device *dev, u8 state, u8 outside_intr), +static void set_chan_state (struct net_device *dev, u8 state), nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble), - reset_timer (struct device *dev), - chan_disc (struct device *dev), - chan_timer (unsigned long data); + reset_timer (struct net_device *dev), + chan_disc (struct net_device *dev), + chan_timer (unsigned long d); static u8 bps_to_speed_code (u32 bps); static u8 log2 (u32 n); static unsigned dec_to_uint (u8 *str, int len); -static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn); -static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte); +static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn); +static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte); #ifdef CYCLOMX_X25_DEBUG static void hex_dump(char *msg, unsigned char *p, int len); @@ -187,8 +188,8 @@ int cyx_init (cycx_t *card, wandev_conf_t *conf) /* Initialize protocol-specific fields */ card->mbox = card->hw.dpmbase + X25_MBOX_OFFS; - card->u.x.critical = 0; /* critical section flag */ card->u.x.connection_keys = 0; + card->u.x.lock = SPIN_LOCK_UNLOCKED; /* Configure adapter. Here we set resonable defaults, then parse * device configuration structure and set configuration options. @@ -286,7 +287,6 @@ int cyx_init (cycx_t *card, wandev_conf_t *conf) card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.state = WAN_DISCONNECTED; - card->wandev.enable_tx_int = card->irq_dis_if_send_count = 0; return 0; } @@ -315,7 +315,7 @@ static int update (wan_device_t *wandev) * * Return: 0 o.k. * < 0 failure (channel will not be created) */ -static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf) +static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf) { cycx_t *card = wandev->private; x25_channel_t *chan; @@ -338,21 +338,23 @@ static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf) chan->rx_skb = NULL; /* only used in svc connected thru crossover cable */ chan->local_addr = NULL; - chan->lock = SPIN_LOCK_UNLOCKED; if (conf->addr[0] == '@') { /* SVC */ - int local_len = strlen(conf->local_addr); + int len = strlen(conf->local_addr); - if (local_len) { - if (local_len > WAN_ADDRESS_SZ) { + if (len) { + if (len > WAN_ADDRESS_SZ) { printk(KERN_ERR "%s: %s local addr too long!\n", wandev->name, chan->name); kfree(chan); return -EINVAL; - } else if ((chan->local_addr = kmalloc(local_len + 1, - GFP_KERNEL)) == NULL) { - kfree(chan); - return ENOMEM; + } else { + chan->local_addr = kmalloc(len + 1, GFP_KERNEL); + + if (!chan->local_addr) { + kfree(chan); + return ENOMEM; + } } strncpy(chan->local_addr, conf->local_addr, @@ -387,6 +389,7 @@ static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf) if (err) { if (chan->local_addr) kfree(chan->local_addr); + kfree(chan); return err; } @@ -399,7 +402,7 @@ static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf) } /* Delete logical channel. */ -static int del_if (wan_device_t *wandev, struct device *dev) +static int del_if (wan_device_t *wandev, struct net_device *dev) { if (!dev) { printk(KERN_ERR "cycx_x25:del_if:dev == NULL!\n"); @@ -408,6 +411,7 @@ static int del_if (wan_device_t *wandev, struct device *dev) if (dev->priv) { x25_channel_t *chan = dev->priv; + if (chan->svc) { if (chan->local_addr) kfree(chan->local_addr); @@ -415,6 +419,7 @@ static int del_if (wan_device_t *wandev, struct device *dev) if (chan->state == WAN_CONNECTED) del_timer(&chan->timer); } + kfree(chan); dev->priv = NULL; } @@ -428,7 +433,7 @@ static int del_if (wan_device_t *wandev, struct device *dev) * This routine is called only once for each interface, during Linux network * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init (struct device *dev) +static int if_init (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -464,7 +469,7 @@ static int if_init (struct device *dev) /* Initialize socket buffers */ dev_init_buffers(dev); - set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTED); return 0; } @@ -473,7 +478,7 @@ static int if_init (struct device *dev) * o if link is disconnected then initiate connection * * Return 0 if O.k. or errno. */ -static int if_open (struct device *dev) +static int if_open (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -481,37 +486,28 @@ static int if_open (struct device *dev) if (dev->start) return -EBUSY; /* only one open is allowed */ - if (test_and_set_bit(0, (void*)&card->wandev.critical)) - return -EAGAIN; - dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; cyclomx_open(card); - card->wandev.critical = 0; return 0; } /* Close network interface. * o reset flags. * o if there's no more open channels then disconnect physical link. */ -static int if_close (struct device *dev) +static int if_close (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; - if (test_and_set_bit(0, (void*)&card->wandev.critical)) - return -EAGAIN; - dev->start = 0; if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING) chan_disc(dev); cyclomx_close(card); - - card->wandev.critical = 0; return 0; } @@ -523,7 +519,7 @@ static int if_close (struct device *dev) * set skb->protocol to 0 and discard packet later. * * Return: media header length. */ -static int if_header (struct sk_buff *skb, struct device *dev, +static int if_header (struct sk_buff *skb, struct net_device *dev, u16 type, void *daddr, void *saddr, unsigned len) { skb->protocol = type; @@ -553,7 +549,7 @@ static int if_rebuild_hdr (struct sk_buff *skb) * bottom half" (with interrupts enabled). * 2. Setting tbusy flag will inhibit further transmit requests from the * protocol stack and can be used for flow control with protocol layer. */ -static int if_send (struct sk_buff *skb, struct device *dev) +static int if_send (struct sk_buff *skb, struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -563,10 +559,6 @@ static int if_send (struct sk_buff *skb, struct device *dev) return -EBUSY; } - dev->tbusy = 1; - - reset_timer(dev); - if (!chan->svc) chan->protocol = skb->protocol; @@ -580,13 +572,17 @@ static int if_send (struct sk_buff *skb, struct device *dev) ++chan->ifstats.tx_errors; } else switch (chan->state) { case WAN_DISCONNECTED: - if (chan_connect(dev)) + if (chan_connect(dev)) { + dev->tbusy = 1; return -EBUSY; + } /* fall thru */ case WAN_CONNECTED: + reset_timer(dev); dev->trans_start = jiffies; + dev->tbusy = 1; + if (chan_send(dev, skb)) { - dev->tbusy = 1; return -EBUSY; } break; @@ -601,7 +597,7 @@ static int if_send (struct sk_buff *skb, struct device *dev) /* Get Ethernet-style interface statistics. * Return a pointer to struct net_device_stats */ -static struct net_device_stats *if_stats (struct device *dev) +static struct net_device_stats *if_stats (struct net_device *dev) { x25_channel_t *chan = dev->priv; @@ -612,25 +608,13 @@ static struct net_device_stats *if_stats (struct device *dev) /* X.25 Interrupt Service Routine. */ static void cyx_isr (cycx_t *card) { - unsigned long host_cpu_flags; TX25Cmd cmd; u16 z = 0; card->in_isr = 1; card->buff_int_mode_unbusy = 0; - - if (test_and_set_bit(0, (void*)&card->wandev.critical)) { - printk(KERN_INFO "cyx_isr: %s, wandev.critical set to 0x%02X\n", - card->devname, card->wandev.critical); - card->in_isr = 0; - return; - } - - /* For all interrupts set the critical flag to CRITICAL_RX_INTR. - * If the if_send routine is called with this flag set it will set - * the enable transmit flag to 1. (for a delayed interrupt) */ - card->wandev.critical = CRITICAL_IN_ISR; cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd)); + switch (cmd.command) { case X25_DATA_INDICATION: rx_intr(card, &cmd); @@ -668,16 +652,7 @@ static void cyx_isr (cycx_t *card) cycx_poke(&card->hw, 0, &z, sizeof(z)); cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z)); - - card->wandev.critical = CRITICAL_INTR_HANDLED; - - if (card->wandev.enable_tx_int) - card->wandev.enable_tx_int = 0; - - spin_lock_irqsave(&card->lock, host_cpu_flags); card->in_isr = 0; - card->wandev.critical = 0; - spin_unlock_irqrestore(&card->lock, host_cpu_flags); if (card->buff_int_mode_unbusy) mark_bh(NET_BH); @@ -688,7 +663,7 @@ static void cyx_isr (cycx_t *card) * o Clear 'tbusy' flag */ static void tx_intr (cycx_t *card, TX25Cmd *cmd) { - struct device *dev; + struct net_device *dev; wan_device_t *wandev = &card->wandev; u8 lcn; @@ -720,7 +695,7 @@ static void tx_intr (cycx_t *card, TX25Cmd *cmd) static void rx_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; x25_channel_t *chan; struct sk_buff *skb; u8 bitm, lcn; @@ -740,11 +715,12 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd) chan = dev->priv; reset_timer(dev); - if (chan->drop_sequence) + if (chan->drop_sequence) { if (!bitm) chan->drop_sequence = 0; else return; + } if ((skb = chan->rx_skb) == NULL) { /* Allocate new socket buffer */ @@ -799,29 +775,30 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd) static void connect_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev = NULL; + struct net_device *dev = NULL; x25_channel_t *chan; - u8 data[32], - local[24], + u8 d[32], + loc[24], rem[24]; - u8 lcn, sizelocal, sizerem; + u8 lcn, sizeloc, sizerem; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); - cycx_peek(&card->hw, cmd->buf + 5, &sizelocal, sizeof(sizelocal)); - cycx_peek(&card->hw, cmd->buf + 6, data, cmd->len - 6); + cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc)); + cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6); - sizerem = sizelocal >> 4; - sizelocal &= 0x0F; + sizerem = sizeloc >> 4; + sizeloc &= 0x0F; - local[0] = rem[0] = '\0'; + loc[0] = rem[0] = '\0'; - if (sizelocal) - nibble_to_byte(data, local, sizelocal, 0); + if (sizeloc) + nibble_to_byte(d, loc, sizeloc, 0); if (sizerem) - nibble_to_byte(data + (sizelocal >> 1), rem, sizerem, sizelocal & 1); + nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1); + dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n", - lcn, local, rem); + lcn, loc, rem); if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) { /* Invalid channel, discard packet */ printk(KERN_INFO "%s: connect not expected: remote %s!\n", @@ -832,14 +809,14 @@ static void connect_intr (cycx_t *card, TX25Cmd *cmd) chan = dev->priv; chan->lcn = lcn; x25_connect_response(card, chan); - set_chan_state(dev, WAN_CONNECTED, IN_INTR); + set_chan_state(dev, WAN_CONNECTED); } /* Connect confirm interrupt handler. */ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; x25_channel_t *chan; u8 lcn, key; @@ -858,14 +835,14 @@ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd) clear_bit(--key, (void*)&card->u.x.connection_keys); chan = dev->priv; chan->lcn = lcn; - set_chan_state(dev, WAN_CONNECTED, IN_INTR); + set_chan_state(dev, WAN_CONNECTED); } /* Disonnect confirm interrupt handler. */ static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; u8 lcn; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); @@ -878,22 +855,26 @@ static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd) return; } - set_chan_state(dev, WAN_DISCONNECTED, IN_INTR); + set_chan_state(dev, WAN_DISCONNECTED); } /* disconnect interrupt handler. */ static void disconnect_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; u8 lcn; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); dprintk(KERN_INFO "disconnect_intr:lcn=%d\n", lcn); - x25_disconnect_response(card, 0, lcn); - if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) - set_chan_state(dev, WAN_DISCONNECTED, IN_INTR); + if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) { + x25_channel_t *chan = dev->priv; + + x25_disconnect_response(card, chan->link, lcn); + set_chan_state(dev, WAN_DISCONNECTED); + } else + x25_disconnect_response(card, 0, lcn); } /* LOG interrupt handler. */ @@ -960,55 +941,51 @@ static void hex_dump(char *msg, unsigned char *p, int len) printk(KERN_INFO "%s: %s\n", msg, hex); } #endif -/* CYCLOM X Firmware-Specific Functions - * - * Almost all X.25 commands can unexpetedly fail due to so called 'X.25 - * asynchronous events' such as restart, interrupt, incoming call request, - * call clear request, etc. They can't be ignored and have to be dealt with - * immediately. To tackle with this problem we execute each interface command - * in a loop until good return code is received or maximum number of retries - * is reached. Each interface command returns non-zero return code, an - * asynchronous event/error handler x25_error() is called. - */ +/* CYCLOM X Firmware-Specific Functions */ /* Exec x25 command. */ static int x25_exec (cycx_t *card, int command, int link, - void *data1, int len1, void *data2, int len2) + void *d1, int len1, void *d2, int len2) { TX25Cmd c; + unsigned long flags; u32 addr = 0x1200 + 0x2E0 * link + 0x1E2; + u8 retry = MAX_CMD_RETRY; int err = 0; c.command = command; c.link = link; c.len = len1 + len2; - if (test_and_set_bit(0, (void*)&card->u.x.critical)) - return -EAGAIN; + spin_lock_irqsave(&card->u.x.lock, flags); /* write command */ cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf)); /* write x25 data */ - if (data1) { - cycx_poke(&card->hw, addr, data1, len1); + if (d1) { + cycx_poke(&card->hw, addr, d1, len1); - if (data2) + if (d2) { if (len2 > 254) { u32 addr1 = 0xA00 + 0x400 * link; - cycx_poke(&card->hw, addr + len1, data2, 249); - cycx_poke(&card->hw, addr1, ((u8*) data2) + 249, + cycx_poke(&card->hw, addr + len1, d2, 249); + cycx_poke(&card->hw, addr1, ((u8*) d2) + 249, len2 - 249); } else - cycx_poke(&card->hw, addr + len1, data2, len2); + cycx_poke(&card->hw, addr + len1, d2, len2); + } } /* generate interruption, executing command */ cycx_intr(&card->hw); /* wait till card->mbox == 0 */ - err = cycx_exec(card->mbox); - card->u.x.critical = 0; + do { + err = cycx_exec(card->mbox); + } while (retry-- && err); + + spin_unlock_irqrestore(&card->u.x.lock, flags); return err; } @@ -1110,6 +1087,7 @@ static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble) while (len) { *d++ = '0' + (*s >> 4); + if (--len) { *d++ = '0' + (*s & 0x0F); --len; @@ -1125,9 +1103,8 @@ static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble) static int x25_place_call (cycx_t *card, x25_channel_t *chan) { int err = 0, - retry = MAX_CMD_RETRY, len; - char data[64], + char d[64], nibble = 0, mylen = chan->local_addr ? strlen(chan->local_addr) : 0, remotelen = strlen(chan->addr); @@ -1143,24 +1120,24 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan) set_bit(key, (void*)&card->u.x.connection_keys); ++key; dprintk(KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key); - memset(data, 0, sizeof(data)); - data[1] = key; /* user key */ - data[2] = 0x10; - data[4] = 0x0B; - - len = byte_to_nibble(chan->addr, data + 6, &nibble); - len += chan->local_addr ? byte_to_nibble(chan->local_addr, - data + 6 + len, &nibble) : 0; + memset(d, 0, sizeof(d)); + d[1] = key; /* user key */ + d[2] = 0x10; + d[4] = 0x0B; + + len = byte_to_nibble(chan->addr, d + 6, &nibble); + + if (chan->local_addr) + len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble); + if (nibble) ++len; - data[5] = mylen << 4 | remotelen; - data[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */ - - do err = x25_exec(card, X25_CONNECT_REQUEST, chan->link, - &data, 7 + len + 1, NULL, 0); - while (err && retry--); - if (err) + d[5] = mylen << 4 | remotelen; + d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */ + + if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link, + &d, 7 + len + 1, NULL, 0)) != 0) clear_bit(--key, (void*)&card->u.x.connection_keys); else { chan->lcn = -key; @@ -1173,82 +1150,60 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan) /* Place X.25 CONNECT RESPONSE. */ static int x25_connect_response (cycx_t *card, x25_channel_t *chan) { - int err = 0, - retry = MAX_CMD_RETRY; - char data[32]; + u8 d[8]; - memset(data, 0, sizeof(data)); - data[0] = data[3] = chan->lcn; - data[2] = 0x10; - data[4] = 0x0F; - data[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */ + memset(d, 0, sizeof(d)); + d[0] = d[3] = chan->lcn; + d[2] = 0x10; + d[4] = 0x0F; + d[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */ - do err = x25_exec(card, X25_CONNECT_RESPONSE, chan->link, - &data, 8, NULL, 0); - while (err && retry--); - - return err; + return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0); } /* Place X.25 DISCONNECT RESPONSE. */ static int x25_disconnect_response (cycx_t *card, u8 link, u8 lcn) { - int err = 0, - retry = MAX_CMD_RETRY; - char data[5]; - - memset(data, 0, sizeof(data)); - data[0] = data[3] = lcn; - data[2] = 0x10; - data[4] = 0x17; - do err = x25_exec(card, X25_DISCONNECT_RESPONSE, link, - &data, 5, NULL, 0); - while (err && retry--); + char d[5]; - return err; + memset(d, 0, sizeof(d)); + d[0] = d[3] = lcn; + d[2] = 0x10; + d[4] = 0x17; + return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0); } /* Clear X.25 call. */ static int x25_clear_call (cycx_t *card, u8 link, u8 lcn, u8 cause, u8 diagn) { - int retry = MAX_CMD_RETRY, - err; - u8 data[7]; - - memset(data, 0, sizeof(data)); - data[0] = data[3] = lcn; - data[2] = 0x10; - data[4] = 0x13; - data[5] = cause; - data[6] = diagn; + u8 d[7]; - do err = x25_exec(card, X25_DISCONNECT_REQUEST, link, data, 7, NULL, 0); - while (err && retry--); + memset(d, 0, sizeof(d)); + d[0] = d[3] = lcn; + d[2] = 0x10; + d[4] = 0x13; + d[5] = cause; + d[6] = diagn; - return err; + return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0); } /* Send X.25 data packet. */ static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf) { - int err = 0, - retry = MAX_CMD_RETRY; - u8 data[] = "?\xFF\x10??"; - - data[0] = data[3] = lcn; - data[4] = bitm; + u8 d[] = "?\xFF\x10??"; - do err = x25_exec(card, X25_DATA_REQUEST, link, &data, 5, buf, len); - while (err && retry--); + d[0] = d[3] = lcn; + d[4] = bitm; - return err; + return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len); } /* Miscellaneous */ /* Find network device by its channel number. */ -static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) +static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; for (; dev; dev = dev->slave) if (((x25_channel_t*)dev->priv)->lcn == lcn) @@ -1257,9 +1212,9 @@ static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) } /* Find network device by its remote dte address. */ -static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) +static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; for (; dev; dev = dev->slave) if (!strcmp (((x25_channel_t*)dev->priv)->addr, dte)) @@ -1274,7 +1229,7 @@ static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) * Return: 0 connected * >0 connection in progress * <0 failure */ -static int chan_connect (struct device *dev) +static int chan_connect (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1286,31 +1241,31 @@ static int chan_connect (struct device *dev) card->devname, chan->addr); if (x25_place_call(card, chan)) return -EIO; - set_chan_state(dev, WAN_CONNECTING, OUT_INTR); + set_chan_state(dev, WAN_CONNECTING); return 1; } else - set_chan_state(dev, WAN_CONNECTED, OUT_INTR); + set_chan_state(dev, WAN_CONNECTED); return 0; } /* Disconnect logical channel. * o if SVC then clear X.25 call */ -static void chan_disc (struct device *dev) +static void chan_disc (struct net_device *dev) { x25_channel_t *chan = dev->priv; if (chan->svc) { x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0); - set_chan_state(dev, WAN_DISCONNECTING, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTING); } else - set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTED); } /* Called by kernel timer */ -static void chan_timer (unsigned long data) +static void chan_timer (unsigned long d) { - struct device *dev = (struct device*) data; + struct net_device *dev = (struct net_device*) d; x25_channel_t *chan = dev->priv; switch (chan->state) { @@ -1325,16 +1280,13 @@ static void chan_timer (unsigned long data) } /* Set logical channel state. */ -static void set_chan_state (struct device *dev, u8 state, u8 outside_intr) +static void set_chan_state (struct net_device *dev, u8 state) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; u32 flags = 0; - if (outside_intr) - spin_lock(&card->lock); - else - spin_lock_irqsave(&card->lock, flags); + spin_lock_irqsave(&card->lock, flags); if (chan->state != state) { if (chan->svc && chan->state == WAN_CONNECTED) @@ -1370,16 +1322,14 @@ static void set_chan_state (struct device *dev, u8 state, u8 outside_intr) *(unsigned short*)dev->dev_addr = 0; chan->lcn = 0; } + dev->tbusy = 0; break; } chan->state = state; } - if (outside_intr) - spin_unlock(&card->lock); - else - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&card->lock, flags); } /* Send packet on a logical channel. @@ -1395,7 +1345,7 @@ static void set_chan_state (struct device *dev, u8 state, u8 outside_intr) * the packet into 'complete sequence' using M-bit. * 2. When transmission is complete, an event notification should be issued * to the router. */ -static int chan_send (struct device *dev, struct sk_buff *skb) +static int chan_send (struct net_device *dev, struct sk_buff *skb) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1468,7 +1418,7 @@ static unsigned dec_to_uint (u8 *str, int len) return val; } -static void reset_timer(struct device *dev) +static void reset_timer(struct net_device *dev) { x25_channel_t *chan = dev->priv; @@ -1520,7 +1470,7 @@ static void x25_dump_stats(TX25Stats *stats) static void x25_dump_devs(wan_device_t *wandev) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; printk (KERN_INFO "x25 dev states\n"); printk (KERN_INFO "name: addr: tbusy:\n"); diff --git a/drivers/net/daynaport.c b/drivers/net/daynaport.c index 777a1dcab..02ebff8b6 100644 --- a/drivers/net/daynaport.c +++ b/drivers/net/daynaport.c @@ -37,33 +37,33 @@ static const char *version = #include <linux/etherdevice.h> #include "8390.h" -int ns8390_probe1(struct device *dev, int word16, char *name, int id, int prom); +int ns8390_probe1(struct net_device *dev, int word16, char *name, int id, int prom); -static int ns8390_open(struct device *dev); -static void ns8390_no_reset(struct device *dev); -static int ns8390_close_card(struct device *dev); +static int ns8390_open(struct net_device *dev); +static void ns8390_no_reset(struct net_device *dev); +static int ns8390_close_card(struct net_device *dev); -static void interlan_reset(struct device *dev); +static void interlan_reset(struct net_device *dev); -static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void dayna_block_input(struct device *dev, int count, +static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void dayna_block_output(struct device *dev, int count, +static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void sane_block_input(struct device *dev, int count, +static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void sane_block_output(struct device *dev, int count, +static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void slow_sane_block_input(struct device *dev, int count, +static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void slow_sane_block_output(struct device *dev, int count, +static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); @@ -199,7 +199,7 @@ int apple_8390_mem_probe(volatile unsigned short *p) int ns8390_probe(struct nubus_device_specifier *d, int slot, struct nubus_type *match) { - struct device *dev; + struct net_device *dev; volatile unsigned short *i; volatile unsigned char *p; int plen; @@ -336,7 +336,7 @@ membad: return -ENODEV; } -int ns8390_probe1(struct device *dev, int word16, char *model_name, int type, int promoff) +int ns8390_probe1(struct net_device *dev, int word16, char *model_name, int type, int promoff) { static unsigned version_printed = 0; @@ -469,14 +469,14 @@ int ns8390_probe1(struct device *dev, int word16, char *model_name, int type, in return 0; } -static int ns8390_open(struct device *dev) +static int ns8390_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static void ns8390_no_reset(struct device *dev) +static void ns8390_no_reset(struct net_device *dev) { if (ei_debug > 1) printk("Need to reset the NS8390 t=%lu...", jiffies); @@ -485,7 +485,7 @@ static void ns8390_no_reset(struct device *dev) return; } -static int ns8390_close_card(struct device *dev) +static int ns8390_close_card(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -504,7 +504,7 @@ struct nubus_device_specifier nubus_8390={ * Interlan Specific Code Starts Here */ -static void interlan_reset(struct device *dev) +static void interlan_reset(struct net_device *dev) { unsigned char *target=nubus_slot_addr(dev->irq); if (ei_debug > 1) @@ -531,7 +531,7 @@ static void interlan_reset(struct device *dev) The only complications are that the ring buffer wraps. */ -static void dayna_cpu_memcpy(struct device *dev, void *to, int from, int count) +static void dayna_cpu_memcpy(struct net_device *dev, void *to, int from, int count) { volatile unsigned short *ptr; unsigned short *target=to; @@ -554,7 +554,7 @@ static void dayna_cpu_memcpy(struct device *dev, void *to, int from, int count) } } -static void cpu_dayna_memcpy(struct device *dev, int to, const void *from, int count) +static void cpu_dayna_memcpy(struct net_device *dev, int to, const void *from, int count) { volatile unsigned short *ptr; const unsigned short *src=from; @@ -577,7 +577,7 @@ static void cpu_dayna_memcpy(struct device *dev, int to, const void *from, int c } } -static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; dayna_cpu_memcpy(dev, (void *)hdr, hdr_start, 4); @@ -585,7 +585,7 @@ static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, in hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void dayna_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -610,7 +610,7 @@ static void dayna_block_input(struct device *dev, int count, struct sk_buff *skb } } -static void dayna_block_output(struct device *dev, int count, const unsigned char *buf, +static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; @@ -623,7 +623,7 @@ static void dayna_block_output(struct device *dev, int count, const unsigned cha */ -static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; memcpy((void *)hdr, (char *)dev->mem_start+hdr_start, 4); @@ -631,7 +631,7 @@ static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void sane_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -652,7 +652,7 @@ static void sane_block_input(struct device *dev, int count, struct sk_buff *skb, } -static void sane_block_output(struct device *dev, int count, const unsigned char *buf, +static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; @@ -684,7 +684,7 @@ static void word_memcpy_fromcard(void *tp, const void *fp, int count) *to++=*from++; } -static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4); @@ -692,7 +692,7 @@ static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void slow_sane_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -712,7 +712,7 @@ static void slow_sane_block_input(struct device *dev, int count, struct sk_buff } } -static void slow_sane_block_output(struct device *dev, int count, const unsigned char *buf, +static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index ccd35038e..cd7d1c43c 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -379,8 +379,7 @@ Fix bug in pci_probe() for 64 bit systems reported by <belliott@accessone.com>. 0.533 9-Jan-98 Fix more 64 bit bugs reported by <jal@cs.brown.edu>. - 0.534 24-Jan-98 Fix last (?) endian bug from - <Geert.Uytterhoeven@cs.kuleuven.ac.be> + 0.534 24-Jan-98 Fix last (?) endian bug from <geert@linux-m68k.org> 0.535 21-Feb-98 Fix Ethernet Address PROM reset bug for DC21040. 0.536 21-Mar-98 Change pci_probe() to use the pci_dev structure. **Incompatible with 2.0.x from here.** @@ -447,6 +446,7 @@ static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com #include <linux/delay.h> #include <linux/init.h> #include <linux/version.h> +#include <linux/spinlock.h> #include <asm/bitops.h> #include <asm/io.h> @@ -454,7 +454,6 @@ static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com #include <asm/byteorder.h> #include <asm/unaligned.h> #include <asm/uaccess.h> -#include <asm/spinlock.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> @@ -826,7 +825,7 @@ struct de4x5_private { struct sk_buff *skb; /* Save the (re-ordered) skb's */ } cache; struct de4x5_srom srom; /* A copy of the SROM */ - struct device *next_module; /* Link to the next module */ + struct net_device *next_module; /* Link to the next module */ int rx_ovf; /* Check for 'RX overflow' tag */ int useSROM; /* For non-DEC card use SROM */ int useMII; /* Infoblock using the MII */ @@ -839,7 +838,7 @@ struct de4x5_private { int infoleaf_offset; /* SROM infoleaf for controller */ s32 infoblock_csr6; /* csr6 value in SROM infoblock */ int infoblock_media; /* infoblock media */ - int (*infoleaf_fn)(struct device *); /* Pointer to infoleaf function */ + int (*infoleaf_fn)(struct net_device *); /* Pointer to infoleaf function */ u_char *rst; /* Pointer to Type 5 reset info */ u_char ibn; /* Infoblock number */ struct parameters params; /* Command line/ #defined params */ @@ -895,63 +894,63 @@ static struct { /* ** Public Functions */ -static int de4x5_open(struct device *dev); -static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev); +static int de4x5_open(struct net_device *dev); +static int de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int de4x5_close(struct device *dev); -static struct net_device_stats *de4x5_get_stats(struct device *dev); -static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len); -static void set_multicast_list(struct device *dev); -static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int de4x5_close(struct net_device *dev); +static struct net_device_stats *de4x5_get_stats(struct net_device *dev); +static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len); +static void set_multicast_list(struct net_device *dev); +static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* ** Private functions */ -static int de4x5_hw_init(struct device *dev, u_long iobase); -static int de4x5_init(struct device *dev); -static int de4x5_sw_reset(struct device *dev); -static int de4x5_rx(struct device *dev); -static int de4x5_tx(struct device *dev); -static int de4x5_ast(struct device *dev); -static int de4x5_txur(struct device *dev); -static int de4x5_rx_ovfc(struct device *dev); - -static int autoconf_media(struct device *dev); -static void create_packet(struct device *dev, char *frame, int len); +static int de4x5_hw_init(struct net_device *dev, u_long iobase); +static int de4x5_init(struct net_device *dev); +static int de4x5_sw_reset(struct net_device *dev); +static int de4x5_rx(struct net_device *dev); +static int de4x5_tx(struct net_device *dev); +static int de4x5_ast(struct net_device *dev); +static int de4x5_txur(struct net_device *dev); +static int de4x5_rx_ovfc(struct net_device *dev); + +static int autoconf_media(struct net_device *dev); +static void create_packet(struct net_device *dev, char *frame, int len); static void de4x5_us_delay(u32 usec); static void de4x5_ms_delay(u32 msec); -static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb); -static int dc21040_autoconf(struct device *dev); -static int dc21041_autoconf(struct device *dev); -static int dc21140m_autoconf(struct device *dev); -static int dc2114x_autoconf(struct device *dev); -static int srom_autoconf(struct device *dev); -static int de4x5_suspect_state(struct device *dev, int timeout, int prev_state, int (*fn)(struct device *, int), int (*asfn)(struct device *)); -static int dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct device *, int)); -static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); -static int test_for_100Mb(struct device *dev, int msec); -static int wait_for_link(struct device *dev); -static int test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec); -static int is_spd_100(struct device *dev); -static int is_100_up(struct device *dev); -static int is_10_up(struct device *dev); -static int is_anc_capable(struct device *dev); -static int ping_media(struct device *dev, int msec); -static struct sk_buff *de4x5_alloc_rx_buff(struct device *dev, int index, int len); -static void de4x5_free_rx_buffs(struct device *dev); -static void de4x5_free_tx_buffs(struct device *dev); -static void de4x5_save_skbs(struct device *dev); -static void de4x5_rst_desc_ring(struct device *dev); -static void de4x5_cache_state(struct device *dev, int flag); -static void de4x5_put_cache(struct device *dev, struct sk_buff *skb); -static void de4x5_putb_cache(struct device *dev, struct sk_buff *skb); -static struct sk_buff *de4x5_get_cache(struct device *dev); -static void de4x5_setup_intr(struct device *dev); -static void de4x5_init_connection(struct device *dev); -static int de4x5_reset_phy(struct device *dev); -static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr); -static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec); -static int test_tp(struct device *dev, s32 msec); +static void load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb); +static int dc21040_autoconf(struct net_device *dev); +static int dc21041_autoconf(struct net_device *dev); +static int dc21140m_autoconf(struct net_device *dev); +static int dc2114x_autoconf(struct net_device *dev); +static int srom_autoconf(struct net_device *dev); +static int de4x5_suspect_state(struct net_device *dev, int timeout, int prev_state, int (*fn)(struct net_device *, int), int (*asfn)(struct net_device *)); +static int dc21040_state(struct net_device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct net_device *, int)); +static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); +static int test_for_100Mb(struct net_device *dev, int msec); +static int wait_for_link(struct net_device *dev); +static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec); +static int is_spd_100(struct net_device *dev); +static int is_100_up(struct net_device *dev); +static int is_10_up(struct net_device *dev); +static int is_anc_capable(struct net_device *dev); +static int ping_media(struct net_device *dev, int msec); +static struct sk_buff *de4x5_alloc_rx_buff(struct net_device *dev, int index, int len); +static void de4x5_free_rx_buffs(struct net_device *dev); +static void de4x5_free_tx_buffs(struct net_device *dev); +static void de4x5_save_skbs(struct net_device *dev); +static void de4x5_rst_desc_ring(struct net_device *dev); +static void de4x5_cache_state(struct net_device *dev, int flag); +static void de4x5_put_cache(struct net_device *dev, struct sk_buff *skb); +static void de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb); +static struct sk_buff *de4x5_get_cache(struct net_device *dev); +static void de4x5_setup_intr(struct net_device *dev); +static void de4x5_init_connection(struct net_device *dev); +static int de4x5_reset_phy(struct net_device *dev); +static void reset_init_sia(struct net_device *dev, s32 sicr, s32 strr, s32 sigr); +static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec); +static int test_tp(struct net_device *dev, s32 msec); static int EISA_signature(char *name, s32 eisa_id); static int PCI_signature(char *name, struct bus_type *lp); static void DevicePresent(u_long iobase); @@ -965,10 +964,10 @@ static short srom_data(u_int command, u_long address); /*static void srom_busy(u_int command, u_long address);*/ static void sendto_srom(u_int command, u_long addr); static int getfrom_srom(u_long addr); -static int srom_map_media(struct device *dev); -static int srom_infoleaf_info(struct device *dev); -static void srom_init(struct device *dev); -static void srom_exec(struct device *dev, u_char *p); +static int srom_map_media(struct net_device *dev); +static int srom_infoleaf_info(struct net_device *dev); +static void srom_init(struct net_device *dev); +static void srom_exec(struct net_device *dev, u_char *p); static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr); static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr); static int mii_rdata(u_long ioaddr); @@ -979,51 +978,51 @@ static void mii_address(u_char addr, u_long ioaddr); static void sendto_mii(u32 command, int data, u_long ioaddr); static int getfrom_mii(u32 command, u_long ioaddr); static int mii_get_oui(u_char phyaddr, u_long ioaddr); -static int mii_get_phy(struct device *dev); -static void SetMulticastFilter(struct device *dev); -static int get_hw_addr(struct device *dev); -static void srom_repair(struct device *dev, int card); -static int test_bad_enet(struct device *dev, int status); +static int mii_get_phy(struct net_device *dev); +static void SetMulticastFilter(struct net_device *dev); +static int get_hw_addr(struct net_device *dev); +static void srom_repair(struct net_device *dev, int card); +static int test_bad_enet(struct net_device *dev, int status); static int an_exception(struct bus_type *lp); #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) -static void eisa_probe(struct device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); #endif -static void pci_probe(struct device *dev, u_long iobase); +static void pci_probe(struct net_device *dev, u_long iobase); static void srom_search(struct pci_dev *pdev); -static char *build_setup_frame(struct device *dev, int mode); -static void disable_ast(struct device *dev); -static void enable_ast(struct device *dev, u32 time_out); -static long de4x5_switch_mac_port(struct device *dev); -static int gep_rd(struct device *dev); -static void gep_wr(s32 data, struct device *dev); -static void timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec); -static void yawn(struct device *dev, int state); -static void link_modules(struct device *dev, struct device *tmp); -static void de4x5_parse_params(struct device *dev); -static void de4x5_dbg_open(struct device *dev); -static void de4x5_dbg_mii(struct device *dev, int k); -static void de4x5_dbg_media(struct device *dev); +static char *build_setup_frame(struct net_device *dev, int mode); +static void disable_ast(struct net_device *dev); +static void enable_ast(struct net_device *dev, u32 time_out); +static long de4x5_switch_mac_port(struct net_device *dev); +static int gep_rd(struct net_device *dev); +static void gep_wr(s32 data, struct net_device *dev); +static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec); +static void yawn(struct net_device *dev, int state); +static void link_modules(struct net_device *dev, struct net_device *tmp); +static void de4x5_parse_params(struct net_device *dev); +static void de4x5_dbg_open(struct net_device *dev); +static void de4x5_dbg_mii(struct net_device *dev, int k); +static void de4x5_dbg_media(struct net_device *dev); static void de4x5_dbg_srom(struct de4x5_srom *p); static void de4x5_dbg_rx(struct sk_buff *skb, int len); static int de4x5_strncmp(char *a, char *b, int n); -static int dc21041_infoleaf(struct device *dev); -static int dc21140_infoleaf(struct device *dev); -static int dc21142_infoleaf(struct device *dev); -static int dc21143_infoleaf(struct device *dev); -static int type0_infoblock(struct device *dev, u_char count, u_char *p); -static int type1_infoblock(struct device *dev, u_char count, u_char *p); -static int type2_infoblock(struct device *dev, u_char count, u_char *p); -static int type3_infoblock(struct device *dev, u_char count, u_char *p); -static int type4_infoblock(struct device *dev, u_char count, u_char *p); -static int type5_infoblock(struct device *dev, u_char count, u_char *p); -static int compact_infoblock(struct device *dev, u_char count, u_char *p); +static int dc21041_infoleaf(struct net_device *dev); +static int dc21140_infoleaf(struct net_device *dev); +static int dc21142_infoleaf(struct net_device *dev); +static int dc21143_infoleaf(struct net_device *dev); +static int type0_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type1_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type2_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type3_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type4_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type5_infoblock(struct net_device *dev, u_char count, u_char *p); +static int compact_infoblock(struct net_device *dev, u_char count, u_char *p); #ifdef MODULE int init_module(void); void cleanup_module(void); -static struct device *unlink_modules(struct device *p); -static struct device *insert_device(struct device *dev, u_long iobase, - int (*init)(struct device *)); +static struct net_device *unlink_modules(struct net_device *p); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, + int (*init)(struct net_device *)); static int count_adapters(void); static int loading_module = 1; MODULE_PARM(de4x5_debug, "i"); @@ -1046,7 +1045,7 @@ static int forceEISA = 0; static int num_de4x5s = 0; static int cfrv = 0, useSROM = 0; static int lastPCI = -1; -static struct device *lastModule = NULL; +static struct net_device *lastModule = NULL; static struct pci_dev *pdev = NULL; /* @@ -1054,7 +1053,7 @@ static struct pci_dev *pdev = NULL; */ struct InfoLeaf { int chipset; - int (*fn)(struct device *); + int (*fn)(struct net_device *); }; static struct InfoLeaf infoleaf_array[] = { {DC21041, dc21041_infoleaf}, @@ -1067,7 +1066,7 @@ static struct InfoLeaf infoleaf_array[] = { /* ** List the SROM info block functions */ -static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = { +static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = { type0_infoblock, type1_infoblock, type2_infoblock, @@ -1107,7 +1106,7 @@ static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = { ** more info. */ int __init -de4x5_probe(struct device *dev) +de4x5_probe(struct net_device *dev) { u_long iobase = dev->base_addr; @@ -1122,7 +1121,7 @@ de4x5_probe(struct device *dev) } static int __init -de4x5_hw_init(struct device *dev, u_long iobase) +de4x5_hw_init(struct net_device *dev, u_long iobase) { struct bus_type *lp = &bus; int i, status=0; @@ -1339,7 +1338,7 @@ de4x5_hw_init(struct device *dev, u_long iobase) static int -de4x5_open(struct device *dev) +de4x5_open(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1419,7 +1418,7 @@ de4x5_open(struct device *dev) ** ttcp source). */ static int -de4x5_init(struct device *dev) +de4x5_init(struct net_device *dev) { /* Lock out other processes whilst setting up the hardware */ test_and_set_bit(0, (void *)&dev->tbusy); @@ -1433,7 +1432,7 @@ de4x5_init(struct device *dev) } static int -de4x5_sw_reset(struct device *dev) +de4x5_sw_reset(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1510,7 +1509,7 @@ de4x5_sw_reset(struct device *dev) ** Writes a socket buffer address to the next available transmit descriptor. */ static int -de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) +de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1590,7 +1589,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct de4x5_private *lp; s32 imr, omr, sts, limit; u_long iobase; @@ -1654,7 +1653,7 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static int -de4x5_rx(struct device *dev) +de4x5_rx(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1733,7 +1732,7 @@ de4x5_rx(struct device *dev) ** Buffer sent - check for TX buffer errors. */ static int -de4x5_tx(struct device *dev) +de4x5_tx(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1784,7 +1783,7 @@ de4x5_tx(struct device *dev) } static int -de4x5_ast(struct device *dev) +de4x5_ast(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -1807,7 +1806,7 @@ de4x5_ast(struct device *dev) } static int -de4x5_txur(struct device *dev) +de4x5_txur(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1830,7 +1829,7 @@ de4x5_txur(struct device *dev) } static int -de4x5_rx_ovfc(struct device *dev) +de4x5_rx_ovfc(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1851,7 +1850,7 @@ de4x5_rx_ovfc(struct device *dev) } static int -de4x5_close(struct device *dev) +de4x5_close(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1889,7 +1888,7 @@ de4x5_close(struct device *dev) } static struct net_device_stats * -de4x5_get_stats(struct device *dev) +de4x5_get_stats(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1900,7 +1899,7 @@ de4x5_get_stats(struct device *dev) } static void -de4x5_local_stats(struct device *dev, char *buf, int pkt_len) +de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -1939,7 +1938,7 @@ de4x5_local_stats(struct device *dev, char *buf, int pkt_len) ** the descriptor register is read only to the hardware. */ static void -load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) +load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int entry = (lp->tx_new ? lp->tx_new-1 : lp->txRingSize-1); @@ -1961,7 +1960,7 @@ load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) ** Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1993,7 +1992,7 @@ set_multicast_list(struct device *dev) ** Little endian crc one liner from Matt Thomas, DEC. */ static void -SetMulticastFilter(struct device *dev) +SetMulticastFilter(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct dev_mc_list *dmi=dev->mc_list; @@ -2055,7 +2054,7 @@ SetMulticastFilter(struct device *dev) ** the motherboard. Upto 15 EISA devices are supported. */ static void __init -eisa_probe(struct device *dev, u_long ioaddr) +eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots, status, device; u_char irq; @@ -2137,7 +2136,7 @@ eisa_probe(struct device *dev, u_long ioaddr) #define PCI_LAST_DEV 32 static void __init -pci_probe(struct device *dev, u_long ioaddr) +pci_probe(struct net_device *dev, u_long ioaddr) { u_char pb, pbus, dev_num, dnum, timer; u_short vendor, index, status; @@ -2192,7 +2191,7 @@ pci_probe(struct device *dev, u_long ioaddr) lp->chipset = device; /* Get the board I/O address (64 bits on sparc64) */ - iobase = pdev->base_address[0] & CBIO_MASK; + iobase = pdev->resource[0].start; /* Fetch the IRQ to be used */ irq = pdev->irq; @@ -2278,7 +2277,7 @@ srom_search(struct pci_dev *dev) lp->chipset = device; /* Get the board I/O address (64 bits on sparc64) */ - iobase = dev->base_address[0] & CBIO_MASK; + iobase = dev->resource[0].start; /* Fetch the IRQ to be used */ irq = dev->irq; @@ -2308,9 +2307,9 @@ srom_search(struct pci_dev *dev) } static void __init -link_modules(struct device *dev, struct device *tmp) +link_modules(struct net_device *dev, struct net_device *tmp) { - struct device *p=dev; + struct net_device *p=dev; if (p) { while (((struct de4x5_private *)(p->priv))->next_module) { @@ -2335,7 +2334,7 @@ link_modules(struct device *dev, struct device *tmp) ** sneaky and changed the port on us. */ static int -autoconf_media(struct device *dev) +autoconf_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2376,7 +2375,7 @@ autoconf_media(struct device *dev) ** timeouts don't effectively duplicate packets on the network. */ static int -dc21040_autoconf(struct device *dev) +dc21040_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2447,9 +2446,9 @@ dc21040_autoconf(struct device *dev) } static int -dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, +dc21040_state(struct net_device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, - int (*fn)(struct device *, int)) + int (*fn)(struct net_device *, int)) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2486,9 +2485,9 @@ dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, } static int -de4x5_suspect_state(struct device *dev, int timeout, int prev_state, - int (*fn)(struct device *, int), - int (*asfn)(struct device *)) +de4x5_suspect_state(struct net_device *dev, int timeout, int prev_state, + int (*fn)(struct net_device *, int), + int (*asfn)(struct net_device *)) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2530,7 +2529,7 @@ de4x5_suspect_state(struct device *dev, int timeout, int prev_state, ** when the media is found. */ static int -dc21041_autoconf(struct device *dev) +dc21041_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2732,7 +2731,7 @@ dc21041_autoconf(struct device *dev) ** register, except at the first power up negotiation. */ static int -dc21140m_autoconf(struct device *dev) +dc21140m_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int ana, anlpa, cap, cr, slnk, sr; @@ -2916,7 +2915,7 @@ dc21140m_autoconf(struct device *dev) ** Only _10Mb and _100Mb are tested here. */ static int -dc2114x_autoconf(struct device *dev) +dc2114x_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3167,7 +3166,7 @@ printk("Huh?: media:%02x\n", lp->media); } static int -srom_autoconf(struct device *dev) +srom_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3180,7 +3179,7 @@ srom_autoconf(struct device *dev) ** The early return avoids a media state / SROM media space clash. */ static int -srom_map_media(struct device *dev) +srom_map_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3244,7 +3243,7 @@ srom_map_media(struct device *dev) } static void -de4x5_init_connection(struct device *dev) +de4x5_init_connection(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3273,7 +3272,7 @@ de4x5_init_connection(struct device *dev) ** on the signal pin use. Do a double reset to ensure a reset. */ static int -de4x5_reset_phy(struct device *dev) +de4x5_reset_phy(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3307,7 +3306,7 @@ de4x5_reset_phy(struct device *dev) } static int -test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) +test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3345,7 +3344,7 @@ test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 } static int -test_tp(struct device *dev, s32 msec) +test_tp(struct net_device *dev, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3374,7 +3373,7 @@ test_tp(struct device *dev, s32 msec) #define SAMPLE_INTERVAL 500 /* ms */ #define SAMPLE_DELAY 2000 /* ms */ static int -test_for_100Mb(struct device *dev, int msec) +test_for_100Mb(struct net_device *dev, int msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int gep = 0, ret = ((lp->chipset & ~0x00ff)==DC2114x? -1 :GEP_SLNK); @@ -3405,7 +3404,7 @@ test_for_100Mb(struct device *dev, int msec) } static int -wait_for_link(struct device *dev) +wait_for_link(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3427,7 +3426,7 @@ wait_for_link(struct device *dev) ** */ static int -test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec) +test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int test; @@ -3451,7 +3450,7 @@ test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec) } static int -is_spd_100(struct device *dev) +is_spd_100(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3475,7 +3474,7 @@ is_spd_100(struct device *dev) } static int -is_100_up(struct device *dev) +is_100_up(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3496,7 +3495,7 @@ is_100_up(struct device *dev) } static int -is_10_up(struct device *dev) +is_10_up(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3519,7 +3518,7 @@ is_10_up(struct device *dev) } static int -is_anc_capable(struct device *dev) +is_anc_capable(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3538,7 +3537,7 @@ is_anc_capable(struct device *dev) ** media is bad or unconnected. */ static int -ping_media(struct device *dev, int msec) +ping_media(struct net_device *dev, int msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3579,7 +3578,7 @@ ping_media(struct device *dev, int msec) ** into which the packet is copied. */ static struct sk_buff * -de4x5_alloc_rx_buff(struct device *dev, int index, int len) +de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p; @@ -3630,7 +3629,7 @@ de4x5_alloc_rx_buff(struct device *dev, int index, int len) } static void -de4x5_free_rx_buffs(struct device *dev) +de4x5_free_rx_buffs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -3647,7 +3646,7 @@ de4x5_free_rx_buffs(struct device *dev) } static void -de4x5_free_tx_buffs(struct device *dev) +de4x5_free_tx_buffs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -3676,7 +3675,7 @@ de4x5_free_tx_buffs(struct device *dev) ** packet meaningful. */ static void -de4x5_save_skbs(struct device *dev) +de4x5_save_skbs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3697,7 +3696,7 @@ de4x5_save_skbs(struct device *dev) } static void -de4x5_rst_desc_ring(struct device *dev) +de4x5_rst_desc_ring(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3729,7 +3728,7 @@ de4x5_rst_desc_ring(struct device *dev) } static void -de4x5_cache_state(struct device *dev, int flag) +de4x5_cache_state(struct net_device *dev, int flag) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3759,7 +3758,7 @@ de4x5_cache_state(struct device *dev, int flag) } static void -de4x5_put_cache(struct device *dev, struct sk_buff *skb) +de4x5_put_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p; @@ -3776,7 +3775,7 @@ de4x5_put_cache(struct device *dev, struct sk_buff *skb) } static void -de4x5_putb_cache(struct device *dev, struct sk_buff *skb) +de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p = lp->cache.skb; @@ -3788,7 +3787,7 @@ de4x5_putb_cache(struct device *dev, struct sk_buff *skb) } static struct sk_buff * -de4x5_get_cache(struct device *dev) +de4x5_get_cache(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p = lp->cache.skb; @@ -3806,7 +3805,7 @@ de4x5_get_cache(struct device *dev) ** is received and the auto-negotiation status is NWAY OK. */ static int -test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec) +test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3834,7 +3833,7 @@ test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec) } static void -de4x5_setup_intr(struct device *dev) +de4x5_setup_intr(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3855,7 +3854,7 @@ de4x5_setup_intr(struct device *dev) ** */ static void -reset_init_sia(struct device *dev, s32 csr13, s32 csr14, s32 csr15) +reset_init_sia(struct net_device *dev, s32 csr13, s32 csr14, s32 csr15) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3889,7 +3888,7 @@ reset_init_sia(struct device *dev, s32 csr13, s32 csr14, s32 csr15) ** Create a loopback ethernet packet */ static void -create_packet(struct device *dev, char *frame, int len) +create_packet(struct net_device *dev, char *frame, int len) { int i; char *buf = frame; @@ -4098,7 +4097,7 @@ enet_addr_rst(u_long aprom_addr) ** as the first three are invariant - assigned to an organisation. */ static int -get_hw_addr(struct device *dev) +get_hw_addr(struct net_device *dev) { u_long iobase = dev->base_addr; int broken, i, k, tmp, status = 0; @@ -4212,7 +4211,7 @@ de4x5_strncmp(char *a, char *b, int n) } static void -srom_repair(struct device *dev, int card) +srom_repair(struct net_device *dev, int card) { struct bus_type *lp = &bus; @@ -4233,7 +4232,7 @@ srom_repair(struct device *dev, int card) ** to be true so far (2 for 2). */ static int -test_bad_enet(struct device *dev, int status) +test_bad_enet(struct net_device *dev, int status) { struct bus_type *lp = &bus; int i, tmp; @@ -4387,7 +4386,7 @@ getfrom_srom(u_long addr) } static int -srom_infoleaf_info(struct device *dev) +srom_infoleaf_info(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i, count; @@ -4435,7 +4434,7 @@ srom_infoleaf_info(struct device *dev) ** will follow the discovery process from MII address 1-31 then 0. */ static void -srom_init(struct device *dev) +srom_init(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; @@ -4480,7 +4479,7 @@ srom_init(struct device *dev) ** to the GEP register (21140) or csr15 GEP portion (2114[23]). */ static void -srom_exec(struct device *dev, u_char *p) +srom_exec(struct net_device *dev, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -4511,13 +4510,13 @@ srom_exec(struct device *dev, u_char *p) ** since the existing code will be satisfactory for all boards. */ static int -dc21041_infoleaf(struct device *dev) +dc21041_infoleaf(struct net_device *dev) { return DE4X5_AUTOSENSE_MS; } static int -dc21140_infoleaf(struct device *dev) +dc21140_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4555,7 +4554,7 @@ dc21140_infoleaf(struct device *dev) } static int -dc21142_infoleaf(struct device *dev) +dc21142_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4590,7 +4589,7 @@ dc21142_infoleaf(struct device *dev) } static int -dc21143_infoleaf(struct device *dev) +dc21143_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4628,7 +4627,7 @@ dc21143_infoleaf(struct device *dev) ** we'll reuse the dc21140m_autoconf function. Non MII media only. */ static int -compact_infoblock(struct device *dev, u_char count, u_char *p) +compact_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6; @@ -4668,7 +4667,7 @@ compact_infoblock(struct device *dev, u_char count, u_char *p) ** This block describes non MII media for the DC21140[A] only. */ static int -type0_infoblock(struct device *dev, u_char count, u_char *p) +type0_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6, len = (*p & BLOCK_LEN)+1; @@ -4708,7 +4707,7 @@ type0_infoblock(struct device *dev, u_char count, u_char *p) /* These functions are under construction! */ static int -type1_infoblock(struct device *dev, u_char count, u_char *p) +type1_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4747,7 +4746,7 @@ type1_infoblock(struct device *dev, u_char count, u_char *p) } static int -type2_infoblock(struct device *dev, u_char count, u_char *p) +type2_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4788,7 +4787,7 @@ type2_infoblock(struct device *dev, u_char count, u_char *p) } static int -type3_infoblock(struct device *dev, u_char count, u_char *p) +type3_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4829,7 +4828,7 @@ type3_infoblock(struct device *dev, u_char count, u_char *p) } static int -type4_infoblock(struct device *dev, u_char count, u_char *p) +type4_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6, len = (*p & BLOCK_LEN)+1; @@ -4874,7 +4873,7 @@ type4_infoblock(struct device *dev, u_char count, u_char *p) ** (chips) through the General Purpose Register. */ static int -type5_infoblock(struct device *dev, u_char count, u_char *p) +type5_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -5074,7 +5073,7 @@ mii_get_oui(u_char phyaddr, u_long ioaddr) ** The SROM spec forces us to search addresses [1-31 0]. Bummer. */ static int -mii_get_phy(struct device *dev) +mii_get_phy(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5138,7 +5137,7 @@ mii_get_phy(struct device *dev) } static char * -build_setup_frame(struct device *dev, int mode) +build_setup_frame(struct net_device *dev, int mode) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -5170,7 +5169,7 @@ build_setup_frame(struct device *dev, int mode) } static void -enable_ast(struct device *dev, u32 time_out) +enable_ast(struct net_device *dev, u32 time_out) { timeout(dev, (void *)&de4x5_ast, (u_long)dev, time_out); @@ -5178,7 +5177,7 @@ enable_ast(struct device *dev, u32 time_out) } static void -disable_ast(struct device *dev) +disable_ast(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -5188,7 +5187,7 @@ disable_ast(struct device *dev) } static long -de4x5_switch_mac_port(struct device *dev) +de4x5_switch_mac_port(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5224,7 +5223,7 @@ de4x5_switch_mac_port(struct device *dev) } static void -gep_wr(s32 data, struct device *dev) +gep_wr(s32 data, struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5239,7 +5238,7 @@ gep_wr(s32 data, struct device *dev) } static int -gep_rd(struct device *dev) +gep_rd(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5254,7 +5253,7 @@ gep_rd(struct device *dev) } static void -timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec) +timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int dt; @@ -5276,7 +5275,7 @@ timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec) } static void -yawn(struct device *dev, int state) +yawn(struct net_device *dev, int state) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5324,7 +5323,7 @@ yawn(struct device *dev, int state) } static void -de4x5_parse_params(struct device *dev) +de4x5_parse_params(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; char *p, *q, t; @@ -5370,7 +5369,7 @@ de4x5_parse_params(struct device *dev) } static void -de4x5_dbg_open(struct device *dev) +de4x5_dbg_open(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -5421,7 +5420,7 @@ de4x5_dbg_open(struct device *dev) } static void -de4x5_dbg_mii(struct device *dev, int k) +de4x5_dbg_mii(struct net_device *dev, int k) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5449,7 +5448,7 @@ de4x5_dbg_mii(struct device *dev, int k) } static void -de4x5_dbg_media(struct device *dev) +de4x5_dbg_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -5542,7 +5541,7 @@ de4x5_dbg_rx(struct sk_buff *skb, int len) ** this function is only used for my testing. */ static int -de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd) +de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data; @@ -5751,7 +5750,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd) ** to "do the right thing". */ #define LP(a) ((struct de4x5_private *)(a)) -static struct device *mdev = NULL; +static struct net_device *mdev = NULL; static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ MODULE_PARM(io, "i"); @@ -5759,7 +5758,7 @@ int init_module(void) { int i, num, status = -EIO; - struct device *p; + struct net_device *p; num = count_adapters(); @@ -5802,10 +5801,10 @@ cleanup_module(void) return; } -static struct device * -unlink_modules(struct device *p) +static struct net_device * +unlink_modules(struct net_device *p) { - struct device *next = NULL; + struct net_device *next = NULL; if (p->priv) { /* Private areas allocated? */ struct de4x5_private *lp = (struct de4x5_private *)p->priv; @@ -5856,17 +5855,17 @@ count_adapters(void) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * __init -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +static struct net_device * __init +insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL); if (new == NULL) { printk("de4x5.c: Device not initialised, insufficient memory\n"); return NULL; } else { - memset((char *)new, 0, sizeof(struct device)+8); + memset((char *)new, 0, sizeof(struct net_device)+8); new->name = (char *)(new + 1); new->base_addr = iobase; /* assign the io address */ new->init = init; /* initialisation routine */ diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 5e8050300..1805ae5f3 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -243,24 +243,24 @@ typedef unsigned char byte; * Index to functions, as function prototypes. */ /* Routines used internally. (See "convenience macros") */ -static byte de600_read_status(struct device *dev); -static byte de600_read_byte(unsigned char type, struct device *dev); +static byte de600_read_status(struct net_device *dev); +static byte de600_read_byte(unsigned char type, struct net_device *dev); /* Put in the device structure. */ -static int de600_open(struct device *dev); -static int de600_close(struct device *dev); -static struct net_device_stats *get_stats(struct device *dev); -static int de600_start_xmit(struct sk_buff *skb, struct device *dev); +static int de600_open(struct net_device *dev); +static int de600_close(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev); /* Dispatch from interrupts. */ static void de600_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int de600_tx_intr(struct device *dev, int irq_status); -static void de600_rx_intr(struct device *dev); +static int de600_tx_intr(struct net_device *dev, int irq_status); +static void de600_rx_intr(struct net_device *dev); /* Initialization */ -static void trigger_interrupt(struct device *dev); -int de600_probe(struct device *dev); -static int adapter_init(struct device *dev); +static void trigger_interrupt(struct net_device *dev); +int de600_probe(struct net_device *dev); +static int adapter_init(struct net_device *dev); /* * D-Link driver variables: @@ -310,7 +310,7 @@ static int was_down = 0; #define tx_page_adr(a) (((a) + 1) * MEM_2K) static inline byte -de600_read_status(struct device *dev) +de600_read_status(struct net_device *dev) { byte status; @@ -322,7 +322,7 @@ de600_read_status(struct device *dev) } static inline byte -de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */ +de600_read_byte(unsigned char type, struct net_device *dev) { /* dev used by macros */ byte lo; (void)outb_p((type), DATA_PORT); @@ -340,7 +340,7 @@ de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros * there is a non-reboot way to recover if something goes wrong. */ static int -de600_open(struct device *dev) +de600_open(struct net_device *dev) { if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", dev)) { printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ); @@ -360,7 +360,7 @@ de600_open(struct device *dev) * The inverse routine to de600_open(). */ static int -de600_close(struct device *dev) +de600_close(struct net_device *dev) { select_nic(); rx_page = 0; @@ -378,13 +378,13 @@ de600_close(struct device *dev) } static struct net_device_stats * -get_stats(struct device *dev) +get_stats(struct net_device *dev) { return (struct net_device_stats *)(dev->priv); } static inline void -trigger_interrupt(struct device *dev) +trigger_interrupt(struct net_device *dev) { de600_put_command(FLIP_IRQ); select_prn(); @@ -398,7 +398,7 @@ trigger_interrupt(struct device *dev) * Start sending. */ static int -de600_start_xmit(struct sk_buff *skb, struct device *dev) +de600_start_xmit(struct sk_buff *skb, struct net_device *dev) { int transmit_from; int len; @@ -483,7 +483,7 @@ de600_start_xmit(struct sk_buff *skb, struct device *dev) static void de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; byte irq_status; int retrig = 0; int boguscount = 0; @@ -532,7 +532,7 @@ de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) } static int -de600_tx_intr(struct device *dev, int irq_status) +de600_tx_intr(struct net_device *dev, int irq_status) { /* * Returns 1 if tx still not done @@ -568,7 +568,7 @@ de600_tx_intr(struct device *dev, int irq_status) * We have a good packet, get it out of the adapter. */ static void -de600_rx_intr(struct device *dev) +de600_rx_intr(struct net_device *dev) { struct sk_buff *skb; int i; @@ -628,7 +628,7 @@ de600_rx_intr(struct device *dev) } int __init -de600_probe(struct device *dev) +de600_probe(struct net_device *dev) { int i; static struct net_device_stats de600_netstats; @@ -707,7 +707,7 @@ de600_probe(struct device *dev) } static int -adapter_init(struct device *dev) +adapter_init(struct net_device *dev) { int i; long flags; @@ -818,7 +818,7 @@ de600_rspace(struct sock *sk) #ifdef MODULE static char nullname[8]; -static struct device de600_dev = { +static struct net_device de600_dev = { nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe }; int diff --git a/drivers/net/de620.c b/drivers/net/de620.c index 8ae2803a3..3f138239f 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -209,20 +209,20 @@ MODULE_PARM(de620_debug, "i"); */ /* Put in the device structure. */ -static int de620_open(struct device *); -static int de620_close(struct device *); -static struct net_device_stats *get_stats(struct device *); -static void de620_set_multicast_list(struct device *); -static int de620_start_xmit(struct sk_buff *, struct device *); +static int de620_open(struct net_device *); +static int de620_close(struct net_device *); +static struct net_device_stats *get_stats(struct net_device *); +static void de620_set_multicast_list(struct net_device *); +static int de620_start_xmit(struct sk_buff *, struct net_device *); /* Dispatch from interrupts. */ static void de620_interrupt(int, void *, struct pt_regs *); -static int de620_rx_intr(struct device *); +static int de620_rx_intr(struct net_device *); /* Initialization */ -static int adapter_init(struct device *); -int de620_probe(struct device *); -static int read_eeprom(struct device *); +static int adapter_init(struct net_device *); +int de620_probe(struct net_device *); +static int read_eeprom(struct net_device *); /* @@ -260,7 +260,7 @@ static struct nic { static int tot_cnt; #endif static inline byte -de620_ready(struct device *dev) +de620_ready(struct net_device *dev) { byte value; register short int cnt = 0; @@ -275,7 +275,7 @@ de620_ready(struct device *dev) } static inline void -de620_send_command(struct device *dev, byte cmd) +de620_send_command(struct net_device *dev, byte cmd) { de620_ready(dev); if (cmd == W_DUMMY) @@ -289,7 +289,7 @@ de620_send_command(struct device *dev, byte cmd) } static inline void -de620_put_byte(struct device *dev, byte value) +de620_put_byte(struct net_device *dev, byte value) { /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ de620_ready(dev); @@ -298,7 +298,7 @@ de620_put_byte(struct device *dev, byte value) } static inline byte -de620_read_byte(struct device *dev) +de620_read_byte(struct net_device *dev) { byte value; @@ -310,7 +310,7 @@ de620_read_byte(struct device *dev) } static inline void -de620_write_block(struct device *dev, byte *buffer, int count) +de620_write_block(struct net_device *dev, byte *buffer, int count) { #ifndef LOWSPEED byte uflip = NIC_Cmd ^ (DS0 | DS1); @@ -346,7 +346,7 @@ de620_write_block(struct device *dev, byte *buffer, int count) } static inline void -de620_read_block(struct device *dev, byte *data, int count) +de620_read_block(struct net_device *dev, byte *data, int count) { #ifndef LOWSPEED byte value; @@ -381,7 +381,7 @@ de620_read_block(struct device *dev, byte *data, int count) } static inline void -de620_set_delay(struct device *dev) +de620_set_delay(struct net_device *dev) { de620_ready(dev); outb(W_DFR, DATA_PORT); @@ -405,7 +405,7 @@ de620_set_delay(struct device *dev) } static inline void -de620_set_register(struct device *dev, byte reg, byte value) +de620_set_register(struct net_device *dev, byte reg, byte value) { de620_ready(dev); outb(reg, DATA_PORT); @@ -415,7 +415,7 @@ de620_set_register(struct device *dev, byte reg, byte value) } static inline byte -de620_get_register(struct device *dev, byte reg) +de620_get_register(struct net_device *dev, byte reg) { byte value; @@ -436,7 +436,7 @@ de620_get_register(struct device *dev, byte reg) * */ static int -de620_open(struct device *dev) +de620_open(struct net_device *dev) { if (request_irq(dev->irq, de620_interrupt, 0, "de620", dev)) { printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq); @@ -457,7 +457,7 @@ de620_open(struct device *dev) * */ static int -de620_close(struct device *dev) +de620_close(struct net_device *dev) { /* disable recv */ de620_set_register(dev, W_TCR, RXOFF); @@ -474,7 +474,7 @@ de620_close(struct device *dev) * Return current statistics * */ -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { return (struct net_device_stats *)(dev->priv); } @@ -486,7 +486,7 @@ static struct net_device_stats *get_stats(struct device *dev) * */ -static void de620_set_multicast_list(struct device *dev) +static void de620_set_multicast_list(struct net_device *dev) { if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) { /* Enable promiscuous mode */ @@ -511,7 +511,7 @@ static void de620_set_multicast_list(struct device *dev) * Start sending. */ static int -de620_start_xmit(struct sk_buff *skb, struct device *dev) +de620_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; int len; @@ -592,7 +592,7 @@ de620_start_xmit(struct sk_buff *skb, struct device *dev) static void de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; byte irq_status; int bogus_count = 0; int again = 0; @@ -634,7 +634,7 @@ de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) * */ static int -de620_rx_intr(struct device *dev) +de620_rx_intr(struct net_device *dev) { struct header_buf { byte status; @@ -733,7 +733,7 @@ de620_rx_intr(struct device *dev) * */ static int -adapter_init(struct device *dev) +adapter_init(struct net_device *dev) { int i; static int was_down = 0; @@ -821,7 +821,7 @@ adapter_init(struct device *dev) * Check if there is a DE-620 connected */ int __init -de620_probe(struct device *dev) +de620_probe(struct net_device *dev) { static struct net_device_stats de620_netstats; int i; @@ -914,7 +914,7 @@ de620_probe(struct device *dev) #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); static unsigned short __init -ReadAWord(struct device *dev, int from) +ReadAWord(struct net_device *dev, int from) { unsigned short data; int nbits; @@ -957,7 +957,7 @@ ReadAWord(struct device *dev, int from) } static int __init -read_eeprom(struct device *dev) +read_eeprom(struct net_device *dev) { unsigned short wrd; @@ -1000,7 +1000,7 @@ read_eeprom(struct device *dev) */ #ifdef MODULE static char nullname[8] = ""; -static struct device de620_dev = { +static struct net_device de620_dev = { nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe }; int diff --git a/drivers/net/declance.c b/drivers/net/declance.c index b5c5b4f42..4964a3fe0 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -263,7 +263,7 @@ struct lance_private { unsigned short busmaster_regval; - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct lance_private *next_module; /* Pointers to the ring buffers as seen from the CPU */ @@ -444,7 +444,7 @@ void cp_from_buf(void *to, unsigned char *from, int len) /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring(struct device *dev) +static void lance_init_ring(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -548,7 +548,7 @@ static int init_restart_lance(struct lance_private *lp) return 0; } -static int lance_rx(struct device *dev) +static int lance_rx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -630,7 +630,7 @@ static int lance_rx(struct device *dev) return 0; } -static int lance_tx(struct device *dev) +static int lance_tx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -707,7 +707,7 @@ static int lance_tx(struct device *dev) static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; int csr0; @@ -770,9 +770,9 @@ static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open(struct device *dev) +static int lance_open(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -806,7 +806,7 @@ static int lance_open(struct device *dev) return status; } -static int lance_close(struct device *dev) +static int lance_close(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -825,7 +825,7 @@ static int lance_close(struct device *dev) return 0; } -static inline int lance_reset(struct device *dev) +static inline int lance_reset(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -848,7 +848,7 @@ static inline int lance_reset(struct device *dev) return status; } -static int lance_start_xmit(struct sk_buff *skb, struct device *dev) +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -917,14 +917,14 @@ static int lance_start_xmit(struct sk_buff *skb, struct device *dev) return status; } -static struct net_device_stats *lance_get_stats(struct device *dev) +static struct net_device_stats *lance_get_stats(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; return &lp->stats; } -static void lance_load_multicast(struct device *dev) +static void lance_load_multicast(struct net_device *dev) { volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); volatile u16 *mcast_table = (u16 *) & ib->filter; @@ -975,7 +975,7 @@ static void lance_load_multicast(struct device *dev) return; } -static void lance_set_multicast(struct device *dev) +static void lance_set_multicast(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -1005,7 +1005,7 @@ static void lance_set_multicast(struct device *dev) dev->tbusy = 0; } -__initfunc(static int dec_lance_init(struct device *dev, const int type)) +static int __init dec_lance_init(struct net_device *dev, const int type) { static unsigned version_printed = 0; struct lance_private *lp; @@ -1200,7 +1200,7 @@ __initfunc(static int dec_lance_init(struct device *dev, const int type)) /* Find all the lance cards on the system and initialize them */ -__initfunc(int dec_lance_probe(struct device *dev)) +int __init dec_lance_probe(struct net_device *dev) { static int called = 0; diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index 84915977e..be62ef741 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -236,29 +236,29 @@ static const char *version = "defxx.c:v1.04 09/16/96 Lawrence V. Stefani (stefa /* Define global routines */ -int dfx_probe(struct device *dev); +int dfx_probe(struct net_device *dev); /* Define module-wide (static) routines */ -static struct device *dfx_alloc_device(struct device *dev, u16 iobase); +static struct net_device *dfx_alloc_device(struct net_device *dev, u16 iobase); -static void dfx_bus_init(struct device *dev); +static void dfx_bus_init(struct net_device *dev); static void dfx_bus_config_check(DFX_board_t *bp); -static int dfx_driver_init(struct device *dev); +static int dfx_driver_init(struct net_device *dev); static int dfx_adap_init(DFX_board_t *bp); -static int dfx_open(struct device *dev); -static int dfx_close(struct device *dev); +static int dfx_open(struct net_device *dev); +static int dfx_close(struct net_device *dev); static void dfx_int_pr_halt_id(DFX_board_t *bp); static void dfx_int_type_0_process(DFX_board_t *bp); static void dfx_int_common(DFX_board_t *bp); static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct net_device_stats *dfx_ctl_get_stats(struct device *dev); -static void dfx_ctl_set_multicast_list(struct device *dev); -static int dfx_ctl_set_mac_address(struct device *dev, void *addr); +static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev); +static void dfx_ctl_set_multicast_list(struct net_device *dev); +static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr); static int dfx_ctl_update_cam(DFX_board_t *bp); static int dfx_ctl_update_filters(DFX_board_t *bp); @@ -271,7 +271,7 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type); static void dfx_rcv_init(DFX_board_t *bp); static void dfx_rcv_queue_process(DFX_board_t *bp); -static int dfx_xmt_queue_pkt(struct sk_buff *skb, struct device *dev); +static int dfx_xmt_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void dfx_xmt_done(DFX_board_t *bp); static void dfx_xmt_flush(DFX_board_t *bp); @@ -446,7 +446,7 @@ static inline void dfx_port_read_long( * the device structure. */ -int __init dfx_probe(struct device *dev) +int __init dfx_probe(struct net_device *dev) { int i; /* used in for loops */ int version_disp; /* was version info string already displayed? */ @@ -549,11 +549,12 @@ int __init dfx_probe(struct device *dev) /* Get I/O base address from PCI Configuration Space */ - port = pdev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; + port = pdev->resource[1].start; /* Verify port address range is not already being used */ port_len = PFI_K_CSR_IO_LEN; + if (check_region(port, port_len) == 0) { /* Allocate a new device structure for this adapter */ @@ -638,9 +639,9 @@ int __init dfx_probe(struct device *dev) * None */ -struct device __init *dfx_alloc_device( struct device *dev, u16 iobase) +struct net_device __init *dfx_alloc_device( struct net_device *dev, u16 iobase) { - struct device *tmp_dev; /* pointer to a device structure */ + struct net_device *tmp_dev; /* pointer to a device structure */ DBG_printk("In dfx_alloc_device...\n"); @@ -729,7 +730,7 @@ struct device __init *dfx_alloc_device( struct device *dev, u16 iobase) * enabled yet. */ -void __init dfx_bus_init(struct device *dev) +void __init dfx_bus_init(struct net_device *dev) { DFX_board_t *bp = (DFX_board_t *)dev->priv; u8 val; /* used for I/O read/writes */ @@ -962,7 +963,7 @@ void __init dfx_bus_config_check(DFX_board_t *bp) * returning from this routine. */ -int __init dfx_driver_init(struct device *dev) +int __init dfx_driver_init(struct net_device *dev) { DFX_board_t *bp = (DFX_board_t *)dev->priv; int alloc_size; /* total buffer size needed */ @@ -1370,7 +1371,7 @@ int dfx_adap_init( */ int dfx_open( - struct device *dev + struct net_device *dev ) { @@ -1462,7 +1463,7 @@ int dfx_open( */ int dfx_close( - struct device *dev + struct net_device *dev ) { @@ -1882,7 +1883,7 @@ void dfx_interrupt( ) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; DFX_board_t *bp; /* private board structure pointer */ u8 tmp; /* used for disabling/enabling ints */ @@ -1990,7 +1991,7 @@ void dfx_interrupt( */ struct net_device_stats *dfx_ctl_get_stats( - struct device *dev + struct net_device *dev ) { @@ -2178,7 +2179,7 @@ struct net_device_stats *dfx_ctl_get_stats( */ void dfx_ctl_set_multicast_list( - struct device *dev + struct net_device *dev ) { @@ -2296,7 +2297,7 @@ void dfx_ctl_set_multicast_list( */ int dfx_ctl_set_mac_address( - struct device *dev, + struct net_device *dev, void *addr ) @@ -3188,7 +3189,7 @@ void dfx_rcv_queue_process( int dfx_xmt_queue_pkt( struct sk_buff *skb, - struct device *dev + struct net_device *dev ) { @@ -3294,7 +3295,7 @@ int dfx_xmt_queue_pkt( * wide. */ - p_xmt_descr->long_0 = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len + 3) << PI_XMT_DESCR_V_SEG_LEN)); + p_xmt_descr->long_0 = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len) << PI_XMT_DESCR_V_SEG_LEN)); p_xmt_descr->long_1 = (u32) virt_to_bus(skb->data); /* diff --git a/drivers/net/defxx.h b/drivers/net/defxx.h index 2681188d4..d602b2589 100644 --- a/drivers/net/defxx.h +++ b/drivers/net/defxx.h @@ -1755,7 +1755,7 @@ typedef struct DFX_board_tag /* Store device, bus-specific, and parameter information for this adapter */ - struct device *dev; /* pointer to device structure */ + struct net_device *dev; /* pointer to device structure */ u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */ u16 base_addr; /* base I/O address (same as dev->base_addr) */ struct pci_dev * pci_dev; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 1be3c5dda..bfcc78744 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -416,39 +416,39 @@ struct depca_private { /* ** Public Functions */ -static int depca_open(struct device *dev); -static int depca_start_xmit(struct sk_buff *skb, struct device *dev); +static int depca_open(struct net_device *dev); +static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev); static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int depca_close(struct device *dev); -static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *depca_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int depca_close(struct net_device *dev); +static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct net_device_stats *depca_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* ** Private functions */ -static int depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot); -static void depca_init_ring(struct device *dev); -static int depca_rx(struct device *dev); -static int depca_tx(struct device *dev); +static int depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot); +static void depca_init_ring(struct net_device *dev); +static int depca_rx(struct net_device *dev); +static int depca_tx(struct net_device *dev); -static void LoadCSRs(struct device *dev); -static int InitRestartDepca(struct device *dev); +static void LoadCSRs(struct net_device *dev); +static int InitRestartDepca(struct net_device *dev); static void DepcaSignature(char *name, u_long paddr); static int DevicePresent(u_long ioaddr); -static int get_hw_addr(struct device *dev); +static int get_hw_addr(struct net_device *dev); static int EISA_signature(char *name, s32 eisa_id); -static void SetMulticastFilter(struct device *dev); -static void isa_probe(struct device *dev, u_long iobase); -static void eisa_probe(struct device *dev, u_long iobase); +static void SetMulticastFilter(struct net_device *dev); +static void isa_probe(struct net_device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); #ifdef CONFIG_MCA -static void mca_probe(struct device *dev, u_long iobase); +static void mca_probe(struct net_device *dev, u_long iobase); #endif -static struct device *alloc_device(struct device *dev, u_long iobase); +static struct net_device *alloc_device(struct net_device *dev, u_long iobase); static int depca_dev_index(char *s); -static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)); -static int load_packet(struct device *dev, struct sk_buff *skb); -static void depca_dbg_open(struct device *dev); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)); +static int load_packet(struct net_device *dev, struct sk_buff *skb); +static void depca_dbg_open(struct net_device *dev); #ifdef MODULE int init_module(void); @@ -477,7 +477,7 @@ static char *adapter_name = '\0'; /* If no PROM when loadable module outw(STOP, DEPCA_DATA) int __init -depca_probe(struct device *dev) +depca_probe(struct net_device *dev) { int tmp = num_depcas, status = -ENODEV; u_long iobase = dev->base_addr; @@ -511,7 +511,7 @@ depca_probe(struct device *dev) } static int __init -depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot) +depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot) { struct depca_private *lp; int i, j, offset, netRAM, mem_len, status=0; @@ -723,7 +723,7 @@ depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot) static int -depca_open(struct device *dev) +depca_open(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -774,7 +774,7 @@ depca_open(struct device *dev) /* Initialize the lance Rx and Tx descriptor rings. */ static void -depca_init_ring(struct device *dev) +depca_init_ring(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_int i; @@ -817,7 +817,7 @@ depca_init_ring(struct device *dev) ** Writes a socket buffer to TX descriptor ring and starts transmission */ static int -depca_start_xmit(struct sk_buff *skb, struct device *dev) +depca_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -877,7 +877,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev) static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct depca_private *lp; s16 csr0, nicsr; u_long ioaddr; @@ -926,7 +926,7 @@ depca_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static int -depca_rx(struct device *dev) +depca_rx(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; int i, entry; @@ -1026,7 +1026,7 @@ depca_rx(struct device *dev) ** Buffer sent - check for buffer errors. */ static int -depca_tx(struct device *dev) +depca_tx(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; int entry; @@ -1064,7 +1064,7 @@ depca_tx(struct device *dev) } static int -depca_close(struct device *dev) +depca_close(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; s16 nicsr; @@ -1105,7 +1105,7 @@ depca_close(struct device *dev) return 0; } -static void LoadCSRs(struct device *dev) +static void LoadCSRs(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1122,7 +1122,7 @@ static void LoadCSRs(struct device *dev) return; } -static int InitRestartDepca(struct device *dev) +static int InitRestartDepca(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1154,7 +1154,7 @@ static int InitRestartDepca(struct device *dev) } static struct net_device_stats * -depca_get_stats(struct device *dev) +depca_get_stats(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; @@ -1167,7 +1167,7 @@ depca_get_stats(struct device *dev) ** Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1199,7 +1199,7 @@ set_multicast_list(struct device *dev) ** Big endian crc one liner is mine, all mine, ha ha ha ha! ** LANCE calculates its hash codes big endian. */ -static void SetMulticastFilter(struct device *dev) +static void SetMulticastFilter(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; struct dev_mc_list *dmi=dev->mc_list; @@ -1249,7 +1249,7 @@ static void SetMulticastFilter(struct device *dev) ** Microchannel bus I/O device probe */ static void __init -mca_probe(struct device *dev, u_long ioaddr) +mca_probe(struct net_device *dev, u_long ioaddr) { unsigned char pos[2]; unsigned char where; @@ -1398,7 +1398,7 @@ responding.\n", dev->name, iobase); ** ISA bus I/O device probe */ static void __init -isa_probe(struct device *dev, u_long ioaddr) +isa_probe(struct net_device *dev, u_long ioaddr) { int i = num_depcas, maxSlots; s32 ports[] = DEPCA_IO_PORTS; @@ -1437,7 +1437,7 @@ isa_probe(struct device *dev, u_long ioaddr) ** the motherboard. Upto 15 EISA devices are supported. */ static void __init -eisa_probe(struct device *dev, u_long ioaddr) +eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots; u_long iobase; @@ -1483,10 +1483,10 @@ eisa_probe(struct device *dev, u_long ioaddr) ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * __init -alloc_device(struct device *dev, u_long iobase) +static struct net_device * __init +alloc_device(struct net_device *dev, u_long iobase) { - struct device *adev = NULL; + struct net_device *adev = NULL; int fixed = 0, new_dev = 0; num_eth = depca_dev_index(dev->name); @@ -1528,12 +1528,12 @@ alloc_device(struct device *dev, u_long iobase) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * __init -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +static struct net_device * __init +insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL); if (new == NULL) { printk("eth%d: Device not initialised, insufficient memory\n",num_eth); return NULL; @@ -1681,7 +1681,7 @@ DevicePresent(u_long ioaddr) ** with x=1. */ static int __init -get_hw_addr(struct device *dev) +get_hw_addr(struct net_device *dev) { u_long ioaddr = dev->base_addr; int i, k, tmp, status = 0; @@ -1712,7 +1712,7 @@ get_hw_addr(struct device *dev) /* ** Load a packet into the shared memory */ -static int load_packet(struct device *dev, struct sk_buff *skb) +static int load_packet(struct net_device *dev, struct sk_buff *skb) { struct depca_private *lp = (struct depca_private *)dev->priv; int i, entry, end, len, status = 0; @@ -1801,7 +1801,7 @@ EISA_signature(char *name, s32 eisa_id) return status; } -static void depca_dbg_open(struct device *dev) +static void depca_dbg_open(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1880,7 +1880,7 @@ static void depca_dbg_open(struct device *dev) ** effective uid is checked in those cases. ** All multicast IOCTLs will not work here and are for testing purposes only. */ -static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct depca_private *lp = (struct depca_private *)dev->priv; struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data; @@ -2015,7 +2015,7 @@ static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd) #ifdef MODULE static char devicename[9] = {0,}; -static struct device thisDepca = { +static struct net_device thisDepca = { devicename, /* device name is inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x200, 7, /* I/O address, IRQ */ diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index 8588a8b4a..2558f2a91 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -183,7 +183,7 @@ int dgrs_nicmode = 0; * Chain of device structures */ #ifdef MODULE - static struct device *dgrs_root_dev = NULL; + static struct net_device *dgrs_root_dev = NULL; #endif /* @@ -195,7 +195,7 @@ typedef struct * Stuff for generic ethercard I/F */ char devname[8]; /* "ethN" string */ - struct device *next_dev; + struct net_device *next_dev; struct net_device_stats stats; /* @@ -240,7 +240,7 @@ typedef struct */ int nports; /* Number of physical ports (4 or 6) */ int chan; /* Channel # (1-6) for this device */ - struct device *devtbl[6]; /* Ptrs to N device structs */ + struct net_device *devtbl[6]; /* Ptrs to N device structs */ } DGRS_PRIV; @@ -249,7 +249,7 @@ typedef struct * reset or un-reset the IDT processor */ static void -proc_reset(struct device *dev0, int reset) +proc_reset(struct net_device *dev0, int reset) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; @@ -273,7 +273,7 @@ proc_reset(struct device *dev0, int reset) * See if the board supports bus master DMA */ static int -check_board_dma(struct device *dev0) +check_board_dma(struct net_device *dev0) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; ulong x; @@ -347,7 +347,7 @@ check_board_dma(struct device *dev0) */ static int do_plx_dma( - struct device *dev, + struct net_device *dev, ulong pciaddr, ulong lcladdr, int len, @@ -453,7 +453,7 @@ do_plx_dma( */ void dgrs_rcv_frame( - struct device *dev0, + struct net_device *dev0, DGRS_PRIV *priv0, I596_CB *cbp ) @@ -463,7 +463,7 @@ dgrs_rcv_frame( struct sk_buff *skb; uchar *putp; uchar *p; - struct device *devN; + struct net_device *devN; DGRS_PRIV *privN; /* @@ -689,10 +689,10 @@ out: * end of the traditional 82596 RFD structure. */ -static int dgrs_start_xmit(struct sk_buff *skb, struct device *devN) +static int dgrs_start_xmit(struct sk_buff *skb, struct net_device *devN) { DGRS_PRIV *privN = (DGRS_PRIV *) devN->priv; - struct device *dev0; + struct net_device *dev0; DGRS_PRIV *priv0; I596_RBD *rbdp; int count; @@ -788,7 +788,7 @@ no_resources: * Open the interface */ static int -dgrs_open( struct device *dev ) +dgrs_open( struct net_device *dev ) { dev->tbusy = 0; dev->interrupt = 0; @@ -804,7 +804,7 @@ dgrs_open( struct device *dev ) /* * Close the interface */ -static int dgrs_close( struct device *dev ) +static int dgrs_close( struct net_device *dev ) { dev->start = 0; dev->tbusy = 1; @@ -819,7 +819,7 @@ static int dgrs_close( struct device *dev ) /* * Get statistics */ -static struct net_device_stats *dgrs_get_stats( struct device *dev ) +static struct net_device_stats *dgrs_get_stats( struct net_device *dev ) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; @@ -830,7 +830,7 @@ static struct net_device_stats *dgrs_get_stats( struct device *dev ) * Set multicast list and/or promiscuous mode */ -static void dgrs_set_multicast_list( struct device *dev) +static void dgrs_set_multicast_list( struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; @@ -840,7 +840,7 @@ static void dgrs_set_multicast_list( struct device *dev) /* * Unique ioctl's */ -static int dgrs_ioctl(struct device *devN, struct ifreq *ifr, int cmd) +static int dgrs_ioctl(struct net_device *devN, struct ifreq *ifr, int cmd) { DGRS_PRIV *privN = (DGRS_PRIV *) devN->priv; DGRS_IOCTL ioc; @@ -905,7 +905,7 @@ static int dgrs_ioctl(struct device *devN, struct ifreq *ifr, int cmd) static void dgrs_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev0 = (struct device *) dev_id; + struct net_device *dev0 = (struct net_device *) dev_id; DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; I596_CB *cbp; int cmd; @@ -992,7 +992,7 @@ ack_intr: * Download the board firmware */ static int __init -dgrs_download(struct device *dev0) +dgrs_download(struct net_device *dev0) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; int is; @@ -1151,7 +1151,7 @@ dgrs_download(struct device *dev0) * Probe (init) a board */ int __init -dgrs_probe1(struct device *dev) +dgrs_probe1(struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1225,7 +1225,7 @@ dgrs_probe1(struct device *dev) } int __init -dgrs_initclone(struct device *dev) +dgrs_initclone(struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1241,7 +1241,7 @@ dgrs_initclone(struct device *dev) static int __init dgrs_found_device( - struct device *dev, + struct net_device *dev, int io, ulong mem, int irq, @@ -1254,12 +1254,12 @@ dgrs_found_device( #ifdef MODULE { /* Allocate and fill new device structure. */ - int dev_size = sizeof(struct device) + sizeof(DGRS_PRIV); + int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV); int i; - dev = (struct device *) kmalloc(dev_size, GFP_KERNEL); + dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); memset(dev, 0, dev_size); - dev->priv = ((void *)dev) + sizeof(struct device); + dev->priv = ((void *)dev) + sizeof(struct net_device); priv = (DGRS_PRIV *)dev->priv; dev->name = priv->devname; /* An empty string. */ @@ -1291,15 +1291,15 @@ dgrs_found_device( priv->nports = priv->bcomm->bc_nports; for (i = 1; i < priv->nports; ++i) { - struct device *devN; + struct net_device *devN; DGRS_PRIV *privN; /* Allocate new dev and priv structures */ - devN = (struct device *) kmalloc(dev_size, GFP_KERNEL); + devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); /* Make it an exact copy of dev[0]... */ memcpy(devN, dev, dev_size); - devN->priv = ((void *)devN) + sizeof(struct device); + devN->priv = ((void *)devN) + sizeof(struct net_device); privN = (DGRS_PRIV *)devN->priv; /* ... but seset devname to a NULL string */ @@ -1361,7 +1361,7 @@ dgrs_found_device( static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; static int __init -dgrs_scan(struct device *dev) +dgrs_scan(struct net_device *dev) { int cards_found = 0; uint io; @@ -1395,28 +1395,14 @@ dgrs_scan(struct device *dev) &pci_device_fn)) break; -#if LINUX_VERSION_CODE < 0x20100 - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &plxreg); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &io); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_2, &mem); -#else pdev = pci_find_slot(pci_bus, pci_device_fn); pci_irq = pdev->irq; - plxreg = pdev->base_address[0]; - io = pdev->base_address[1]; - mem = pdev->base_address[2]; -#endif + plxreg = pdev->resource[0].start; + io = pdev->resource[1].start; + mem = pdev->resource[2].start; pcibios_read_config_dword(pci_bus, pci_device_fn, 0x30, &plxdma); irq = pci_irq; - plxreg &= ~15; - io &= ~3; - mem &= ~15; plxdma &= ~15; /* @@ -1588,7 +1574,7 @@ cleanup_module(void) { while (dgrs_root_dev) { - struct device *next_dev; + struct net_device *next_dev; DGRS_PRIV *priv; priv = (DGRS_PRIV *) dgrs_root_dev->priv; @@ -1615,7 +1601,7 @@ cleanup_module(void) #else int __init -dgrs_probe(struct device *dev) +dgrs_probe(struct net_device *dev) { int cards_found; diff --git a/drivers/net/dlci.c b/drivers/net/dlci.c index 9d177a0b7..a8c52f0d6 100644 --- a/drivers/net/dlci.c +++ b/drivers/net/dlci.c @@ -60,11 +60,11 @@ static const char *devname = "dlci"; static const char *version = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org"; -static struct device *open_dev[CONFIG_DLCI_COUNT]; +static struct net_device *open_dev[CONFIG_DLCI_COUNT]; static char *basename[16]; -int dlci_init(struct device *dev); +int dlci_init(struct net_device *dev); /* allow FRAD's to register their name as a valid FRAD */ int register_frad(const char *name) @@ -122,7 +122,7 @@ int unregister_frad(const char *name) * the upper network layers */ -static int dlci_header(struct sk_buff *skb, struct device *dev, +static int dlci_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -161,7 +161,7 @@ static int dlci_header(struct sk_buff *skb, struct device *dev, return(hlen); } -static void dlci_receive(struct sk_buff *skb, struct device *dev) +static void dlci_receive(struct sk_buff *skb, struct net_device *dev) { struct dlci_local *dlp; struct frhdr *hdr; @@ -234,7 +234,7 @@ static void dlci_receive(struct sk_buff *skb, struct device *dev) dev_kfree_skb(skb); } -static int dlci_transmit(struct sk_buff *skb, struct device *dev) +static int dlci_transmit(struct sk_buff *skb, struct net_device *dev) { struct dlci_local *dlp; int ret; @@ -284,7 +284,7 @@ static int dlci_transmit(struct sk_buff *skb, struct device *dev) return(ret); } -int dlci_config(struct device *dev, struct dlci_conf *conf, int get) +int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get) { struct dlci_conf config; struct dlci_local *dlp; @@ -318,7 +318,7 @@ int dlci_config(struct device *dev, struct dlci_conf *conf, int get) return(0); } -int dlci_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct dlci_local *dlp; @@ -350,7 +350,7 @@ int dlci_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) return(0); } -static int dlci_change_mtu(struct device *dev, int new_mtu) +static int dlci_change_mtu(struct net_device *dev, int new_mtu) { struct dlci_local *dlp; @@ -359,7 +359,7 @@ static int dlci_change_mtu(struct device *dev, int new_mtu) return((*dlp->slave->change_mtu)(dlp->slave, new_mtu)); } -static int dlci_open(struct device *dev) +static int dlci_open(struct net_device *dev) { struct dlci_local *dlp; struct frad_local *flp; @@ -386,7 +386,7 @@ static int dlci_open(struct device *dev) return 0; } -static int dlci_close(struct device *dev) +static int dlci_close(struct net_device *dev) { struct dlci_local *dlp; struct frad_local *flp; @@ -403,7 +403,7 @@ static int dlci_close(struct device *dev) return 0; } -static struct net_device_stats *dlci_get_stats(struct device *dev) +static struct net_device_stats *dlci_get_stats(struct net_device *dev) { struct dlci_local *dlp; @@ -414,14 +414,14 @@ static struct net_device_stats *dlci_get_stats(struct device *dev) int dlci_add(struct dlci_add *dlci) { - struct device *master, *slave; + struct net_device *master, *slave; struct dlci_local *dlp; struct frad_local *flp; int err, i; char buf[10]; /* validate slave device */ - slave = dev_get(dlci->devname); + slave = __dev_get_by_name(dlci->devname); if (!slave) return(-ENODEV); @@ -500,11 +500,11 @@ int dlci_del(struct dlci_add *dlci) { struct dlci_local *dlp; struct frad_local *flp; - struct device *master, *slave; + struct net_device *master, *slave; int i, err; /* validate slave device */ - master = dev_get(dlci->devname); + master = __dev_get_by_name(dlci->devname); if (!master) return(-ENODEV); @@ -569,7 +569,7 @@ int dlci_ioctl(unsigned int cmd, void *arg) return(err); } -int dlci_init(struct device *dev) +int dlci_init(struct net_device *dev) { struct dlci_local *dlp; diff --git a/drivers/net/dmfe.c b/drivers/net/dmfe.c new file mode 100644 index 000000000..81cb3edb2 --- /dev/null +++ b/drivers/net/dmfe.c @@ -0,0 +1,1517 @@ +/* + dmfe.c: Version 1.26 + + A Davicom DM9102 fast ethernet driver for Linux. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 1. + + Compiler command: + "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall + -Wstrict-prototypes -O6 -c dmfe.c" + + The following steps teach you how to active DM9102 board: + 1. Used the upper compiler command to compile dmfe.c + 2. insert dmfe module into kernel + "insmod dmfe" ;;Auto Detection Mode + "insmod dmfe mode=0" ;;Force 10M Half Duplex + "insmod dmfe mode=1" ;;Force 100M Half Duplex + "insmod dmfe mode=4" ;;Force 10M Full Duplex + "insmod dmfe mode=5" ;;Force 100M Full Duplex + 3. config a dm9102 network interface + "ifconfig eth0 172.22.3.18" + 4. active the IP routing table + "route add -net 172.22.3.0 eth0" + 5. Well done. Your DM9102 adapter actived now. + + Author: Sten Wang, E-mail: sten_wang@davicom.com.tw + + Date: 10/28,1998 + + (C)Copyright 1997-1998 DAVICOM Semiconductor, Inc. All Rights Reserved. + + Marcelo Tosatti <marcelo@conectiva.com.br> : + Made it compile in 2.3 (device to net_device) + + Alan Cox <alan@redhat.com> : + Removed the back compatibility support + Reformatted, fixing spelling etc as I went + Removed IRQ 0-15 assumption + + TODO + + Check and fix on 64bit and big endian boxes. + Sort out the PCI latency. + + */ + +#include <linux/config.h> +#include <linux/module.h> + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/malloc.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/version.h> + +#include <linux/delay.h> +#include <asm/processor.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/dma.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> + + +/* Board/System/Debug information/definition ---------------- */ +#define PCI_DM9102_ID 0x91021282 /* Davicom DM9102 ID */ +#define PCI_DM9100_ID 0x91001282 /* Davicom DM9100 ID */ + +#define DMFE_SUCC 0 +#define DM9102_IO_SIZE 0x80 +#define TX_FREE_DESC_CNT 0x1 /* Tx packet count */ +#define TX_DESC_CNT 0x10 /* Allocated Tx descriptors */ +#define RX_DESC_CNT 0x10 /* Allocated Rx descriptors */ +#define DESC_ALL_CNT TX_DESC_CNT+RX_DESC_CNT +#define TX_BUF_ALLOC 0x600 +#define RX_ALLOC_SIZE 0x620 +#define DM910X_RESET 1 +#define CR6_DEFAULT 0x002c0000 /* SF, MII, HD */ +#define CR7_DEFAULT 0x1a2cd +#define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ +#define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ +#define MAX_PACKET_SIZE 1514 +#define DMFE_MAX_MULTICAST 14 +#define RX_MAX_TRAFFIC 0x5000 +#define MAX_CHECK_PACKET 0x8000 + +#define DMFE_10MHF 0 +#define DMFE_100MHF 1 +#define DMFE_10MFD 4 +#define DMFE_100MFD 5 +#define DMFE_AUTO 8 + +#define DMFE_TIMER_WUT jiffies+HZ*1 /* timer wakeup time : 1 second */ +#define DMFE_TX_TIMEOUT HZ*2 /* tx packet time-out time */ + +#define DMFE_DBUG(dbug_now, msg, vaule) if (dmfe_debug || dbug_now) printk("DBUG: %s %x\n", msg, vaule) + +#define DELAY_5US udelay(5) /* udelay scale 1 usec */ + +#define DELAY_1US udelay(1) /* udelay scale 1 usec */ + +#define SHOW_MEDIA_TYPE(mode) printk("\n<WARN> Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); + + +/* CR9 definition: SROM/MII */ +#define CR9_SROM_READ 0x4800 +#define CR9_SRCS 0x1 +#define CR9_SRCLK 0x2 +#define CR9_CRDOUT 0x8 +#define SROM_DATA_0 0x0 +#define SROM_DATA_1 0x4 +#define PHY_DATA_1 0x20000 +#define PHY_DATA_0 0x00000 +#define MDCLKH 0x10000 + +#define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);DELAY_5US;outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);DELAY_5US;outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);DELAY_5US; + +/* Structure/enum declaration ------------------------------- */ +struct tx_desc { + u32 tdes0, tdes1, tdes2, tdes3; + u32 tx_skb_ptr; + u32 tx_buf_ptr; + u32 next_tx_desc; + u32 reserved; +}; + +struct rx_desc { + u32 rdes0, rdes1, rdes2, rdes3; + u32 rx_skb_ptr; + u32 rx_buf_ptr; + u32 next_rx_desc; + u32 reserved; +}; + +struct dmfe_board_info { + u32 chip_id; /* Chip vendor/Device ID */ + u32 chip_revesion; /* Chip revesion */ + struct net_device *next_dev; /* next device */ + + struct pci_dev *net_dev; /* PCI device */ + + u32 ioaddr; /* I/O base address */ + u32 cr5_data; + u32 cr6_data; + u32 cr7_data; + u32 cr15_data; + +/* descriptor pointer */ + unsigned char *buf_pool_ptr; /* Tx buffer pool memory */ + unsigned char *buf_pool_start; /* Tx buffer pool align dword */ + unsigned char *desc_pool_ptr; /* descriptor pool memory */ + struct tx_desc *first_tx_desc; + struct tx_desc *tx_insert_ptr; + struct tx_desc *tx_remove_ptr; + struct rx_desc *first_rx_desc; + struct rx_desc *rx_insert_ptr; + struct rx_desc *rx_ready_ptr; /* packet come pointer */ + u32 tx_packet_cnt; /* transmitted packet count */ + u32 rx_avail_cnt; /* available rx descriptor count */ + u32 interval_rx_cnt; /* rx packet count a callback time */ + + u8 media_mode; /* user specify media mode */ + u8 op_mode; /* real work media mode */ + u8 phy_addr; + u8 link_failed; /* Ever link failed */ + u8 wait_reset; /* Hardware failed, need to reset */ + u8 in_reset_state; /* Now driver in reset routine */ + u8 rx_error_cnt; /* recievd abnormal case count */ + u8 dm910x_chk_mode; /* Operating mode check */ + struct timer_list timer; + struct enet_statistics stats; /* statistic counter */ + unsigned char srom[128]; +}; + +enum dmfe_offsets { + DCR0 = 0, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, DCR5 = 0x28, + DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, DCR10 = 0x50, DCR11 = 0x58, + DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70, DCR15 = 0x78 +}; + +enum dmfe_CR6_bits { + CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, CR6_FDM = 0x200, + CR6_TXSC = 0x2000, CR6_STI = 0x100000, CR6_SFT = 0x200000, CR6_RXA = 0x40000000 +}; + +/* Global variable declaration ----------------------------- */ + +static int dmfe_debug = 0; +static unsigned char dmfe_media_mode = 8; +static struct net_device *dmfe_root_dev = NULL; /* First device */ +static u32 dmfe_cr6_user_set = 0; + +/* For module input parameter */ +static int debug = 0; +static u32 cr6set = 0; +static unsigned char mode = 8; +static u8 chkmode = 1; + +unsigned long CrcTable[256] = +{ + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL +}; + +/* function declaration ------------------------------------- */ +int dmfe_reg_board(struct net_device *); +static int dmfe_open(struct net_device *); +static int dmfe_start_xmit(struct sk_buff *, struct net_device *); +static int dmfe_stop(struct net_device *); +static struct enet_statistics *dmfe_get_stats(struct net_device *); +static void dmfe_set_filter_mode(struct net_device *); +static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int); +static u16 read_srom_word(long, int); +static void dmfe_interrupt(int, void *, struct pt_regs *); +static void dmfe_descriptor_init(struct dmfe_board_info *, u32); +static void allocated_rx_buffer(struct dmfe_board_info *); +static void update_cr6(u32, u32); +static void send_filter_frame(struct net_device *, int); +static u16 phy_read(u32, u8, u8); +static void phy_write(u32, u8, u8, u16); +static void phy_write_1bit(u32, u32); +static u16 phy_read_1bit(u32); +static void parser_ctrl_info(struct dmfe_board_info *); +static void dmfe_sense_speed(struct dmfe_board_info *); +static void dmfe_process_mode(struct dmfe_board_info *); +static void dmfe_timer(unsigned long); +static void dmfe_rx_packet(struct net_device *, struct dmfe_board_info *); +static void dmfe_reused_skb(struct dmfe_board_info *, struct sk_buff *); +static void dmfe_dynamic_reset(struct net_device *); +static void dmfe_free_rxbuffer(struct dmfe_board_info *); +static void dmfe_init_dm910x(struct net_device *); +static unsigned long cal_CRC(unsigned char *, unsigned int); + +/* DM910X network board routine ---------------------------- */ + +/* + * Search DM910X board, allocate space and register it + */ + +int dmfe_reg_board(struct net_device *dev) +{ + u32 pci_iobase; + u16 dm9102_count = 0; + u8 pci_irqline; + static int index = 0; /* For multiple call */ + struct dmfe_board_info *db; /* Point a board information structure */ + int i; + struct pci_dev *net_dev = NULL; + + DMFE_DBUG(0, "dmfe_reg_board()", 0); + + if (!pci_present()) + return -ENODEV; + + index = 0; + while ((net_dev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, net_dev))) + { + u32 pci_id; + u8 pci_cmd; + + index++; + if (pci_read_config_dword(net_dev, PCI_VENDOR_ID, &pci_id) != DMFE_SUCC) + continue; + + if (pci_id != PCI_DM9102_ID) + continue; + + pci_iobase = net_dev->resource[0].start; + pci_irqline = net_dev->irq; + + /* Enable Master/IO access, Disable memory access */ + + pci_set_master(net_dev); + + pci_read_config_byte(net_dev, PCI_COMMAND, &pci_cmd); + pci_cmd |= PCI_COMMAND_IO; + pci_cmd &= ~PCI_COMMAND_MEMORY; + pci_write_config_byte(net_dev, PCI_COMMAND, pci_cmd); + + /* Set Latency Timer 80h */ + + /* FIXME: setting values > 32 breaks some SiS 559x stuff. + Need a PCI quirk.. */ + + pci_write_config_byte(net_dev, PCI_LATENCY_TIMER, 0x80); + + /* IO range and interrupt check */ + + if (check_region(pci_iobase, DM9102_IO_SIZE)) /* IO range check */ + continue; + + /* Found DM9102 card and PCI resource allocated OK */ + dm9102_count++; /* Found a DM9102 card */ + + /* Init network device */ + dev = init_etherdev(dev, 0); + + /* Allocated board information structure */ + db = (void *) (kmalloc(sizeof(*db), GFP_KERNEL | GFP_DMA)); + if(db==NULL) + continue; /* Out of memory */ + + memset(db, 0, sizeof(*db)); + dev->priv = db; /* link device and board info */ + db->next_dev = dmfe_root_dev; + dmfe_root_dev = dev; + + db->chip_id = pci_id; /* keep Chip vandor/Device ID */ + db->ioaddr = pci_iobase; + pci_read_config_dword(net_dev, 8, &db->chip_revesion); + + db->net_dev = net_dev; + + dev->base_addr = pci_iobase; + dev->irq = pci_irqline; + dev->open = &dmfe_open; + dev->hard_start_xmit = &dmfe_start_xmit; + dev->stop = &dmfe_stop; + dev->get_stats = &dmfe_get_stats; + dev->set_multicast_list = &dmfe_set_filter_mode; + dev->do_ioctl = &dmfe_do_ioctl; + + request_region(pci_iobase, DM9102_IO_SIZE, dev->name); + + /* read 64 word srom data */ + for (i = 0; i < 64; i++) + ((u16 *) db->srom)[i] = read_srom_word(pci_iobase, i); + + /* Set Node address */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = db->srom[20 + i]; + + dev = 0; /* NULL device */ + } + +#ifdef MODULE + if (!dm9102_count) + printk(KERN_WARNING "dmfe: Can't find DM910X board\n"); +#endif + return dm9102_count ? 0 : -ENODEV; +} + +/* + * Open the interface. + * The interface is opened whenever "ifconfig" actives it. + */ + +static int dmfe_open(struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + + DMFE_DBUG(0, "dmfe_open", 0); + + if (request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev)) + return -EAGAIN; + + /* Allocated Tx/Rx descriptor memory */ + db->desc_pool_ptr = kmalloc(sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, GFP_KERNEL | GFP_DMA); + if (db->desc_pool_ptr == NULL) + return -ENOMEM; + + if ((u32) db->desc_pool_ptr & 0x1f) + db->first_tx_desc = (struct tx_desc *) (((u32) db->desc_pool_ptr & ~0x1f) + 0x20); + else + db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr; + + /* Allocated Tx buffer memory */ + + db->buf_pool_ptr = kmalloc(TX_BUF_ALLOC * TX_DESC_CNT + 4, GFP_KERNEL | GFP_DMA); + if (db->buf_pool_ptr == NULL) { + kfree(db->desc_pool_ptr); + return -ENOMEM; + } + + if ((u32) db->buf_pool_ptr & 0x3) + db->buf_pool_start = (char *) (((u32) db->buf_pool_ptr & ~0x3) + 0x4); + else + db->buf_pool_start = db->buf_pool_ptr; + + /* system variable init */ + db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set; + db->tx_packet_cnt = 0; + db->rx_avail_cnt = 0; + db->link_failed = 0; + db->wait_reset = 0; + db->in_reset_state = 0; + db->rx_error_cnt = 0; + + if (chkmode && (db->chip_revesion < 0x02000030)) { + db->dm910x_chk_mode = 1; /* Enter the check mode */ + } else { + db->dm910x_chk_mode = 4; /* Enter the normal mode */ + } + + /* Initilize DM910X board */ + dmfe_init_dm910x(dev); + + /* Active System Interface */ + dev->tbusy = 0; /* Can transmit packet */ + dev->start = 1; /* interface ready */ + MOD_INC_USE_COUNT; + + /* set and active a timer process */ + init_timer(&db->timer); + db->timer.expires = DMFE_TIMER_WUT; + db->timer.data = (unsigned long) dev; + db->timer.function = &dmfe_timer; + add_timer(&db->timer); + + return 0; +} + +/* + * Initialize DM910X board + * Reset DM910X board + * Initialize TX/Rx descriptor chain structure + * Send the set-up frame + * Enable Tx/Rx machine + */ + +static void dmfe_init_dm910x(struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + u32 ioaddr = db->ioaddr; + + DMFE_DBUG(0, "dmfe_init_dm910x()", 0); + + /* Reset DM910x board : need 32 PCI clock to complete */ + outl(DM910X_RESET, ioaddr + DCR0); + DELAY_5US; + outl(0, ioaddr + DCR0); + + outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */ + outl(0x80, ioaddr + DCR12); /* Reset DM9102 phyxcer */ + outl(0x0, ioaddr + DCR12); /* Clear RESET signal */ + + /* Parser control information: Phy addr */ + parser_ctrl_info(db); + db->media_mode = dmfe_media_mode; + if (db->media_mode & DMFE_AUTO) + dmfe_sense_speed(db); + else + db->op_mode = db->media_mode; + dmfe_process_mode(db); + + /* Initiliaze Transmit/Receive decriptor and CR3/4 */ + dmfe_descriptor_init(db, ioaddr); + + /* Init CR6 to program DM910x operation */ + update_cr6(db->cr6_data, ioaddr); + + /* Send setup frame */ + send_filter_frame(dev, 0); + + /* Init CR5/CR7, interrupt active bit */ + outl(0xffffffff, ioaddr + DCR5); /* clear all CR5 status */ + db->cr7_data = CR7_DEFAULT; + outl(db->cr7_data, ioaddr + DCR7); + + /* Init CR15, Tx jabber and Rx watchdog timer */ + db->cr15_data = CR15_DEFAULT; + outl(db->cr15_data, ioaddr + DCR15); + + /* Enable DM910X Tx/Rx function */ + db->cr6_data |= CR6_RXSC | CR6_TXSC; + update_cr6(db->cr6_data, ioaddr); + +} + + +/* + * Hardware start transmission. + * Send a packet to media from the upper layer. + */ + +static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + struct tx_desc *txptr; + + DMFE_DBUG(0, "dmfe_start_xmit", 0); + + if ((dev->tbusy == 1) && (db->tx_packet_cnt != 0)) + return 1; + else + dev->tbusy = 0; + + /* Too large packet check */ + if (skb->len > MAX_PACKET_SIZE) { + printk(KERN_ERR "%s: oversized frame (%d bytes) received.\n", dev->name, (u16) skb->len); + dev_kfree_skb(skb); + return 0; + } + /* No Tx resource check, it never happen nromally */ + if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) { + printk(KERN_WARNING "%s: No Tx resource, enter xmit() again \n", dev->name); + dev_kfree_skb(skb); + dev->tbusy = 1; + return -EBUSY; + } + + /* transmit this packet */ + txptr = db->tx_insert_ptr; + memcpy((char *) txptr->tx_buf_ptr, (char *) skb->data, skb->len); + txptr->tdes1 = 0xe1000000 | skb->len; + txptr->tdes0 = 0x80000000; /* set owner bit to DM910X */ + + /* Point to next transmit free descriptor */ + db->tx_insert_ptr = (struct tx_desc *) txptr->next_tx_desc; + + /* transmit counter increase 1 */ + db->tx_packet_cnt++; + db->stats.tx_packets++; + + /* issue Tx polling command */ + outl(0x1, dev->base_addr + DCR1); + + /* Tx resource check */ + if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) + dev->tbusy = 1; + + /* Set transmit time stamp */ + dev->trans_start = jiffies; /* saved the time stamp */ + + /* free this SKB */ + dev_kfree_skb(skb); + return 0; +} + +/* + * Stop the interface. + * The interface is stopped when it is brought. + */ + +static int dmfe_stop(struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + u32 ioaddr = dev->base_addr; + + DMFE_DBUG(0, "dmfe_stop", 0); + + /* disable system */ + dev->start = 0; /* interface disable */ + dev->tbusy = 1; /* can't transmit */ + + /* Reset & stop DM910X board */ + outl(DM910X_RESET, ioaddr + DCR0); + DELAY_5US; + + /* deleted timer */ + del_timer(&db->timer); + + /* free interrupt */ + free_irq(dev->irq, dev); + + /* free allocated rx buffer */ + dmfe_free_rxbuffer(db); + + /* free all descriptor memory and buffer memory */ + kfree(db->desc_pool_ptr); + kfree(db->buf_pool_ptr); + + MOD_DEC_USE_COUNT; + + return 0; +} + +/* + * DM9102 insterrupt handler + * receive the packet to upper layer, free the transmitted packet + */ + +static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct tx_desc *txptr; + struct dmfe_board_info *db; + u32 ioaddr; + + if (!dev) { + DMFE_DBUG(1, "dmfe_interrupt() without device arg", 0); + return; + } + if (dev->interrupt) { + DMFE_DBUG(1, "dmfe_interrupt() re-entry ", 0); + return; + } + + /* A real interrupt coming */ + dev->interrupt = 1; /* Lock interrupt */ + db = (struct dmfe_board_info *) dev->priv; + ioaddr = dev->base_addr; + + DMFE_DBUG(0, "dmfe_interrupt()", 0); + + /* Disable all interrupt in CR7 to solve the interrupt edge problem */ + outl(0, ioaddr + DCR7); + + /* Got DM910X status */ + db->cr5_data = inl(ioaddr + DCR5); + outl(db->cr5_data, ioaddr + DCR5); + /* printk("CR5=%x\n", db->cr5_data); */ + + /* Check system status */ + if (db->cr5_data & 0x2000) { + /* A system bus error occurred */ + DMFE_DBUG(1, "A system bus error occurred. CR5=", db->cr5_data); + dev->tbusy = 1; + db->wait_reset = 1; /* Need to RESET */ + outl(0, ioaddr + DCR7); /* disable all interrupt */ + dev->interrupt = 0; /* unlock interrupt */ + return; + } + /* Free the transmitted descriptor */ + txptr = db->tx_remove_ptr; + while (db->tx_packet_cnt) { + /* printk("tdes0=%x\n", txptr->tdes0); */ + if (txptr->tdes0 & 0x80000000) + break; + if ((txptr->tdes0 & TDES0_ERR_MASK) && (txptr->tdes0 != 0x7fffffff)) { + /* printk("tdes0=%x\n", txptr->tdes0); */ + db->stats.tx_errors++; + } + txptr = (struct tx_desc *) txptr->next_tx_desc; + db->tx_packet_cnt--; + } + db->tx_remove_ptr = (struct tx_desc *) txptr; + + if (dev->tbusy && (db->tx_packet_cnt < TX_FREE_DESC_CNT)) { + dev->tbusy = 0; /* free a resource */ + mark_bh(NET_BH); /* active bottom half */ + } + /* Received the coming packet */ + if (db->rx_avail_cnt) + dmfe_rx_packet(dev, db); + + /* reallocated rx descriptor buffer */ + if (db->rx_avail_cnt < RX_DESC_CNT) + allocated_rx_buffer(db); + + /* Mode Check */ + if (db->dm910x_chk_mode & 0x2) { + db->dm910x_chk_mode = 0x4; + db->cr6_data |= 0x100; + update_cr6(db->cr6_data, db->ioaddr); + } + dev->interrupt = 0; /* release interrupt lock */ + + /* Restore CR7 to enable interrupt mask */ + + if (db->interval_rx_cnt > RX_MAX_TRAFFIC) + db->cr7_data = 0x1a28d; + else + db->cr7_data = 0x1a2cd; + outl(db->cr7_data, ioaddr + DCR7); +} + +/* + * Receive the come packet and pass to upper layer + */ + +static void dmfe_rx_packet(struct net_device *dev, struct dmfe_board_info *db) +{ + struct rx_desc *rxptr; + struct sk_buff *skb; + int rxlen; + + rxptr = db->rx_ready_ptr; + + while (db->rx_avail_cnt) { + if (rxptr->rdes0 & 0x80000000) /* packet owner check */ + break; + + db->rx_avail_cnt--; + db->interval_rx_cnt++; + + if ((rxptr->rdes0 & 0x300) != 0x300) { + /* A packet without First/Last flag */ + /* reused this SKB */ + DMFE_DBUG(0, "Reused SK buffer, rdes0", rxptr->rdes0); + dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr); + db->rx_error_cnt++; + } else { + rxlen = ((rxptr->rdes0 >> 16) & 0x3fff) - 4; /* skip CRC */ + + /* A packet with First/Last flag */ + if (rxptr->rdes0 & 0x8000) { /* error summary bit check */ + /* This is a error packet */ + /* printk("rdes0 error : %x \n", rxptr->rdes0); */ + db->stats.rx_errors++; + if (rxptr->rdes0 & 1) + db->stats.rx_fifo_errors++; + if (rxptr->rdes0 & 2) + db->stats.rx_crc_errors++; + if (rxptr->rdes0 & 0x80) + db->stats.rx_length_errors++; + } + if (!(rxptr->rdes0 & 0x8000) || + ((db->cr6_data & CR6_PM) && (rxlen > 6))) { + skb = (struct sk_buff *) rxptr->rx_skb_ptr; + + /* Received Packet CRC check need or not */ + if ((db->dm910x_chk_mode & 1) && (cal_CRC(skb->tail, rxlen) != (*(unsigned long *) (skb->tail + rxlen)))) { + /* Found a error received packet */ + dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr); + db->dm910x_chk_mode = 3; + } else { + /* A good packet coming, send to upper layer */ + skb->dev = dev; + skb_put(skb, rxlen); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); /* Send to upper layer */ + /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ + dev->last_rx = jiffies; + db->stats.rx_packets++; + } + } else { + DMFE_DBUG(0, "Reused SK buffer, rdes0", rxptr->rdes0); + dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr); + } + } + + rxptr = (struct rx_desc *) rxptr->next_rx_desc; + } + + db->rx_ready_ptr = rxptr; +} + +/* + * Get statistics from driver. + */ + +static struct enet_statistics *dmfe_get_stats(struct net_device *dev) +{ + struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv; + + DMFE_DBUG(0, "dmfe_get_stats", 0); + return &db->stats; +} + +/* + * Set DM910X multicast address + */ + +static void dmfe_set_filter_mode(struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + + DMFE_DBUG(0, "dmfe_set_filter_mode()", 0); + + if (dev->flags & IFF_PROMISC) { + DMFE_DBUG(0, "Enable PROM Mode", 0); + db->cr6_data |= CR6_PM | CR6_PBF; + update_cr6(db->cr6_data, db->ioaddr); + return; + } + if (dev->flags & IFF_ALLMULTI || dev->mc_count > DMFE_MAX_MULTICAST) { + DMFE_DBUG(0, "Pass all multicast address", dev->mc_count); + db->cr6_data &= ~(CR6_PM | CR6_PBF); + db->cr6_data |= CR6_PAM; + return; + } + DMFE_DBUG(0, "Set multicast address", dev->mc_count); + send_filter_frame(dev, dev->mc_count); +} + +/* + * Process the upper socket ioctl command + */ + +static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + DMFE_DBUG(0, "dmfe_do_ioctl()", 0); + return 0; +} + +/* + * A periodic timer routine + * Dynamic media sense, allocated Rx buffer... + */ + +static void dmfe_timer(unsigned long data) +{ + u32 tmp_cr8; + unsigned char tmp_cr12; + struct net_device *dev = (struct net_device *) data; + struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv; + + DMFE_DBUG(0, "dmfe_timer()", 0); + + /* Do reset now */ + if (db->in_reset_state) + return; + + /* Operating Mode Check */ + if ((db->dm910x_chk_mode & 0x1) && (db->stats.rx_packets > MAX_CHECK_PACKET)) { + db->dm910x_chk_mode = 0x4; + } + /* Dynamic reset DM910X : system error or transmit time-out */ + tmp_cr8 = inl(db->ioaddr + DCR8); + if ((db->interval_rx_cnt == 0) && (tmp_cr8)) { + db->wait_reset = 1; + /* printk("CR8 %x, Interval Rx %x\n", tmp_cr8, db->interval_rx_cnt); */ + } + /* Receiving Traffic check */ + if (db->interval_rx_cnt > RX_MAX_TRAFFIC) + db->cr7_data = 0x1a28d; + else + db->cr7_data = 0x1a2cd; + outl(db->cr7_data, db->ioaddr + DCR7); + + db->interval_rx_cnt = 0; + + if (db->wait_reset | (db->tx_packet_cnt && + ((jiffies - dev->trans_start) > DMFE_TX_TIMEOUT)) | (db->rx_error_cnt > 3)) { + /* printk("wait_reset %x, tx cnt %x, rx err %x, time %x\n", db->wait_reset, db->tx_packet_cnt, db->rx_error_cnt, jiffies-dev->trans_start); */ + DMFE_DBUG(0, "Warn!! Warn!! Tx/Rx moniotr step1", db->tx_packet_cnt); + dmfe_dynamic_reset(dev); + db->timer.expires = DMFE_TIMER_WUT; + add_timer(&db->timer); + return; + } + db->rx_error_cnt = 0; /* Clear previous counter */ + + /* Link status check, Dynamic media type change */ + tmp_cr12 = inb(db->ioaddr + DCR12); + if (db->chip_revesion == 0x02000030) { + if (tmp_cr12 & 2) + tmp_cr12 = 0x0; /* Link failed */ + else + tmp_cr12 = 0x3; /* Link OK */ + } + if (!(tmp_cr12 & 0x3) && !db->link_failed) { + /* Link Failed */ + DMFE_DBUG(0, "Link Failed", tmp_cr12); + db->link_failed = 1; + phy_write(db->ioaddr, db->phy_addr, 0, 0x8000); /* reset Phy controller */ + } else if ((tmp_cr12 & 0x3) && db->link_failed) { + DMFE_DBUG(0, "Link link OK", tmp_cr12); + db->link_failed = 0; + if (db->media_mode & DMFE_AUTO) + dmfe_sense_speed(db); + dmfe_process_mode(db); + update_cr6(db->cr6_data, db->ioaddr); + /* SHOW_MEDIA_TYPE(db->op_mode); */ + } + /* reallocated rx descriptor buffer */ + if (db->rx_avail_cnt < RX_DESC_CNT) + allocated_rx_buffer(db); + + /* Timer active again */ + db->timer.expires = DMFE_TIMER_WUT; + add_timer(&db->timer); +} + +/* + * Dynamic reset the DM910X board + * Stop DM910X board + * Free Tx/Rx allocated memory + * Reset DM910X board + * Re-initilize DM910X board + */ + +static void dmfe_dynamic_reset(struct net_device *dev) +{ + struct dmfe_board_info *db = dev->priv; + + DMFE_DBUG(0, "dmfe_dynamic_reset()", 0); + + /* Enter dynamic reset route */ + db->in_reset_state = 1; + + /* Disable upper layer interface */ + dev->tbusy = 1; /* transmit packet disable */ + dev->start = 0; /* interface not ready */ + + db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */ + update_cr6(db->cr6_data, dev->base_addr); + + /* Free Rx Allocate buffer */ + dmfe_free_rxbuffer(db); + + /* system variable init */ + db->tx_packet_cnt = 0; + db->rx_avail_cnt = 0; + db->link_failed = 0; + db->wait_reset = 0; + db->rx_error_cnt = 0; + + /* Re-initilize DM910X board */ + dmfe_init_dm910x(dev); + + /* Restart upper layer interface */ + dev->tbusy = 0; /* Can transmit packet */ + dev->start = 1; /* interface ready */ + + /* Leave dynamic reser route */ + db->in_reset_state = 0; +} + +/* + * Free all allocated rx buffer + */ + +static void dmfe_free_rxbuffer(struct dmfe_board_info *db) +{ + DMFE_DBUG(0, "dmfe_free_rxbuffer()", 0); + + /* free allocated rx buffer */ + while (db->rx_avail_cnt) { + dev_kfree_skb((void *) (db->rx_ready_ptr->rx_skb_ptr)); + db->rx_ready_ptr = (struct rx_desc *) db->rx_ready_ptr->next_rx_desc; + db->rx_avail_cnt--; + } +} + +/* + * Reused the SK buffer + */ + +static void dmfe_reused_skb(struct dmfe_board_info *db, struct sk_buff *skb) +{ + struct rx_desc *rxptr = db->rx_insert_ptr; + + if (!(rxptr->rdes0 & 0x80000000)) { + rxptr->rx_skb_ptr = (u32) skb; + rxptr->rdes2 = virt_to_bus(skb->tail); + rxptr->rdes0 = 0x80000000; + db->rx_avail_cnt++; + db->rx_insert_ptr = (struct rx_desc *) rxptr->next_rx_desc; + } else + DMFE_DBUG(0, "SK Buffer reused method error", db->rx_avail_cnt); +} + +/* + * Initialize transmit/Receive descriptor + * Using Chain structure, and allocated Tx/Rx buffer + */ + +static void dmfe_descriptor_init(struct dmfe_board_info *db, u32 ioaddr) +{ + struct tx_desc *tmp_tx; + struct rx_desc *tmp_rx; + unsigned char *tmp_buf; + int i; + + DMFE_DBUG(0, "dmfe_descriptor_init()", 0); + + /* tx descriptor start pointer */ + db->tx_insert_ptr = db->first_tx_desc; + db->tx_remove_ptr = db->first_tx_desc; + outl(virt_to_bus(db->first_tx_desc), ioaddr + DCR4); /* Init CR4 */ + + /* rx descriptor start pointer */ + db->first_rx_desc = (struct rx_desc *) + ((u32) db->first_tx_desc + sizeof(struct rx_desc) * TX_DESC_CNT); + db->rx_insert_ptr = db->first_rx_desc; + db->rx_ready_ptr = db->first_rx_desc; + outl(virt_to_bus(db->first_rx_desc), ioaddr + DCR3); /* Init CR3 */ + + /* Init Transmit chain */ + tmp_buf = db->buf_pool_start; + for (tmp_tx = db->first_tx_desc, i = 0; i < TX_DESC_CNT; i++, tmp_tx++) { + tmp_tx->tx_buf_ptr = (u32) tmp_buf; + tmp_tx->tdes0 = 0; + tmp_tx->tdes1 = 0x81000000; /* IC, chain */ + tmp_tx->tdes2 = (u32) virt_to_bus(tmp_buf); + tmp_tx->tdes3 = (u32) virt_to_bus(tmp_tx) + sizeof(struct tx_desc); + tmp_tx->next_tx_desc = (u32) ((u32) tmp_tx + sizeof(struct tx_desc)); + tmp_buf = (unsigned char *) ((u32) tmp_buf + TX_BUF_ALLOC); + } + (--tmp_tx)->tdes3 = (u32) virt_to_bus(db->first_tx_desc); + tmp_tx->next_tx_desc = (u32) db->first_tx_desc; + + /* Init Receive descriptor chain */ + for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; i++, tmp_rx++) { + tmp_rx->rdes0 = 0; + tmp_rx->rdes1 = 0x01000600; + tmp_rx->rdes3 = (u32) virt_to_bus(tmp_rx) + sizeof(struct rx_desc); + tmp_rx->next_rx_desc = (u32) ((u32) tmp_rx + sizeof(struct rx_desc)); + } + (--tmp_rx)->rdes3 = (u32) virt_to_bus(db->first_rx_desc); + tmp_rx->next_rx_desc = (u32) db->first_rx_desc; + + /* pre-allocated Rx buffer */ + allocated_rx_buffer(db); +} + +/* + * Update CR6 vaule + * Firstly stop DM910X , then written value and start + */ + +static void update_cr6(u32 cr6_data, u32 ioaddr) +{ + u32 cr6_tmp; + + cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */ + outl(cr6_tmp, ioaddr + DCR6); + DELAY_5US; + outl(cr6_data, ioaddr + DCR6); + cr6_tmp = inl(ioaddr + DCR6); + /* printk("CR6 update %x ", cr6_tmp); */ +} + +/* + * Send a setup frame + * This setup frame initilize DM910X addres filter mode + */ + +static void send_filter_frame(struct net_device *dev, int mc_cnt) +{ + struct dmfe_board_info *db = dev->priv; + struct dev_mc_list *mcptr; + struct tx_desc *txptr; + u16 *addrptr; + u32 *suptr; + int i; + + DMFE_DBUG(0, "send_filetr_frame()", 0); + + txptr = db->tx_insert_ptr; + suptr = (u32 *) txptr->tx_buf_ptr; + + /* broadcast address */ + *suptr++ = 0xffff; + *suptr++ = 0xffff; + *suptr++ = 0xffff; + + /* Node address */ + addrptr = (u16 *) dev->dev_addr; + *suptr++ = addrptr[0]; + *suptr++ = addrptr[1]; + *suptr++ = addrptr[2]; + + /* fit the multicast address */ + for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { + addrptr = (u16 *) mcptr->dmi_addr; + *suptr++ = addrptr[0]; + *suptr++ = addrptr[1]; + *suptr++ = addrptr[2]; + } + + for (; i < 14; i++) { + *suptr++ = 0xffff; + *suptr++ = 0xffff; + *suptr++ = 0xffff; + } + + /* prepare the setup frame */ + db->tx_packet_cnt++; + dev->tbusy = 1; + txptr->tdes1 = 0x890000c0; + txptr->tdes0 = 0x80000000; + db->tx_insert_ptr = (struct tx_desc *) txptr->next_tx_desc; + + update_cr6(db->cr6_data | 0x2000, dev->base_addr); + outl(0x1, dev->base_addr + DCR1); + update_cr6(db->cr6_data, dev->base_addr); + dev->trans_start = jiffies; + +} + +/* + * Allocate rx buffer, + * Allocate as many Rx buffers as possible. + */ +static void allocated_rx_buffer(struct dmfe_board_info *db) +{ + struct rx_desc *rxptr; + struct sk_buff *skb; + + rxptr = db->rx_insert_ptr; + + while (db->rx_avail_cnt < RX_DESC_CNT) { + if ((skb = alloc_skb(RX_ALLOC_SIZE, GFP_ATOMIC)) == NULL) + break; + rxptr->rx_skb_ptr = (u32) skb; + rxptr->rdes2 = virt_to_bus(skb->tail); + rxptr->rdes0 = 0x80000000; + rxptr = (struct rx_desc *) rxptr->next_rx_desc; + db->rx_avail_cnt++; + } + + db->rx_insert_ptr = rxptr; +} + +/* + * Read one word data from the serial ROM + */ + +static u16 read_srom_word(long ioaddr, int offset) +{ + int i; + u16 srom_data = 0; + long cr9_ioaddr = ioaddr + DCR9; + + outl(CR9_SROM_READ, cr9_ioaddr); + outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); + + /* Send the Read Command 110b */ + SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); + SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); + SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); + + /* Send the offset */ + for (i = 5; i >= 0; i--) { + srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; + SROM_CLK_WRITE(srom_data, cr9_ioaddr); + } + + outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); + + for (i = 16; i > 0; i--) { + outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); + DELAY_5US; + srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0); + outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); + DELAY_5US; + } + + outl(CR9_SROM_READ, cr9_ioaddr); + return srom_data; +} + +/* + * Parser Control media block to get Phy address + */ + +static void parser_ctrl_info(struct dmfe_board_info *db) +{ + int i; + char *sdata = db->srom; + unsigned char count; + + /* point to info leaf0 */ + count = *(sdata + 33); + + /* Point to First media block */ + sdata += 34; + for (i = 0; i < count; i++) { + if (*(sdata + 1) == 1) { + db->phy_addr = *(sdata + 2); + break; + } + sdata += ((unsigned char) *(sdata) & 0x7f) + 1; + } + + if (i >= count) { + printk("Can't found Control Block\n"); + db->phy_addr = 1; + } +} + +/* + * Auto sense the media mode + */ + +static void dmfe_sense_speed(struct dmfe_board_info *db) +{ + int i; + u16 phy_mode; + + for (i = 1000; i; i--) { + DELAY_5US; + phy_mode = phy_read(db->ioaddr, db->phy_addr, 1); + if ((phy_mode & 0x24) == 0x24) + break; + } + + if (i) { + phy_mode = phy_read(db->ioaddr, db->phy_addr, 17) & 0xf000; + /* printk("Phy_mode %x ",phy_mode); */ + switch (phy_mode) { + case 0x1000: + db->op_mode = DMFE_10MHF; + break; + case 0x2000: + db->op_mode = DMFE_10MFD; + break; + case 0x4000: + db->op_mode = DMFE_100MHF; + break; + case 0x8000: + db->op_mode = DMFE_100MFD; + break; + default: + db->op_mode = DMFE_100MHF; + DMFE_DBUG(1, "Media Type error, phy reg17", phy_mode); + break; + } + } else { + db->op_mode = DMFE_100MHF; + DMFE_DBUG(0, "Link Failed :", phy_mode); + } +} + +/* + * Process op-mode + * AUTO mode : PHY controller in Auto-negotiation Mode + * Force mode: PHY controller in force mode with HUB + * N-way force capability with SWITCH + */ + +static void dmfe_process_mode(struct dmfe_board_info *db) +{ + u16 phy_reg; + + /* Full Duplex Mode Check */ + db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */ + if (db->op_mode & 0x4) + db->cr6_data |= CR6_FDM; + + if (!(db->media_mode & DMFE_AUTO)) { /* Force Mode Check */ + /* User force the media type */ + phy_reg = phy_read(db->ioaddr, db->phy_addr, 5); + /* printk("Nway phy_reg5 %x ",phy_reg); */ + if (phy_reg & 0x1) { + /* parter own the N-Way capability */ + phy_reg = phy_read(db->ioaddr, db->phy_addr, 4) & ~0x1e0; + switch (db->op_mode) { + case DMFE_10MHF: + phy_reg |= 0x20; + break; + case DMFE_10MFD: + phy_reg |= 0x40; + break; + case DMFE_100MHF: + phy_reg |= 0x80; + break; + case DMFE_100MFD: + phy_reg |= 0x100; + break; + } + phy_write(db->ioaddr, db->phy_addr, 4, phy_reg); + } else { + /* parter without the N-Way capability */ + switch (db->op_mode) { + case DMFE_10MHF: + phy_reg = 0x0; + break; + case DMFE_10MFD: + phy_reg = 0x100; + break; + case DMFE_100MHF: + phy_reg = 0x2000; + break; + case DMFE_100MFD: + phy_reg = 0x2100; + break; + } + phy_write(db->ioaddr, db->phy_addr, 0, phy_reg); + } + } +} + +/* + * Write a word to Phy register + */ + +static void phy_write(u32 iobase, u8 phy_addr, u8 offset, u16 phy_data) +{ + u16 i; + u32 ioaddr = iobase + DCR9; + + /* Send 33 synchronization clock to Phy controller */ + for (i = 0; i < 35; i++) + phy_write_1bit(ioaddr, PHY_DATA_1); + + /* Send start command(01) to Phy */ + phy_write_1bit(ioaddr, PHY_DATA_0); + phy_write_1bit(ioaddr, PHY_DATA_1); + + /* Send write command(01) to Phy */ + phy_write_1bit(ioaddr, PHY_DATA_0); + phy_write_1bit(ioaddr, PHY_DATA_1); + + /* Send Phy addres */ + for (i = 0x10; i > 0; i = i >> 1) + phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); + + /* Send register addres */ + for (i = 0x10; i > 0; i = i >> 1) + phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); + + /* written trasnition */ + phy_write_1bit(ioaddr, PHY_DATA_1); + phy_write_1bit(ioaddr, PHY_DATA_0); + + /* Write a word data to PHY controller */ + for (i = 0x8000; i > 0; i >>= 1) + phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0); +} + +/* + * Read a word data from phy register + */ + +static u16 phy_read(u32 iobase, u8 phy_addr, u8 offset) +{ + int i; + u16 phy_data; + u32 ioaddr = iobase + DCR9; + + /* Send 33 synchronization clock to Phy controller */ + for (i = 0; i < 35; i++) + phy_write_1bit(ioaddr, PHY_DATA_1); + + /* Send start command(01) to Phy */ + phy_write_1bit(ioaddr, PHY_DATA_0); + phy_write_1bit(ioaddr, PHY_DATA_1); + + /* Send read command(10) to Phy */ + phy_write_1bit(ioaddr, PHY_DATA_1); + phy_write_1bit(ioaddr, PHY_DATA_0); + + /* Send Phy addres */ + for (i = 0x10; i > 0; i = i >> 1) + phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); + + /* Send register addres */ + for (i = 0x10; i > 0; i = i >> 1) + phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); + + /* Skip transition state */ + phy_read_1bit(ioaddr); + + /* read 16bit data */ + for (phy_data = 0, i = 0; i < 16; i++) { + phy_data <<= 1; + phy_data |= phy_read_1bit(ioaddr); + } + + return phy_data; +} + +/* + * Write one bit data to Phy Controller + */ + +static void phy_write_1bit(u32 ioaddr, u32 phy_data) +{ + outl(phy_data, ioaddr); /* MII Clock Low */ + DELAY_1US; + outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ + DELAY_1US; + outl(phy_data, ioaddr); /* MII Clock Low */ + DELAY_1US; +} + +/* + * Read one bit phy data from PHY controller + */ + +static u16 phy_read_1bit(u32 ioaddr) +{ + u16 phy_data; + + outl(0x50000, ioaddr); + DELAY_1US; + phy_data = (inl(ioaddr) >> 19) & 0x1; + outl(0x40000, ioaddr); + DELAY_1US; + + return phy_data; +} + +/* + * Calculate the CRC valude of the Rx packet + */ + +static unsigned long cal_CRC(unsigned char *Data, unsigned int Len) +{ + unsigned long Crc = 0xffffffff; + + while (Len--) { + Crc = CrcTable[(Crc ^ *Data++) & 0xFF] ^ (Crc >> 8); + } + + return ~Crc; + +} + +#ifdef MODULE + +MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); +MODULE_DESCRIPTION("Davicom DM910X fast ethernet driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(mode, "i"); +MODULE_PARM(cr6set, "i"); +MODULE_PARM(chkmode, "i"); + +/* Description: + * when user used insmod to add module, system invoked init_module() + * to initilize and register. + */ + +int init_module(void) +{ + DMFE_DBUG(0, "init_module() ", debug); + + if (debug) + dmfe_debug = debug; /* set debug flag */ + if (cr6set) + dmfe_cr6_user_set = cr6set; + + switch (mode) { + case 0: + case 1: + case 4: + case 5: + dmfe_media_mode = mode; + break; + default: + dmfe_media_mode = 8; + break; + } + + return dmfe_reg_board(0); /* search board and register */ +} + +/* + * Description: + * when user used rmmod to delete module, system invoked clean_module() + * to un-register device. + */ + +void cleanup_module(void) +{ + struct net_device *next_dev; + + DMFE_DBUG(0, "clean_module()", 0); + + while (dmfe_root_dev) { + next_dev = ((struct dmfe_board_info *) dmfe_root_dev->priv)->next_dev; + unregister_netdev(dmfe_root_dev); + release_region(dmfe_root_dev->base_addr, DM9102_IO_SIZE); + kfree(dmfe_root_dev->priv); /* free board information */ + kfree(dmfe_root_dev); /* free device structure */ + dmfe_root_dev = next_dev; + } + DMFE_DBUG(0, "clean_module() exit", 0); +} + +#endif /* MODULE */ diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index c27d4628c..dae428320 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -53,34 +53,34 @@ #include <linux/etherdevice.h> #include <linux/skbuff.h> -static int dummy_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *dummy_get_stats(struct device *dev); +static int dummy_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *dummy_get_stats(struct net_device *dev); -static int dummy_open(struct device *dev) +static int dummy_open(struct net_device *dev) { MOD_INC_USE_COUNT; return 0; } -static int dummy_close(struct device *dev) +static int dummy_close(struct net_device *dev) { MOD_DEC_USE_COUNT; return 0; } /* fake multicast ability */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { } #ifdef CONFIG_NET_FASTROUTE -static int dummy_accept_fastpath(struct device *dev, struct dst_entry *dst) +static int dummy_accept_fastpath(struct net_device *dev, struct dst_entry *dst) { return -1; } #endif -int __init dummy_init(struct device *dev) +int __init dummy_init(struct net_device *dev) { /* Initialize the device structure. */ dev->hard_start_xmit = dummy_xmit; @@ -107,7 +107,7 @@ int __init dummy_init(struct device *dev) return 0; } -static int dummy_xmit(struct sk_buff *skb, struct device *dev) +static int dummy_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats; dev_kfree_skb(skb); @@ -119,7 +119,7 @@ static int dummy_xmit(struct sk_buff *skb, struct device *dev) return 0; } -static struct net_device_stats *dummy_get_stats(struct device *dev) +static struct net_device_stats *dummy_get_stats(struct net_device *dev) { struct net_device_stats *stats = (struct net_device_stats *) dev->priv; return stats; @@ -127,7 +127,7 @@ static struct net_device_stats *dummy_get_stats(struct device *dev) #ifdef MODULE -static int __init dummy_probe(struct device *dev) +static int __init dummy_probe(struct net_device *dev) { dummy_init(dev); return 0; @@ -135,7 +135,7 @@ static int __init dummy_probe(struct device *dev) static char dummy_name[16]; -static struct device dev_dummy = { +static struct net_device dev_dummy = { dummy_name, /* Needs to be writeable */ 0, 0, 0, 0, 0x0, 0, diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index 571ff901b..4ea0e6b71 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -75,7 +75,7 @@ extern inline void mem_on(short port, volatile char *mem_base, { /* This is a little weird: set the shared memory window by doing a read. The low address bits specify the starting page. */ - mem_base[start_page]; + readb(mem_base+start_page); inb(port + E21_MEM_ENABLE); outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON); } @@ -95,19 +95,19 @@ extern inline void mem_off(short port) #define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */ #define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */ -int e2100_probe(struct device *dev); -int e21_probe1(struct device *dev, int ioaddr); +int e2100_probe(struct net_device *dev); +int e21_probe1(struct net_device *dev, int ioaddr); -static int e21_open(struct device *dev); -static void e21_reset_8390(struct device *dev); -static void e21_block_input(struct device *dev, int count, +static int e21_open(struct net_device *dev); +static void e21_reset_8390(struct net_device *dev); +static void e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void e21_block_output(struct device *dev, int count, +static void e21_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int e21_close(struct device *dev); +static int e21_close(struct net_device *dev); /* Probe for the E2100 series ethercards. These cards have an 8390 at the @@ -117,7 +117,7 @@ static int e21_close(struct device *dev); station address). */ -int __init e2100_probe(struct device *dev) +int __init e2100_probe(struct net_device *dev) { int *port; int base_addr = dev->base_addr; @@ -137,7 +137,7 @@ int __init e2100_probe(struct device *dev) return ENODEV; } -int __init e21_probe1(struct device *dev, int ioaddr) +int __init e21_probe1(struct net_device *dev, int ioaddr) { int i, status; unsigned char *station_addr = dev->dev_addr; @@ -254,7 +254,7 @@ int __init e21_probe1(struct device *dev, int ioaddr) } static int -e21_open(struct device *dev) +e21_open(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -277,7 +277,7 @@ e21_open(struct device *dev) } static void -e21_reset_8390(struct device *dev) +e21_reset_8390(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -295,7 +295,7 @@ e21_reset_8390(struct device *dev) appears at the start of the shared memory. */ static void -e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { short ioaddr = dev->base_addr; @@ -319,7 +319,7 @@ e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) The E21xx makes block_input() especially easy by wrapping the top ring buffer to the bottom automatically. */ static void -e21_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { short ioaddr = dev->base_addr; char *shared_mem = (char *)dev->mem_start; @@ -333,7 +333,7 @@ e21_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off } static void -e21_block_output(struct device *dev, int count, const unsigned char *buf, +e21_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { short ioaddr = dev->base_addr; @@ -349,7 +349,7 @@ e21_block_output(struct device *dev, int count, const unsigned char *buf, } static int -e21_close(struct device *dev) +e21_close(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -386,7 +386,7 @@ struct netdev_entry e21_drv = #define MAX_E21_CARDS 4 /* Max number of E21 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_E21_CARDS] = { 0, }; -static struct device dev_e21[MAX_E21_CARDS] = { +static struct net_device dev_e21[MAX_E21_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -413,7 +413,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { - struct device *dev = &dev_e21[this_dev]; + struct net_device *dev = &dev_e21[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -444,7 +444,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { - struct device *dev = &dev_e21[this_dev]; + struct net_device *dev = &dev_e21[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* NB: e21_close() handles free_irq */ diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 08a9a17ac..f436802eb 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -23,7 +23,8 @@ This is a compatibility hardware problem. Versions: - 0.11d added __initdata, __initfunc stuff; call spin_lock_init + 0.11e some tweaks about multiple cards support (PdP, jul/aug 1999) + 0.11d added __initdata, __init stuff; call spin_lock_init in eepro_probe1. Replaced "eepro" by dev->name. Augmented the code protected by spin_lock in interrupt routine (PdP, 12/12/1998) @@ -149,7 +150,7 @@ static const char *version = /* For linux 2.1.xx */ #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155 -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include <linux/init.h> #include <linux/delay.h> @@ -157,7 +158,6 @@ static const char *version = /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */ #define SLOW_DOWN inb(0x80) /* udelay(2) */ -#define compat_init_func(X) __initfunc(X) #define compat_init_data __initdata #else @@ -166,7 +166,6 @@ static const char *version = #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb), (mode) ) #define test_and_set_bit(a,b) set_bit((a),(b)) #define SLOW_DOWN SLOW_DOWN_IO -#define compat_init_func(X) X #define compat_init_data #endif @@ -303,21 +302,21 @@ struct eepro_local { /* Index to functions, as function prototypes. */ -extern int eepro_probe(struct device *dev); +extern int eepro_probe(struct net_device *dev); -static int eepro_probe1(struct device *dev, short ioaddr); -static int eepro_open(struct device *dev); -static int eepro_send_packet(struct sk_buff *skb, struct device *dev); +static int eepro_probe1(struct net_device *dev, short ioaddr); +static int eepro_open(struct net_device *dev); +static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev); static void eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eepro_rx(struct device *dev); -static void eepro_transmit_interrupt(struct device *dev); -static int eepro_close(struct device *dev); -static struct enet_statistics *eepro_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void eepro_rx(struct net_device *dev); +static void eepro_transmit_interrupt(struct net_device *dev); +static int eepro_close(struct net_device *dev); +static struct enet_statistics *eepro_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); static int read_eeprom(int ioaddr, int location); -static void hardware_send_packet(struct device *dev, void *buf, short length); -static int eepro_grab_irq(struct device *dev); +static void hardware_send_packet(struct net_device *dev, void *buf, short length); +static int eepro_grab_irq(struct net_device *dev); /* Details of the i82595. @@ -461,7 +460,7 @@ buffer (transmit-buffer = 32K - receive-buffer). struct netdev_entry netcard_drv = {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; #else -compat_init_func(int eepro_probe(struct device *dev)) +int __init eepro_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -575,7 +574,7 @@ void printEEPROMInfo(short ioaddr) probes on the ISA bus. A good device probe avoids doing writes, and verifies that the correct device exists and functions. */ -int eepro_probe1(struct device *dev, short ioaddr) +int eepro_probe1(struct net_device *dev, short ioaddr) { unsigned short station_addr[6], id, counter; int i,j, irqMask; @@ -746,7 +745,7 @@ int eepro_probe1(struct device *dev, short ioaddr) static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1}; static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1}; -static int eepro_grab_irq(struct device *dev) +static int eepro_grab_irq(struct net_device *dev) { int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12 }; int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr; @@ -804,7 +803,7 @@ static int eepro_grab_irq(struct device *dev) return dev->irq; } -static int eepro_open(struct device *dev) +static int eepro_open(struct net_device *dev) { unsigned short temp_reg, old8, old9; int irqMask; @@ -984,7 +983,7 @@ static int eepro_open(struct device *dev) return 0; } -static int eepro_send_packet(struct sk_buff *skb, struct device *dev) +static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1087,8 +1086,8 @@ static int eepro_send_packet(struct sk_buff *skb, struct device *dev) static void eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; - /* (struct device *)(irq2dev_map[irq]);*/ + struct net_device *dev = (struct net_device *)dev_id; + /* (struct net_device *)(irq2dev_map[irq]);*/ struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr, status, boguscount = 20; @@ -1155,7 +1154,7 @@ eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) return; } -static int eepro_close(struct device *dev) +static int eepro_close(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1207,7 +1206,7 @@ static int eepro_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ static struct enet_statistics * -eepro_get_stats(struct device *dev) +eepro_get_stats(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; @@ -1217,7 +1216,7 @@ eepro_get_stats(struct device *dev) /* Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1386,7 +1385,7 @@ read_eeprom(int ioaddr, int location) } static void -hardware_send_packet(struct device *dev, void *buf, short length) +hardware_send_packet(struct net_device *dev, void *buf, short length) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1503,7 +1502,7 @@ hardware_send_packet(struct device *dev, void *buf, short length) } static void -eepro_rx(struct device *dev) +eepro_rx(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr, rcv_ram = dev->mem_end; @@ -1597,7 +1596,7 @@ eepro_rx(struct device *dev) } static void -eepro_transmit_interrupt(struct device *dev) +eepro_transmit_interrupt(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1655,7 +1654,7 @@ eepro_transmit_interrupt(struct device *dev) #define MAX_EEPRO 8 static char devicename[MAX_EEPRO][9]; -static struct device dev_eepro[MAX_EEPRO]; +static struct net_device dev_eepro[MAX_EEPRO]; static int io[MAX_EEPRO] = { #ifdef PnPWakeup @@ -1663,17 +1662,10 @@ static int io[MAX_EEPRO] = { #else 0x200, /* Why? */ #endif - -1, -1, -1, -1, -1, -1, -1}; -static int irq[MAX_EEPRO] = {0, 0, 0, 0, 0, 0, 0, 0}; + [1 ... MAX_EEPRO - 1] = -1 }; +static int irq[MAX_EEPRO] = { [0 ... MAX_EEPRO-1] = 0 }; static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */ - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024), - (RCV_RAM/1024) + [0 ... MAX_EEPRO-1] = RCV_RAM/1024 }; static int n_eepro = 0; @@ -1681,9 +1673,9 @@ static int n_eepro = 0; #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155 MODULE_AUTHOR("Pascal Dupuis <dupuis@lei.ucl.ac.be> for the 2.1 stuff (locking,...)"); MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver"); -MODULE_PARM(io, "i"); -MODULE_PARM(irq, "i"); -MODULE_PARM(mem, "i"); +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i"); +MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i"); #endif int @@ -1693,7 +1685,7 @@ init_module(void) printk("eepro_init_module: You should not use auto-probing with insmod!\n"); while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) { - struct device *d = &dev_eepro[n_eepro]; + struct net_device *d = &dev_eepro[n_eepro]; d->name = devicename[n_eepro]; /* inserted by drivers/net/net_init.c */ d->mem_end = mem[n_eepro]; d->base_addr = io[n_eepro]; @@ -1713,7 +1705,7 @@ cleanup_module(void) int i; for (i=0; i<n_eepro; i++) { - struct device *d = &dev_eepro[i]; + struct net_device *d = &dev_eepro[i]; unregister_netdev(d); kfree_s(d->priv,sizeof(struct eepro_local)); diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 69d383a45..e1a4a3c91 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -1,14 +1,14 @@ -/* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */ +/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */ /* NOTICE: this version tested with kernels 1.3.72 and later only! - Written 1996-1998 by Donald Becker. + Written 1996-1999 by Donald Becker. This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. - This driver is for the Intel EtherExpress Pro 100B boards. - It should work with other i82557 and i82558 boards. - To use a built-in driver, install as drivers/net/eepro100.c. + This driver is for the Intel EtherExpress Pro100 (Speedo3) design. + It should work with all i82557/558/559 boards. + To use as a module, use the compile-command at the end of the file. The author may be reached as becker@CESDIS.usra.edu, or C/O @@ -16,15 +16,17 @@ Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771 For updates see http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html - There is also a mailing list based at + For installation instructions + http://cesdis.gsfc.nasa.gov/linux/misc/modules.html + There is a Majordomo mailing list based at linux-eepro100@cesdis.gsfc.nasa.gov */ static const char *version = -"eepro100.c:v1.06 10/16/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n"; +"eepro100.c:v1.09j 7/27/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n"; /* A few user-configurable values that apply to all boards. - First set are undocumented and spelled per Intel recommendations. */ + First set is undocumented and spelled per Intel recommendations. */ static int congenb = 0; /* Enable congestion control in the DP83840. */ static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */ @@ -38,14 +40,45 @@ static int rxdmacount = 0; static int rx_copybreak = 200; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static int max_interrupt_work = 200; +static int max_interrupt_work = 20; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */ -static int multicast_filter_limit = 3; +static int multicast_filter_limit = 64; -#include <linux/module.h> +/* 'options' is used to pass a transceiver override or full-duplex flag + e.g. "options=16" for FD, "options=32" for 100mbps-only. */ +static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1}; +static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; +#ifdef MODULE +static int debug = -1; /* The debug level */ +#endif + +/* A few values that may be tweaked. */ +/* The ring sizes should be a power of two for efficiency. */ +#define TX_RING_SIZE 32 /* Effectively 2 entries fewer. */ +#define RX_RING_SIZE 32 +/* Actual number of TX packets queued, must be <= TX_RING_SIZE-2. */ +#define TX_QUEUE_LIMIT 12 + +/* Operational parameters that usually are not changed. */ + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (2*HZ) +/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/ +#define PKT_BUF_SZ 1536 + +#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) +#warning You must compile this file with the correct options! +#warning See the last lines of the source file. +#error You must compile this driver with "-O". +#endif #include <linux/version.h> +#include <linux/module.h> +#ifdef MODVERSIONS +#include <linux/modversions.h> +#endif + #include <linux/kernel.h> #include <linux/string.h> #include <linux/timer.h> @@ -53,19 +86,24 @@ static int multicast_filter_limit = 3; #include <linux/ioport.h> #include <linux/malloc.h> #include <linux/interrupt.h> +#ifdef HAS_PCI_NETIF +#include "pci-netif.h" +#else #include <linux/pci.h> +#if LINUX_VERSION_CODE < 0x20155 +#include <linux/bios32.h> /* Ignore the bogus warning in 2.1.100+ */ +#endif +#endif +#include <linux/spinlock.h> +#include <asm/bitops.h> +#include <asm/io.h> + #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> -#include <asm/spinlock.h> -#include <asm/bitops.h> -#include <asm/io.h> - -/* - * Module documentation - */ +#if LINUX_VERSION_CODE > 0x20118 && defined(MODULE) MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>"); MODULE_DESCRIPTION("Intel i82557/i82558 PCI EtherExpressPro driver"); MODULE_PARM(debug, "i"); @@ -79,16 +117,39 @@ MODULE_PARM(rxdmacount, "i"); MODULE_PARM(rx_copybreak, "i"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(multicast_filter_limit, "i"); +#endif #define RUN_AT(x) (jiffies + (x)) - +/* Condensed bus+endian portability operations. */ +#define virt_to_le32bus(addr) cpu_to_le32(virt_to_bus(addr)) +#define le32bus_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) + +#if (LINUX_VERSION_CODE < 0x20123) +#define test_and_set_bit(val, addr) set_bit(val, addr) +#define le16_to_cpu(val) (val) +#define cpu_to_le16(val) (val) +#define le32_to_cpu(val) (val) +#define cpu_to_le32(val) (val) +#define spin_lock_irqsave(&sp->lock, flags) save_flags(flags); cli(); +#define spin_unlock_irqrestore(&sp->lock, flags); restore_flags(flags); +#endif +#if LINUX_VERSION_CODE < 0x20159 +#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE); +#else #define dev_free_skb(skb) dev_kfree_skb(skb); +#endif +#if ! defined(CAP_NET_ADMIN) +#define capable(CAP_XXX) (suser()) +#endif +#if ! defined(HAS_NETIF_QUEUE) +#define netif_wake_queue(dev) mark_bh(NET_BH); +#endif /* The total I/O port extent of the board. The registers beyond 0x18 only exist on the i82558. */ #define SPEEDO3_TOTAL_SIZE 0x20 -int speedo_debug = 0; +int speedo_debug = 1; /* Theory of Operation @@ -222,15 +283,52 @@ having to sign an Intel NDA when I'm helping Intel sell their own product! */ -/* A few values that may be tweaked. */ -/* The ring sizes should be a power of two for efficiency. */ -#define TX_RING_SIZE 16 /* Effectively 2 entries fewer. */ -#define RX_RING_SIZE 16 -/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/ -#define PKT_BUF_SZ 1536 +/* This table drives the PCI probe routines. */ +static struct net_device * +speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT ((800*HZ)/1000) +#ifdef USE_IO +#define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR1 +#define SPEEDO_SIZE 32 +#else +#define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR0 +#define SPEEDO_SIZE 0x1000 +#endif + +#if defined(HAS_PCI_NETIF) +struct pci_id_info static pci_tbl[] = { + { "Intel PCI EtherExpress Pro100", + { 0x12298086, 0xffffffff,}, SPEEDO_IOTYPE, SPEEDO_SIZE, + 0, speedo_found1 }, + {0,}, /* 0 terminated list. */ +}; +#else +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +}; +struct pci_id_info { + const char *name; + u16 vendor_id, device_id, device_id_mask, flags; + int io_size; + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); +} static pci_tbl[] = { + { "Intel PCI EtherExpress Pro100", + 0x8086, 0x1229, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 32, speedo_found1 }, + {0,}, /* 0 terminated list. */ +}; +#endif + +#ifndef USE_IO +#define inb readb +#define inw readw +#define inl readl +#define outb writeb +#define outw writew +#define outl writel +#endif /* How to wait for the command unit to accept a command. Typically this takes 0 ticks. */ @@ -241,10 +339,6 @@ static inline void wait_for_cmd_done(long cmd_ioaddr) while(inb(cmd_ioaddr) && --wait >= 0); } -/* Operational parameter that usually are not changed. */ - -/* The rest of these values should never change. */ - /* Offsets to the various registers. All accesses need not be longword aligned. */ enum speedo_offsets { @@ -257,33 +351,41 @@ enum speedo_offsets { }; /* Commands that can be put in a command list entry. */ enum commands { - CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, - CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7, - CmdSuspend = 0x4000, /* Suspend after completion. */ - CmdIntr = 0x2000, /* Interrupt after completion. */ - CmdTxFlex = 0x0008, /* Use "Flexible mode" for CmdTx command. */ + CmdNOp = 0, CmdIASetup = 0x10000, CmdConfigure = 0x20000, + CmdMulticastList = 0x30000, CmdTx = 0x40000, CmdTDR = 0x50000, + CmdDump = 0x60000, CmdDiagnose = 0x70000, + CmdSuspend = 0x40000000, /* Suspend after completion. */ + CmdIntr = 0x20000000, /* Interrupt after completion. */ + CmdTxFlex = 0x00080000, /* Use "Flexible mode" for CmdTx command. */ }; +/* Do atomically if possible. */ +#if defined(__i386__) || defined(__alpha__) +#define clear_suspend(cmd) clear_bit(30, &(cmd)->cmd_status) +#elif defined(__powerpc__) +#define clear_suspend(cmd) clear_bit(6, &(cmd)->cmd_status) +#else +#define clear_suspend(cmd) (cmd)->cmd_status &= cpu_to_le32(~CmdSuspend) +#endif -/* The SCB accepts the following controls for the Tx and Rx units: */ -#define CU_START 0x0010 -#define CU_RESUME 0x0020 -#define CU_STATSADDR 0x0040 -#define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */ -#define CU_CMD_BASE 0x0060 /* Base address to add to add CU commands. */ -#define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */ - -#define RX_START 0x0001 -#define RX_RESUME 0x0002 -#define RX_ABORT 0x0004 -#define RX_ADDR_LOAD 0x0006 -#define RX_RESUMENR 0x0007 -#define INT_MASK 0x0100 -#define DRVR_INT 0x0200 /* Driver generated interrupt. */ +enum SCBCmdBits { + SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000, + SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400, + SCBTriggerIntr=0x0200, SCBMaskAll=0x0100, + /* The rest are Rx and Tx commands. */ + CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050, + CUCmdBase=0x0060, /* CU Base address (set to zero) . */ + CUDumpStats=0x0070, /* Dump then reset stats counters. */ + RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006, + RxResumeNoResources=0x0007, +}; + +enum SCBPort_cmds { + PortReset=0, PortSelfTest=1, PortPartialReset=2, PortDump=3, +}; /* The Speedo3 Rx and Tx frame/buffer descriptors. */ struct descriptor { /* A generic descriptor. */ - s16 status; /* Offset 0. */ - s16 command; /* Offset 2. */ + s32 cmd_status; /* All command and status fields. */ u32 link; /* struct descriptor * */ unsigned char params[0]; }; @@ -293,8 +395,7 @@ struct RxFD { /* Receive frame descriptor. */ s32 status; u32 link; /* struct RxFD * */ u32 rx_buf_addr; /* void * */ - u16 count; - u16 size; + u32 count; }; /* Selected elements of the Tx/RxFD.status word. */ @@ -302,7 +403,7 @@ enum RxFD_bits { RxComplete=0x8000, RxOK=0x2000, RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010, RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002, - StatusComplete=0x8000, + TxUnderrun=0x1000, StatusComplete=0x8000, }; struct TxFD { /* Transmit frame descriptor set. */ @@ -338,49 +439,57 @@ struct speedo_stats { u32 done_marker; }; +/* Do not change the position (alignment) of the first few elements! + The later elements are grouped for cache locality. */ struct speedo_private { - char devname[8]; /* Used only for kernel debugging. */ - const char *product_name; - struct device *next_module; - spinlock_t lock; - struct TxFD tx_ring[TX_RING_SIZE] /* Commands (usually CmdTxPacket). */ - __attribute__ ((aligned (L1_CACHE_BYTES)));; - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct TxFD tx_ring[TX_RING_SIZE]; /* Commands (usually CmdTxPacket). */ + struct RxFD *rx_ringp[RX_RING_SIZE]; /* Rx descriptor, used as ring. */ + /* The addresses of a Tx/Rx-in-place packets/buffers. */ struct sk_buff* tx_skbuff[TX_RING_SIZE]; - struct descriptor *last_cmd; /* Last command sent. */ - /* Rx descriptor ring & addresses of receive-in-place skbuffs. */ - struct RxFD *rx_ringp[RX_RING_SIZE]; struct sk_buff* rx_skbuff[RX_RING_SIZE]; + struct descriptor *last_cmd; /* Last command sent. */ + unsigned int cur_tx, dirty_tx; /* The ring entries to be free()ed. */ + spinlock_t lock; /* Group with Tx control cache line. */ + u32 tx_threshold; /* The value for txdesc.count. */ struct RxFD *last_rxf; /* Last command sent. */ + unsigned int cur_rx, dirty_rx; /* The next free ring entry */ + long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ + const char *product_name; + struct net_device *next_module; + void *priv_addr; /* Unaligned address for kfree */ struct enet_statistics stats; struct speedo_stats lstats; + int chip_id; + unsigned char pci_bus, pci_devfn, acpi_pwr; struct timer_list timer; /* Media selection timer. */ - long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ - unsigned int cur_rx, cur_tx; /* The next free ring entry */ - unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ int mc_setup_frm_len; /* The length of an allocated.. */ struct descriptor *mc_setup_frm; /* ..multicast setup frame. */ int mc_setup_busy; /* Avoid double-use of setup frame. */ + int in_interrupt; /* Word-aligned dev->interrupt */ char rx_mode; /* Current PROMISC/ALLMULTI setting. */ unsigned int tx_full:1; /* The Tx queue is full. */ unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int default_port:1; /* Last dev->if_port value. */ + unsigned int flow_ctrl:1; /* Use 802.3x flow control. */ unsigned int rx_bug:1; /* Work around receiver hang errata. */ unsigned int rx_bug10:1; /* Receiver might hang at 10mbps. */ unsigned int rx_bug100:1; /* Receiver might hang at 100mbps. */ + unsigned char default_port:8; /* Last dev->if_port value. */ unsigned short phy[2]; /* PHY media interfaces available. */ + unsigned short advertising; /* Current PHY advertised caps. */ + unsigned short partner; /* Link partner caps. */ + long last_reset; }; /* The parameters for a CmdConfigure operation. There are so many options that it would be difficult to document each bit. We mostly use the default or recommended settings. */ const char i82557_config_cmd[22] = { - 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ + 22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ 0, 0x2E, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ 0x3f, 0x05, }; const char i82558_config_cmd[22] = { - 22, 0x08, 0, 1, 0, 0x80, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ + 22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ 0, 0x2E, 0, 0x60, 0x08, 0x88, 0x68, 0, 0x40, 0xf2, 0xBD, /* 0xBD->0xFD=Force full-duplex */ 0x31, 0x05, }; @@ -394,35 +503,26 @@ static const char *phys[] = { enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240, S80C24, I82555, DP83840A=10, }; static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 }; +#define EE_READ_CMD (6) -static void speedo_found1(struct device *dev, long ioaddr, int irq, - int card_idx); - -static int read_eeprom(long ioaddr, int location, int addr_len); +static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); static int mdio_read(long ioaddr, int phy_id, int location); static int mdio_write(long ioaddr, int phy_id, int location, int value); -static int speedo_open(struct device *dev); +static int speedo_open(struct net_device *dev); +static void speedo_resume(struct net_device *dev); static void speedo_timer(unsigned long data); -static void speedo_init_rx_ring(struct device *dev); -static int speedo_start_xmit(struct sk_buff *skb, struct device *dev); -static int speedo_rx(struct device *dev); +static void speedo_init_rx_ring(struct net_device *dev); +static void speedo_tx_timeout(struct net_device *dev); +static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int speedo_rx(struct net_device *dev); static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int speedo_close(struct device *dev); -static struct enet_statistics *speedo_get_stats(struct device *dev); -static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static void set_rx_mode(struct device *dev); +static int speedo_close(struct net_device *dev); +static struct enet_statistics *speedo_get_stats(struct net_device *dev); +static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static void set_rx_mode(struct net_device *dev); -/* The parameters that may be passed in... */ -/* 'options' is used to pass a transceiver override or full-duplex flag - e.g. "options=16" for FD, "options=32" for 100mbps-only. */ -static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -#ifdef MODULE -static int debug = -1; /* The debug level */ -#endif - #ifdef honor_default_port /* Optional driver feature to allow forcing the transceiver setting. Not recommended. */ @@ -431,9 +531,10 @@ static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100, #endif /* A list of all installed Speedo devices, for removing the driver module. */ -static struct device *root_speedo_dev = NULL; +static struct net_device *root_speedo_dev = NULL; -int eepro100_init(struct device *dev) +#if ! defined(HAS_PCI_NETIF) +int eepro100_init(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; @@ -443,6 +544,7 @@ int eepro100_init(struct device *dev) for (; pci_index < 8; pci_index++) { unsigned char pci_bus, pci_device_fn, pci_latency; + u32 pciaddr; long ioaddr; int irq; @@ -453,13 +555,42 @@ int eepro100_init(struct device *dev) pci_index, &pci_bus, &pci_device_fn)) break; +#if LINUX_VERSION_CODE >= 0x20155 || PCI_SUPPORT_1 { struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[1]; /* Use [0] to mem-map */ +#ifdef USE_IO + pciaddr = pdev->resource[1].start; +#else + pciaddr = pdev->resource[0].start; +#endif irq = pdev->irq; } +#else + { + u8 pci_irq_line; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq_line); + /* Note: BASE_ADDRESS_0 is for memory-mapping the registers. */ +#ifdef USE_IO + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pciaddr); +#else + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pciaddr); +#endif + irq = pci_irq_line; + } +#endif /* Remove I/O space marker in bit 0. */ - ioaddr &= ~3; + if (pciaddr & 1) { + ioaddr = pciaddr & ~3UL; + if (check_region(ioaddr, 32)) + continue; + } else if ((ioaddr = (long)ioremap(pciaddr & ~0xfUL, 0x1000)) == 0) { + printk(KERN_INFO "Failed to map PCI address %#x.\n", + pciaddr); + continue; + } if (speedo_debug > 2) printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n", ioaddr, irq); @@ -485,25 +616,29 @@ int eepro100_init(struct device *dev) } else if (speedo_debug > 1) printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); - speedo_found1(dev, ioaddr, irq, cards_found); + speedo_found1(pci_bus, pci_device_fn, dev, ioaddr, irq, 0,cards_found); dev = NULL; cards_found++; } return cards_found; } +#endif -static void speedo_found1(struct device *dev, long ioaddr, int irq, - int card_idx) +static struct net_device * +speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int card_idx) { - static int did_version = 0; /* Already printed version info. */ struct speedo_private *sp; - char *product; + const char *product; int i, option; - u16 eeprom[0x40]; - + u16 eeprom[0x100]; + int acpi_idle_state = 0; +#ifndef MODULE + static int did_version = 0; /* Already printed version info. */ if (speedo_debug > 0 && did_version++ == 0) printk(version); +#endif dev = init_etherdev(dev, sizeof(struct speedo_private)); @@ -514,16 +649,31 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, else option = 0; +#if defined(HAS_PCI_NETIF) + acpi_idle_state = acpi_set_pwr_state(pci_bus, pci_devfn, ACPI_D0); +#endif + /* Read the station address EEPROM before doing the reset. - Perhaps this should even be done before accepting the device, - then we wouldn't have a device name with which to report the error. */ + Nominally his should even be done before accepting the device, but + then we wouldn't have a device name with which to report the error. + The size test is for 6 bit vs. 8 bit address serial EEPROMs. + */ { u16 sum = 0; int j; - int addr_len = read_eeprom(ioaddr, 0, 6) == 0xffff ? 8 : 6; + int read_cmd, ee_size; + + if ((do_eeprom_cmd(ioaddr, EE_READ_CMD << 24, 27) & 0xffe0000) + == 0xffe0000) { + ee_size = 0x100; + read_cmd = EE_READ_CMD << 24; + } else { + ee_size = 0x40; + read_cmd = EE_READ_CMD << 22; + } - for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom(ioaddr, i, addr_len); + for (j = 0, i = 0; i < ee_size; i++) { + u16 value = do_eeprom_cmd(ioaddr, read_cmd | (i << 16), 27); eeprom[i] = value; sum += value; if (i < 3) { @@ -542,12 +692,12 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, /* Reset the chip: stop Tx and Rx processes and clear counters. This takes less than 10usec and will easily finish before the next action. */ - outl(0, ioaddr + SCBPort); + outl(PortReset, ioaddr + SCBPort); if (eeprom[3] & 0x0100) product = "OEM i82557/i82558 10/100 Ethernet"; else - product = "Intel EtherExpress Pro 10/100"; + product = pci_tbl[chip_idx].name; printk(KERN_INFO "%s: %s at %#3lx, ", dev->name, product, ioaddr); @@ -600,7 +750,7 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, self_test_results = (s32*) ((((long) str) + 15) & ~0xf); self_test_results[0] = 0; self_test_results[1] = -1; - outl(virt_to_bus(self_test_results) | 1, ioaddr + SCBPort); + outl(virt_to_bus(self_test_results) | PortSelfTest, ioaddr + SCBPort); do { udelay(10); } while (self_test_results[1] == -1 && --boguscnt >= 0); @@ -624,19 +774,33 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, } #endif /* kernel_bloat */ + outl(PortReset, ioaddr + SCBPort); +#if defined(HAS_PCI_NETIF) + /* Return the chip to its original power state. */ + acpi_set_pwr_state(pci_bus, pci_devfn, acpi_idle_state); +#endif + /* We do a request_region() only to register /proc/ioports info. */ request_region(ioaddr, SPEEDO3_TOTAL_SIZE, "Intel Speedo3 Ethernet"); dev->base_addr = ioaddr; dev->irq = irq; - if (dev->priv == NULL) - dev->priv = kmalloc(sizeof(*sp), GFP_KERNEL); sp = dev->priv; + if (dev->priv == NULL) { + void *mem = kmalloc(sizeof(*sp), GFP_KERNEL); + dev->priv = sp = mem; /* Cache align here if kmalloc does not. */ + sp->priv_addr = mem; + } memset(sp, 0, sizeof(*sp)); sp->next_module = root_speedo_dev; root_speedo_dev = dev; + sp->pci_bus = pci_bus; + sp->pci_devfn = pci_devfn; + sp->chip_id = chip_idx; + sp->acpi_pwr = acpi_idle_state; + sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0; if (card_idx >= 0) { if (full_duplex[card_idx] >= 0) @@ -659,7 +823,7 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &speedo_ioctl; - return; + return dev; } /* Serial EEPROM section. @@ -668,47 +832,33 @@ static void speedo_found1(struct device *dev, long ioaddr, int irq, #define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ #define EE_CS 0x02 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x01 -#define EE_WRITE_1 0x05 #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define EE_ENB (0x4800 | EE_CS) +#define EE_WRITE_0 0x4802 +#define EE_WRITE_1 0x4806 +#define EE_OFFSET SCBeeprom /* Delay between EEPROM clock transitions. - This will actually work with no delay on 33Mhz PCI. */ -#define eeprom_delay(nanosec) udelay(1); - -/* The EEPROM commands include the alway-set leading bit. */ -#define EE_WRITE_CMD (5 << addr_len) -#define EE_READ_CMD (6 << addr_len) -#define EE_ERASE_CMD (7 << addr_len) + The code works with no delay on 33Mhz PCI. */ +#define eeprom_delay() inw(ee_addr) -static int read_eeprom(long ioaddr, int location, int addr_len) +static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) { - unsigned short retval = 0; - int ee_addr = ioaddr + SCBeeprom; - int read_cmd = location | EE_READ_CMD; - int i; + unsigned retval = 0; + long ee_addr = ioaddr + SCBeeprom; - outw(EE_ENB & ~EE_CS, ee_addr); - outw(EE_ENB, ee_addr); + outw(EE_ENB | EE_SHIFT_CLK, ee_addr); - /* Shift the read command bits out. */ - for (i = 12; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - outw(EE_ENB | dataval, ee_addr); - eeprom_delay(100); - outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(150); - } - outw(EE_ENB, ee_addr); - - for (i = 15; i >= 0; i--) { - outw(EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay(100); + /* Shift the command bits out. */ + do { + short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; + outw(dataval, ee_addr); + eeprom_delay(); + outw(dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(); retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0); - outw(EE_ENB, ee_addr); - eeprom_delay(100); - } + } while (--cmd_len >= 0); + outw(EE_ENB, ee_addr); /* Terminate the EEPROM access. */ outw(EE_ENB & ~EE_CS, ee_addr); @@ -723,6 +873,7 @@ static int mdio_read(long ioaddr, int phy_id, int location) val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val); + break; } } while (! (val & 0x10000000)); return val & 0xffff; @@ -737,6 +888,7 @@ static int mdio_write(long ioaddr, int phy_id, int location, int value) val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val); + break; } } while (! (val & 0x10000000)); return val & 0xffff; @@ -744,26 +896,36 @@ static int mdio_write(long ioaddr, int phy_id, int location, int value) static int -speedo_open(struct device *dev) +speedo_open(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; -#ifdef notdef - /* We could reset the chip, but should not need to. */ - /* In fact we MUST NOT, unless we also re-do the init */ - outl(0, ioaddr + SCBPort); - udelay(10); +#if defined(HAS_PCI_NETIF) + acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, ACPI_D0); #endif - /* This had better be initialized before we initialize the interrupt! */ - sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; - if (speedo_debug > 1) printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); -#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us - /* Retrigger negotiation to reset previous errors. */ + /* Set up the Tx queue early.. */ + sp->cur_tx = 0; + sp->dirty_tx = 0; + sp->last_cmd = 0; + sp->tx_full = 0; + sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; + sp->in_interrupt = 0; + + /* .. we can safely take handler calls during init. */ + if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev)) { + return -EAGAIN; + } + MOD_INC_USE_COUNT; + + dev->if_port = sp->default_port; +#if 0 + /* With some transceivers we must retrigger negotiation to reset + power-up errors. */ if ((sp->phy[0] & 0x8000) == 0) { int phy_addr = sp->phy[0] & 0x1f ; /* Use 0x3300 for restarting NWay, other values to force xcvr: @@ -780,85 +942,30 @@ speedo_open(struct device *dev) } #endif - /* Load the statistics block address. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(virt_to_bus(&sp->lstats), ioaddr + SCBPointer); - outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd); - sp->lstats.done_marker = 0; - speedo_init_rx_ring(dev); - wait_for_cmd_done(ioaddr + SCBCmd); - outl(0, ioaddr + SCBPointer); - outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd); - /* Todo: verify that we must wait for previous command completion. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(virt_to_bus(sp->rx_ringp[0]), ioaddr + SCBPointer); - outw(INT_MASK | RX_START, ioaddr + SCBCmd); - - /* Fill the first command with our physical address. */ - { - u16 *eaddrs = (u16 *)dev->dev_addr; - u16 *setup_frm = (u16 *)&(sp->tx_ring[0].tx_desc_addr); - - /* Avoid a bug(?!) here by marking the command already completed. */ - sp->tx_ring[0].status = ((CmdSuspend | CmdIASetup) << 16) | 0xa000; - sp->tx_ring[0].link = virt_to_bus(&(sp->tx_ring[1])); - *setup_frm++ = eaddrs[0]; - *setup_frm++ = eaddrs[1]; - *setup_frm++ = eaddrs[2]; - } - sp->last_cmd = (struct descriptor *)&sp->tx_ring[0]; - sp->cur_tx = 1; - sp->dirty_tx = 0; - sp->tx_full = 0; - - wait_for_cmd_done(ioaddr + SCBCmd); - outl(0, ioaddr + SCBPointer); - outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd); - - dev->if_port = sp->default_port; + /* Fire up the hardware. */ + speedo_resume(dev); dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; - /* Start the chip's Tx process and unmask interrupts. */ - /* Todo: verify that we must wait for previous command completion. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(virt_to_bus(&sp->tx_ring[0]), ioaddr + SCBPointer); - outw(CU_START, ioaddr + SCBCmd); - /* Setup the chip and configure the multicast list. */ sp->mc_setup_frm = NULL; sp->mc_setup_frm_len = 0; sp->mc_setup_busy = 0; sp->rx_mode = -1; /* Invalid -> always reset the mode. */ + sp->flow_ctrl = sp->partner = 0; set_rx_mode(dev); + if ((sp->phy[0] & 0x8000) == 0) + sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4); if (speedo_debug > 2) { printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n", dev->name, inw(ioaddr + SCBStatus)); } - wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_DUMPSTATS, ioaddr + SCBCmd); - - /* - * Request the IRQ last, after we have set up all data structures. - * It would be bad to get an interrupt before we're ready. - */ - if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, - "Intel EtherExpress Pro 10/100 Ethernet", dev)) { - return -EAGAIN; - } - - /* No need to wait for the command unit to accept here. */ - if ((sp->phy[0] & 0x8000) == 0) - mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); - - MOD_INC_USE_COUNT; - /* Set the timer. The timer serves a dual purpose: 1) to monitor the media interface (e.g. link beat) and perhaps switch to an alternate media type @@ -870,20 +977,104 @@ speedo_open(struct device *dev) sp->timer.function = &speedo_timer; /* timer handler */ add_timer(&sp->timer); + /* No need to wait for the command unit to accept here. */ + if ((sp->phy[0] & 0x8000) == 0) + mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); return 0; } +/* Start the chip hardware after a full reset. */ +static void speedo_resume(struct net_device *dev) +{ + struct speedo_private *sp = (struct speedo_private *)dev->priv; + long ioaddr = dev->base_addr; + + outw(SCBMaskAll, ioaddr + SCBCmd); + + /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */ + sp->tx_threshold = 0x01208000; + + /* Set the segment registers to '0'. */ + wait_for_cmd_done(ioaddr + SCBCmd); + outl(0, ioaddr + SCBPointer); + outb(RxAddrLoad, ioaddr + SCBCmd); + wait_for_cmd_done(ioaddr + SCBCmd); + outb(CUCmdBase, ioaddr + SCBCmd); + wait_for_cmd_done(ioaddr + SCBCmd); + + /* Load the statistics block and rx ring addresses. */ + outl(virt_to_bus(&sp->lstats), ioaddr + SCBPointer); + outb(CUStatsAddr, ioaddr + SCBCmd); + sp->lstats.done_marker = 0; + wait_for_cmd_done(ioaddr + SCBCmd); + + outl(virt_to_bus(sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]), + ioaddr + SCBPointer); + outb(RxStart, ioaddr + SCBCmd); + wait_for_cmd_done(ioaddr + SCBCmd); + + outb(CUDumpStats, ioaddr + SCBCmd); + + /* Fill the first command with our physical address. */ + { + int entry = sp->cur_tx++ % TX_RING_SIZE; + struct descriptor *cur_cmd = (struct descriptor *)&sp->tx_ring[entry]; + + /* Avoid a bug(?!) here by marking the command already completed. */ + cur_cmd->cmd_status = cpu_to_le32((CmdSuspend | CmdIASetup) | 0xa000); + cur_cmd->link = + virt_to_le32bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]); + memcpy(cur_cmd->params, dev->dev_addr, 6); + if (sp->last_cmd) + clear_suspend(sp->last_cmd); + sp->last_cmd = cur_cmd; + } + + /* Start the chip's Tx process and unmask interrupts. */ + wait_for_cmd_done(ioaddr + SCBCmd); + outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]), + ioaddr + SCBPointer); + outw(CUStart, ioaddr + SCBCmd); +} + /* Media monitoring and control. */ static void speedo_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct speedo_private *sp = (struct speedo_private *)dev->priv; + long ioaddr = dev->base_addr; + int phy_num = sp->phy[0] & 0x1f; + + /* We have MII and lost link beat. */ + if ((sp->phy[0] & 0x8000) == 0) { + int partner = mdio_read(ioaddr, phy_num, 5); + if (partner != sp->partner) { + int flow_ctrl = sp->advertising & partner & 0x0400 ? 1 : 0; + sp->partner = partner; + if (flow_ctrl != sp->flow_ctrl) { + sp->flow_ctrl = flow_ctrl; + sp->rx_mode = -1; /* Trigger a reload. */ + } + /* Clear sticky bit. */ + mdio_read(ioaddr, phy_num, 1); + /* If link beat has returned... */ + if (mdio_read(ioaddr, phy_num, 1) & 0x0004) + dev->flags |= IFF_RUNNING; + else + dev->flags &= ~IFF_RUNNING; + } + } if (speedo_debug > 3) { - long ioaddr = dev->base_addr; printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n", dev->name, inw(ioaddr + SCBStatus)); } + /* This has a small false-trigger window. */ + if (test_bit(0, (void*)&dev->tbusy) && + (jiffies - dev->trans_start) > TX_TIMEOUT) { + speedo_tx_timeout(dev); + sp->last_reset = jiffies; + } if (sp->rx_mode < 0 || (sp->rx_bug && jiffies - sp->last_rx_time > 2*HZ)) { /* We haven't received a packet in a Long Time. We might have been @@ -896,9 +1087,42 @@ static void speedo_timer(unsigned long data) add_timer(&sp->timer); } +static void speedo_show_state(struct net_device *dev) +{ + struct speedo_private *sp = (struct speedo_private *)dev->priv; + long ioaddr = dev->base_addr; + int phy_num = sp->phy[0] & 0x1f; + int i; + + /* Print a few items for debugging. */ + if (speedo_debug > 0) { + int i; + printk(KERN_DEBUG "%s: Tx ring dump, Tx queue %d / %d:\n", dev->name, + sp->cur_tx, sp->dirty_tx); + for (i = 0; i < TX_RING_SIZE; i++) + printk(KERN_DEBUG "%s: %c%c%d %8.8x.\n", dev->name, + i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ', + i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ', + i, sp->tx_ring[i].status); + } + printk(KERN_DEBUG "%s:Printing Rx ring (next to receive into %d).\n", + dev->name, sp->cur_rx); + + for (i = 0; i < RX_RING_SIZE; i++) + printk(KERN_DEBUG " Rx ring entry %d %8.8x.\n", + i, (int)sp->rx_ringp[i]->status); + + for (i = 0; i < 16; i++) { + if (i == 6) i = 21; + printk(KERN_DEBUG " PHY index %d register %d is %4.4x.\n", + phy_num, i, mdio_read(ioaddr, phy_num, i)); + } + +} + /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -speedo_init_rx_ring(struct device *dev) +speedo_init_rx_ring(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; struct RxFD *rxf, *last_rxf = NULL; @@ -917,9 +1141,9 @@ speedo_init_rx_ring(struct device *dev) sp->rx_ringp[i] = rxf; skb_reserve(skb, sizeof(struct RxFD)); if (last_rxf) - last_rxf->link = virt_to_bus(rxf); + last_rxf->link = virt_to_le32bus(rxf); last_rxf = rxf; - rxf->status = 0x00000001; /* '1' is flag value only. */ + rxf->status = cpu_to_le32(0x00000001); /* '1' is flag value only. */ rxf->link = 0; /* None yet. */ /* This field unused by i82557, we use it as a consistency check. */ #ifdef final_version @@ -927,35 +1151,45 @@ speedo_init_rx_ring(struct device *dev) #else rxf->rx_buf_addr = virt_to_bus(skb->tail); #endif - rxf->count = 0; - rxf->size = PKT_BUF_SZ; + rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); } sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); /* Mark the last entry as end-of-list. */ - last_rxf->status = 0xC0000002; /* '2' is flag value only. */ + last_rxf->status = cpu_to_le32(0xC0000002); /* '2' is flag value only. */ sp->last_rxf = last_rxf; } -static void speedo_tx_timeout(struct device *dev) +static void speedo_tx_timeout(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; + int status = inw(ioaddr + SCBStatus); + + /* Trigger a stats dump to give time before the reset. */ + speedo_get_stats(dev); printk(KERN_WARNING "%s: Transmit timed out: status %4.4x " " %4.4x at %d/%d command %8.8x.\n", - dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd), + dev->name, status, inw(ioaddr + SCBCmd), sp->dirty_tx, sp->cur_tx, sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status); - if ((inw(ioaddr + SCBStatus) & 0x00C0) != 0x0080) { + speedo_show_state(dev); + if ((status & 0x00C0) != 0x0080 + && (status & 0x003C) == 0x0010) { + /* Only the command unit has stopped. */ printk(KERN_WARNING "%s: Trying to restart the transmitter...\n", dev->name); outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]), ioaddr + SCBPointer); - outw(CU_START, ioaddr + SCBCmd); + outw(CUStart, ioaddr + SCBCmd); } else { - outw(DRVR_INT, ioaddr + SCBCmd); + /* Reset the Tx and Rx units. */ + outl(PortReset, ioaddr + SCBPort); + if (speedo_debug > 0) + speedo_show_state(dev); + udelay(10); + speedo_resume(dev); } -#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ if ((sp->phy[0] & 0x8000) == 0) { int phy_addr = sp->phy[0] & 0x1f; @@ -967,14 +1201,13 @@ static void speedo_tx_timeout(struct device *dev) mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); #endif } -#endif sp->stats.tx_errors++; dev->trans_start = jiffies; return; } static int -speedo_start_xmit(struct sk_buff *skb, struct device *dev) +speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -989,7 +1222,7 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev) return 1; if (tickssofar < TX_TIMEOUT) { /* Reap sent packets from the full Tx queue. */ - outw(DRVR_INT, ioaddr + SCBCmd); + outw(SCBTriggerIntr, ioaddr + SCBCmd); return 1; } speedo_tx_timeout(dev); @@ -1003,43 +1236,39 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev) unsigned long flags; spin_lock_irqsave(&sp->lock, flags); - /* Calculate the Tx descriptor entry. */ entry = sp->cur_tx++ % TX_RING_SIZE; sp->tx_skbuff[entry] = skb; /* Todo: be a little more clever about setting the interrupt bit. */ sp->tx_ring[entry].status = - (CmdSuspend | CmdTx | CmdTxFlex) << 16; + cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex); sp->tx_ring[entry].link = - virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]); + virt_to_le32bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]); sp->tx_ring[entry].tx_desc_addr = - virt_to_bus(&sp->tx_ring[entry].tx_buf_addr0); - /* The data region is always in one buffer descriptor, Tx FIFO - threshold of 256. */ - sp->tx_ring[entry].count = 0x01208000; - sp->tx_ring[entry].tx_buf_addr0 = virt_to_bus(skb->data); - sp->tx_ring[entry].tx_buf_size0 = skb->len; + virt_to_le32bus(&sp->tx_ring[entry].tx_buf_addr0); + /* The data region is always in one buffer descriptor. */ + sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold); + sp->tx_ring[entry].tx_buf_addr0 = virt_to_le32bus(skb->data); + sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len); /* Todo: perhaps leave the interrupt bit set if the Tx queue is more than half full. Argument against: we should be receiving packets and scavenging the queue. Argument for: if so, it shouldn't matter. */ - sp->last_cmd->command &= ~(CmdSuspend | CmdIntr); - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - /* Trigger the command unit resume. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_RESUME, ioaddr + SCBCmd); - + { + struct descriptor *last_cmd = sp->last_cmd; + sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; + clear_suspend(last_cmd); + } + if (sp->cur_tx - sp->dirty_tx >= TX_QUEUE_LIMIT) + sp->tx_full = 1; + else + clear_bit(0, (void*)&dev->tbusy); spin_unlock_irqrestore(&sp->lock, flags); } - - /* Leave room for set_rx_mode() to fill two entries. */ - if (sp->cur_tx - sp->dirty_tx > TX_RING_SIZE - 3) - sp->tx_full = 1; - else - clear_bit(0, (void*)&dev->tbusy); - + wait_for_cmd_done(ioaddr + SCBCmd); + outw(CUResume, ioaddr + SCBCmd); dev->trans_start = jiffies; return 0; @@ -1049,7 +1278,7 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct speedo_private *sp; long ioaddr, boguscnt = max_interrupt_work; unsigned short status; @@ -1063,9 +1292,14 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ioaddr = dev->base_addr; sp = (struct speedo_private *)dev->priv; - spin_lock(&sp->lock); - #ifndef final_version + /* A lock to prevent simultaneous entry on SMP machines. */ + if (test_and_set_bit(0, (void*)&sp->in_interrupt)) { + printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n", + dev->name); + sp->in_interrupt = 0; /* Avoid halting machine. */ + return; + } dev->interrupt = 1; #endif @@ -1085,37 +1319,44 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) speedo_rx(dev); if (status & 0x1000) { - if ((status & 0x003c) == 0x0028) /* No more Rx buffers. */ - outw(RX_RESUMENR, ioaddr + SCBCmd); - else if ((status & 0x003c) == 0x0008) { /* No resources (why?!) */ - /* No idea of what went wrong. Restart the receiver. */ - outl(virt_to_bus(sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]), - ioaddr + SCBPointer); - outw(RX_START, ioaddr + SCBCmd); - } - sp->stats.rx_errors++; + if ((status & 0x003c) == 0x0028) /* No more Rx buffers. */ + outw(RxResumeNoResources, ioaddr + SCBCmd); + else if ((status & 0x003c) == 0x0008) { /* No resources (why?!) */ + /* No idea of what went wrong. Restart the receiver. */ + outl(virt_to_bus(sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]), + ioaddr + SCBPointer); + outw(RxStart, ioaddr + SCBCmd); + } + sp->stats.rx_errors++; } /* User interrupt, Command/Tx unit interrupt or CU not active. */ if (status & 0xA400) { - unsigned int dirty_tx = sp->dirty_tx; + unsigned int dirty_tx; + spin_lock(&sp->lock); + dirty_tx = sp->dirty_tx; while (sp->cur_tx - dirty_tx > 0) { int entry = dirty_tx % TX_RING_SIZE; - int status = sp->tx_ring[entry].status; + int status = le32_to_cpu(sp->tx_ring[entry].status); if (speedo_debug > 5) printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n", entry, status); if ((status & StatusComplete) == 0) break; /* It still hasn't been processed. */ + if (status & TxUnderrun) + if (sp->tx_threshold < 0x01e08000) + sp->tx_threshold += 0x00040000; /* Free the original skb. */ if (sp->tx_skbuff[entry]) { sp->stats.tx_packets++; /* Count only user packets. */ - sp->stats.tx_bytes += sp->tx_skbuff[entry]->len; /* Count transmitted bytes */ +#if LINUX_VERSION_CODE > 0x20127 + sp->stats.tx_bytes += sp->tx_skbuff[entry]->len; +#endif dev_free_skb(sp->tx_skbuff[entry]); sp->tx_skbuff[entry] = 0; - } else if ((sp->tx_ring[entry].status&0x70000) == CmdNOp << 16) + } else if ((status & 0x70000) == CmdNOp) sp->mc_setup_busy = 0; dirty_tx++; } @@ -1129,15 +1370,16 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) } #endif - if (sp->tx_full && dev->tbusy - && dirty_tx > sp->cur_tx - TX_RING_SIZE + 2) { + sp->dirty_tx = dirty_tx; + if (sp->tx_full + && sp->cur_tx - dirty_tx < TX_QUEUE_LIMIT - 1) { /* The ring is no longer full, clear tbusy. */ sp->tx_full = 0; clear_bit(0, (void*)&dev->tbusy); - mark_bh(NET_BH); - } - - sp->dirty_tx = dirty_tx; + spin_unlock(&sp->lock); + netif_wake_queue(dev); + } else + spin_unlock(&sp->lock); } if (--boguscnt < 0) { @@ -1154,12 +1396,12 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) dev->name, inw(ioaddr + SCBStatus)); dev->interrupt = 0; - spin_unlock(&sp->lock); + clear_bit(0, (void*)&sp->in_interrupt); return; } static int -speedo_rx(struct device *dev) +speedo_rx(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; int entry = sp->cur_rx % RX_RING_SIZE; @@ -1170,26 +1412,25 @@ speedo_rx(struct device *dev) printk(KERN_DEBUG " In speedo_rx().\n"); /* If we own the next entry, it's a new packet. Send it up. */ while (sp->rx_ringp[entry] != NULL && - (status = sp->rx_ringp[entry]->status) & RxComplete) { + (status = le32_to_cpu(sp->rx_ringp[entry]->status)) & RxComplete) { + int pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff; if (--rx_work_limit < 0) break; if (speedo_debug > 4) printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status, - sp->rx_ringp[entry]->count & 0x3fff); - if ((status & (RxErrTooBig|RxOK)) != RxOK) { + pkt_len); + if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) { if (status & RxErrTooBig) printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, " "status %8.8x!\n", dev->name, status); - else if ( ! (status & 0x2000)) { + else if ( ! (status & RxOK)) { /* There was a fatal error. This *should* be impossible. */ sp->stats.rx_errors++; printk(KERN_ERR "%s: Anomalous event in speedo_rx(), " - "status %8.8x.\n", - dev->name, status); + "status %8.8x.\n", dev->name, status); } } else { - int pkt_len = sp->rx_ringp[entry]->count & 0x3fff; struct sk_buff *skb; /* Check if the packet is long enough to just accept without @@ -1201,13 +1442,11 @@ speedo_rx(struct device *dev) /* 'skb_put()' points to the start of sk_buff data area. */ #if 1 || USE_IP_CSUM /* Packet is in one chunk -- we can copy + cksum. */ - eth_copy_and_sum(skb, - bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), - pkt_len, 0); + eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0); skb_put(skb, pkt_len); #else - memcpy(skb_put(skb, pkt_len), - bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len); + memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, + pkt_len); #endif } else { void *temp; @@ -1220,24 +1459,28 @@ speedo_rx(struct device *dev) } sp->rx_skbuff[entry] = NULL; temp = skb_put(skb, pkt_len); +#if !defined(final_version) && !defined(__powerpc__) if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp) printk(KERN_ERR "%s: Rx consistency error -- the skbuff " "addresses do not match in speedo_rx: %p vs. %p " "/ %p.\n", dev->name, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), skb->head, temp); +#endif sp->rx_ringp[entry] = NULL; } skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); sp->stats.rx_packets++; - sp->stats.rx_bytes += pkt_len; /* Count received bytes */ +#if LINUX_VERSION_CODE > 0x20127 + sp->stats.rx_bytes += pkt_len; +#endif } entry = (++sp->cur_rx) % RX_RING_SIZE; } /* Refill the Rx ring buffers. */ - for (; sp->dirty_rx < sp->cur_rx; sp->dirty_rx++) { + for (; sp->cur_rx - sp->dirty_rx > 0; sp->dirty_rx++) { struct RxFD *rxf; entry = sp->dirty_rx % RX_RING_SIZE; if (sp->rx_skbuff[entry] == NULL) { @@ -1252,16 +1495,15 @@ speedo_rx(struct device *dev) rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; skb->dev = dev; skb_reserve(skb, sizeof(struct RxFD)); - rxf->rx_buf_addr = virt_to_bus(skb->tail); + rxf->rx_buf_addr = virt_to_le32bus(skb->tail); } else { rxf = sp->rx_ringp[entry]; } - rxf->status = 0xC0000001; /* '1' for driver use only. */ + rxf->status = cpu_to_le32(0xC0000001); /* '1' for driver use only. */ rxf->link = 0; /* None yet. */ - rxf->count = 0; - rxf->size = PKT_BUF_SZ; - sp->last_rxf->link = virt_to_bus(rxf); - sp->last_rxf->status &= ~0xC0000000; + rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); + sp->last_rxf->link = virt_to_le32bus(rxf); + sp->last_rxf->status &= cpu_to_le32(~0xC0000000); sp->last_rxf = rxf; } @@ -1270,7 +1512,7 @@ speedo_rx(struct device *dev) } static int -speedo_close(struct device *dev) +speedo_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct speedo_private *sp = (struct speedo_private *)dev->priv; @@ -1287,8 +1529,8 @@ speedo_close(struct device *dev) del_timer(&sp->timer); /* Disable interrupts, and stop the chip's Rx process. */ - outw(INT_MASK, ioaddr + SCBCmd); - outw(INT_MASK | RX_ABORT, ioaddr + SCBCmd); + outw(SCBMaskAll, ioaddr + SCBCmd); + outw(SCBMaskAll | RxAbort, ioaddr + SCBCmd); free_irq(dev->irq, dev); @@ -1297,8 +1539,12 @@ speedo_close(struct device *dev) struct sk_buff *skb = sp->rx_skbuff[i]; sp->rx_skbuff[i] = 0; /* Clear the Rx descriptors. */ - if (skb) + if (skb) { +#if LINUX_VERSION_CODE < 0x20100 + skb->free = 1; +#endif dev_free_skb(skb); + } } for (i = 0; i < TX_RING_SIZE; i++) { @@ -1314,22 +1560,13 @@ speedo_close(struct device *dev) } /* Print a few items for debugging. */ - if (speedo_debug > 3) { - int phy_num = sp->phy[0] & 0x1f; - printk(KERN_DEBUG "%s:Printing Rx ring (next to receive into %d).\n", - dev->name, sp->cur_rx); - - for (i = 0; i < RX_RING_SIZE; i++) - printk(KERN_DEBUG " Rx ring entry %d %8.8x.\n", - i, (int)sp->rx_ringp[i]->status); - - for (i = 0; i < 5; i++) - printk(KERN_DEBUG " PHY index %d register %d is %4.4x.\n", - phy_num, i, mdio_read(ioaddr, phy_num, i)); - for (i = 21; i < 26; i++) - printk(KERN_DEBUG " PHY index %d register %d is %4.4x.\n", - phy_num, i, mdio_read(ioaddr, phy_num, i)); - } + if (speedo_debug > 3) + speedo_show_state(dev); + +#if defined(HAS_PCI_NETIF) + /* Alt: acpi_set_pwr_state(pci_bus, pci_devfn, sp->acpi_pwr); */ + acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, ACPI_D2); +#endif MOD_DEC_USE_COUNT; return 0; @@ -1348,49 +1585,65 @@ speedo_close(struct device *dev) Oh, and incoming frames are dropped while executing dump-stats! */ static struct enet_statistics * -speedo_get_stats(struct device *dev) +speedo_get_stats(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; - if (sp->lstats.done_marker == 0xA007) { /* Previous dump finished */ - sp->stats.tx_aborted_errors += sp->lstats.tx_coll16_errs; - sp->stats.tx_window_errors += sp->lstats.tx_late_colls; - sp->stats.tx_fifo_errors += sp->lstats.tx_underruns; - sp->stats.tx_fifo_errors += sp->lstats.tx_lost_carrier; - /*sp->stats.tx_deferred += sp->lstats.tx_deferred;*/ - sp->stats.collisions += sp->lstats.tx_total_colls; - sp->stats.rx_crc_errors += sp->lstats.rx_crc_errs; - sp->stats.rx_frame_errors += sp->lstats.rx_align_errs; - sp->stats.rx_over_errors += sp->lstats.rx_resource_errs; - sp->stats.rx_fifo_errors += sp->lstats.rx_overrun_errs; - sp->stats.rx_length_errors += sp->lstats.rx_runt_errs; + /* Update only if the previous dump finished. */ + if (sp->lstats.done_marker == le32_to_cpu(0xA007)) { + sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats.tx_coll16_errs); + sp->stats.tx_window_errors += le32_to_cpu(sp->lstats.tx_late_colls); + sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats.tx_underruns); + sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats.tx_lost_carrier); + /*sp->stats.tx_deferred += le32_to_cpu(sp->lstats.tx_deferred);*/ + sp->stats.collisions += le32_to_cpu(sp->lstats.tx_total_colls); + sp->stats.rx_crc_errors += le32_to_cpu(sp->lstats.rx_crc_errs); + sp->stats.rx_frame_errors += le32_to_cpu(sp->lstats.rx_align_errs); + sp->stats.rx_over_errors += le32_to_cpu(sp->lstats.rx_resource_errs); + sp->stats.rx_fifo_errors += le32_to_cpu(sp->lstats.rx_overrun_errs); + sp->stats.rx_length_errors += le32_to_cpu(sp->lstats.rx_runt_errs); sp->lstats.done_marker = 0x0000; if (dev->start) { wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_DUMPSTATS, ioaddr + SCBCmd); + outw(CUDumpStats, ioaddr + SCBCmd); } } return &sp->stats; } -static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; int phy = sp->phy[0] & 0x1f; +#if defined(HAS_PCI_NETIF) + int saved_acpi; +#endif switch(cmd) { case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ data[0] = phy; case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ +#if defined(HAS_PCI_NETIF) + saved_acpi = acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, ACPI_D0); data[3] = mdio_read(ioaddr, data[0], data[1]); + acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, saved_acpi); +#else + data[3] = mdio_read(ioaddr, data[0], data[1]); +#endif return 0; case SIOCDEVPRIVATE+2: /* Write the specified MII register */ if (!capable(CAP_NET_ADMIN)) return -EPERM; +#if defined(HAS_PCI_NETIF) + saved_acpi = acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, ACPI_D0); + mdio_write(ioaddr, data[0], data[1], data[2]); + acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, saved_acpi); +#else mdio_write(ioaddr, data[0], data[1], data[2]); +#endif return 0; default: return -EOPNOTSUPP; @@ -1406,8 +1659,7 @@ static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd) loaded the link -- we convert the current command block, normally a Tx command, into a no-op and link it to the new command. */ -static void -set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1440,9 +1692,9 @@ set_rx_mode(struct device *dev) sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; sp->tx_skbuff[entry] = 0; /* Redundant. */ - sp->tx_ring[entry].status = (CmdSuspend | CmdConfigure) << 16; + sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdConfigure); sp->tx_ring[entry].link = - virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); + virt_to_le32bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr; /* Construct a full CmdConfig frame. */ memcpy(config_cmd_data, i82558_config_cmd, sizeof(i82558_config_cmd)); @@ -1450,6 +1702,7 @@ set_rx_mode(struct device *dev) config_cmd_data[4] = rxdmacount; config_cmd_data[5] = txdmacount + 0x80; config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0; + config_cmd_data[19] = sp->flow_ctrl ? 0xBD : 0x80; config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0; config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05; if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */ @@ -1457,11 +1710,9 @@ set_rx_mode(struct device *dev) config_cmd_data[8] = 0; } /* Trigger the command unit resume. */ - last_cmd->command &= ~CmdSuspend; - wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_RESUME, ioaddr + SCBCmd); - + clear_suspend(last_cmd); + outw(CUResume, ioaddr + SCBCmd); spin_unlock_irqrestore(&sp->lock, flags); } @@ -1477,12 +1728,12 @@ set_rx_mode(struct device *dev) sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; sp->tx_skbuff[entry] = 0; - sp->tx_ring[entry].status = (CmdSuspend | CmdMulticastList) << 16; + sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdMulticastList); sp->tx_ring[entry].link = - virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); + virt_to_le32bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */ setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr; - *setup_params++ = dev->mc_count*6; + *setup_params++ = cpu_to_le16(dev->mc_count*6); /* Fill in the multicast addresses. */ for (i = 0, mclist = dev->mc_list; i < dev->mc_count; i++, mclist = mclist->next) { @@ -1492,12 +1743,10 @@ set_rx_mode(struct device *dev) *setup_params++ = *eaddrs++; } - last_cmd->command &= ~CmdSuspend; - - /* Immediately trigger the command unit resume. */ wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_RESUME, ioaddr + SCBCmd); - + clear_suspend(last_cmd); + /* Immediately trigger the command unit resume. */ + outw(CUResume, ioaddr + SCBCmd); spin_unlock_irqrestore(&sp->lock, flags); } else if (new_rx_mode == 0) { struct dev_mc_list *mclist; @@ -1521,7 +1770,7 @@ set_rx_mode(struct device *dev) } } /* If we are busy, someone might be quickly adding to the MC list. - Try again later when the list changes stop. */ + Try again later when the list updates stop. */ if (sp->mc_setup_busy) { sp->rx_mode = -1; return; @@ -1532,11 +1781,11 @@ set_rx_mode(struct device *dev) printk(KERN_DEBUG "%s: Constructing a setup frame at %p, " "%d bytes.\n", dev->name, sp->mc_setup_frm, sp->mc_setup_frm_len); - mc_setup_frm->status = 0; - mc_setup_frm->command = CmdSuspend | CmdIntr | CmdMulticastList; + mc_setup_frm->cmd_status = + cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList); /* Link set below. */ setup_params = (u16 *)&mc_setup_frm->params; - *setup_params++ = dev->mc_count*6; + *setup_params++ = cpu_to_le16(dev->mc_count*6); /* Fill in the multicast addresses. */ for (i = 0, mclist = dev->mc_list; i < dev->mc_count; i++, mclist = mclist->next) { @@ -1548,7 +1797,6 @@ set_rx_mode(struct device *dev) /* Disable interrupts while playing with the Tx Cmd list. */ spin_lock_irqsave(&sp->lock, flags); - entry = sp->cur_tx++ % TX_RING_SIZE; last_cmd = sp->last_cmd; sp->last_cmd = mc_setup_frm; @@ -1556,21 +1804,18 @@ set_rx_mode(struct device *dev) /* Change the command to a NoOp, pointing to the CmdMulti command. */ sp->tx_skbuff[entry] = 0; - sp->tx_ring[entry].status = CmdNOp << 16; - sp->tx_ring[entry].link = virt_to_bus(mc_setup_frm); + sp->tx_ring[entry].status = cpu_to_le32(CmdNOp); + sp->tx_ring[entry].link = virt_to_le32bus(mc_setup_frm); /* Set the link in the setup frame. */ mc_setup_frm->link = - virt_to_bus(&(sp->tx_ring[(entry+1) % TX_RING_SIZE])); - - last_cmd->command &= ~CmdSuspend; + virt_to_le32bus(&(sp->tx_ring[(entry+1) % TX_RING_SIZE])); - /* Immediately trigger the command unit resume. */ wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_RESUME, ioaddr + SCBCmd); - + clear_suspend(last_cmd); + /* Immediately trigger the command unit resume. */ + outw(CUResume, ioaddr + SCBCmd); spin_unlock_irqrestore(&sp->lock, flags); - if (speedo_debug > 5) printk(" CmdMCSetup frame length %d in entry %d.\n", dev->mc_count, entry); @@ -1581,42 +1826,64 @@ set_rx_mode(struct device *dev) #ifdef MODULE -int -init_module(void) +int init_module(void) { int cards_found; if (debug >= 0) speedo_debug = debug; + /* Always emit the version message. */ if (speedo_debug) printk(KERN_INFO "%s", version); - root_speedo_dev = NULL; +#if defined(HAS_PCI_NETIF) + cards_found = netif_pci_probe(pci_tbl, NULL); + if (cards_found < 0) + printk(KERN_INFO "eepro100: No cards found, driver not installed.\n"); + return cards_found; +#else cards_found = eepro100_init(NULL); - return cards_found ? 0 : -ENODEV; + if (cards_found <= 0) { + printk(KERN_INFO "eepro100: No cards found, driver not installed.\n"); + return -ENODEV; + } +#endif + return 0; } -void -cleanup_module(void) +void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_speedo_dev) { - next_dev = ((struct speedo_private *)root_speedo_dev->priv)->next_module; + struct speedo_private *sp = (void *)root_speedo_dev->priv; unregister_netdev(root_speedo_dev); +#ifdef USE_IO release_region(root_speedo_dev->base_addr, SPEEDO3_TOTAL_SIZE); +#else + iounmap((char *)root_speedo_dev->base_addr); +#endif +#if defined(HAS_PCI_NETIF) + acpi_set_pwr_state(sp->pci_bus, sp->pci_devfn, sp->acpi_pwr); +#endif + next_dev = sp->next_module; + if (sp->priv_addr) + kfree(sp->priv_addr); kfree(root_speedo_dev); root_speedo_dev = next_dev; } } + #else /* not MODULE */ -int eepro100_probe(struct device *dev) + +int eepro100_probe(struct net_device *dev) { int cards_found = 0; cards_found = eepro100_init(dev); + /* Only emit the version if the driver is being used. */ if (speedo_debug > 0 && cards_found) printk(version); @@ -1626,8 +1893,9 @@ int eepro100_probe(struct device *dev) /* * Local variables: - * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" - * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS` `[ -f ./pci-netif.h ] && echo -DHAS_PCI_NETIF`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * simple-compile-command: "gcc -DMODULE -D__KERNEL__ -O6 -c eepro100.c" * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index f8088862e..e319463be 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -121,7 +121,7 @@ #include <linux/skbuff.h> #include <linux/malloc.h> -#include <asm/spinlock.h> +#include <linux/spinlock.h> #ifndef NET_DEBUG #define NET_DEBUG 4 @@ -236,34 +236,34 @@ static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 }; * Prototypes for Linux interface */ -extern int express_probe(struct device *dev); -static int eexp_open(struct device *dev); -static int eexp_close(struct device *dev); -static struct net_device_stats *eexp_stats(struct device *dev); -static int eexp_xmit(struct sk_buff *buf, struct device *dev); +extern int express_probe(struct net_device *dev); +static int eexp_open(struct net_device *dev); +static int eexp_close(struct net_device *dev); +static struct net_device_stats *eexp_stats(struct net_device *dev); +static int eexp_xmit(struct sk_buff *buf, struct net_device *dev); static void eexp_irq(int irq, void *dev_addr, struct pt_regs *regs); -static void eexp_set_multicast(struct device *dev); +static void eexp_set_multicast(struct net_device *dev); /* * Prototypes for hardware access functions */ -static void eexp_hw_rx_pio(struct device *dev); -static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf, +static void eexp_hw_rx_pio(struct net_device *dev); +static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, unsigned short len); -static int eexp_hw_probe(struct device *dev,unsigned short ioaddr); +static int eexp_hw_probe(struct net_device *dev,unsigned short ioaddr); static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location); -static unsigned short eexp_hw_lasttxstat(struct device *dev); -static void eexp_hw_txrestart(struct device *dev); +static unsigned short eexp_hw_lasttxstat(struct net_device *dev); +static void eexp_hw_txrestart(struct net_device *dev); -static void eexp_hw_txinit (struct device *dev); -static void eexp_hw_rxinit (struct device *dev); +static void eexp_hw_txinit (struct net_device *dev); +static void eexp_hw_rxinit (struct net_device *dev); -static void eexp_hw_init586 (struct device *dev); -static void eexp_setup_filter (struct device *dev); +static void eexp_hw_init586 (struct net_device *dev); +static void eexp_setup_filter (struct net_device *dev); static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"}; enum eexp_iftype {AUI=0, BNC=1, TPE=2}; @@ -275,37 +275,37 @@ enum eexp_iftype {AUI=0, BNC=1, TPE=2}; * Primitive hardware access functions. */ -static inline unsigned short scb_status(struct device *dev) +static inline unsigned short scb_status(struct net_device *dev) { return inw(dev->base_addr + 0xc008); } -static inline unsigned short scb_rdcmd(struct device *dev) +static inline unsigned short scb_rdcmd(struct net_device *dev) { return inw(dev->base_addr + 0xc00a); } -static inline void scb_command(struct device *dev, unsigned short cmd) +static inline void scb_command(struct net_device *dev, unsigned short cmd) { outw(cmd, dev->base_addr + 0xc00a); } -static inline void scb_wrcbl(struct device *dev, unsigned short val) +static inline void scb_wrcbl(struct net_device *dev, unsigned short val) { outw(val, dev->base_addr + 0xc00c); } -static inline void scb_wrrfa(struct device *dev, unsigned short val) +static inline void scb_wrrfa(struct net_device *dev, unsigned short val) { outw(val, dev->base_addr + 0xc00e); } -static inline void set_loopback(struct device *dev) +static inline void set_loopback(struct net_device *dev) { outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config); } -static inline void clear_loopback(struct device *dev) +static inline void clear_loopback(struct net_device *dev) { outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config); } @@ -325,7 +325,7 @@ static inline unsigned short int SHADOW(short int addr) * checks for presence of EtherExpress card */ -int __init express_probe(struct device *dev) +int __init express_probe(struct net_device *dev) { unsigned short *port; static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 }; @@ -356,7 +356,7 @@ int __init express_probe(struct device *dev) * open and initialize the adapter, ready for use */ -static int eexp_open(struct device *dev) +static int eexp_open(struct net_device *dev) { int irq = dev->irq; unsigned short ioaddr = dev->base_addr; @@ -397,7 +397,7 @@ static int eexp_open(struct device *dev) * close and disable the interface, leaving the 586 in reset. */ -static int eexp_close(struct device *dev) +static int eexp_close(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; struct net_local *lp = dev->priv; @@ -426,7 +426,7 @@ static int eexp_close(struct device *dev) * Return interface stats */ -static struct net_device_stats *eexp_stats(struct device *dev) +static struct net_device_stats *eexp_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -438,7 +438,7 @@ static struct net_device_stats *eexp_stats(struct device *dev) * nothing has become jammed in the CU. */ -static void unstick_cu(struct device *dev) +static void unstick_cu(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -519,7 +519,7 @@ static void unstick_cu(struct device *dev) * Called to transmit a packet, or to allow us to right ourselves * if the kernel thinks we've died. */ -static int eexp_xmit(struct sk_buff *buf, struct device *dev) +static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -601,7 +601,7 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev) * check to make sure we've not become wedged. */ -static unsigned short eexp_start_irq(struct device *dev, +static unsigned short eexp_start_irq(struct net_device *dev, unsigned short status) { unsigned short ack_cmd = SCB_ack(status); @@ -659,7 +659,7 @@ static unsigned short eexp_start_irq(struct device *dev, return ack_cmd; } -static void eexp_cmd_clear(struct device *dev) +static void eexp_cmd_clear(struct net_device *dev) { unsigned long int oldtime = jiffies; while (scb_rdcmd(dev) && ((jiffies-oldtime)<10)); @@ -670,7 +670,7 @@ static void eexp_cmd_clear(struct device *dev) static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs) { - struct device *dev = dev_info; + struct net_device *dev = dev_info; struct net_local *lp; unsigned short ioaddr,status,ack_cmd; unsigned short old_read_ptr, old_write_ptr; @@ -781,7 +781,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs) * Set the cable type to use. */ -static void eexp_hw_set_interface(struct device *dev) +static void eexp_hw_set_interface(struct net_device *dev) { unsigned char oldval = inb(dev->base_addr + 0x300e); oldval &= ~0x82; @@ -802,7 +802,7 @@ static void eexp_hw_set_interface(struct device *dev) * descriptor, though we don't bother trying to fix broken ones. */ -static void eexp_hw_rx_pio(struct device *dev) +static void eexp_hw_rx_pio(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short rx_block = lp->rx_ptr; @@ -897,7 +897,7 @@ static void eexp_hw_rx_pio(struct device *dev) * buffer region. */ -static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf, +static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, unsigned short len) { struct net_local *lp = (struct net_local *)dev->priv; @@ -961,7 +961,7 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf, * than one card in a machine. */ -static int __init eexp_hw_probe(struct device *dev, unsigned short ioaddr) +static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr) { unsigned short hw_addr[3]; unsigned char buswidth; @@ -1134,7 +1134,7 @@ static unsigned short __init eexp_hw_readeeprom(unsigned short ioaddr, * again */ -static unsigned short eexp_hw_lasttxstat(struct device *dev) +static unsigned short eexp_hw_lasttxstat(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short tx_block = lp->tx_reap; @@ -1205,7 +1205,7 @@ static unsigned short eexp_hw_lasttxstat(struct device *dev) * we were working on, or the idle loop if we had finished for the time. */ -static void eexp_hw_txrestart(struct device *dev) +static void eexp_hw_txrestart(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -1251,7 +1251,7 @@ static void eexp_hw_txrestart(struct device *dev) * the 586 command unit is continuously active. */ -static void eexp_hw_txinit(struct device *dev) +static void eexp_hw_txinit(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short tx_block = TX_BUF_START; @@ -1293,7 +1293,7 @@ static void eexp_hw_txinit(struct device *dev) * "out of resources" messages). */ -static void eexp_hw_rxinit(struct device *dev) +static void eexp_hw_rxinit(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short rx_block = lp->rx_buf_start; @@ -1352,7 +1352,7 @@ static void eexp_hw_rxinit(struct device *dev) * the hardware is configured correctly. */ -static void eexp_hw_init586(struct device *dev) +static void eexp_hw_init586(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -1475,7 +1475,7 @@ static void eexp_hw_init586(struct device *dev) return; } -static void eexp_setup_filter(struct device *dev) +static void eexp_setup_filter(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; unsigned short ioaddr = dev->base_addr; @@ -1512,7 +1512,7 @@ static void eexp_setup_filter(struct device *dev) * Set or clear the multicast filter for this adaptor. */ static void -eexp_set_multicast(struct device *dev) +eexp_set_multicast(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -1564,7 +1564,7 @@ eexp_set_multicast(struct device *dev) static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, }; -static struct device dev_eexp[EEXP_MAX_CARDS] = +static struct net_device dev_eexp[EEXP_MAX_CARDS] = { { NULL, /* will allocate dynamically */ 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe }, @@ -1585,7 +1585,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_eexp[this_dev]; + struct net_device *dev = &dev_eexp[this_dev]; dev->name = namelist + (NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -1608,7 +1608,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_eexp[this_dev]; + struct net_device *dev = &dev_eexp[this_dev]; if (dev->priv != NULL) { unregister_netdev(dev); kfree(dev->priv); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 1c5d85721..2ff81fba1 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -151,8 +151,8 @@ IVc. Errata /* The rest of these values should never change. */ -static struct device *epic_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx); enum pci_flags_bit { @@ -164,7 +164,7 @@ struct chip_info { const char *name; u16 vendor_id, device_id, device_id_mask, pci_flags; int io_size, min_latency; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); } chip_tbl[] = { {"SMSC EPIC/100 83c170", 0x10B8, 0x0005, 0x7fff, @@ -217,7 +217,7 @@ struct epic_rx_desc { struct epic_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; /* Tx and Rx rings here so that they remain paragraph aligned. */ struct epic_rx_desc rx_ring[RX_RING_SIZE]; @@ -253,28 +253,28 @@ struct epic_private { static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int epic_open(struct device *dev); +static int epic_open(struct net_device *dev); static int read_eeprom(long ioaddr, int location); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); -static void epic_restart(struct device *dev); +static void epic_restart(struct net_device *dev); static void epic_timer(unsigned long data); -static void epic_tx_timeout(struct device *dev); -static void epic_init_ring(struct device *dev); -static int epic_start_xmit(struct sk_buff *skb, struct device *dev); -static int epic_rx(struct device *dev); +static void epic_tx_timeout(struct net_device *dev); +static void epic_init_ring(struct net_device *dev); +static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int epic_rx(struct net_device *dev); static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static int epic_close(struct device *dev); -static struct net_device_stats *epic_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int epic_close(struct net_device *dev); +static struct net_device_stats *epic_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed EPIC devices, for removing the driver module. */ -static struct device *root_epic_dev = NULL; +static struct net_device *root_epic_dev = NULL; #ifndef CARDBUS -int epic100_probe(struct device *dev) +int epic100_probe(struct net_device *dev) { int cards_found = 0; int chip_idx, irq; @@ -285,7 +285,7 @@ int epic100_probe(struct device *dev) struct pci_dev *pcidev = NULL; while ((pcidev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pcidev)) != NULL) { - long pci_ioaddr = pcidev->base_address[0] & ~3; + long pci_ioaddr = pcidev->resource[0].start; int vendor = pcidev->vendor; int device = pcidev->device; @@ -381,8 +381,8 @@ int epic100_probe(struct device *dev) } #endif /* not CARDBUS */ -static struct device *epic_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int card_idx) { struct epic_private *ep; @@ -589,7 +589,7 @@ static void mdio_write(long ioaddr, int phy_id, int location, int value) static int -epic_open(struct device *dev) +epic_open(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -680,7 +680,7 @@ epic_open(struct device *dev) /* Reset the chip to recover from a PCI transaction error. This may occur at interrupt time. */ -static void epic_pause(struct device *dev) +static void epic_pause(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -701,7 +701,7 @@ static void epic_pause(struct device *dev) epic_rx(dev); } -static void epic_restart(struct device *dev) +static void epic_restart(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -752,7 +752,7 @@ static void epic_restart(struct device *dev) static void epic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -784,7 +784,7 @@ static void epic_timer(unsigned long data) } } -static void epic_tx_timeout(struct device *dev) +static void epic_tx_timeout(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -815,7 +815,7 @@ static void epic_tx_timeout(struct device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -epic_init_ring(struct device *dev) +epic_init_ring(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int i; @@ -856,7 +856,7 @@ epic_init_ring(struct device *dev) } static int -epic_start_xmit(struct sk_buff *skb, struct device *dev) +epic_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int entry; @@ -920,7 +920,7 @@ epic_start_xmit(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; int status, boguscnt = max_interrupt_work; @@ -1063,7 +1063,7 @@ static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) return; } -static int epic_rx(struct device *dev) +static int epic_rx(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int entry = ep->cur_rx % RX_RING_SIZE; @@ -1139,7 +1139,7 @@ static int epic_rx(struct device *dev) return work_done; } -static int epic_close(struct device *dev) +static int epic_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -1195,7 +1195,7 @@ static int epic_close(struct device *dev) return 0; } -static struct net_device_stats *epic_get_stats(struct device *dev) +static struct net_device_stats *epic_get_stats(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1237,7 +1237,7 @@ static inline unsigned ether_crc_le(int length, unsigned char *data) } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -1276,7 +1276,7 @@ static void set_rx_mode(struct device *dev) return; } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; @@ -1325,7 +1325,7 @@ static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) static dev_node_t *epic_attach(dev_locator_t *loc) { - struct device *dev; + struct net_device *dev; u16 dev_id; u32 io; u8 bus, devfn, irq; @@ -1357,7 +1357,7 @@ static dev_node_t *epic_attach(dev_locator_t *loc) static void epic_suspend(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_suspend(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1372,7 +1372,7 @@ static void epic_suspend(dev_node_t *node) } static void epic_resume(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_resume(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1384,7 +1384,7 @@ static void epic_resume(dev_node_t *node) } static void epic_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_detach(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1423,7 +1423,7 @@ int init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&epic_ops); diff --git a/drivers/net/eql.c b/drivers/net/eql.c index d677dbf1b..820bc5d4f 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -150,27 +150,27 @@ static const char *version = #endif static unsigned int eql_debug = EQL_DEBUG; -int eql_init(struct device *dev); /* */ -static int eql_open(struct device *dev); /* */ -static int eql_close(struct device *dev); /* */ -static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd); /* */ -static int eql_slave_xmit(struct sk_buff *skb, struct device *dev); /* */ +int eql_init(struct net_device *dev); /* */ +static int eql_open(struct net_device *dev); /* */ +static int eql_close(struct net_device *dev); /* */ +static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* */ +static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev); /* */ -static struct net_device_stats *eql_get_stats(struct device *dev); /* */ +static struct net_device_stats *eql_get_stats(struct net_device *dev); /* */ /* ioctl() handlers ---------------- */ -static int eql_enslave(struct device *dev, slaving_request_t *srq); /* */ -static int eql_emancipate(struct device *dev, slaving_request_t *srq); /* */ +static int eql_enslave(struct net_device *dev, slaving_request_t *srq); /* */ +static int eql_emancipate(struct net_device *dev, slaving_request_t *srq); /* */ -static int eql_g_slave_cfg(struct device *dev, slave_config_t *sc); /* */ -static int eql_s_slave_cfg(struct device *dev, slave_config_t *sc); /* */ +static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ +static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ -static int eql_g_master_cfg(struct device *dev, master_config_t *mc); /* */ -static int eql_s_master_cfg(struct device *dev, master_config_t *mc); /* */ +static int eql_g_master_cfg(struct net_device *dev, master_config_t *mc); /* */ +static int eql_s_master_cfg(struct net_device *dev, master_config_t *mc); /* */ -static inline int eql_is_slave(struct device *dev); /* */ -static inline int eql_is_master(struct device *dev); /* */ +static inline int eql_is_slave(struct net_device *dev); /* */ +static inline int eql_is_master(struct net_device *dev); /* */ static slave_t *eql_new_slave(void); /* */ static void eql_delete_slave(slave_t *slave); /* */ @@ -181,16 +181,16 @@ static inline int eql_number_slaves(slave_queue_t *queue); /* */ static inline int eql_is_empty(slave_queue_t *queue); /* */ static inline int eql_is_full(slave_queue_t *queue); /* */ -static slave_queue_t *eql_new_slave_queue(struct device *dev); /* */ +static slave_queue_t *eql_new_slave_queue(struct net_device *dev); /* */ static void eql_delete_slave_queue(slave_queue_t *queue); /* */ static int eql_insert_slave(slave_queue_t *queue, slave_t *slave); /* */ static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave); /* */ -/* static int eql_insert_slave_dev(slave_queue_t *queue, struct device *dev); -* */ -static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev); /* */ +/* static int eql_insert_slave_dev(slave_queue_t *queue, struct net_device *dev); -* */ +static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ -static inline struct device *eql_best_slave_dev(slave_queue_t *queue); /* */ +static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue); /* */ static inline slave_t *eql_best_slave(slave_queue_t *queue); /* */ static inline slave_t *eql_first_slave(slave_queue_t *queue); /* */ static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave); /* */ @@ -198,18 +198,18 @@ static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave); /* static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave); /* */ static inline void eql_schedule_slaves(slave_queue_t *queue); /* */ -static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct device *dev); /* */ +static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ /* static inline eql_lock_slave_queue(slave_queue_t *queue); -* */ /* static inline eql_unlock_slave_queue(slave_queue_t *queue); -* */ static void eql_timer(unsigned long param); /* */ -/* struct device * interface functions +/* struct net_device * interface functions --------------------------------------------------------- */ -int __init eql_init(struct device *dev) +int __init eql_init(struct net_device *dev) { static unsigned version_printed = 0; /* static unsigned num_masters = 0; */ @@ -268,7 +268,7 @@ int __init eql_init(struct device *dev) return 0; } -static int eql_open(struct device *dev) +static int eql_open(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; slave_queue_t *new_queue; @@ -301,7 +301,7 @@ static int eql_open(struct device *dev) } -static int eql_close(struct device *dev) +static int eql_close(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; @@ -327,7 +327,7 @@ static int eql_close(struct device *dev) } -static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { if(cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG && !capable(CAP_NET_ADMIN)) @@ -352,10 +352,10 @@ static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd) } -static int eql_slave_xmit(struct sk_buff *skb, struct device *dev) +static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; - struct device *slave_dev = 0; + struct net_device *slave_dev = 0; slave_t *slave; if (skb == NULL) @@ -394,7 +394,7 @@ static int eql_slave_xmit(struct sk_buff *skb, struct device *dev) } -static struct net_device_stats * eql_get_stats(struct device *dev) +static struct net_device_stats * eql_get_stats(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; return eql->stats; @@ -404,10 +404,10 @@ static struct net_device_stats * eql_get_stats(struct device *dev) * Private ioctl functions */ -static int eql_enslave(struct device *dev, slaving_request_t *srqp) +static int eql_enslave(struct net_device *dev, slaving_request_t *srqp) { - struct device *master_dev; - struct device *slave_dev; + struct net_device *master_dev; + struct net_device *slave_dev; slaving_request_t srq; int err; @@ -427,7 +427,7 @@ static int eql_enslave(struct device *dev, slaving_request_t *srqp) srq.slave_name, srq.priority); #endif master_dev = dev; /* for "clarity" */ - slave_dev = dev_get (srq.slave_name); + slave_dev = __dev_get_by_name (srq.slave_name); if (master_dev != 0 && slave_dev != 0) { @@ -465,10 +465,10 @@ static int eql_enslave(struct device *dev, slaving_request_t *srqp) return -EINVAL; } -static int eql_emancipate(struct device *dev, slaving_request_t *srqp) +static int eql_emancipate(struct net_device *dev, slaving_request_t *srqp) { - struct device *master_dev; - struct device *slave_dev; + struct net_device *master_dev; + struct net_device *slave_dev; slaving_request_t srq; int err; @@ -481,7 +481,7 @@ static int eql_emancipate(struct device *dev, slaving_request_t *srqp) printk ("%s: emancipate `%s`\n", dev->name, srq.slave_name); #endif master_dev = dev; /* for "clarity" */ - slave_dev = dev_get (srq.slave_name); + slave_dev = __dev_get_by_name (srq.slave_name); if ( eql_is_slave (slave_dev) ) /* really is a slave */ { @@ -494,11 +494,11 @@ static int eql_emancipate(struct device *dev, slaving_request_t *srqp) } -static int eql_g_slave_cfg(struct device *dev, slave_config_t *scp) +static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp) { slave_t *slave; equalizer_t *eql; - struct device *slave_dev; + struct net_device *slave_dev; slave_config_t sc; int err; @@ -511,7 +511,7 @@ static int eql_g_slave_cfg(struct device *dev, slave_config_t *scp) printk ("%s: get config for slave `%s'\n", dev->name, sc.slave_name); #endif eql = (equalizer_t *) dev->priv; - slave_dev = dev_get (sc.slave_name); + slave_dev = __dev_get_by_name (sc.slave_name); if ( eql_is_slave (slave_dev) ) { @@ -530,11 +530,11 @@ static int eql_g_slave_cfg(struct device *dev, slave_config_t *scp) } -static int eql_s_slave_cfg(struct device *dev, slave_config_t *scp) +static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp) { slave_t *slave; equalizer_t *eql; - struct device *slave_dev; + struct net_device *slave_dev; slave_config_t sc; int err; @@ -549,7 +549,7 @@ static int eql_s_slave_cfg(struct device *dev, slave_config_t *scp) eql = (equalizer_t *) dev->priv; - slave_dev = dev_get (sc.slave_name); + slave_dev = __dev_get_by_name (sc.slave_name); if ( eql_is_slave (slave_dev) ) { @@ -566,7 +566,7 @@ static int eql_s_slave_cfg(struct device *dev, slave_config_t *scp) } -static int eql_g_master_cfg(struct device *dev, master_config_t *mcp) +static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp) { equalizer_t *eql; master_config_t mc; @@ -591,7 +591,7 @@ static int eql_g_master_cfg(struct device *dev, master_config_t *mcp) } -static int eql_s_master_cfg(struct device *dev, master_config_t *mcp) +static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp) { equalizer_t *eql; master_config_t mc; @@ -618,7 +618,7 @@ static int eql_s_master_cfg(struct device *dev, master_config_t *mcp) * Private device support functions */ -static inline int eql_is_slave(struct device *dev) +static inline int eql_is_slave(struct net_device *dev) { if (dev) { @@ -629,7 +629,7 @@ static inline int eql_is_slave(struct device *dev) } -static inline int eql_is_master(struct device *dev) +static inline int eql_is_master(struct net_device *dev) { if (dev) { @@ -695,7 +695,7 @@ static inline int eql_is_full(slave_queue_t *queue) return 0; } -static slave_queue_t *eql_new_slave_queue(struct device *dev) +static slave_queue_t *eql_new_slave_queue(struct net_device *dev) { slave_queue_t *queue; slave_t *head_slave; @@ -804,7 +804,7 @@ static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave) } -static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev) +static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev) { slave_t *prev; slave_t *curr; @@ -832,7 +832,7 @@ static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev) } -static inline struct device *eql_best_slave_dev(slave_queue_t *queue) +static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue) { if (queue->best_slave != 0) { @@ -853,7 +853,7 @@ static inline slave_t *eql_best_slave(slave_queue_t *queue) static inline void eql_schedule_slaves(slave_queue_t *queue) { - struct device *master_dev = queue->master_dev; + struct net_device *master_dev = queue->master_dev; slave_t *best_slave = 0; slave_t *slave_corpse = 0; @@ -937,7 +937,7 @@ static inline void eql_schedule_slaves(slave_queue_t *queue) } -static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct device *dev) +static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev) { slave_t *slave = 0; slave = eql_first_slave(queue); @@ -1014,7 +1014,7 @@ static void eql_timer(unsigned long param) } #ifdef MODULE -static struct device dev_eql = +static struct net_device dev_eql = { "eql", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, eql_init }; diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index 71d0631e7..8292fbe43 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -61,17 +61,17 @@ static const char *version = #include <linux/etherdevice.h> #include "8390.h" -int es_probe(struct device *dev); -int es_probe1(struct device *dev, int ioaddr); +int es_probe(struct net_device *dev); +int es_probe1(struct net_device *dev, int ioaddr); -static int es_open(struct device *dev); -static int es_close(struct device *dev); +static int es_open(struct net_device *dev); +static int es_close(struct net_device *dev); -static void es_reset_8390(struct device *dev); +static void es_reset_8390(struct net_device *dev); -static void es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void es_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void es_block_output(struct device *dev, int count, const unsigned char *buf, int start_page); +static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); #define ES_START_PG 0x00 /* First page of TX buffer */ #define ES_STOP_PG 0x40 /* Last page +1 of RX ring */ @@ -124,7 +124,7 @@ static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15}; * PROM for a match against the Racal-Interlan assigned value. */ -int __init es_probe(struct device *dev) +int __init es_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -151,7 +151,7 @@ int __init es_probe(struct device *dev) return ENODEV; } -int __init es_probe1(struct device *dev, int ioaddr) +int __init es_probe1(struct net_device *dev, int ioaddr) { int i; unsigned long eisa_id; @@ -284,7 +284,7 @@ int __init es_probe1(struct device *dev, int ioaddr) * file, this just toggles the "Board Enable" bits (bit 2 and 0). */ -static void es_reset_8390(struct device *dev) +static void es_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; unsigned long end; @@ -318,7 +318,7 @@ static void es_reset_8390(struct device *dev) */ static void -es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - ES_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -331,7 +331,7 @@ es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) * be rounded up to a doubleword value via es_get_8390_hdr() above. */ -static void es_block_input(struct device *dev, int count, struct sk_buff *skb, +static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (ES_START_PG<<8); @@ -348,7 +348,7 @@ static void es_block_input(struct device *dev, int count, struct sk_buff *skb, } } -static void es_block_output(struct device *dev, int count, +static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - ES_START_PG)<<8); @@ -357,7 +357,7 @@ static void es_block_output(struct device *dev, int count, memcpy_toio(shmem, buf, count); } -static int es_open(struct device *dev) +static int es_open(struct net_device *dev) { ei_open(dev); @@ -366,7 +366,7 @@ static int es_open(struct device *dev) return 0; } -static int es_close(struct device *dev) +static int es_close(struct net_device *dev) { if (ei_debug > 1) @@ -383,7 +383,7 @@ static int es_close(struct device *dev) #define MAX_ES_CARDS 4 /* Max number of ES3210 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ES_CARDS] = { 0, }; -static struct device dev_es3210[MAX_ES_CARDS] = { +static struct net_device dev_es3210[MAX_ES_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -406,7 +406,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { - struct device *dev = &dev_es3210[this_dev]; + struct net_device *dev = &dev_es3210[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -434,7 +434,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { - struct device *dev = &dev_es3210[this_dev]; + struct net_device *dev = &dev_es3210[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 8958374d4..7ca5801b2 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -171,7 +171,6 @@ static char *version = #else #define __init #define __initdata -#define __initfunc(x) x #endif #if LINUX_VERSION_CODE < 0x20138 @@ -407,9 +406,9 @@ struct eth16i_local { /* Function prototypes */ -extern int eth16i_probe(struct device *dev); +extern int eth16i_probe(struct net_device *dev); -static int eth16i_probe1(struct device *dev, int ioaddr); +static int eth16i_probe1(struct net_device *dev, int ioaddr); static int eth16i_check_signature(int ioaddr); static int eth16i_probe_port(int ioaddr); static void eth16i_set_port(int ioaddr, int porttype); @@ -419,26 +418,26 @@ static int eth16i_get_irq(int ioaddr); static int eth16i_read_eeprom(int ioaddr, int offset); static int eth16i_read_eeprom_word(int ioaddr); static void eth16i_eeprom_cmd(int ioaddr, unsigned char command); -static int eth16i_open(struct device *dev); -static int eth16i_close(struct device *dev); -static int eth16i_tx(struct sk_buff *skb, struct device *dev); -static void eth16i_rx(struct device *dev); +static int eth16i_open(struct net_device *dev); +static int eth16i_close(struct net_device *dev); +static int eth16i_tx(struct sk_buff *skb, struct net_device *dev); +static void eth16i_rx(struct net_device *dev); static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eth16i_reset(struct device *dev); -static void eth16i_skip_packet(struct device *dev); -static void eth16i_multicast(struct device *dev); +static void eth16i_reset(struct net_device *dev); +static void eth16i_skip_packet(struct net_device *dev); +static void eth16i_multicast(struct net_device *dev); static void eth16i_select_regbank(unsigned char regbank, int ioaddr); -static void eth16i_initialize(struct device *dev); +static void eth16i_initialize(struct net_device *dev); #if 0 -static int eth16i_set_irq(struct device *dev); +static int eth16i_set_irq(struct net_device *dev); #endif #ifdef MODULE static ushort eth16i_parse_mediatype(const char* s); #endif -static struct enet_statistics *eth16i_get_stats(struct device *dev); +static struct enet_statistics *eth16i_get_stats(struct net_device *dev); static char *cardname = "ICL EtherTeam 16i/32"; @@ -450,7 +449,7 @@ static char *cardname = "ICL EtherTeam 16i/32"; #else /* Not HAVE_DEVLIST */ -int __init eth16i_probe(struct device *dev) +int __init eth16i_probe(struct net_device *dev) { int i; int ioaddr; @@ -484,7 +483,7 @@ int __init eth16i_probe(struct device *dev) } #endif /* Not HAVE_DEVLIST */ -static int __init eth16i_probe1(struct device *dev, int ioaddr) +static int __init eth16i_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; boot = 1; /* To inform initilization that we are in boot probe */ @@ -593,7 +592,7 @@ static int __init eth16i_probe1(struct device *dev, int ioaddr) } -static void eth16i_initialize(struct device *dev) +static void eth16i_initialize(struct net_device *dev) { int ioaddr = dev->base_addr; int i, node_w = 0; @@ -824,7 +823,7 @@ static int eth16i_receive_probe_packet(int ioaddr) } #if 0 -static int eth16i_set_irq(struct device* dev) +static int eth16i_set_irq(struct net_device* dev) { const int ioaddr = dev->base_addr; const int irq = dev->irq; @@ -966,7 +965,7 @@ static void eth16i_eeprom_cmd(int ioaddr, unsigned char command) } } -static int eth16i_open(struct device *dev) +static int eth16i_open(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1007,7 +1006,7 @@ static int eth16i_open(struct device *dev) return 0; } -static int eth16i_close(struct device *dev) +static int eth16i_close(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1036,7 +1035,7 @@ static int eth16i_close(struct device *dev) return 0; } -static int eth16i_tx(struct sk_buff *skb, struct device *dev) +static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1185,7 +1184,7 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev) return status; } -static void eth16i_rx(struct device *dev) +static void eth16i_rx(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1300,7 +1299,7 @@ static void eth16i_rx(struct device *dev) static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct eth16i_local *lp; int ioaddr = 0, status; @@ -1406,7 +1405,7 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -static void eth16i_skip_packet(struct device *dev) +static void eth16i_skip_packet(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1418,7 +1417,7 @@ static void eth16i_skip_packet(struct device *dev) while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0); } -static void eth16i_reset(struct device *dev) +static void eth16i_reset(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1441,7 +1440,7 @@ static void eth16i_reset(struct device *dev) BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); } -static void eth16i_multicast(struct device *dev) +static void eth16i_multicast(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1454,7 +1453,7 @@ static void eth16i_multicast(struct device *dev) } } -static struct enet_statistics *eth16i_get_stats(struct device *dev) +static struct enet_statistics *eth16i_get_stats(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; @@ -1492,7 +1491,7 @@ static ushort eth16i_parse_mediatype(const char* s) #define NAMELEN 8 /* number of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, }; -static struct device dev_eth16i[MAX_ETH16I_CARDS] = { +static struct net_device dev_eth16i[MAX_ETH16I_CARDS] = { { NULL, 0, 0, 0, 0, @@ -1533,7 +1532,7 @@ int init_module(void) for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) { - struct device *dev = &dev_eth16i[this_dev]; + struct net_device *dev = &dev_eth16i[this_dev]; dev->name = namelist + (NAMELEN*this_dev); dev->irq = 0; /* irq[this_dev]; */ @@ -1575,7 +1574,7 @@ void cleanup_module(void) for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) { - struct device* dev = &dev_eth16i[this_dev]; + struct net_device* dev = &dev_eth16i[this_dev]; if(dev->priv != NULL) { diff --git a/drivers/net/ethertap.c b/drivers/net/ethertap.c index d0cc26e51..0b5aa3db8 100644 --- a/drivers/net/ethertap.c +++ b/drivers/net/ethertap.c @@ -33,19 +33,19 @@ * Index to functions. */ -int ethertap_probe(struct device *dev); -static int ethertap_open(struct device *dev); -static int ethertap_start_xmit(struct sk_buff *skb, struct device *dev); -static int ethertap_close(struct device *dev); -static struct net_device_stats *ethertap_get_stats(struct device *dev); +int ethertap_probe(struct net_device *dev); +static int ethertap_open(struct net_device *dev); +static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ethertap_close(struct net_device *dev); +static struct net_device_stats *ethertap_get_stats(struct net_device *dev); static void ethertap_rx(struct sock *sk, int len); #ifdef CONFIG_ETHERTAP_MC -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif static int ethertap_debug = 0; -static struct device *tap_map[32]; /* Returns the tap device for a given netlink */ +static struct net_device *tap_map[32]; /* Returns the tap device for a given netlink */ /* * Board-specific info in dev->priv. @@ -65,7 +65,7 @@ struct net_local * hardware it would have to check what was present. */ -int __init ethertap_probe(struct device *dev) +int __init ethertap_probe(struct net_device *dev) { memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6); if (dev->mem_start & 0xf) @@ -109,7 +109,7 @@ int __init ethertap_probe(struct device *dev) * Open/initialize the board. */ -static int ethertap_open(struct device *dev) +static int ethertap_open(struct net_device *dev) { struct net_local *lp = (struct net_local*)dev->priv; @@ -142,7 +142,7 @@ static unsigned ethertap_mc_hash(__u8 *dest) return 1U << (idx&0x1F); } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { unsigned groups = ~0; struct net_local *lp = (struct net_local *)dev->priv; @@ -169,7 +169,7 @@ static void set_multicast_list(struct device *dev) * it for 2.0 so that we dev_kfree_skb() the locked original. */ -static int ethertap_start_xmit(struct sk_buff *skb, struct device *dev) +static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; #ifdef CONFIG_ETHERTAP_MC @@ -227,7 +227,7 @@ static int ethertap_start_xmit(struct sk_buff *skb, struct device *dev) return 0; } -static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct device *dev) +static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; #ifdef CONFIG_ETHERTAP_MC @@ -295,7 +295,7 @@ static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct device *dev) static void ethertap_rx(struct sock *sk, int len) { - struct device *dev = tap_map[sk->protocol]; + struct net_device *dev = tap_map[sk->protocol]; struct sk_buff *skb; if (dev==NULL) { @@ -311,7 +311,7 @@ static void ethertap_rx(struct sock *sk, int len) ethertap_rx_skb(skb, dev); } -static int ethertap_close(struct device *dev) +static int ethertap_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; struct sock *sk = lp->nl; @@ -331,7 +331,7 @@ static int ethertap_close(struct device *dev) return 0; } -static struct net_device_stats *ethertap_get_stats(struct device *dev) +static struct net_device_stats *ethertap_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -344,7 +344,7 @@ MODULE_PARM(unit,"i"); static char devicename[9] = { 0, }; -static struct device dev_ethertap = +static struct net_device dev_ethertap = { devicename, 0, 0, 0, 0, diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 5f3b8d744..40e2ec507 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -288,36 +288,36 @@ struct ewrk3_private { /* ** Public Functions */ -static int ewrk3_open(struct device *dev); -static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev); +static int ewrk3_open(struct net_device *dev); +static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int ewrk3_close(struct device *dev); -static struct net_device_stats *ewrk3_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); -static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int ewrk3_close(struct net_device *dev); +static struct net_device_stats *ewrk3_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* ** Private functions */ -static int ewrk3_hw_init(struct device *dev, u_long iobase); -static void ewrk3_init(struct device *dev); -static int ewrk3_rx(struct device *dev); -static int ewrk3_tx(struct device *dev); +static int ewrk3_hw_init(struct net_device *dev, u_long iobase); +static void ewrk3_init(struct net_device *dev); +static int ewrk3_rx(struct net_device *dev); +static int ewrk3_tx(struct net_device *dev); static void EthwrkSignature(char *name, char *eeprom_image); static int DevicePresent(u_long iobase); -static void SetMulticastFilter(struct device *dev); +static void SetMulticastFilter(struct net_device *dev); static int EISA_signature(char *name, s32 eisa_id); static int Read_EEPROM(u_long iobase, u_char eaddr); static int Write_EEPROM(short data, u_long iobase, u_char eaddr); -static u_char get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType); +static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType); -static void isa_probe(struct device *dev, u_long iobase); -static void eisa_probe(struct device *dev, u_long iobase); -static struct device *alloc_device(struct device *dev, u_long iobase); +static void isa_probe(struct net_device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); +static struct net_device *alloc_device(struct net_device *dev, u_long iobase); static int ewrk3_dev_index(char *s); -static struct device *insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *)); #ifdef MODULE @@ -343,7 +343,7 @@ static int num_ewrk3s = 0, num_eth = 0; mdelay(1);\ } -int __init ewrk3_probe(struct device *dev) +int __init ewrk3_probe(struct net_device *dev) { int tmp = num_ewrk3s, status = -ENODEV; u_long iobase = dev->base_addr; @@ -376,7 +376,7 @@ int __init ewrk3_probe(struct device *dev) } static int __init -ewrk3_hw_init(struct device *dev, u_long iobase) +ewrk3_hw_init(struct net_device *dev, u_long iobase) { struct ewrk3_private *lp; int i, status = 0; @@ -621,7 +621,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase) } -static int ewrk3_open(struct device *dev) +static int ewrk3_open(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -690,7 +690,7 @@ static int ewrk3_open(struct device *dev) /* ** Initialize the EtherWORKS 3 operating conditions */ -static void ewrk3_init(struct device *dev) +static void ewrk3_init(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_char csr, page; @@ -724,7 +724,7 @@ static void ewrk3_init(struct device *dev) /* ** Writes a socket buffer to the free page queue */ -static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) +static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -873,7 +873,7 @@ static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) */ static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct ewrk3_private *lp; u_long iobase; u_char icr, cr, csr; @@ -934,7 +934,7 @@ static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } -static int ewrk3_rx(struct device *dev) +static int ewrk3_rx(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1078,7 +1078,7 @@ static int ewrk3_rx(struct device *dev) /* ** Buffer sent - check for TX buffer errors. */ -static int ewrk3_tx(struct device *dev) +static int ewrk3_tx(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1114,7 +1114,7 @@ static int ewrk3_tx(struct device *dev) return 0; } -static int ewrk3_close(struct device *dev) +static int ewrk3_close(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1152,7 +1152,7 @@ static int ewrk3_close(struct device *dev) return 0; } -static struct net_device_stats *ewrk3_get_stats(struct device *dev) +static struct net_device_stats *ewrk3_get_stats(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; @@ -1163,7 +1163,7 @@ static struct net_device_stats *ewrk3_get_stats(struct device *dev) /* ** Set or clear the multicast filter for this adapter. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1196,7 +1196,7 @@ static void set_multicast_list(struct device *dev) ** Note that when clearing the table, the broadcast bit must remain asserted ** to receive broadcast messages. */ -static void SetMulticastFilter(struct device *dev) +static void SetMulticastFilter(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; @@ -1282,7 +1282,7 @@ static void SetMulticastFilter(struct device *dev) /* ** ISA bus I/O device probe */ -static void __init isa_probe(struct device *dev, u_long ioaddr) +static void __init isa_probe(struct net_device *dev, u_long ioaddr) { int i = num_ewrk3s, maxSlots; u_long iobase; @@ -1322,7 +1322,7 @@ static void __init isa_probe(struct device *dev, u_long ioaddr) ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. */ -static void __init eisa_probe(struct device *dev, u_long ioaddr) +static void __init eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots; u_long iobase; @@ -1369,10 +1369,10 @@ static void __init eisa_probe(struct device *dev, u_long ioaddr) ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * __init -alloc_device(struct device *dev, u_long iobase) +static struct net_device * __init +alloc_device(struct net_device *dev, u_long iobase) { - struct device *adev = NULL; + struct net_device *adev = NULL; int fixed = 0, new_dev = 0; num_eth = ewrk3_dev_index(dev->name); @@ -1414,12 +1414,12 @@ alloc_device(struct device *dev, u_long iobase) ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static __init struct device * -insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)) +static struct net_device * __init +insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *) kmalloc(sizeof(struct device) + 8, GFP_KERNEL); + new = (struct net_device *) kmalloc(sizeof(struct net_device) + 8, GFP_KERNEL); if (new == NULL) { printk("eth%d: Device not initialised, insufficient memory\n", num_eth); return NULL; @@ -1570,7 +1570,7 @@ static int __init DevicePresent(u_long iobase) return status; } -static u_char __init get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType) +static u_char __init get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType) { int i, j, k; u_short chksum; @@ -1658,7 +1658,7 @@ static int __init EISA_signature(char *name, s32 eisa_id) ** Perform IOCTL call functions here. Some are privileged operations and the ** effective uid is checked in those cases. */ -static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data; @@ -1879,7 +1879,7 @@ static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd) #ifdef MODULE static char devicename[9] = {0,}; -static struct device thisEthwrk = +static struct net_device thisEthwrk = { devicename, /* device name is inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff --git a/drivers/net/fc/.cvsignore b/drivers/net/fc/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/drivers/net/fc/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/drivers/net/fc/Makefile b/drivers/net/fc/Makefile new file mode 100644 index 000000000..6fd921f52 --- /dev/null +++ b/drivers/net/fc/Makefile @@ -0,0 +1,28 @@ + +# Makefile for linux/drivers/net/fc +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +L_TARGET := fc.a +L_OBJS := +M_OBJS := +MX_OBJS := +MOD_LIST_NAME := FC_MODULES +FC_SRCS = $(wildcard $(L_OBJS:%.o=%.c)) + +ifeq ($(CONFIG_IPHASE5526),y) +L_OBJS += iph5526.o +else + ifeq ($(CONFIG_IPHASE5526),m) + M_OBJS += iph5526.o + endif +endif + +include $(TOPDIR)/Rules.make + +clean: + rm *.o + diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c new file mode 100644 index 000000000..9cad49031 --- /dev/null +++ b/drivers/net/fc/iph5526.c @@ -0,0 +1,4702 @@ +/********************************************************************** + * iph5526.c: IP/SCSI driver for the Interphase 5526 PCI Fibre Channel + * Card. + * Copyright (C) 1999 Vineet M Abraham <vma@iol.unh.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + *********************************************************************/ +/********************************************************************** +Log: +Vineet M Abraham +02.12.99 Support multiple cards. +03.15.99 Added Fabric support. +04.04.99 Added N_Port support. +04.15.99 Added SCSI support. +06.18.99 Added ABTS Protocol. +06.24.99 Fixed data corruption when multiple XFER_RDYs are received. +07.07.99 Can be loaded as part of the Kernel. Changed semaphores. Added + more checks before invalidating SEST entries. +07.08.99 Added Broadcast IP stuff and fixed an unicast timeout bug. +***********************************************************************/ +/* TODO: + R_T_TOV set to 15msec in Loop topology. Need to be 100 msec. + SMP testing. + Fix ADISC Tx before completing FLOGI. +*/ + +static const char *version = + "iph5526.c:v1.0 07.08.99 Vineet Abraham (vma@iol.unh.edu)\n"; + +#include <linux/module.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/delay.h> +#include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/timer.h> +#include <linux/spinlock.h> +#include <asm/system.h> +#include <asm/io.h> + +#include <linux/netdevice.h> +#include <linux/fcdevice.h> /* had the declarations for init_fcdev among others + includes if_fcdevice.h */ + +#include <linux/blk.h> +#include "../../scsi/sd.h" +#include "../../scsi/scsi.h" +#include "../../scsi/hosts.h" +#include "../../fc4/fcp.h" + +/* driver specific header files */ +#include "tach.h" +#include "tach_structs.h" +#include "iph5526_ip.h" +#include "iph5526_scsi.h" +#include "iph5526_novram.c" + +#define RUN_AT(x) (jiffies + (x)) + +#define DEBUG_5526_0 0 +#define DEBUG_5526_1 0 +#define DEBUG_5526_2 0 + +#if DEBUG_5526_0 +#define DPRINTK(format, a...) {printk("%s: ", fi->name); \ + printk(format, ##a); \ + printk("\n");} +#define ENTER(x) {printk("%s: ", fi->name); \ + printk("iph5526.c : entering %s()\n", x);} +#define LEAVE(x) {printk("%s: ", fi->name); \ + printk("iph5526.c : leaving %s()\n",x);} + +#else +#define DPRINTK(format, a...) {} +#define ENTER(x) {} +#define LEAVE(x) {} +#endif + +#if DEBUG_5526_1 +#define DPRINTK1(format, a...) {printk("%s: ", fi->name); \ + printk(format, ##a); \ + printk("\n");} +#else +#define DPRINTK1(format, a...) {} +#endif + +#if DEBUG_5526_2 +#define DPRINTK2(format, a...) {printk("%s: ", fi->name); \ + printk(format, ##a); \ + printk("\n");} +#else +#define DPRINTK2(format, a...) {} +#endif + +#define T_MSG(format, a...) {printk("%s: ", fi->name); \ + printk(format, ##a);\ + printk("\n");} + +#define ALIGNED_SFS_ADDR(addr) ((((unsigned long)(addr) + (SFS_BUFFER_SIZE - 1)) & ~(SFS_BUFFER_SIZE - 1)) - (unsigned long)(addr)) +#define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr)) + + +#define MAX_FC_CARDS 2 +static struct fc_info *fc[MAX_FC_CARDS+1]; +static unsigned int pci_irq_line = 0; +static struct { + unsigned short vendor_id; + unsigned short device_id; + char *name; +} +clone_list[] __initdata = { + {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, "Interphase Fibre Channel HBA"}, + {PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, "Interphase Fibre Channel HBA"}, + {0,} +}; + +static void tachyon_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs); + +static int initialize_register_pointers(struct fc_info *fi); +void clean_up_memory(struct fc_info *fi); + +static int tachyon_init(struct fc_info *fi); +static int build_queues(struct fc_info *fi); +static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short rx_id, char *data); +static int get_free_header(struct fc_info *fi); +static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len); +static int get_free_EDB(struct fc_info *fi); +static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int int_required, u_int frame_class); +static void write_to_tachyon_registers(struct fc_info *fi); +static void reset_latch(struct fc_info *fi); +static void reset_tachyon(struct fc_info *fi, u_int value); +static void take_tachyon_offline(struct fc_info *fi); +static void read_novram(struct fc_info *fi); +static void reset_ichip(struct fc_info *fi); +static void update_OCQ_indx(struct fc_info *fi); +static void update_IMQ_indx(struct fc_info *fi, int count); +static void update_SFSBQ_indx(struct fc_info *fi); +static void update_MFSBQ_indx(struct fc_info *fi, int count); +static void update_tachyon_header_indx(struct fc_info *fi); +static void update_EDB_indx(struct fc_info *fi); +static void handle_FM_interrupt(struct fc_info *fi); +static void handle_MFS_interrupt(struct fc_info *fi); +static void handle_OOO_interrupt(struct fc_info *fi); +static void handle_SFS_interrupt(struct fc_info *fi); +static void handle_OCI_interrupt(struct fc_info *fi); +static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi); +static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi); +static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi); +static void handle_Unknown_Frame_interrupt(struct fc_info *fi); +static void handle_Busied_Frame_interrupt(struct fc_info *fi); +static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi); +static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi); +static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi); +static void completion_message_handler(struct fc_info *fi, u_int imq_int_type); +static void fill_login_frame(struct fc_info *fi, u_int logi); + +static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short ox_id, u_int frame_class); +static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int int_required, u_int frame_class); +static int validate_login(struct fc_info *fi, u_int *base_ptr); +static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr); +static void remove_from_address_cache(struct fc_info *fi, u_int *data, u_int cmnd_code); +static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr); +static int sid_logged_in(struct fc_info *fi, u_int s_id); +static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data); +static int display_cache(struct fc_info *fi); + +static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id); +static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id); +static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id); +static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id); +static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id); +static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, u_short reason_code, u_short expln_code); +static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size); +static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id); +static void tx_name_server_req(struct fc_info *fi, u_int req); +static void rscn_handler(struct fc_info *fi, u_int node_id); +static void tx_scr(struct fc_info *fi); +static void scr_timer(unsigned long data); +static void explore_fabric(struct fc_info *fi, u_int *buff_addr); +static void perform_adisc(struct fc_info *fi); +static void local_port_discovery(struct fc_info *fi); +static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code); +static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id); +static void add_display_cache_timer(struct fc_info *fi); + +/* Timers... */ +static void nos_ols_timer(unsigned long data); +static void loop_timer(unsigned long data); +static void fabric_explore_timer(unsigned long data); +static void port_discovery_timer(unsigned long data); +static void display_cache_timer(unsigned long data); + +/* SCSI Stuff */ +static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni); +static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target); +static void update_FCP_CMND_indx(struct fc_info *fi); +static int get_free_SDB(struct fc_info *fi); +static void update_SDB_indx(struct fc_info *fi); +static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action); +static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id); +static int abort_exchange(struct fc_info *fi, u_short ox_id); +static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id); +static int get_scsi_oxid(struct fc_info *fi); +static void update_scsi_oxid(struct fc_info *fi); + +Scsi_Host_Template driver_template = IPH5526_SCSI_FC; + + +#ifdef CONFIG_PCI +static int iph5526_probe_pci(struct net_device *dev); +#endif + + +int __init iph5526_probe(struct net_device *dev) +{ +#ifdef CONFIG_PCI + if (pci_present() && (iph5526_probe_pci(dev) == 0)) + return 0; +#endif + return -ENODEV; +} + +#ifdef CONFIG_PCI +static int __init iph5526_probe_pci(struct net_device *dev) +{ +#ifndef MODULE +struct fc_info *fi; +static int count = 0; +#endif +#ifdef MODULE +struct fc_info *fi = (struct fc_info *)dev->priv; +#endif + +#ifndef MODULE + if(fc[count] != NULL) { + if (dev == NULL) { + dev = init_fcdev(NULL, 0); + if (dev == NULL) + return -ENOMEM; + } + fi = fc[count]; +#endif + fi->dev = dev; + dev->base_addr = fi->base_addr; + dev->irq = fi->irq; + if (dev->priv == NULL) + dev->priv = fi; + fcdev_init(dev); + /* Assign ur MAC address. + */ + dev->dev_addr[0] = (fi->g.my_port_name_high & 0x0000FF00) >> 8; + dev->dev_addr[1] = fi->g.my_port_name_high; + dev->dev_addr[2] = (fi->g.my_port_name_low & 0xFF000000) >> 24; + dev->dev_addr[3] = (fi->g.my_port_name_low & 0x00FF0000) >> 16; + dev->dev_addr[4] = (fi->g.my_port_name_low & 0x0000FF00) >> 8; + dev->dev_addr[5] = fi->g.my_port_name_low; +#ifndef MODULE + count++; + } + else + return -ENODEV; +#endif + display_cache(fi); + return 0; +} +#endif /* CONFIG_PCI */ + +static int __init fcdev_init(struct net_device *dev) +{ + dev->open = iph5526_open; + dev->stop = iph5526_close; + dev->hard_start_xmit = iph5526_send_packet; + dev->get_stats = iph5526_get_stats; + dev->set_multicast_list = NULL; + dev->change_mtu = iph5526_change_mtu; +#ifndef MODULE + fc_setup(dev); +#endif + return 0; +} + +/* initialize tachyon and take it OnLine */ +static int tachyon_init(struct fc_info *fi) +{ + ENTER("tachyon_init"); + if (build_queues(fi) == 0) { + T_MSG("build_queues() failed"); + return 0; + } + + /* Retrieve your port/node name. + */ + read_novram(fi); + + reset_ichip(fi); + + reset_tachyon(fi, SOFTWARE_RESET); + + LEAVE("tachyon_init"); + return 1; +} + +/* Build the 4 Qs - IMQ, OCQ, MFSBQ, SFSBQ */ +/* Lots of dma_pages needed as Tachyon DMAs almost everything into + * host memory. + */ +static int build_queues(struct fc_info *fi) +{ +int i,j; +u_char *addr; + ENTER("build_queues"); + /* Initializing Queue Variables. + */ + fi->q.ptr_host_ocq_cons_indx = NULL; + fi->q.ptr_host_hpcq_cons_indx = NULL; + fi->q.ptr_host_imq_prod_indx = NULL; + + fi->q.ptr_ocq_base = NULL; + fi->q.ocq_len = 0; + fi->q.ocq_end = 0; + fi->q.ocq_prod_indx = 0; + + fi->q.ptr_imq_base = NULL; + fi->q.imq_len = 0; + fi->q.imq_end = 0; + fi->q.imq_cons_indx = 0; + fi->q.imq_prod_indx = 0; + + fi->q.ptr_mfsbq_base = NULL; + fi->q.mfsbq_len = 0; + fi->q.mfsbq_end = 0; + fi->q.mfsbq_prod_indx = 0; + fi->q.mfsbq_cons_indx = 0; + fi->q.mfsbuff_len = 0; + fi->q.mfsbuff_end = 0; + fi->g.mfs_buffer_count = 0; + + fi->q.ptr_sfsbq_base = NULL; + fi->q.sfsbq_len = 0; + fi->q.sfsbq_end = 0; + fi->q.sfsbq_prod_indx = 0; + fi->q.sfsbq_cons_indx = 0; + fi->q.sfsbuff_len = 0; + fi->q.sfsbuff_end = 0; + + fi->q.sdb_indx = 0; + fi->q.fcp_cmnd_indx = 0; + + fi->q.ptr_edb_base = NULL; + fi->q.edb_buffer_indx = 0; + fi->q.ptr_tachyon_header_base = NULL; + fi->q.tachyon_header_indx = 0; + fi->node_info_list = NULL; + fi->ox_id_list = NULL; + fi->g.loop_up = FALSE; + fi->g.ptp_up = FALSE; + fi->g.link_up = FALSE; + fi->g.fabric_present = FALSE; + fi->g.n_port_try = FALSE; + fi->g.dont_init = FALSE; + fi->g.nport_timer_set = FALSE; + fi->g.lport_timer_set = FALSE; + fi->g.no_of_targets = 0; + fi->g.sem = 0; + fi->g.perform_adisc = FALSE; + fi->g.e_i = 0; + + /* build OCQ */ + if ( (fi->q.ptr_ocq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) { + T_MSG("failed to get OCQ page"); + return 0; + } + /* set up the OCQ structures */ + for (i = 0; i < OCQ_LENGTH; i++) + fi->q.ptr_odb[i] = fi->q.ptr_ocq_base + NO_OF_ENTRIES*i; + + /* build IMQ */ + if ( (fi->q.ptr_imq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) { + T_MSG("failed to get IMQ page"); + return 0; + } + for (i = 0; i < IMQ_LENGTH; i++) + fi->q.ptr_imqe[i] = fi->q.ptr_imq_base + NO_OF_ENTRIES*i; + + /* build MFSBQ */ + if ( (fi->q.ptr_mfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) { + T_MSG("failed to get MFSBQ page"); + return 0; + } + memset((char *)fi->q.ptr_mfsbq_base, 0, MFSBQ_LENGTH * 32); + /* Allocate one huge chunk of memory... helps while reassembling + * frames. + */ + if ( (addr = (u_char *)__get_free_pages(GFP_KERNEL, 5) ) == 0) { + T_MSG("failed to get MFSBQ page"); + return 0; + } + /* fill in addresses of empty buffers */ + for (i = 0; i < MFSBQ_LENGTH; i++) { + for (j = 0; j < NO_OF_ENTRIES; j++) { + *(fi->q.ptr_mfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr)); + addr += MFS_BUFFER_SIZE; + } + } + + /* The number of entries in each MFS buffer is 8. There are 8 + * MFS buffers. That leaves us with 4096-256 bytes. We use them + * as temporary space for ELS frames. This is done to make sure that + * the addresses are aligned. + */ + fi->g.els_buffer[0] = fi->q.ptr_mfsbq_base + MFSBQ_LENGTH*NO_OF_ENTRIES; + for (i = 1; i < MAX_PENDING_FRAMES; i++) + fi->g.els_buffer[i] = fi->g.els_buffer[i-1] + 64; + + /* build SFSBQ */ + if ( (fi->q.ptr_sfsbq_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) { + T_MSG("failed to get SFSBQ page"); + return 0; + } + memset((char *)fi->q.ptr_sfsbq_base, 0, SFSBQ_LENGTH * 32); + /* fill in addresses of empty buffers */ + for (i = 0; i < SFSBQ_LENGTH; i++) + for (j = 0; j < NO_OF_ENTRIES; j++){ + addr = kmalloc(SFS_BUFFER_SIZE*2, GFP_KERNEL); + if (addr == NULL){ + T_MSG("ptr_sfs_buffer : memory not allocated"); + return 0; + } + else { + int offset = ALIGNED_SFS_ADDR(addr); + memset((char *)addr, 0, SFS_BUFFER_SIZE); + fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES +j] = (u_int *)addr; + addr += offset; + *(fi->q.ptr_sfsbq_base + i*NO_OF_ENTRIES + j) = htonl(virt_to_bus(addr)); + } + } + + /* The number of entries in each SFS buffer is 8. There are 8 + * MFS buffers. That leaves us with 4096-256 bytes. We use them + * as temporary space for ARP frames. This is done inorder to + * support HW_Types of 0x1 and 0x6. + */ + fi->g.arp_buffer = (char *)fi->q.ptr_sfsbq_base + SFSBQ_LENGTH*NO_OF_ENTRIES*4; + + /* build EDB */ + if ((fi->q.ptr_edb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5) ) == 0) { + T_MSG("failed to get EDB page"); + return 0; + } + for (i = 0; i < EDB_LEN; i++) + fi->q.ptr_edb[i] = fi->q.ptr_edb_base + 2*i; + + /* build SEST */ + + /* OX_IDs range from 0x0 - 0x4FFF. + */ + if ((fi->q.ptr_sest_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) { + T_MSG("failed to get SEST page"); + return 0; + } + for (i = 0; i < SEST_LENGTH; i++) + fi->q.ptr_sest[i] = fi->q.ptr_sest_base + NO_OF_ENTRIES*i; + + if ((fi->q.ptr_sdb_base = (u_int *)__get_free_pages(GFP_KERNEL, 5)) == 0) { + T_MSG("failed to get SDB page"); + return 0; + } + for (i = 0 ; i < NO_OF_SDB_ENTRIES; i++) + fi->q.ptr_sdb_slot[i] = fi->q.ptr_sdb_base + (SDB_SIZE/4)*i; + + if ((fi->q.ptr_fcp_cmnd_base = (u_int *)__get_free_pages(GFP_KERNEL, 0)) == 0) { + T_MSG("failed to get FCP_CMND page"); + return 0; + } + for (i = 0; i < NO_OF_FCP_CMNDS; i++) + fi->q.ptr_fcp_cmnd[i] = fi->q.ptr_fcp_cmnd_base + NO_OF_ENTRIES*i; + + /* Allocate space for Tachyon Header as well... + */ + if ((fi->q.ptr_tachyon_header_base = (u_int *)__get_free_pages(GFP_KERNEL, 0) ) == 0) { + T_MSG("failed to get tachyon_header page"); + return 0; + } + for (i = 0; i < NO_OF_TACH_HEADERS; i++) + fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 16*i; + + /* Allocate memory for indices. + * Indices should be aligned on 32 byte boundries. + */ + fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL); + if (fi->q.host_ocq_cons_indx == NULL){ + T_MSG("fi->q.host_ocq_cons_indx : memory not allocated"); + return 0; + } + fi->q.ptr_host_ocq_cons_indx = fi->q.host_ocq_cons_indx; + if ((u_long)(fi->q.host_ocq_cons_indx) % 32) + fi->q.host_ocq_cons_indx++; + + fi->q.host_hpcq_cons_indx = kmalloc(2*32, GFP_KERNEL); + if (fi->q.host_hpcq_cons_indx == NULL){ + T_MSG("fi->q.host_hpcq_cons_indx : memory not allocated"); + return 0; + } + fi->q.ptr_host_hpcq_cons_indx= fi->q.host_hpcq_cons_indx; + if ((u_long)(fi->q.host_hpcq_cons_indx) % 32) + fi->q.host_hpcq_cons_indx++; + + fi->q.host_imq_prod_indx = kmalloc(2*32, GFP_KERNEL); + if (fi->q.host_imq_prod_indx == NULL){ + T_MSG("fi->q.host_imq_prod_indx : memory not allocated"); + return 0; + } + fi->q.ptr_host_imq_prod_indx = fi->q.host_imq_prod_indx; + if ((u_long)(fi->q.host_imq_prod_indx) % 32) + fi->q.host_imq_prod_indx++; + + LEAVE("build_queues"); + return 1; +} + + +static void write_to_tachyon_registers(struct fc_info *fi) +{ +u_int bus_addr, bus_indx_addr, i; + + ENTER("write_to_tachyon_registers"); + + /* Clear Queues each time Tachyon is reset */ + memset((char *)fi->q.ptr_ocq_base, 0, OCQ_LENGTH * 32); + memset((char *)fi->q.ptr_imq_base, 0, IMQ_LENGTH * 32); + memset((char *)fi->q.ptr_edb_base, 0, EDB_LEN * 8); + memset((char *)fi->q.ptr_sest_base, 0, SEST_LENGTH * 32); + memset((char *)fi->q.ptr_sdb_base, 0, NO_OF_SDB_ENTRIES * SDB_SIZE); + memset((char *)fi->q.ptr_tachyon_header_base, 0xFF, NO_OF_TACH_HEADERS * TACH_HEADER_SIZE); + for (i = 0; i < SEST_LENGTH; i++) + fi->q.free_scsi_oxid[i] = OXID_AVAILABLE; + for (i = 0; i < NO_OF_SDB_ENTRIES; i++) + fi->q.sdb_slot_status[i] = SDB_FREE; + + take_tachyon_offline(fi); + writel(readl(fi->t_r.ptr_tach_config_reg) | SCSI_ENABLE | WRITE_STREAM_SIZE | READ_STREAM_SIZE | PARITY_EVEN | OOO_REASSEMBLY_DISABLE, fi->t_r.ptr_tach_config_reg); + + /* Write OCQ registers */ + fi->q.ocq_prod_indx = 0; + *(fi->q.host_ocq_cons_indx) = 0; + + /* The Tachyon needs to be passed the "real" address */ + bus_addr = virt_to_bus(fi->q.ptr_ocq_base); + writel(bus_addr, fi->t_r.ptr_ocq_base_reg); + writel(OCQ_LENGTH - 1, fi->t_r. ptr_ocq_len_reg); + bus_indx_addr = virt_to_bus(fi->q.host_ocq_cons_indx); + writel(bus_indx_addr, fi->t_r.ptr_ocq_cons_indx_reg); + + /* Write IMQ registers */ + fi->q.imq_cons_indx = 0; + *(fi->q.host_imq_prod_indx) = 0; + bus_addr = virt_to_bus(fi->q.ptr_imq_base); + writel(bus_addr, fi->t_r.ptr_imq_base_reg); + writel(IMQ_LENGTH - 1, fi->t_r.ptr_imq_len_reg); + bus_indx_addr = virt_to_bus(fi->q.host_imq_prod_indx); + writel(bus_indx_addr, fi->t_r.ptr_imq_prod_indx_reg); + + /* Write MFSBQ registers */ + fi->q.mfsbq_prod_indx = MFSBQ_LENGTH - 1; + fi->q.mfsbuff_end = MFS_BUFFER_SIZE - 1; + fi->q.mfsbq_cons_indx = 0; + bus_addr = virt_to_bus(fi->q.ptr_mfsbq_base); + writel(bus_addr, fi->t_r.ptr_mfsbq_base_reg); + writel(MFSBQ_LENGTH - 1, fi->t_r.ptr_mfsbq_len_reg); + writel(fi->q.mfsbuff_end, fi->t_r.ptr_mfsbuff_len_reg); + /* Do this last as tachyon will prefetch the + * first entry as soon as we write to it. + */ + writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg); + + /* Write SFSBQ registers */ + fi->q.sfsbq_prod_indx = SFSBQ_LENGTH - 1; + fi->q.sfsbuff_end = SFS_BUFFER_SIZE - 1; + fi->q.sfsbq_cons_indx = 0; + bus_addr = virt_to_bus(fi->q.ptr_sfsbq_base); + writel(bus_addr, fi->t_r.ptr_sfsbq_base_reg); + writel(SFSBQ_LENGTH - 1, fi->t_r.ptr_sfsbq_len_reg); + writel(fi->q.sfsbuff_end, fi->t_r.ptr_sfsbuff_len_reg); + /* Do this last as tachyon will prefetch the first + * entry as soon as we write to it. + */ + writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg); + + /* Write SEST registers */ + bus_addr = virt_to_bus(fi->q.ptr_sest_base); + writel(bus_addr, fi->t_r.ptr_sest_base_reg); + writel(SEST_LENGTH - 1, fi->t_r.ptr_sest_len_reg); + /* the last 2 bits _should_ be 1 */ + writel(SEST_BUFFER_SIZE - 1, fi->t_r.ptr_scsibuff_len_reg); + + /* write AL_TIME & E_D_TOV into the registers */ + writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg); + /* Tell Tachyon to pick a Soft Assigned AL_PA */ + writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg); + + /* Read the WWN from EEPROM . But, for now we assign it here. */ + writel(WORLD_WIDE_NAME_LOW, fi->t_r.ptr_fm_wwn_low_reg); + writel(WORLD_WIDE_NAME_HIGH, fi->t_r.ptr_fm_wwn_hi_reg); + + DPRINTK1("TACHYON initializing as L_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + + LEAVE("write_to_tachyon_registers"); +} + + +static void tachyon_interrupt(int irq, void* dev_id, struct pt_regs* regs) +{ +struct Scsi_Host *host = dev_id; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata; +struct fc_info *fi = hostdata->fi; +u_long flags; + spin_lock_irqsave(&fi->fc_lock, flags); + tachyon_interrupt_handler(irq, dev_id, regs); + spin_unlock_irqrestore(&fi->fc_lock, flags); +} + +static void tachyon_interrupt_handler(int irq, void* dev_id, struct pt_regs* regs) +{ +struct Scsi_Host *host = dev_id; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata; +struct fc_info *fi = hostdata->fi; +u_int *ptr_imq_entry; +u_int imq_int_type, current_IMQ_index = 0, prev_IMQ_index; +int index, no_of_entries = 0; + + DPRINTK("\n"); + ENTER("tachyon_interrupt"); + if (fi->q.host_imq_prod_indx != NULL) { + current_IMQ_index = ntohl(*(fi->q.host_imq_prod_indx)); + } + else { + /* _Should not_ happen */ + T_MSG("IMQ_indx NULL. DISABLING INTERRUPTS!!!\n"); + writel(0x0, fi->i_r.ptr_ichip_hw_control_reg); + } + + if (current_IMQ_index > fi->q.imq_cons_indx) + no_of_entries = current_IMQ_index - fi->q.imq_cons_indx; + else + if (current_IMQ_index < fi->q.imq_cons_indx) + no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index); + + if (no_of_entries == 0) { + u_int ichip_status; + ichip_status = readl(fi->i_r.ptr_ichip_hw_status_reg); + if (ichip_status & 0x20) { + /* Should _never_ happen. Might require a hard reset */ + T_MSG("Too bad... PCI Bus Error. Resetting (i)chip"); + reset_ichip(fi); + T_MSG("DISABLING INTERRUPTS!!!\n"); + writel(0x0, fi->i_r.ptr_ichip_hw_control_reg); + } + } + + prev_IMQ_index = current_IMQ_index; + for (index = 0; index < no_of_entries; index++) { + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + imq_int_type = ntohl(*ptr_imq_entry); + + completion_message_handler(fi, imq_int_type); + if ((fi->g.link_up == FALSE) && ((imq_int_type == MFS_BUF_WARN) || (imq_int_type == SFS_BUF_WARN) || (imq_int_type == IMQ_BUF_WARN))) + break; + update_IMQ_indx(fi, 1); + + /* Check for more entries */ + current_IMQ_index = ntohl(*(fi->q.host_imq_prod_indx)); + if (current_IMQ_index != prev_IMQ_index) { + no_of_entries++; + prev_IMQ_index = current_IMQ_index; + } + } /*end of for loop*/ + return; + LEAVE("tachyon_interrupt"); +} + + +static void handle_SFS_BUF_WARN_interrupt(struct fc_info *fi) +{ +int i; + ENTER("handle_SFS_BUF_WARN_interrupt"); + if (fi->g.link_up == FALSE) { + reset_tachyon(fi, SOFTWARE_RESET); + return; + } + /* Free up all but one entry in the Q. + */ + for (i = 0; i < ((SFSBQ_LENGTH - 1) * NO_OF_ENTRIES); i++) { + handle_SFS_interrupt(fi); + update_IMQ_indx(fi, 1); + } + LEAVE("handle_SFS_BUF_WARN_interrupt"); +} + +/* Untested_Code_Begin */ +static void handle_MFS_BUF_WARN_interrupt(struct fc_info *fi) +{ +int i; + ENTER("handle_MFS_BUF_WARN_interrupt"); + if (fi->g.link_up == FALSE) { + reset_tachyon(fi, SOFTWARE_RESET); + return; + } + /* FIXME: freeing up 8 entries. + */ + for (i = 0; i < NO_OF_ENTRIES; i++) { + handle_MFS_interrupt(fi); + update_IMQ_indx(fi, 1); + } + LEAVE("handle_MFS_BUF_WARN_interrupt"); +} +/*Untested_Code_End */ + +static void handle_IMQ_BUF_WARN_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +u_int imq_int_type, current_IMQ_index = 0, temp_imq_cons_indx; +int index, no_of_entries = 0; + + ENTER("handle_IMQ_BUF_WARN_interrupt"); + if (fi->g.link_up == FALSE) { + reset_tachyon(fi, SOFTWARE_RESET); + return; + } + current_IMQ_index = ntohl(*(fi->q.host_imq_prod_indx)); + + if (current_IMQ_index > fi->q.imq_cons_indx) + no_of_entries = current_IMQ_index - fi->q.imq_cons_indx; + else + if (current_IMQ_index < fi->q.imq_cons_indx) + no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index); + /* We dont want to look at the same IMQ entry again. + */ + temp_imq_cons_indx = fi->q.imq_cons_indx + 1; + if (no_of_entries != 0) + no_of_entries -= 1; + for (index = 0; index < no_of_entries; index++) { + ptr_imq_entry = fi->q.ptr_imqe[temp_imq_cons_indx]; + imq_int_type = ntohl(*ptr_imq_entry); + if (imq_int_type != IMQ_BUF_WARN) + completion_message_handler(fi, imq_int_type); + temp_imq_cons_indx++; + if (temp_imq_cons_indx == IMQ_LENGTH) + temp_imq_cons_indx = 0; + } /*end of for loop*/ + if (no_of_entries != 0) + update_IMQ_indx(fi, no_of_entries); + LEAVE("handle_IMQ_BUF_WARN_interrupt"); +} + +static void completion_message_handler(struct fc_info *fi, u_int imq_int_type) +{ + switch(imq_int_type) { + case OUTBOUND_COMPLETION: + DPRINTK("OUTBOUND_COMPLETION message received"); + break; + case OUTBOUND_COMPLETION_I: + DPRINTK("OUTBOUND_COMPLETION_I message received"); + handle_OCI_interrupt(fi); + break; + case OUT_HI_PRI_COMPLETION: + DPRINTK("OUT_HI_PRI_COMPLETION message received"); + break; + case OUT_HI_PRI_COMPLETION_I: + DPRINTK("OUT_HI_PRI_COMPLETION_I message received"); + break; + case INBOUND_MFS_COMPLETION: + DPRINTK("INBOUND_MFS_COMPLETION message received"); + handle_MFS_interrupt(fi); + break; + case INBOUND_OOO_COMPLETION: + DPRINTK("INBOUND_OOO_COMPLETION message received"); + handle_OOO_interrupt(fi); + break; + case INBOUND_SFS_COMPLETION: + DPRINTK("INBOUND_SFS_COMPLETION message received"); + handle_SFS_interrupt(fi); + break; + case INBOUND_UNKNOWN_FRAME_I: + DPRINTK("INBOUND_UNKNOWN_FRAME message received"); + handle_Unknown_Frame_interrupt(fi); + break; + case INBOUND_BUSIED_FRAME: + DPRINTK("INBOUND_BUSIED_FRAME message received"); + handle_Busied_Frame_interrupt(fi); + break; + case FRAME_MGR_INTERRUPT: + DPRINTK("FRAME_MGR_INTERRUPT message received"); + handle_FM_interrupt(fi); + break; + case READ_STATUS: + DPRINTK("READ_STATUS message received"); + break; + case SFS_BUF_WARN: + DPRINTK("SFS_BUF_WARN message received"); + handle_SFS_BUF_WARN_interrupt(fi); + break; + case MFS_BUF_WARN: + DPRINTK("MFS_BUF_WARN message received"); + handle_MFS_BUF_WARN_interrupt(fi); + break; + case IMQ_BUF_WARN: + DPRINTK("IMQ_BUF_WARN message received"); + handle_IMQ_BUF_WARN_interrupt(fi); + break; + case INBOUND_C1_TIMEOUT: + DPRINTK("INBOUND_C1_TIMEOUT message received"); + break; + case BAD_SCSI_FRAME: + DPRINTK("BAD_SCSI_FRAME message received"); + handle_Bad_SCSI_Frame_interrupt(fi); + break; + case INB_SCSI_STATUS_COMPLETION: + DPRINTK("INB_SCSI_STATUS_COMPL message received"); + handle_Inbound_SCSI_Status_interrupt(fi); + break; + case INBOUND_SCSI_COMMAND: + DPRINTK("INBOUND_SCSI_COMMAND message received"); + handle_Inbound_SCSI_Command_interrupt(fi); + break; + case INBOUND_SCSI_DATA_COMPLETION: + DPRINTK("INBOUND_SCSI_DATA message received"); + /* Only for targets */ + break; + default: + T_MSG("DEFAULT message received, type = %x", imq_int_type); + return; + } + reset_latch(fi); +} + +static void handle_OCI_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +u_long transaction_id = 0; +unsigned short status, seq_count, transmitted_ox_id; +struct Scsi_Host *host = fi->host; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata; +Scsi_Cmnd *Cmnd; +u_int tag; + + ENTER("handle_OCI_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + transaction_id = ntohl(*(ptr_imq_entry + 1)); + status = ntohl(*(ptr_imq_entry + 2)) >> 16; + seq_count = ntohl(*(ptr_imq_entry + 3)); + DPRINTK("transaction_id= %x", (u_int)transaction_id); + tag = transaction_id & 0xFFFF0000; + transmitted_ox_id = transaction_id; + + /* The INT could be either due to TIME_OUT | BAD_ALPA. + * But we check only for TimeOuts. Bad AL_PA will + * caught by FM_interrupt handler. + */ + + if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && (!fi->g.perform_adisc)){ + DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id); + + /* Is it a SCSI frame that is timing out ? Not a very good check... + */ + if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) { + /* If it is a Bad AL_PA, we report it as BAD_TARGET. + * Else, we allow the command to time-out. A Link + * re-initialization could be taking place. + */ + if (tag == FC_SCSI_BAD_TARGET) { + Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID]; + hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL; + if (Cmnd != NULL) { + Cmnd->result = DID_BAD_TARGET << 16; + (*Cmnd->scsi_done) (Cmnd); + } + else + T_MSG("NULL Command out of handler!"); + } /* if Bad Target */ + else { + u_char missing_target = tag >> 16; + struct fc_node_info *q = fi->node_info_list; + /* A Node that we thought was logged in has gone + * away. We are the optimistic kind and we keep + * hoping that our dear little Target will come back + * to us. For now we log him out. + */ + DPRINTK2("Missing Target = %d", missing_target); + while (q != NULL) { + if (q->target_id == missing_target) { + T_MSG("Target %d Logged out", q->target_id); + q->login = LOGIN_ATTEMPTED; + if (fi->num_nodes > 0) + fi->num_nodes--; + tx_logi(fi, ELS_PLOGI, q->d_id); + break; + } + else + q = q->next; + } + } + } /* End of SCSI frame timing out. */ + else { + if (seq_count > 1) { + /* An IP frame was transmitted to a Bad AL_PA. Free up + * the skb used. + */ + dev_kfree_skb((struct sk_buff *)(bus_to_virt(transaction_id))); + } + } /* End of IP frame timing out. */ + } /* End of frame timing out. */ + else { + /* Frame was transmitted successfully. Check if it was an ELS + * frame or an IP frame or a Bad_Target_Notification frame (in + * case of a ptp_link). Ugly! + */ + if ((status == 0) && (seq_count == 0)) { + u_int tag = transaction_id & 0xFFFF0000; + /* Continue with port discovery after an ELS is successfully + * transmitted. (status == 0). + */ + DPRINTK("tag = %x", tag); + switch(tag) { + case ELS_FLOGI: + /* Letz use the Name Server instead */ + fi->g.explore_fabric = TRUE; + fi->g.port_discovery = FALSE; + fi->g.alpa_list_index = MAX_NODES; + add_to_ox_id_list(fi, transaction_id, tag); + break; + case ELS_PLOGI: + if (fi->g.fabric_present && (fi->g.name_server == FALSE)) + add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI); + else + add_to_ox_id_list(fi, transaction_id, tag); + break; + case FC_SCSI_BAD_TARGET: + Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID]; + hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL; + if (Cmnd != NULL) { + Cmnd->result = DID_BAD_TARGET << 16; + (*Cmnd->scsi_done) (Cmnd); + } + else + T_MSG("NULL Command out of handler!"); + break; + default: + add_to_ox_id_list(fi, transaction_id, tag); + } + + if (fi->g.alpa_list_index >= MAX_NODES) { + if (fi->g.port_discovery == TRUE) { + fi->g.port_discovery = FALSE; + add_display_cache_timer(fi); + } + fi->g.alpa_list_index = MAX_NODES; + } + if (fi->g.port_discovery == TRUE) + local_port_discovery(fi); + } + else { + /* An IP frame has been successfully transmitted. + * Free the skb that was used for this IP frame. + */ + if ((status == 0) && (seq_count > 1)) { + dev_kfree_skb((struct sk_buff *)(bus_to_virt(transaction_id))); + } + } + } + LEAVE("handle_OCI_interrupt"); +} + +/* Right now we discard OOO frames */ +static void handle_OOO_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +int queue_indx, offset, payload_size; +int no_of_buffers = 1; /* header is in a separate buffer */ + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN; + /* Calculate total number of buffers */ + no_of_buffers += payload_size / MFS_BUFFER_SIZE; + if (payload_size % MFS_BUFFER_SIZE) + no_of_buffers++; + + /* provide Tachyon will another set of buffers */ + fi->g.mfs_buffer_count += no_of_buffers; + if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) { + int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES; + fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count; + update_MFSBQ_indx(fi, count); + } +} + +static void handle_MFS_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry, *buff_addr; +u_int type_of_frame, s_id; +int queue_indx, offset, payload_size, starting_indx, starting_offset; +u_short received_ox_id; +int no_of_buffers = 1; /* header is in a separate buffer */ +struct sk_buff *skb; +int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1; + ENTER("handle_MFS_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + DPRINTK("queue_indx = %d, offset = %d\n", queue_indx, offset); + payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN; + DPRINTK("payload_size = %d", payload_size); + /* Calculate total number of buffers */ + no_of_buffers += payload_size / MFS_BUFFER_SIZE; + if (payload_size % MFS_BUFFER_SIZE) + no_of_buffers++; + DPRINTK("no_of_buffers = %d", no_of_buffers); + + if ((no_of_buffers - 1) <= offset) { + starting_offset = offset - (no_of_buffers - 1); + starting_indx = queue_indx; + } + else { + int temp = no_of_buffers - (offset + 1); + int no_of_queues = temp / NO_OF_ENTRIES; + starting_offset = temp % NO_OF_ENTRIES; + if (starting_offset != 0) { + no_of_wrap_buffs = starting_offset - 1; //exclude header + starting_offset = NO_OF_ENTRIES - starting_offset; + no_of_queues++; + } + starting_indx = queue_indx - no_of_queues; + if (starting_indx < 0) { + no_of_wrap_buffs -= (starting_indx + 1) * NO_OF_ENTRIES; + starting_indx = MFSBQ_LENGTH + starting_indx; + wrap_around = TRUE; + } + } + + DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = %d\n", starting_indx, starting_offset, no_of_wrap_buffs); + /* Get Tachyon Header from first buffer */ + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + starting_indx*NO_OF_ENTRIES + starting_offset))); + + + /* extract Type of Frame */ + type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000; + s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + received_ox_id = ntohl(*(buff_addr + 6)) >> 16; + buff_addr += MFS_BUFFER_SIZE/4; + DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, s_id, received_ox_id); + + switch(type_of_frame) { + case TYPE_LLC_SNAP: + skb = dev_alloc_skb(payload_size); + if (skb == NULL) { + printk(KERN_NOTICE "%s: In handle_MFS_interrupt() Memory squeeze, dropping packet.\n", fi->name); + fi->fc_stats.rx_dropped++; + fi->g.mfs_buffer_count += no_of_buffers; + if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) { + int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES; + fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count; + update_MFSBQ_indx(fi, count); + return; + } + } + if (wrap_around) { + int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE; + int tail_size = payload_size - wrap_size; + DPRINTK("wrap_size = %d, tail_size = %d\n", wrap_size, tail_size); + if (no_of_wrap_buffs) + memcpy(skb_put(skb, wrap_size), buff_addr, wrap_size); + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base))); + memcpy(skb_put(skb, tail_size), buff_addr, tail_size); + } + else + memcpy(skb_put(skb, payload_size), buff_addr, payload_size); + rx_net_mfs_packet(fi, skb); + break; + default: + T_MSG("Unknown Frame Type received. Type = %x", type_of_frame); + } + + /* provide Tachyon will another set of buffers */ + fi->g.mfs_buffer_count += no_of_buffers; + if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) { + int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES; + fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count; + update_MFSBQ_indx(fi, count); + } + LEAVE("handle_MFS_interrupt"); +} + +static void handle_Unknown_Frame_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +int queue_indx, offset; + ENTER("handle_Unknown_Frame_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + /* We discard the "unknown" frame */ + /* provide Tachyon will another set of buffers */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_Unknown_Frame_interrupt"); +} + +static void handle_Busied_Frame_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +int queue_indx, offset; + ENTER("handle_Busied_Frame_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + /* We discard the "busied" frame */ + /* provide Tachyon will another set of buffers */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_Busied_Frame_interrupt"); +} + +static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb; +u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0; +int queue_indx, offset, payload_size, i; +u_short ox_id, rx_id, x_id, mtu = 512; +u_char target_id = 0xFF; + + ENTER("handle_Bad_SCSI_Frame_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + payload_size = ntohl(*(ptr_imq_entry + 2)); + + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset))); + + rctl = ntohl(*(buff_addr + 2)) & 0xFF000000; + s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + ox_id = ntohl(*(buff_addr + 6)) >> 16; + rx_id = ntohl(*(buff_addr + 6)); + x_id = ox_id & MAX_SCSI_XID; + + /* Any frame that comes in with OX_ID that matches an OX_ID + * that has been allocated for SCSI, will be called a Bad + * SCSI frame if the Exchange is not valid any more. + * + * We will also get a Bad SCSI frame interrupt if we receive + * a XFER_RDY with offset != 0. Tachyon washes its hands off + * this Exchange. We have to take care of ourselves. Grrr... + */ + if (rctl == DATA_DESCRIPTOR) { + struct fc_node_info *q = fi->node_info_list; + while (q != NULL) { + if (q->d_id == s_id) { + target_id = q->target_id; + mtu = q->mtu; + break; + } + else + q = q->next; + } + frame_class = target_id; + transfered_len = ntohl(*(buff_addr + 8)); + burst_len = ntohl(*(buff_addr + 9)); + + build_ODB(fi, fi->g.seq_id, s_id, burst_len, 0, mtu, ox_id, rx_id, 0, 0, frame_class << 16); + /* Update the SEQ_ID and Relative Offset in the + * Tachyon Header Structure. + */ + tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5))); + *(tach_header + 5) = htonl(fi->g.seq_id << 24); + *(tach_header + 7) = htonl(transfered_len); + fi->g.odb.hdr_addr = *(fi->q.ptr_sest[x_id] + 5); + + /* Invalidate the EDBs used + */ + ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7))); + + for (i = 0; i < EDB_LEN; i++) + if (fi->q.ptr_edb[i] == ptr_edb) + break; + ptr_edb--; + + if (i < EDB_LEN) { + int j; + do { + ptr_edb += 2; + len += (htonl(*ptr_edb) & 0xFFFF); + j = i; + fi->q.free_edb_list[i++] = EDB_FREE; + if (i == EDB_LEN) { + i = 0; + ptr_edb = fi->q.ptr_edb_base - 1; + } + } while (len < transfered_len); + if (len > transfered_len) { + ptr_edb--; + fi->q.free_edb_list[j] = EDB_BUSY; + } + else + ptr_edb++; + } + else { + T_MSG("EDB not found while freeing"); + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + return; + } + + /* Update the EDB pointer in the ODB. + */ + fi->g.odb.edb_addr = htonl(virt_to_bus(ptr_edb)); + memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB)); + /* Update the EDB pointer in the SEST entry. We might need + * this if get another XFER_RDY for the same Exchange. + */ + *(fi->q.ptr_sest[x_id] + 7) = htonl(virt_to_bus(ptr_edb)); + + update_OCQ_indx(fi); + if (fi->g.seq_id == MAX_SEQ_ID) + fi->g.seq_id = 0; + else + fi->g.seq_id++; + } + else + /* Could be a BA_ACC or a BA_RJT. + */ + if (rctl == RCTL_BASIC_ACC) { + u_int bls_type = remove_from_ox_id_list(fi, ox_id); + DPRINTK1("BA_ACC received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type); + if (bls_type == RCTL_BASIC_ABTS) { + u_int STE_bit; + /* Invalidate resources for that Exchange. + */ + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + if (STE_bit & SEST_V) { + *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV); + invalidate_SEST_entry(fi, ox_id); + } + } + } + else + if (rctl == RCTL_BASIC_RJT) { + u_int bls_type = remove_from_ox_id_list(fi, ox_id); + DPRINTK1("BA_RJT received from S_ID 0x%x with OX_ID = %x in response to %x", s_id, ox_id, bls_type); + if (bls_type == RCTL_BASIC_ABTS) { + u_int STE_bit; + /* Invalidate resources for that Exchange. + */ + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + if (STE_bit & SEST_V) { + *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV); + invalidate_SEST_entry(fi, ox_id); + } + } + } + else + DPRINTK1("Frame with R_CTL = %x received from S_ID 0x%x with OX_ID %x", rctl, s_id, ox_id); + + /* Else, discard the "Bad" SCSI frame. + */ + + /* provide Tachyon will another set of buffers + */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_Bad_SCSI_Frame_interrupt"); +} + +static void handle_Inbound_SCSI_Status_interrupt(struct fc_info *fi) +{ +struct Scsi_Host *host = fi->host; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata; +u_int *ptr_imq_entry, *buff_addr, *ptr_rsp_info, *ptr_sense_info = NULL; +int queue_indx, offset, payload_size; +u_short received_ox_id, x_id; +Scsi_Cmnd *Cmnd; +u_int fcp_status, fcp_rsp_info_len = 0, fcp_sense_info_len = 0, s_id; + ENTER("handle_SCSI_status_interrupt"); + + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset))); + payload_size = ntohl(*(ptr_imq_entry + 2)); + received_ox_id = ntohl(*(buff_addr + 6)) >> 16; + + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset))); + + fcp_status = ntohl(*(buff_addr + 10)); + ptr_rsp_info = buff_addr + 14; + if (fcp_status & FCP_STATUS_RSP_LEN) + fcp_rsp_info_len = ntohl(*(buff_addr + 13)); + + if (fcp_status & FCP_STATUS_SENSE_LEN) { + ptr_sense_info = ptr_rsp_info + fcp_rsp_info_len / 4; + fcp_sense_info_len = ntohl(*(buff_addr + 12)); + DPRINTK("sense_info = %x", (u_int)ntohl(*ptr_sense_info)); + } + DPRINTK("fcp_status = %x, fcp_rsp_len = %x", fcp_status, fcp_rsp_info_len); + x_id = received_ox_id & MAX_SCSI_XID; + Cmnd = hostdata->cmnd_handler[x_id]; + hostdata->cmnd_handler[x_id] = NULL; + if (Cmnd != NULL) { + memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer)); + /* Check if there is a Sense field */ + if (fcp_status & FCP_STATUS_SENSE_LEN) { + int size = sizeof(Cmnd->sense_buffer); + if (fcp_sense_info_len < size) + size = fcp_sense_info_len; + memcpy(Cmnd->sense_buffer, (char *)ptr_sense_info, size); + } + Cmnd->result = fcp_status & FCP_STATUS_MASK; + (*Cmnd->scsi_done) (Cmnd); + } + else + T_MSG("NULL Command out of handler!"); + + invalidate_SEST_entry(fi, received_ox_id); + s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + fi->q.free_scsi_oxid[x_id] = OXID_AVAILABLE; + + /* provide Tachyon will another set of buffers */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_SCSI_status_interrupt"); +} + +static void invalidate_SEST_entry(struct fc_info *fi, u_short received_ox_id) +{ +u_short x_id = received_ox_id & MAX_SCSI_XID; + /* Invalidate SEST entry if it is an OutBound SEST Entry + */ + if (!(received_ox_id & SCSI_READ_BIT)) { + u_int *ptr_tach_header, *ptr_edb; + u_short temp_ox_id = NOT_SCSI_XID; + int i; + *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV); + + /* Invalidate the Tachyon Header structure + */ + ptr_tach_header = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 5))); + for (i = 0; i < NO_OF_TACH_HEADERS; i++) + if(fi->q.ptr_tachyon_header[i] == ptr_tach_header) + break; + if (i < NO_OF_TACH_HEADERS) + memset(ptr_tach_header, 0xFF, 32); + else + T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()"); + + /* Invalidate the EDB used + */ + ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7))); + for (i = 0; i < EDB_LEN; i++) + if (fi->q.ptr_edb[i] == ptr_edb) + break; + ptr_edb--; + if (i < EDB_LEN) { + do { + ptr_edb += 2; + fi->q.free_edb_list[i++] = EDB_FREE; + if (i == EDB_LEN) { + i = 0; + ptr_edb = fi->q.ptr_edb_base - 1; + } + } while ((htonl(*ptr_edb) & 0x80000000) != 0x80000000); + } + else + T_MSG("EDB not found while freeing in invalidate_SEST_entry()"); + + /* Search for its other header structure and destroy it! + */ + if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4))) + ptr_tach_header += 16; + else + ptr_tach_header = fi->q.ptr_tachyon_header_base; + while (temp_ox_id != x_id) { + temp_ox_id = ntohl(*(ptr_tach_header + 6)) >> 16; + if (temp_ox_id == x_id) { + /* Paranoid checking... + */ + for (i = 0; i < NO_OF_TACH_HEADERS; i++) + if(fi->q.ptr_tachyon_header[i] == ptr_tach_header) + break; + if (i < NO_OF_TACH_HEADERS) + memset(ptr_tach_header, 0xFF, 32); + else + T_MSG("Tachyon Header not found while freeing in invalidate_SEST_entry()"); + break; + } + else { + if ((ptr_tach_header + 16) < (fi->q.ptr_tachyon_header_base + (MY_PAGE_SIZE/4))) + ptr_tach_header += 16; + else + ptr_tach_header = fi->q.ptr_tachyon_header_base; + } + } + } + else { + u_short sdb_table_indx; + /* An Inbound Command has completed or needs to be Aborted. + * Clear up the SDB buffers. + */ + sdb_table_indx = *(fi->q.ptr_sest[x_id] + 5); + fi->q.sdb_slot_status[sdb_table_indx] = SDB_FREE; + } +} + +static void handle_Inbound_SCSI_Command_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry; +int queue_indx, offset; + ENTER("handle_Inbound_SCSI_Command_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + /* We discard the SCSI frame as we shouldn't be receiving + * a SCSI Command in the first place + */ + /* provide Tachyon will another set of buffers */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_Inbound_SCSI_Command_interrupt"); +} + +static void handle_SFS_interrupt(struct fc_info *fi) +{ +u_int *ptr_imq_entry, *buff_addr; +u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl; +int queue_indx, offset, payload_size, login_state; +u_short received_ox_id, fs_cmnd_code; + ENTER("handle_SFS_interrupt"); + ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx]; + offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007; + queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000; + queue_indx = queue_indx >> 16; + DPRINTK("queue_indx = %d, offset = %d\n", queue_indx, offset); + payload_size = ntohl(*(ptr_imq_entry + 2)); + DPRINTK("payload_size = %d", payload_size); + + buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset))); + + /* extract Type of Frame */ + type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000; + s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + received_ox_id = ntohl(*(buff_addr + 6)) >> 16; + switch(type_of_frame) { + case TYPE_BLS: + rctl = ntohl(*(buff_addr + 2)) & 0xFF000000; + switch(rctl) { + case RCTL_BASIC_ABTS: + /* As an Initiator, we should never be receiving + * this. + */ + DPRINTK1("ABTS received from S_ID 0x%x with OX_ID = %x", s_id, received_ox_id); + break; + } + break; + case TYPE_ELS: + class_of_frame = ntohl(*(buff_addr + 8)); + login_state = sid_logged_in(fi, s_id); + switch(class_of_frame & 0xFF000000) { + case ELS_PLOGI: + if (s_id != fi->g.my_id) { + u_int ret_code; + DPRINTK1("PLOGI received from D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id); + if ((ret_code = plogi_ok(fi, buff_addr, payload_size)) == 0){ + tx_logi_acc(fi, ELS_ACC, s_id, received_ox_id); + add_to_address_cache(fi, buff_addr); + } + else { + u_short cmnd_code = ret_code >> 16; + u_short expln_code = ret_code; + tx_ls_rjt(fi, s_id, received_ox_id, cmnd_code, expln_code); + } + } + break; + case ELS_ACC: + els_type = remove_from_ox_id_list(fi, received_ox_id); + DPRINTK1("ELS_ACC received from D_ID 0x%x in response to ELS %x", s_id, els_type); + switch(els_type) { + case ELS_PLOGI: + add_to_address_cache(fi, buff_addr); + tx_prli(fi, ELS_PRLI, s_id, OX_ID_FIRST_SEQUENCE); + break; + case ELS_FLOGI: + add_to_address_cache(fi, buff_addr); + fi->g.my_id = ntohl(*(buff_addr + 2)) & 0x00FFFFFF; + fi->g.fabric_present = TRUE; + fi->g.my_ddaa = fi->g.my_id & 0xFFFF00; + /* Login to the Name Server + */ + tx_logi(fi, ELS_PLOGI, DIRECTORY_SERVER); + break; + case ELS_NS_PLOGI: + fi->g.name_server = TRUE; + add_to_address_cache(fi, buff_addr); + tx_name_server_req(fi, FCS_RFC_4); + tx_scr(fi); + /* Some devices have a delay before + * registering with the Name Server + */ + udelay(500); + tx_name_server_req(fi, FCS_GP_ID4); + break; + case ELS_PRLI: + mark_scsi_sid(fi, buff_addr, ADD_ENTRY); + break; + case ELS_ADISC: + if (!(validate_login(fi, buff_addr))) + tx_logo(fi, s_id, OX_ID_FIRST_SEQUENCE); + break; + } + break; + case ELS_PDISC: + DPRINTK1("ELS_PDISC received from D_ID 0x%x", s_id); + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_ADISC: + DPRINTK1("ELS_ADISC received from D_ID 0x%x", s_id); + if (node_logged_in_prev(fi, buff_addr)) + tx_adisc(fi, ELS_ACC, s_id, received_ox_id); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_PRLI: + DPRINTK1("ELS_PRLI received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) { + tx_prli(fi, ELS_ACC, s_id, received_ox_id); + mark_scsi_sid(fi, buff_addr, ADD_ENTRY); + } + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_PRLO: + DPRINTK1("ELS_PRLO received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_OUT) || (login_state == NODE_NOT_PRESENT)) + tx_logo(fi, s_id, received_ox_id); + else + if (login_state == NODE_LOGGED_IN) + + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + if (login_state == NODE_PROCESS_LOGGED_IN) { + tx_prli(fi, ELS_ACC, s_id, received_ox_id); + mark_scsi_sid(fi, buff_addr, DELETE_ENTRY); + } + break; + case ELS_LS_RJT: + els_type = remove_from_ox_id_list(fi, received_ox_id); + DPRINTK1("ELS_LS_RJT received from D_ID 0x%x in response to %x", s_id, els_type); + /* We should be chking the reason code. + */ + switch (els_type) { + case ELS_ADISC: + tx_logi(fi, ELS_PLOGI, s_id); + break; + } + break; + case ELS_LOGO: + els_type = remove_from_ox_id_list(fi, received_ox_id); + DPRINTK1("ELS_LOGO received from D_ID 0x%x in response to %x", s_id, els_type); + remove_from_address_cache(fi, buff_addr, ELS_LOGO); + tx_acc(fi, s_id, received_ox_id); + if (els_type == ELS_ADISC) + tx_logi(fi, ELS_PLOGI, s_id); + break; + case ELS_RSCN: + DPRINTK1("ELS_RSCN received from D_ID 0x%x", s_id); + tx_acc(fi, s_id, received_ox_id); + remove_from_address_cache(fi, buff_addr, ELS_RSCN); + break; + case ELS_FARP_REQ: + /* We do not support FARP. + So, silently discard it */ + DPRINTK1("ELS_FARP_REQ received from D_ID 0x%x", s_id); + break; + case ELS_ABTX: + DPRINTK1("ELS_ABTX received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_FLOGI: + DPRINTK1("ELS_FLOGI received from D_ID 0x%x", s_id); + if (fi->g.ptp_up == TRUE) { + /* The node could have come up as an N_Port + * in a Loop! So,try initializing as an NL_port + */ + take_tachyon_offline(fi); + /* write AL_TIME & E_D_TOV into the registers */ + writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg); + writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg); + DPRINTK1("FLOGI received, TACHYON initializing as L_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } + else { + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + } + break; + case ELS_ADVC: + DPRINTK1("ELS_ADVC received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_ECHO: + DPRINTK1("ELS_ECHO received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_ESTC: + DPRINTK1("ELS_ESTC received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_ESTS: + DPRINTK1("ELS_ESTS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RCS: + DPRINTK1("ELS_RCS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RES: + DPRINTK1("ELS_RES received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RLS: + DPRINTK1("ELS_RLS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RRQ: + DPRINTK1("ELS_RRQ received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RSS: + DPRINTK1("ELS_RSS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RTV: + DPRINTK1("ELS_RTV received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RSI: + DPRINTK1("ELS_RSI received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_TEST: + /* No reply sequence */ + DPRINTK1("ELS_TEST received from D_ID 0x%x", s_id); + break; + case ELS_RNC: + DPRINTK1("ELS_RNC received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_RVCS: + DPRINTK1("ELS_RVCS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_TPLS: + DPRINTK1("ELS_TPLS received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_GAID: + DPRINTK1("ELS_GAID received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_FACT: + DPRINTK1("ELS_FACT received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_FAN: + /* Hmmm... You don't support FAN ??? */ + DPRINTK1("ELS_FAN received from D_ID 0x%x", s_id); + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + break; + case ELS_FDACT: + DPRINTK1("ELS_FDACT received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_NACT: + DPRINTK1("ELS_NACT received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_NDACT: + DPRINTK1("ELS_NDACT received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_QoSR: + DPRINTK1("ELS_QoSR received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + case ELS_FDISC: + DPRINTK1("ELS_FDISC received from D_ID 0x%x", s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + default: + DPRINTK1("ELS Frame %x received from D_ID 0x%x", class_of_frame, s_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) + tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN); + else + tx_logo(fi, s_id, received_ox_id); + break; + } + break; + case TYPE_FC_SERVICES: + fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) >>16; + switch(fs_cmnd_code) { + case FCS_ACC: + els_type = remove_from_ox_id_list(fi, received_ox_id); + DPRINTK1("FCS_ACC received from D_ID 0x%x in response to %x", s_id, els_type); + if (els_type == FCS_GP_ID4) + explore_fabric(fi, buff_addr); + break; + case FCS_REJECT: + DPRINTK1("FCS_REJECT received from D_ID 0x%x in response to %x", s_id, els_type); + break; + } + break; + case TYPE_LLC_SNAP: + rx_net_packet(fi, (u_char *)buff_addr, payload_size); + break; + default: + T_MSG("Frame Type %x received from %x", type_of_frame, s_id); + } + + /* provide Tachyon will another set of buffers */ + if (offset == (NO_OF_ENTRIES - 1)) + update_SFSBQ_indx(fi); + LEAVE("handle_SFS_interrupt"); +} + +static void handle_FM_interrupt(struct fc_info *fi) +{ +u_int fm_status; +u_int tachyon_status; + + ENTER("handle_FM_interrupt"); + fm_status = readl(fi->t_r.ptr_fm_status_reg); + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + DPRINTK("FM_status = %x, Tachyon_status = %x", fm_status, tachyon_status); + if (fm_status & LINK_DOWN) { + T_MSG("Fibre Channel Link DOWN"); + fm_status = readl(fi->t_r.ptr_fm_status_reg); + + del_timer(&fi->explore_timer); + del_timer(&fi->nport_timer); + del_timer(&fi->lport_timer); + del_timer(&fi->display_cache_timer); + fi->g.link_up = FALSE; + if (fi->g.ptp_up == TRUE) + fi->g.n_port_try = FALSE; + fi->g.ptp_up = FALSE; + fi->g.port_discovery = FALSE; + fi->g.explore_fabric = FALSE; + fi->g.perform_adisc = FALSE; + + /* Logout will all nodes */ + if (fi->node_info_list) { + struct fc_node_info *temp_list = fi->node_info_list; + while(temp_list) { + temp_list->login = LOGIN_ATTEMPTED; + temp_list = temp_list->next; + } + fi->num_nodes = 0; + } + + if ((fi->g.n_port_try == FALSE) && (fi->g.dont_init == FALSE)){ + take_tachyon_offline(fi); + /* write AL_TIME & E_D_TOV into the registers */ + writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg); + + if ((fi->g.fabric_present == TRUE) && (fi->g.loop_up == TRUE)) { + u_int al_pa = fi->g.my_id & 0xFF; + writel((al_pa << 24) | LOOP_INIT_FABRIC_ADDRESS | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg); + } + else + if (fi->g.loop_up == TRUE) { + u_int al_pa = fi->g.my_id & 0xFF; + writel((al_pa << 24) | LOOP_INIT_PREVIOUS_ADDRESS, fi->t_r.ptr_fm_config_reg); + } + else + writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg); + fi->g.loop_up = FALSE; + DPRINTK1("In LDWN TACHYON initializing as L_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } + } + + if (fm_status & NON_PARTICIPATING) { + T_MSG("Did not acquire an AL_PA. I am not participating"); + } + else + if ((fm_status & LINK_UP) && ((fm_status & LINK_DOWN) == 0)) { + T_MSG("Fibre Channel Link UP"); + if ((fm_status & NON_PARTICIPATING) != TRUE) { + fi->g.link_up = TRUE; + if (tachyon_status & OSM_FROZEN) { + reset_tachyon(fi, ERROR_RELEASE); + reset_tachyon(fi, OCQ_RESET); + } + init_timer(&fi->explore_timer); + init_timer(&fi->nport_timer); + init_timer(&fi->lport_timer); + init_timer(&fi->display_cache_timer); + if ((fm_status & OLD_PORT) == 0) { + fi->g.loop_up = TRUE; + fi->g.ptp_up = FALSE; + fi->g.my_id = readl(fi->t_r.ptr_fm_config_reg) >> 24; + DPRINTK1("My AL_PA = %x", fi->g.my_id); + fi->g.port_discovery = TRUE; + fi->g.explore_fabric = FALSE; + } + else + if (((fm_status & 0xF0) == OLD_PORT) && ((fm_status & 0x0F) == PORT_STATE_ACTIVE)) { + fi->g.loop_up = FALSE; + fi->g.my_id = 0x0; + /* In a point-to-point configuration, we expect to be + * connected to an F_Port. This driver does not yet support + * a configuration where it is connected to another N_Port + * directly. + */ + fi->g.explore_fabric = TRUE; + fi->g.port_discovery = FALSE; + if (fi->g.n_port_try == FALSE) { + take_tachyon_offline(fi); + /* write R_T_TOV & E_D_TOV into the registers */ + writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg); + writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg); + fi->g.n_port_try = TRUE; + DPRINTK1("In LUP TACHYON initializing as N_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } + else { + fi->g.ptp_up = TRUE; + tx_logi(fi, ELS_FLOGI, F_PORT); + } + } + fi->g.my_ddaa = 0x0; + fi->g.fabric_present = FALSE; + /* We havn't sent out any Name Server Reqs */ + fi->g.name_server = FALSE; + fi->g.alpa_list_index = 0; + fi->g.ox_id = NOT_SCSI_XID; + fi->g.my_mtu = FRAME_SIZE; + + /* Implicitly LOGO with all logged-in nodes. + */ + if (fi->node_info_list) { + struct fc_node_info *temp_list = fi->node_info_list; + while(temp_list) { + temp_list->login = LOGIN_ATTEMPTED; + temp_list = temp_list->next; + } + fi->num_nodes = 0; + fi->g.perform_adisc = TRUE; + //fi->g.perform_adisc = FALSE; + fi->g.port_discovery = FALSE; + tx_logi(fi, ELS_FLOGI, F_PORT); + } + else { + /* If Link coming up for the _first_ time or no nodes + * were logged in before... + */ + fi->g.scsi_oxid = 0; + fi->g.seq_id = 0x00; + fi->g.perform_adisc = FALSE; + } + + /* reset OX_ID table */ + while (fi->ox_id_list) { + struct ox_id_els_map *temp = fi->ox_id_list; + fi->ox_id_list = fi->ox_id_list->next; + kfree(temp); + } + fi->ox_id_list = NULL; + } /* End of if partipating */ + } + + if (fm_status & ELASTIC_STORE_ERROR) { + /* Too much junk on the Link + */ + /* Trying to clear it up by Txing PLOGI to urself */ + if (fi->g.link_up == TRUE) + tx_logi(fi, ELS_PLOGI, fi->g.my_id); + } + + if (fm_status & LOOP_UP) { + if (tachyon_status & OSM_FROZEN) { + reset_tachyon(fi, ERROR_RELEASE); + reset_tachyon(fi, OCQ_RESET); + } + } + + if (fm_status & NOS_OLS_RECEIVED){ + if (fi->g.nport_timer_set == FALSE) { + DPRINTK("NOS/OLS Received"); + DPRINTK("FM_status = %x", fm_status); + fi->nport_timer.function = nos_ols_timer; + fi->nport_timer.data = (unsigned long)fi; + fi->nport_timer.expires = RUN_AT((3*HZ)/100); /* 30 msec */ + init_timer(&fi->nport_timer); + add_timer(&fi->nport_timer); + fi->g.nport_timer_set = TRUE; + } + } + + if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) { + DPRINTK1("Link Fail-I in OLD-PORT."); + take_tachyon_offline(fi); + reset_tachyon(fi, SOFTWARE_RESET); + } + + if (fm_status & LOOP_STATE_TIMEOUT){ + if ((fm_status & 0xF0) == ARBITRATING) + DPRINTK1("ED_TOV timesout.In ARBITRATING state..."); + if ((fm_status & 0xF0) == ARB_WON) + DPRINTK1("ED_TOV timesout.In ARBITRATION WON state..."); + if ((fm_status & 0xF0) == OPEN) + DPRINTK1("ED_TOV timesout.In OPEN state..."); + if ((fm_status & 0xF0) == OPENED) + DPRINTK1("ED_TOV timesout.In OPENED state..."); + if ((fm_status & 0xF0) == TX_CLS) + DPRINTK1("ED_TOV timesout.In XMITTED CLOSE state..."); + if ((fm_status & 0xF0) == RX_CLS) + DPRINTK1("ED_TOV timesout.In RECEIVED CLOSE state..."); + if ((fm_status & 0xF0) == INITIALIZING) + DPRINTK1("ED_TOV timesout.In INITIALIZING state..."); + DPRINTK1("Initializing Loop..."); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } + + if ((fm_status & BAD_ALPA) && (fi->g.loop_up == TRUE)) { + u_char bad_alpa = (readl(fi->t_r.ptr_fm_rx_al_pa_reg) & 0xFF00) >> 8; + if (tachyon_status & OSM_FROZEN) { + reset_tachyon(fi, ERROR_RELEASE); + reset_tachyon(fi, OCQ_RESET); + } + /* Fix for B34 */ + tx_logi(fi, ELS_PLOGI, fi->g.my_id); + + if (!fi->g.port_discovery && !fi->g.perform_adisc) { + if (bad_alpa != 0xFE) + DPRINTK("Bad AL_PA = %x", bad_alpa); + } + else { + if ((fi->g.perform_adisc == TRUE) && (bad_alpa == 0x00)) { + DPRINTK1("Performing ADISC..."); + fi->g.fabric_present = FALSE; + perform_adisc(fi); + } + } + } + + if (fm_status & LIPF_RECEIVED){ + DPRINTK("LIP(F8) Received"); + } + + if (fm_status & LINK_FAILURE) { + if (fm_status & LOSS_OF_SIGNAL) + DPRINTK1("Detected Loss of Signal."); + if (fm_status & OUT_OF_SYNC) + DPRINTK1("Detected Loss of Synchronization."); + } + + if (fm_status & TRANSMIT_PARITY_ERROR) { + /* Bad! Should not happen. Solution-> Hard Reset. + */ + T_MSG("Parity Error. Perform Hard Reset!"); + } + + if (fi->g.alpa_list_index >= MAX_NODES){ + if (fi->g.port_discovery == TRUE) { + fi->g.port_discovery = FALSE; + add_display_cache_timer(fi); + } + fi->g.alpa_list_index = MAX_NODES; + } + + if (fi->g.port_discovery == TRUE) + local_port_discovery(fi); + + LEAVE("handle_FM_interrupt"); + return; +} + +static void local_port_discovery(struct fc_info *fi) +{ + if (fi->g.loop_up == TRUE) { + /* If this is not here, some of the Bad AL_PAs are missed. + */ + udelay(20); + if ((fi->g.alpa_list_index == 0) && (fi->g.fabric_present == FALSE)){ + tx_logi(fi, ELS_FLOGI, F_PORT); + } + else { + int login_state = sid_logged_in(fi, fi->g.my_ddaa | alpa_list[fi->g.alpa_list_index]); + while ((fi->g.alpa_list_index == 0) || ((fi->g.alpa_list_index < MAX_NODES) && ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN) || (alpa_list[fi->g.alpa_list_index] == (fi->g.my_id & 0xFF))))) + fi->g.alpa_list_index++; + if (fi->g.alpa_list_index < MAX_NODES) + tx_logi(fi, ELS_PLOGI, alpa_list[fi->g.alpa_list_index]); + } + fi->g.alpa_list_index++; + if (fi->g.alpa_list_index >= MAX_NODES){ + if (fi->g.port_discovery == TRUE) { + fi->g.port_discovery = FALSE; + add_display_cache_timer(fi); + } + fi->g.alpa_list_index = MAX_NODES; + } + } +} + +static void nos_ols_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info*)data; +u_int fm_status; + fm_status = readl(fi->t_r.ptr_fm_status_reg); + DPRINTK1("FM_status in timer= %x", fm_status); + fi->g.nport_timer_set = FALSE; + del_timer(&fi->nport_timer); + if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE)) + return; + if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_ACTIVE) || ((fm_status & 0x0F) == PORT_STATE_OFFLINE))) { + DPRINTK1("In OLD-PORT after E_D_TOV."); + take_tachyon_offline(fi); + /* write R_T_TOV & E_D_TOV into the registers */ + writel(PTP_TOV_VALUES, fi->t_r.ptr_fm_tov_reg); + writel(BB_CREDIT | NPORT, fi->t_r.ptr_fm_config_reg); + fi->g.n_port_try = TRUE; + DPRINTK1("In timer, TACHYON initializing as N_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } + else + if ((fi->g.lport_timer_set == FALSE) && ((fm_status & 0xF0) == LOOP_FAIL)) { + DPRINTK1("Loop Fail after E_D_TOV."); + fi->lport_timer.function = loop_timer; + fi->lport_timer.data = (unsigned long)fi; + fi->lport_timer.expires = RUN_AT((8*HZ)/100); + init_timer(&fi->lport_timer); + add_timer(&fi->lport_timer); + fi->g.lport_timer_set = TRUE; + take_tachyon_offline(fi); + reset_tachyon(fi, SOFTWARE_RESET); + } + else + if (((fm_status & 0xF0) == OLD_PORT) && (((fm_status & 0x0F) == PORT_STATE_LF1) || ((fm_status & 0x0F) == PORT_STATE_LF2))) { + DPRINTK1("Link Fail-II in OLD-PORT."); + take_tachyon_offline(fi); + reset_tachyon(fi, SOFTWARE_RESET); + } +} + +static void loop_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info*)data; + fi->g.lport_timer_set = FALSE; + del_timer(&fi->lport_timer); + if ((fi->g.ptp_up == TRUE) || (fi->g.loop_up == TRUE)) + return; +} + +static void add_display_cache_timer(struct fc_info *fi) +{ + fi->display_cache_timer.function = display_cache_timer; + fi->display_cache_timer.data = (unsigned long)fi; + fi->display_cache_timer.expires = RUN_AT(fi->num_nodes * HZ); + init_timer(&fi->display_cache_timer); + add_timer(&fi->display_cache_timer); +} + +static void display_cache_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info*)data; + del_timer(&fi->display_cache_timer); + display_cache(fi); + return; +} + +static void reset_tachyon(struct fc_info *fi, u_int value) +{ +u_int tachyon_status, reset_done = OCQ_RESET_STATUS | SCSI_FREEZE_STATUS; +int not_done = 1, i = 0; + writel(value, fi->t_r.ptr_tach_control_reg); + if (value == OCQ_RESET) + fi->q.ocq_prod_indx = 0; + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + + /* Software resets are immediately done, whereas other aren't. It + about 30 clocks to do the reset */ + if (value != SOFTWARE_RESET) { + while(not_done) { + if (i++ > 100000) { + T_MSG("Reset was unsuccessful! Tachyon Status = %x", tachyon_status); + break; + } + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + if ((tachyon_status & reset_done) == 0) + not_done = 0; + } + } + else { + write_to_tachyon_registers(fi); + } +} + +static void take_tachyon_offline(struct fc_info *fi) +{ +u_int fm_status = readl(fi->t_r.ptr_fm_status_reg); + + /* The first two conditions will never be true. The Manual and + * the errata say this. But the current implementation is + * decently stable. + */ + //if ((fm_status & 0xF0) == LOOP_FAIL) { + if (fm_status == LOOP_FAIL) { + // workaround as in P. 89 + writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg); + if (fi->g.loop_up == TRUE) + writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg); + else { + writel(OFFLINE, fi->t_r.ptr_fm_control_reg); + writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg); + } + } + else + //if ((fm_status & LOOP_UP) == LOOP_UP) { + if (fm_status == LOOP_UP) { + writel(SOFTWARE_RESET, fi->t_r.ptr_tach_control_reg); + } + else + writel(OFFLINE, fi->t_r.ptr_fm_control_reg); +} + + +static void read_novram(struct fc_info *fi) +{ +int off = 0; + fi->n_r.ptr_novram_hw_control_reg = fi->i_r.ptr_ichip_hw_control_reg; + fi->n_r.ptr_novram_hw_status_reg = fi->i_r.ptr_ichip_hw_status_reg; + iph5526_nr_do_init(fi); + if (fi->clone_id == PCI_VENDOR_ID_INTERPHASE) + off = 32; + + fi->g.my_node_name_high = (fi->n_r.data[off] << 16) | fi->n_r.data[off+1]; + fi->g.my_node_name_low = (fi->n_r.data[off+2] << 16) | fi->n_r.data[off+3]; + fi->g.my_port_name_high = (fi->n_r.data[off+4] << 16) | fi->n_r.data[off+5]; + fi->g.my_port_name_low = (fi->n_r.data[off+6] << 16) | fi->n_r.data[off+7]; + DPRINTK("node_name = %x %x", fi->g.my_node_name_high, fi->g.my_node_name_low); + DPRINTK("port_name = %x %x", fi->g.my_port_name_high, fi->g.my_port_name_low); +} + +static void reset_ichip(struct fc_info *fi) +{ + /* (i)chip reset */ + writel(ICHIP_HCR_RESET, fi->i_r.ptr_ichip_hw_control_reg); + /*wait for chip to get reset */ + udelay(10000); + /*de-assert reset */ + writel(ICHIP_HCR_DERESET, fi->i_r.ptr_ichip_hw_control_reg); + + /* enable INT lines on the (i)chip */ + writel(ICHIP_HCR_ENABLE_INTA , fi->i_r.ptr_ichip_hw_control_reg); + /* enable byte swap */ + writel(ICHIP_HAMR_BYTE_SWAP_ADDR_TR, fi->i_r.ptr_ichip_hw_addr_mask_reg); +} + +static void tx_logi(struct fc_info *fi, u_int logi, u_int d_id) +{ +int int_required = 1; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +u_int r_ctl = RCTL_ELS_UCTL; +u_int type = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_logi"); + /* We dont want interrupted for our own logi. + * It screws up the port discovery process. + */ + if (d_id == fi->g.my_id) + int_required = 0; + fill_login_frame(fi, logi); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN)); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), r_ctl, type, d_id, my_mtu, int_required, ox_id, logi); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_logi"); + return; +} + +static void tx_logi_acc(struct fc_info *fi, u_int logi, u_int d_id, u_short received_ox_id) +{ +int int_required = 0; +u_int r_ctl = RCTL_ELS_SCTL; +u_int type = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_logi_acc"); + fill_login_frame(fi, logi); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.login, sizeof(LOGIN)); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),sizeof(LOGIN), r_ctl, type, d_id, my_mtu, int_required, received_ox_id, logi); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_logi_acc"); + return; +} + +static void tx_prli(struct fc_info *fi, u_int command_code, u_int d_id, u_short received_ox_id) +{ +int int_required = 1; +u_int r_ctl = RCTL_ELS_UCTL; +u_int type = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_prli"); + if (command_code == ELS_PRLI) + fi->g.prli.cmnd_code = htons((ELS_PRLI | PAGE_LEN) >> 16); + else { + fi->g.prli.cmnd_code = htons((ELS_ACC | PAGE_LEN) >> 16); + int_required = 0; + type = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE; + r_ctl = RCTL_ELS_SCTL; + } + fi->g.prli.payload_length = htons(PRLI_LEN); + fi->g.prli.type_code = htons(FCP_TYPE_CODE); + fi->g.prli.est_image_pair = htons(IMAGE_PAIR); + fi->g.prli.responder_pa = 0; + fi->g.prli.originator_pa = 0; + fi->g.prli.service_params = htonl(INITIATOR_FUNC | READ_XFER_RDY_DISABLED); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.prli, sizeof(PRLI)); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]), sizeof(PRLI), r_ctl, type, d_id, my_mtu, int_required, received_ox_id, command_code); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_prli"); + return; +} + +static void tx_logo(struct fc_info *fi, u_int d_id, u_short received_ox_id) +{ +int int_required = 1; +u_int r_ctl = RCTL_ELS_UCTL; +u_int type = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE | SEQUENCE_INITIATIVE; +int size = sizeof(LOGO); +char fc_id[3]; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_logo"); + fi->g.logo.logo_cmnd = htonl(ELS_LOGO); + fi->g.logo.reserved = 0; + memcpy(fc_id, &(fi->g.my_id), 3); + fi->g.logo.n_port_id_0 = fc_id[0]; + fi->g.logo.n_port_id_1 = fc_id[1]; + fi->g.logo.n_port_id_2 = fc_id[2]; + fi->g.logo.port_name_up = htonl(N_PORT_NAME_HIGH); + fi->g.logo.port_name_low = htonl(N_PORT_NAME_LOW); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.logo, sizeof(LOGO)); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_LOGO); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_logo"); +} + +static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id) +{ +int int_required = 0; +u_int r_ctl = RCTL_ELS_SCTL; +u_int type = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE; +int size = sizeof(ADISC); +u_int my_mtu = fi->g.my_mtu; + fi->g.adisc.ls_cmnd_code = htonl(cmnd_code); + fi->g.adisc.hard_address = htonl(0); + fi->g.adisc.port_name_high = htonl(N_PORT_NAME_HIGH); + fi->g.adisc.port_name_low = htonl(N_PORT_NAME_LOW); + fi->g.adisc.node_name_high = htonl(NODE_NAME_HIGH); + fi->g.adisc.node_name_low = htonl(NODE_NAME_LOW); + fi->g.adisc.n_port_id = htonl(fi->g.my_id); + if (cmnd_code == ELS_ADISC) { + int_required = 1; + r_ctl = RCTL_ELS_UCTL; + type = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; + } + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.adisc, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, cmnd_code); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; +} + +static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, u_short reason_code, u_short expln_code) +{ +int int_required = 0; +u_int r_ctl = RCTL_ELS_SCTL; +u_int type = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE; +int size = sizeof(LS_RJT); +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_ls_rjt"); + fi->g.ls_rjt.cmnd_code = htonl(ELS_LS_RJT); + fi->g.ls_rjt.reason_code = htonl((reason_code << 16) | expln_code); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.ls_rjt, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_LS_RJT); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_ls_rjt"); +} + +static void tx_abts(struct fc_info *fi, u_int d_id, u_short ox_id) +{ +int int_required = 1; +u_int r_ctl = RCTL_BASIC_ABTS; +u_int type = TYPE_BLS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; +int size = 0; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_abts"); + fi->g.type_of_frame = FC_BLS; + tx_exchange(fi, NULL, size, r_ctl, type, d_id, my_mtu, int_required, ox_id, RCTL_BASIC_ABTS); + LEAVE("tx_abts"); +} + +static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size) +{ +int ret_code = 0; +u_short mtu = ntohl(*(buff_addr + 10)) & 0x00000FFF; +u_short class3 = ntohl(*(buff_addr + 25)) >> 16; +u_short class3_conc_seq = ntohl(*(buff_addr + 27)) >> 16; +u_short open_seq = ntohl(*(buff_addr + 28)) >> 16; + DPRINTK1("mtu = %x class3 = %x conc_seq = %x open_seq = %x", mtu, class3, class3_conc_seq, open_seq); + size -= TACHYON_HEADER_LEN; + if (!(class3 & 0x8000)) { + DPRINTK1("Received PLOGI with class3 = %x", class3); + ret_code = (LOGICAL_ERR << 16) | NO_EXPLN; + return ret_code; + } + if (mtu < 256) { + DPRINTK1("Received PLOGI with MTU set to %x", mtu); + ret_code = (LOGICAL_ERR << 16) | RECV_FIELD_SIZE; + return ret_code; + } + if (size != PLOGI_LEN) { + DPRINTK1("Received PLOGI of size %x", size); + ret_code = (LOGICAL_ERR << 16) | INV_PAYLOAD_LEN; + return ret_code; + } + if (class3_conc_seq == 0) { + DPRINTK1("Received PLOGI with conc_seq == 0"); + ret_code = (LOGICAL_ERR << 16) | CONC_SEQ; + return ret_code; + } + if (open_seq == 0) { + DPRINTK1("Received PLOGI with open_seq == 0"); + ret_code = (LOGICAL_ERR << 16) | NO_EXPLN; + return ret_code; + } + + /* Could potentially check for more fields, but might end up + not talking to most of the devices. ;-) */ + /* Things that could get checked are: + common_features = 0x8800 + total_concurrent_seq = at least 1 + */ + return ret_code; +} + +static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id) +{ +int int_required = 0; +u_int r_ctl = RCTL_ELS_SCTL; +u_int type = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE; +int size = sizeof(ACC); +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_acc"); + fi->g.acc.cmnd_code = htonl(ELS_ACC); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.acc, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_ACC); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_acc"); +} + + +static void tx_name_server_req(struct fc_info *fi, u_int req) +{ +int int_required = 1, i, size = 0; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +u_int type = TYPE_FC_SERVICES | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; +u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_CONTROL; +u_int my_mtu = fi->g.my_mtu, d_id = DIRECTORY_SERVER; +CT_HDR ct_hdr; + ENTER("tx_name_server_req"); + /* Fill up CT_Header */ + ct_hdr.rev_in_id = htonl(FC_CT_REV); + ct_hdr.fs_type = DIRECTORY_SERVER_APP; + ct_hdr.fs_subtype = NAME_SERVICE; + ct_hdr.options = 0; + ct_hdr.resv1 = 0; + ct_hdr.cmnd_resp_code = htons(req >> 16); + ct_hdr.max_res_size = 0; + ct_hdr.resv2 = 0; + ct_hdr.reason_code = 0; + ct_hdr.expln_code = 0; + ct_hdr.vendor_unique = 0; + + fi->g.type_of_frame = FC_ELS; + switch(req) { + case FCS_RFC_4: + memcpy(&(fi->g.rfc_4.ct_hdr), &ct_hdr, sizeof(CT_HDR)); + fi->g.rfc_4.s_id = htonl(fi->g.my_id); + for (i = 0; i < 32; i++) + fi->g.rfc_4.bit_map[i] = 0; + /* We support IP & SCSI */ + fi->g.rfc_4.bit_map[2] = 0x01; + fi->g.rfc_4.bit_map[3] = 0x20; + size = sizeof(RFC_4); + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.rfc_4, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req); + break; + case FCS_GP_ID4: + memcpy(&(fi->g.gp_id4.ct_hdr), &ct_hdr, sizeof(CT_HDR)); + fi->g.gp_id4.port_type = htonl(PORT_TYPE_NX_PORTS); + size = sizeof(GP_ID4); + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.gp_id4, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req); + break; + } + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_name_server_req"); +} + +static void tx_scr(struct fc_info *fi) +{ +int int_required = 1, size = sizeof(SCR); +u_short ox_id = OX_ID_FIRST_SEQUENCE; +u_int type = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE; +u_int r_ctl = RCTL_ELS_UCTL; +u_int my_mtu = fi->g.my_mtu, d_id = FABRIC_CONTROLLER; + ENTER("tx_scr"); + fi->g.scr.cmnd_code = htonl(ELS_SCR); + fi->g.scr.reg_function = htonl(FULL_REGISTRATION); + fi->g.type_of_frame = FC_ELS; + memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.scr, size); + tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, ELS_SCR); + fi->g.e_i++; + if (fi->g.e_i == MAX_PENDING_FRAMES) + fi->g.e_i = 0; + LEAVE("tx_scr"); +} + +static void perform_adisc(struct fc_info *fi) +{ +int count = 0; + /* Will be set to TRUE when timer expires in a PLDA environment. + */ + fi->g.port_discovery = FALSE; + + if (fi->node_info_list) { + struct fc_node_info *temp_list = fi->node_info_list; + while(temp_list) { + /* Tx ADISC to all non-fabric based + * entities. + */ + if ((temp_list->d_id & 0xFF0000) != 0xFF0000) + tx_adisc(fi, ELS_ADISC, temp_list->d_id, OX_ID_FIRST_SEQUENCE); + temp_list = temp_list->next; + udelay(20); + count++; + } + } + /* Perform Port Discovery after timer expires. + * We are giving time for the ADISCed nodes to respond + * so that we dont have to perform PLOGI to those whose + * login are _still_ valid. + */ + fi->explore_timer.function = port_discovery_timer; + fi->explore_timer.data = (unsigned long)fi; + fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); + init_timer(&fi->explore_timer); + add_timer(&fi->explore_timer); +} + +static void explore_fabric(struct fc_info *fi, u_int *buff_addr) +{ +u_int *addr = buff_addr + 12; /* index into payload */ +u_char control_code; +u_int d_id; +int count = 0; + ENTER("explore_fabric"); + DPRINTK1("entering explore_fabric"); + + /*fi->g.perform_adisc = TRUE; + fi->g.explore_fabric = TRUE; + perform_adisc(fi);*/ + + do { + d_id = ntohl(*addr) & 0x00FFFFFF; + if (d_id != fi->g.my_id) { + if (sid_logged_in(fi, d_id) == NODE_NOT_PRESENT) + tx_logi(fi, ELS_PLOGI, d_id); + else + if (sid_logged_in(fi, d_id) == NODE_LOGGED_OUT) + tx_adisc(fi, ELS_ADISC, d_id, OX_ID_FIRST_SEQUENCE); + count++; + } + control_code = (ntohl(*addr) & 0xFF000000) >> 24; + addr++; + DPRINTK1("cc = %x, d_id = %x", control_code, d_id); + } while (control_code != 0x80); + + fi->explore_timer.function = fabric_explore_timer; + fi->explore_timer.data = (unsigned long)fi; + /* We give 30 msec for each device to respond and then send out + * our SCSI enquiries. + */ + fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); + init_timer(&fi->explore_timer); + add_timer(&fi->explore_timer); + + DPRINTK1("leaving explore_fabric"); + LEAVE("explore_fabric"); +} + +static void fabric_explore_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info*)data; + del_timer(&fi->explore_timer); + + if ((fi->g.loop_up == TRUE) && (fi->g.ptp_up == FALSE)) { + /* Initiate Local Port Discovery on the Local Loop. + */ + fi->g.port_discovery = TRUE; + fi->g.alpa_list_index = 1; + local_port_discovery(fi); + } + fi->g.explore_fabric = FALSE; + return; +} + +static void port_discovery_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info*)data; + del_timer(&fi->explore_timer); + + if ((fi->g.loop_up == TRUE) && (fi->g.explore_fabric != TRUE)) { + fi->g.port_discovery = TRUE; + fi->g.alpa_list_index = 1; + local_port_discovery(fi); + } + fi->g.perform_adisc = FALSE; + return; +} + +static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code) +{ +struct ox_id_els_map *p, *q = fi->ox_id_list, *r = NULL; +int size = sizeof(struct ox_id_els_map); + while (q != NULL) { + r = q; + q = q->next; + } + p = (struct ox_id_els_map *)kmalloc(size, GFP_ATOMIC); + if (p == NULL) { + T_MSG("kmalloc failed in add_to_ox_id_list()"); + return; + } + p->ox_id = transaction_id; + p->els = cmnd_code; + p->next = NULL; + if (fi->ox_id_list == NULL) + fi->ox_id_list = p; + else + r->next = p; + return; +} + +static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id) +{ +struct ox_id_els_map *p = fi->ox_id_list, *q = fi->ox_id_list; +u_int els_type; + while (q != NULL) { + if (q->ox_id == received_ox_id) { + + if (q == fi->ox_id_list) + fi->ox_id_list = fi->ox_id_list->next; + else + if (q->next == NULL) + p->next = NULL; + else + p->next = q->next; + + els_type = q->els; + kfree(q); + return els_type; + } + p = q; + q = q->next; + } + if (q == NULL) + DPRINTK2("Could not find ox_id %x in ox_id_els_map", received_ox_id); + return 0; +} + +static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short rx_id, char *data) +{ +u_char alpa = d_id & 0x0000FF; +u_int dest_ddaa = d_id &0xFFFF00; + + ENTER("build_tachyon_header"); + DPRINTK("d_id = %x, my_ddaa = %x", d_id, fi->g.my_ddaa); + /* Does it have to go to/thru a Fabric? */ + if ((dest_ddaa != 0) && ((d_id == F_PORT) || (fi->g.fabric_present && (dest_ddaa != fi->g.my_ddaa)))) + alpa = 0x00; + fi->g.tach_header.resv = 0x00000000; + fi->g.tach_header.sof_and_eof = SOFI3 | EOFN; + fi->g.tach_header.dest_alpa = alpa; + /* Set LCr properly to have enuff credit */ + if (alpa == REPLICATE) + fi->g.tach_header.lcr_and_time_stamp = htons(0xC00);/* LCr=3 */ + else + fi->g.tach_header.lcr_and_time_stamp = 0; + fi->g.tach_header.r_ctl_and_d_id = htonl(r_ctl | d_id); + fi->g.tach_header.vc_id_and_s_id = htonl(my_id); + fi->g.tach_header.type_and_f_cntl = htonl(type); + fi->g.tach_header.seq_id = seq_id; + fi->g.tach_header.df_cntl = df_ctl; + fi->g.tach_header.seq_cnt = 0; + fi->g.tach_header.ox_id = htons(ox_id); + fi->g.tach_header.rx_id = htons(rx_id); + fi->g.tach_header.ro = 0; + if (data) { + /* We use the Seq_Count to keep track of IP frames in the + * OCI_interrupt handler. Initial Seq_Count of IP frames is 1. + */ + if (fi->g.type_of_frame == FC_BROADCAST) + fi->g.tach_header.seq_cnt = htons(0x1); + else + fi->g.tach_header.seq_cnt = htons(0x2); + fi->g.tach_header.nw_header.d_naa = htons(0x1000); + fi->g.tach_header.nw_header.s_naa = htons(0x1000); + memcpy(&(fi->g.tach_header.nw_header.dest_high), data, 2); + memcpy(&(fi->g.tach_header.nw_header.dest_low), data + 2, 4); + memcpy(&(fi->g.tach_header.nw_header.source_high), data + 6, 2); + memcpy(&(fi->g.tach_header.nw_header.source_low), data + 8, 4); + } + LEAVE("build_tachyon_header"); +} + +static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len) +{ + fi->g.edb.buf_addr = ntohl((u_int)virt_to_bus(data)); + fi->g.edb.ehf = ntohs(flags); + if (len % 4) + len += (4 - (len % 4)); + fi->g.edb.buf_len = ntohs(len); +} + +static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int int_required, u_int frame_class) +{ + fi->g.odb.seq_d_id = htonl(seq_id << 24 | d_id); + fi->g.odb.tot_len = len; + if (NW_header) + fi->g.odb.tot_len += NW_HEADER_LEN; + if (fi->g.odb.tot_len % 4) + fi->g.odb.tot_len += (4 - (fi->g.odb.tot_len % 4)); + fi->g.odb.tot_len = htonl(fi->g.odb.tot_len); + switch(int_required) { + case NO_COMP_AND_INT: + fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP | cntl); + break; + case INT_AND_COMP_REQ: + fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | cntl); + break; + case NO_INT_COMP_REQ: + fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | cntl); + break; + } + fi->g.odb.rx_id = htons(rx_id); + fi->g.odb.cs_enable = 0; + fi->g.odb.cs_seed = htons(1); + + fi->g.odb.hdr_addr = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx])); + fi->g.odb.frame_len = htons(mtu); + + if (NW_header) { + /* The pointer to the sk_buff is in here. Freed up when the + * OCI_interrupt is received. + */ + fi->g.odb.trans_id = htonl(frame_class); + fi->g.odb.hdr_len = TACHYON_HEADER_LEN + NW_HEADER_LEN; + } + else { + /* helps in tracking transmitted OX_IDs */ + fi->g.odb.trans_id = htonl((frame_class & 0xFFFF0000) | ox_id); + fi->g.odb.hdr_len = TACHYON_HEADER_LEN; + } + fi->g.odb.hdr_len = htons(fi->g.odb.hdr_len); + + fi->g.odb.edb_addr = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx])); +} + +static void fill_login_frame(struct fc_info *fi, u_int logi) +{ +int i; + fi->g.login.ls_cmnd_code= htonl(logi); + fi->g.login.fc_ph_version = htons(PH_VERSION); + if (fi->g.loop_up) + fi->g.login.buff_to_buff_credit = htons(LOOP_BB_CREDIT); + else + if (fi->g.ptp_up) + fi->g.login.buff_to_buff_credit = htons(PT2PT_BB_CREDIT); + if ((logi != ELS_FLOGI) || (logi == ELS_ACC)) + fi->g.login.common_features = htons(PLOGI_C_F); + else + if (logi == ELS_FLOGI) + fi->g.login.common_features = htons(FLOGI_C_F); + fi->g.login.recv_data_field_size = htons(FRAME_SIZE); + fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES); + fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY); + fi->g.login.ED_TOV = htonl(E_D_TOV); + fi->g.login.n_port_name_high = htonl(N_PORT_NAME_HIGH); + fi->g.login.n_port_name_low = htonl(N_PORT_NAME_LOW); + fi->g.login.node_name_high = htonl(NODE_NAME_HIGH); + fi->g.login.node_name_low = htonl(NODE_NAME_LOW); + + /* Fill Class 1 parameters */ + fi->g.login.c_of_s[0].service_options = htons(0); + fi->g.login.c_of_s[0].initiator_ctl = htons(0); + fi->g.login.c_of_s[0].recipient_ctl = htons(0); + fi->g.login.c_of_s[0].recv_data_field_size = htons(0); + fi->g.login.c_of_s[0].concurrent_sequences = htons(0); + fi->g.login.c_of_s[0].n_port_end_to_end_credit = htons(0); + fi->g.login.c_of_s[0].open_seq_per_exchange = htons(0); + fi->g.login.c_of_s[0].resv = htons(0); + + /* Fill Class 2 parameters */ + fi->g.login.c_of_s[1].service_options = htons(0); + fi->g.login.c_of_s[1].initiator_ctl = htons(0); + fi->g.login.c_of_s[1].recipient_ctl = htons(0); + fi->g.login.c_of_s[1].recv_data_field_size = htons(0); + fi->g.login.c_of_s[1].concurrent_sequences = htons(0); + fi->g.login.c_of_s[1].n_port_end_to_end_credit = htons(0); + fi->g.login.c_of_s[1].open_seq_per_exchange = htons(0); + fi->g.login.c_of_s[1].resv = htons(0); + + /* Fill Class 3 parameters */ + if (logi == ELS_FLOGI) + fi->g.login.c_of_s[2].service_options = htons(SERVICE_VALID | SEQUENCE_DELIVERY); + else + fi->g.login.c_of_s[2].service_options = htons(SERVICE_VALID); + fi->g.login.c_of_s[2].initiator_ctl = htons(0); + fi->g.login.c_of_s[2].recipient_ctl = htons(0); + fi->g.login.c_of_s[2].recv_data_field_size = htons(FRAME_SIZE); + fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE); + fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0); + fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE); + fi->g.login.c_of_s[2].resv = htons(0); + + for(i = 0; i < 4; i++) { + fi->g.login.resv[i] = 0; + fi->g.login.vendor_version_level[i] = 0; + } +} + + +/* clear the Interrupt Latch on the (i)chip, so that you can receive + * Interrupts from Tachyon in future + */ +static void reset_latch(struct fc_info *fi) +{ + writel(readl(fi->i_r.ptr_ichip_hw_status_reg) | ICHIP_HSR_INT_LATCH, fi->i_r.ptr_ichip_hw_status_reg); +} + +static void update_OCQ_indx(struct fc_info *fi) +{ + fi->q.ocq_prod_indx++; + if (fi->q.ocq_prod_indx == OCQ_LENGTH) + fi->q.ocq_prod_indx = 0; + writel(fi->q.ocq_prod_indx, fi->t_r.ptr_ocq_prod_indx_reg); +} + +static void update_IMQ_indx(struct fc_info *fi, int count) +{ + fi->q.imq_cons_indx += count; + if (fi->q.imq_cons_indx >= IMQ_LENGTH) + fi->q.imq_cons_indx -= IMQ_LENGTH; + writel(fi->q.imq_cons_indx, fi->t_r.ptr_imq_cons_indx_reg); +} + +static void update_SFSBQ_indx(struct fc_info *fi) +{ + fi->q.sfsbq_prod_indx++; + if (fi->q.sfsbq_prod_indx == SFSBQ_LENGTH) + fi->q.sfsbq_prod_indx = 0; + writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg); +} + +static void update_MFSBQ_indx(struct fc_info *fi, int count) +{ + fi->q.mfsbq_prod_indx += count; + if (fi->q.mfsbq_prod_indx >= MFSBQ_LENGTH) + fi->q.mfsbq_prod_indx -= MFSBQ_LENGTH; + writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg); +} + + +static void update_tachyon_header_indx(struct fc_info *fi) +{ + fi->q.tachyon_header_indx++; + if (fi->q.tachyon_header_indx == NO_OF_TACH_HEADERS) + fi->q.tachyon_header_indx = 0; +} + +static void update_EDB_indx(struct fc_info *fi) +{ + fi->q.edb_buffer_indx++; + if (fi->q.edb_buffer_indx == EDB_LEN) + fi->q.edb_buffer_indx = 0; +} + +static int iph5526_open(struct net_device *dev) +{ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + MOD_INC_USE_COUNT; + return 0; +} + +static int iph5526_close(struct net_device *dev) +{ + dev->tbusy = 1; + dev->start = 0; + MOD_DEC_USE_COUNT; + return 0; +} + +static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev) +{ +struct fc_info *fi = (struct fc_info*)dev->priv; +int status = 0; +short type = 0; +u_long flags; + ENTER("iph5526_send_packet"); + if (dev->tbusy) { + printk(KERN_WARNING "%s: DEVICE BUSY\n", dev->name); + dev->tbusy = 0; + fi->fc_stats.rx_dropped++; + dev->trans_start = jiffies; + return 0; + } + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + printk(KERN_WARNING "%s: Transmitter access conflict.\n", +dev->name); + fi->fc_stats.rx_dropped++; + return 1; + } + else { + struct fcllc *fcllc; + /* Strip off the pseudo header. + */ + skb->data = skb->data + 2*FC_ALEN; + skb->len = skb->len - 2*FC_ALEN; + fcllc = (struct fcllc *)skb->data; + type = ntohs(fcllc->ethertype); + + spin_lock_irqsave(&fi->fc_lock, flags); + switch(type) { + case ETH_P_IP: + status = tx_ip_packet(skb, skb->len, fi); + break; + case ETH_P_ARP: + status = tx_arp_packet(skb->data, skb->len, fi); + break; + default: + T_MSG("WARNING!!! Received Unknown Packet Type... Discarding..."); + fi->fc_stats.rx_dropped++; + break; + } + spin_unlock_irqrestore(&fi->fc_lock, flags); + } + + if (status) { + fi->fc_stats.tx_bytes += skb->len; + fi->fc_stats.tx_packets++; + } + else + fi->fc_stats.rx_dropped++; + dev->trans_start = jiffies; + dev->tbusy = 0; + /* We free up the IP buffers in the OCI_interrupt handler. + * status == 0 implies that the frame was not transmitted. So the + * skb is freed here. + */ + if ((type == ETH_P_ARP) || (status == 0)) + dev_kfree_skb(skb); + mark_bh(NET_BH); + LEAVE("iph5526_send_packet"); + return 0; +} + +static int iph5526_change_mtu(struct net_device *dev, int mtu) +{ + return 0; +} + +static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi) +{ +u_int d_id; +int int_required = 1; +u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA; +u_int type = TYPE_LLC_SNAP; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +u_int mtu; +struct fc_node_info *q; + + ENTER("tx_ip_packet"); + q = look_up_cache(fi, skb->data - 2*FC_ALEN); + if (q != NULL) { + d_id = q->d_id; + DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id); + mtu = q->mtu; + if (q->login == LOGIN_COMPLETED){ + fi->g.type_of_frame = FC_IP; + return tx_exchange(fi, skb->data, len, r_ctl, type, d_id, mtu, int_required, ox_id, virt_to_bus(skb)); + } + + if (q->d_id == BROADCAST) { + struct fc_node_info *p = fi->node_info_list; + int return_value = FALSE; + fi->g.type_of_frame = FC_BROADCAST; + /* Do unicast to local nodes. + */ + int_required = 0; + while(p != NULL) { + d_id = p->d_id; + if ((d_id & 0xFFFF00) == fi->g.my_ddaa) + return_value |= tx_exchange(fi, skb->data, len, r_ctl, type, d_id, fi->g.my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + p = p->next; + } + kfree(q); + return return_value; + } + + if (q->login != LOGIN_COMPLETED) { + DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id); + /* FIXME: we are dumping the frame here */ + tx_logi(fi, ELS_PLOGI, d_id); + } + } + DPRINTK2("Look-Up Cache Failed"); + LEAVE("tx_ip_packet"); + return 0; +} + +static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi) +{ +u_int opcode = data[ARP_OPCODE_0]; +u_int d_id; +int int_required = 0, return_value = FALSE; +u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA; +u_int type = TYPE_LLC_SNAP; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +u_int my_mtu = fi->g.my_mtu; + ENTER("tx_arp_packet"); + + opcode = opcode << 8 | data[ARP_OPCODE_1]; + fi->g.type_of_frame = FC_IP; + + if (opcode == ARPOP_REQUEST) { + struct fc_node_info *q = fi->node_info_list; + d_id = BROADCAST; + return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + /* Some devices support HW_TYPE 0x01 */ + memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN); + fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01; + return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + + /* Do unicast to local nodes. + */ + while(q != NULL) { + fi->g.type_of_frame = FC_BROADCAST; + d_id = q->d_id; + if ((d_id & 0xFFFF00) == fi->g.my_ddaa) { + return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + // Some devices support HW_TYPE 0x01 + memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN); + fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01; + return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + } + q = q->next; + } + return return_value; + } + else + if (opcode == ARPOP_REPLY) { + struct fc_node_info *q; u_int mtu; + DPRINTK("We are sending out an ARP reply"); + q = look_up_cache(fi, data - 2*FC_ALEN); + if (q != NULL) { + d_id = q->d_id; + DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id); + mtu = q->mtu; + if (q->login == LOGIN_COMPLETED){ + tx_exchange(fi, data, len, r_ctl, type, d_id, mtu, int_required, ox_id, TYPE_LLC_SNAP); + /* Some devices support HW_TYPE 0x01 */ + memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN); + fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01; + return tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP); + } + else { + DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id); + tx_logi(fi, ELS_PLOGI, d_id); /* FIXME: we are dumping the frame here */ + } + } + DPRINTK2("Look-Up Cache Failed"); + } + else { + T_MSG("Warning!!! Invalid Opcode in ARP Packet!"); + } + LEAVE("tx_arp_packet"); + return 0; +} + + +static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size) +{ +struct net_device *dev = fi->dev; +struct sk_buff *skb; +u_int skb_size = 0; +struct fch_hdr fch; + ENTER("rx_net_packet"); + skb_size = payload_size - TACHYON_HEADER_LEN; + DPRINTK("skb_size = %d", skb_size); + fi->fc_stats.rx_bytes += skb_size - 2; + skb = dev_alloc_skb(skb_size); + if (skb == NULL) { + printk(KERN_NOTICE "%s: In rx_net_packet() Memory squeeze, dropping packet.\n", dev->name); + fi->fc_stats.rx_dropped++; + return; + } + /* Skip over the Tachyon Frame Header. + */ + buff_addr += TACHYON_HEADER_LEN; + + memcpy(fch.daddr, buff_addr + 2, FC_ALEN); + memcpy(fch.saddr, buff_addr + 10, FC_ALEN); + buff_addr += 2; + memcpy(buff_addr, fch.daddr, FC_ALEN); + memcpy(buff_addr + 6, fch.saddr, FC_ALEN); + skb_reserve(skb, 2); + memcpy(skb_put(skb, skb_size - 2), buff_addr, skb_size - 2); + skb->dev = dev; + skb->protocol = fc_type_trans(skb, dev); + DPRINTK("protocol = %x", skb->protocol); + + /* Hmmm... to accept HW Type 0x01 as well... + */ + if (skb->protocol == ntohs(ETH_P_ARP)) + skb->data[1] = 0x06; + netif_rx(skb); + fi->fc_stats.rx_packets++; + LEAVE("rx_net_packet"); +} + + +static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb) +{ +struct net_device *dev = fi->dev; +struct fch_hdr fch; + ENTER("rx_net_mfs_packet"); + /* Construct your Hard Header */ + memcpy(fch.daddr, skb->data + 2, FC_ALEN); + memcpy(fch.saddr, skb->data + 10, FC_ALEN); + skb_pull(skb, 2); + memcpy(skb->data, fch.daddr, FC_ALEN); + memcpy(skb->data + 6, fch.saddr, FC_ALEN); + skb->dev = dev; + skb->protocol = fc_type_trans(skb, dev); + DPRINTK("protocol = %x", skb->protocol); + netif_rx(skb); + LEAVE("rx_net_mfs_packet"); +} + +unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev) +{ +struct fch_hdr *fch=(struct fch_hdr *)skb->data; +struct fcllc *fcllc; + skb->mac.raw = skb->data; + fcllc = (struct fcllc *)(skb->data + sizeof(struct fch_hdr) + 2); + skb_pull(skb,sizeof(struct fch_hdr) + 2); + + if(*fch->daddr & 1) { + if(!memcmp(fch->daddr,dev->broadcast,FC_ALEN)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_MULTICAST; + } + else if(dev->flags & IFF_PROMISC) { + if(memcmp(fch->daddr, dev->dev_addr, FC_ALEN)) + skb->pkt_type=PACKET_OTHERHOST; + } + + /* Strip the SNAP header from ARP packets since we don't + * pass them through to the 802.2/SNAP layers. + */ + + if (fcllc->dsap == EXTENDED_SAP && + (fcllc->ethertype == ntohs(ETH_P_IP) || + fcllc->ethertype == ntohs(ETH_P_ARP))) { + skb_pull(skb, sizeof(struct fcllc)); + return fcllc->ethertype; + } + return ntohs(ETH_P_802_2); +} + +static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short tx_ox_id, u_int frame_class) +{ +u_char df_ctl; +int NW_flag = 0, h_size, return_value; +u_short rx_id = RX_ID_FIRST_SEQUENCE; +u_int tachyon_status; +u_int my_id = fi->g.my_id; + ENTER("tx_exchange"); + + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu); + if (tachyon_status & OSM_FROZEN) { + reset_tachyon(fi, ERROR_RELEASE); + reset_tachyon(fi, OCQ_RESET); + DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu); + } + if (tx_ox_id == OX_ID_FIRST_SEQUENCE) { + switch(fi->g.type_of_frame) { + case FC_SCSI_READ: + tx_ox_id = fi->g.scsi_oxid | SCSI_READ_BIT; + break; + case FC_SCSI_WRITE: + tx_ox_id = fi->g.scsi_oxid; + break; + default: + tx_ox_id = fi->g.ox_id; + break; + } + } + else { + switch(fi->g.type_of_frame) { + case FC_SCSI_READ: + rx_id = fi->g.scsi_oxid | SCSI_READ_BIT; + break; + case FC_SCSI_WRITE: + rx_id = fi->g.scsi_oxid; + break; + case FC_BLS: + rx_id = RX_ID_FIRST_SEQUENCE; + break; + default: + rx_id = fi->g.ox_id; + break; + } + } + + if (type == TYPE_LLC_SNAP) { + df_ctl = 0x20; + NW_flag = 1; + /* Multi Frame Sequence ? If yes, set RO bit */ + if (len > mtu) + type |= RELATIVE_OFF_PRESENT; + build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, data - 2*FC_ALEN); + } + else { + df_ctl = 0; + /* Multi Frame Sequence ? If yes, set RO bit */ + if (len > mtu) + type |= RELATIVE_OFF_PRESENT; + build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, NULL); + } + + /* Get free Tachyon Headers and EDBs */ + if (get_free_header(fi) || get_free_EDB(fi)) + return 0; + + if ((type & 0xFF000000) == TYPE_LLC_SNAP) { + h_size = TACHYON_HEADER_LEN + NW_HEADER_LEN; + memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), h_size); + } + else + memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN); + + return_value = tx_sequence(fi, data, len, mtu, d_id, tx_ox_id, rx_id, fi->g.seq_id, NW_flag, int_required, frame_class); + + switch(fi->g.type_of_frame) { + case FC_SCSI_READ: + case FC_SCSI_WRITE: + update_scsi_oxid(fi); + break; + case FC_BLS: + break; + default: + fi->g.ox_id++; + if (fi->g.ox_id == 0xFFFF) + fi->g.ox_id = NOT_SCSI_XID; + break; + } + + if (fi->g.seq_id == MAX_SEQ_ID) + fi->g.seq_id = 0; + else + fi->g.seq_id++; + LEAVE("tx_exchange"); + return return_value; +} + +static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int int_required, u_int frame_class) +{ +u_int cntl = 0; +int return_value; + ENTER("tx_sequence"); + build_EDB(fi, data, EDB_END, len); + memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB)); + build_ODB(fi, seq_id, d_id, len, cntl, mtu, ox_id, rx_id, NW_flag, int_required, frame_class); + memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB)); + if (fi->g.link_up != TRUE) { + DPRINTK2("Fibre Channel Link not up. Dropping Exchange!"); + return_value = FALSE; + } + else { + /* To be on the safe side, a check should be included + * at this point to check if we are overrunning + * Tachyon. + */ + update_OCQ_indx(fi); + return_value = TRUE; + } + update_EDB_indx(fi); + update_tachyon_header_indx(fi); + LEAVE("tx_sequence"); + return return_value; +} + +static int get_free_header(struct fc_info *fi) +{ +u_short temp_ox_id; +u_int *tach_header, initial_indx = fi->q.tachyon_header_indx; + /* Check if the header is in use. + * We could have an outstanding command. + * We should find a free slot as we can queue a + * maximum of 32 SCSI commands only. + */ + tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]; + temp_ox_id = ntohl(*(tach_header + 6)) >> 16; + /* We care about the SCSI writes only. Those are the wicked ones + * that need an additional set of buffers. + */ + while(temp_ox_id <= MAX_SCSI_XID) { + update_tachyon_header_indx(fi); + if (fi->q.tachyon_header_indx == initial_indx) { + /* Should never happen. + */ + T_MSG("No free Tachyon headers available"); + reset_tachyon(fi, SOFTWARE_RESET); + return 1; + } + tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]; + temp_ox_id = ntohl(*(tach_header + 6)) >> 16; + } + return 0; +} + +static int get_free_EDB(struct fc_info *fi) +{ +unsigned int initial_indx = fi->q.edb_buffer_indx; + /* Check if the EDB is in use. + * We could have an outstanding SCSI Write command. + * We should find a free slot as we can queue a + * maximum of 32 SCSI commands only. + */ + while (fi->q.free_edb_list[fi->q.edb_buffer_indx] != EDB_FREE) { + update_EDB_indx(fi); + if (fi->q.edb_buffer_indx == initial_indx) { + T_MSG("No free EDB buffers avaliable") + reset_tachyon(fi, SOFTWARE_RESET); + return 1; + } + } + return 0; +} + +static int validate_login(struct fc_info *fi, u_int *base_ptr) +{ +struct fc_node_info *q = fi->node_info_list; +char n_port_name[PORT_NAME_LEN]; +char node_name[NODE_NAME_LEN]; +u_int s_id; + ENTER("validate_login"); + /*index to Port Name in the payload. We need the 8 byte Port Name */ + memcpy(n_port_name, base_ptr + 10, PORT_NAME_LEN); + memcpy(node_name, base_ptr + 12, NODE_NAME_LEN); + s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF; + + /* check if Fibre Channel IDs have changed */ + while(q != NULL) { + if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) { + if ((s_id != q->d_id) || (memcmp(node_name, q->node_name, NODE_NAME_LEN) != 0)) { + DPRINTK1("Fibre Channel ID of Node has changed. Txing LOGO."); + return 0; + } + q->login = LOGIN_COMPLETED; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return 1; + } + q = q->next; + } + DPRINTK1("Port Name does not match. Txing LOGO."); + return 0; + LEAVE("validate_login"); +} + +static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr) +{ +int size = sizeof(struct fc_node_info); +struct fc_node_info *p, *q = fi->node_info_list, *r = NULL; +char n_port_name[PORT_NAME_LEN]; +u_int s_id; + ENTER("add_to_address_cache"); + /*index to Port Name in the payload. We need the 8 byte Port Name */ + memcpy(n_port_name, base_ptr + 13, PORT_NAME_LEN); + s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF; + + /* check if info already exists */ + while(q != NULL) { + if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) { + if (s_id != q->d_id) { + memcpy(&(q->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE)); + q->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF; + q->d_id = s_id; + memcpy(q->node_name, base_ptr + 15, NODE_NAME_LEN); + } + q->login = LOGIN_COMPLETED; + q->scsi = FALSE; + fi->num_nodes++; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return; + } + r = q; + q = q->next; + } + p = (struct fc_node_info *)kmalloc(size, GFP_ATOMIC); + if (p == NULL) { + T_MSG("kmalloc failed in add_to_address_cache()"); + return; + } + memcpy(&(p->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE)); + p->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF; + p->d_id = s_id; + memcpy(p->hw_addr, base_ptr + 13, PORT_NAME_LEN); + memcpy(p->node_name, base_ptr + 15, NODE_NAME_LEN); + p->login = LOGIN_COMPLETED; + p->scsi = FALSE; + p->target_id = 0xFF; + p->next = NULL; + if (fi->node_info_list == NULL) + fi->node_info_list = p; + else + r->next = p; + fi->num_nodes++; +#if DEBUG_5526_2 + display_cache(fi); +#endif + LEAVE("add_to_address_cache"); + return; +} + +static void remove_from_address_cache(struct fc_info *fi, u_int *base_ptr, u_int cmnd_code) +{ +struct fc_node_info *q = fi->node_info_list; +u_int s_id; + ENTER("remove_from_address_cache"); + s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF; + switch(cmnd_code) { + case ELS_LOGO: + /* check if info exists */ + while (q != NULL) { + if (s_id == q->d_id) { + if (q->login == LOGIN_COMPLETED) + q->login = LOGIN_ATTEMPTED; + if (fi->num_nodes > 0) + fi->num_nodes--; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return; + } + q = q->next; + } + DPRINTK1("ELS_LOGO received from node 0x%x which is not logged-in", s_id); + break; + case ELS_RSCN: + { + int payload_len = ntohl(*(base_ptr + 8)) & 0xFF; + int no_of_pages, i; + u_char address_format; + u_short received_ox_id = ntohl(*(base_ptr + 6)) >> 16; + u_int node_id, mask, *page_ptr = base_ptr + 9; + if ((payload_len < 4) || (payload_len > 256)) { + DPRINTK1("RSCN with invalid payload length received"); + tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, RECV_FIELD_SIZE); + return; + } + /* Page_size includes the Command Code */ + no_of_pages = (payload_len / 4) - 1; + for (i = 0; i < no_of_pages; i++) { + address_format = ntohl(*page_ptr) >> 24; + node_id = ntohl(*page_ptr) & 0x00FFFFFF; + switch(address_format) { + case PORT_ADDRESS_FORMAT: + rscn_handler(fi, node_id); + break; + case AREA_ADDRESS_FORMAT: + case DOMAIN_ADDRESS_FORMAT: + if (address_format == AREA_ADDRESS_FORMAT) + mask = 0xFFFF00; + else + mask = 0xFF0000; + while(q != NULL) { + if ((q->d_id & mask) == (node_id & mask)) + rscn_handler(fi, q->d_id); + q = q->next; + } + /* There might be some new nodes to be + * discovered. But, some of the earlier + * requests as a result of the RSCN might be + * in progress. We dont want to duplicate that + * effort. So letz call SCR after a lag. + */ + fi->explore_timer.function = scr_timer; + fi->explore_timer.data = (unsigned long)fi; + fi->explore_timer.expires = RUN_AT((no_of_pages*3*HZ)/100); + init_timer(&fi->explore_timer); + add_timer(&fi->explore_timer); + break; + default: + T_MSG("RSCN with invalid address format received"); + tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, NO_EXPLN); + } + page_ptr += 1; + } /* end of for loop */ + } /* end of case RSCN: */ + break; + } +#if DEBUG_5526_2 + display_cache(fi); +#endif + LEAVE("remove_from_address_cache"); +} + +static void rscn_handler(struct fc_info *fi, u_int node_id) +{ +struct fc_node_info *q = fi->node_info_list; +int login_state = sid_logged_in(fi, node_id); + if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) { + while(q != NULL) { + if (q->d_id == node_id) { + q->login = LOGIN_ATTEMPTED; + if (fi->num_nodes > 0) + fi->num_nodes--; + break; + } + else + q = q->next; + } + } + else + if (login_state == NODE_LOGGED_OUT) + tx_adisc(fi, ELS_ADISC, node_id, OX_ID_FIRST_SEQUENCE); + else + if (login_state == NODE_LOGGED_OUT) + tx_logi(fi, ELS_PLOGI, node_id); +} + +static void scr_timer(unsigned long data) +{ +struct fc_info *fi = (struct fc_info *)data; + del_timer(&fi->explore_timer); + tx_name_server_req(fi, FCS_GP_ID4); +} + +static int sid_logged_in(struct fc_info *fi, u_int s_id) +{ +struct fc_node_info *temp = fi->node_info_list; + while(temp != NULL) + if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) { + if (temp->scsi != FALSE) + return NODE_PROCESS_LOGGED_IN; + else + return NODE_LOGGED_IN; + } + else + if ((temp->d_id == s_id) && (temp->login != LOGIN_COMPLETED)) + return NODE_LOGGED_OUT; + else + temp = temp->next; + return NODE_NOT_PRESENT; +} + +static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action) +{ +struct fc_node_info *temp = fi->node_info_list; +u_int s_id; +u_int service_params; + s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + service_params = ntohl(*(buff_addr + 12)) & 0x000000F0; + while(temp != NULL) + if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) { + if (action == DELETE_ENTRY) { + temp->scsi = FALSE; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return; + } + /* Check if it is a SCSI Target */ + if (!(service_params & TARGET_FUNC)) { + temp->scsi = INITIATOR; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return; + } + temp->scsi = TARGET; + /* This helps to maintain the target_id no matter what your + * Fibre Channel ID is. + */ + if (temp->target_id == 0xFF) { + if (fi->g.no_of_targets <= MAX_SCSI_TARGETS) + temp->target_id = fi->g.no_of_targets++; + else + T_MSG("MAX TARGETS reached!"); + } + else + DPRINTK1("Target_id %d already present", temp->target_id); +#if DEBUG_5526_2 + display_cache(fi); +#endif + return; + } + else + temp = temp->next; + return; +} + +static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr) +{ +struct fc_node_info *temp; +u_char *data = (u_char *)buff_addr; +u_int s_id; +char node_name[NODE_NAME_LEN]; + s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF; + memcpy(node_name, buff_addr + 12, NODE_NAME_LEN); + /* point to port_name in the ADISC payload */ + data += 10 * 4; + /* point to last 6 bytes of port_name */ + data += 2; + temp = look_up_cache(fi, data); + if (temp != NULL) { + if ((temp->d_id == s_id) && (memcmp(node_name, temp->node_name, NODE_NAME_LEN) == 0)) { + temp->login = LOGIN_COMPLETED; +#if DEBUG_5526_2 + display_cache(fi); +#endif + return TRUE; + } + } + return FALSE; +} + +static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data) +{ +struct fc_node_info *temp_list = fi->node_info_list, *q; +u_char n_port_name[FC_ALEN], temp_addr[FC_ALEN]; + ENTER("look_up_cache"); + memcpy(n_port_name, data, FC_ALEN); + while(temp_list) { + if (memcmp(n_port_name, &(temp_list->hw_addr[2]), FC_ALEN) == 0) + return temp_list; + else + temp_list = temp_list->next; + } + + /* Broadcast IP ? + */ + temp_addr[0] = temp_addr[1] = temp_addr[2] = 0xFF; + temp_addr[3] = temp_addr[4] = temp_addr[5] = 0xFF; + if (memcmp(n_port_name, temp_addr, FC_ALEN) == 0) { + q = (struct fc_node_info *)kmalloc(sizeof(struct fc_node_info), GFP_ATOMIC); + if (q == NULL) { + T_MSG("kmalloc failed in look_up_cache()"); + return NULL; + } + q->d_id = BROADCAST; + return q; + } + LEAVE("look_up_cache"); + return NULL; +} + +static int display_cache(struct fc_info *fi) +{ +struct fc_node_info *q = fi->node_info_list; +#if DEBUG_5526_2 +struct ox_id_els_map *temp_ox_id_list = fi->ox_id_list; +#endif +int count = 0, j; + printk("\nFibre Channel Node Information for %s\n", fi->name); + printk("My FC_ID = %x, My WWN = %x %x, ", fi->g.my_id, fi->g.my_node_name_high, fi->g.my_node_name_low); + if (fi->g.ptp_up == TRUE) + printk("Port_Type = N_Port\n"); + if (fi->g.loop_up == TRUE) + printk("Port_Type = L_Port\n"); + while(q != NULL) { + printk("WWN = "); + for (j = 0; j < PORT_NAME_LEN; j++) + printk("%x ", q->hw_addr[j]); + printk("FC_ID = %x, ", q->d_id); + printk("Login = "); + if (q->login == LOGIN_COMPLETED) + printk("ON "); + else + printk("OFF "); + if (q->scsi == TARGET) + printk("Target_ID = %d ", q->target_id); + printk("\n"); + q = q->next; + count++; + } + +#if DEBUG_5526_2 + printk("OX_ID -> ELS Map\n"); + while(temp_ox_id_list) { + printk("ox_id = %x, ELS = %x\n", temp_ox_id_list->ox_id, temp_ox_id_list->els); + temp_ox_id_list = temp_ox_id_list->next; + } +#endif + + return 0; +} + +static struct net_device_stats * iph5526_get_stats(struct net_device *dev) +{ +struct fc_info *fi = (struct fc_info*)dev->priv; + return (struct net_device_stats *) &fi->fc_stats; +} + + +/* SCSI stuff starts here */ + +static struct proc_dir_entry proc_scsi_iph5526 = { + PROC_SCSI_IPH5526_FC, 7, "iph5526", S_IFDIR, S_IRUGO | S_IXUGO, 2 +}; + + +int iph5526_detect(Scsi_Host_Template *tmpt) +{ +struct Scsi_Host *host = NULL; +struct iph5526_hostdata *hostdata; +struct fc_info *fi = NULL; +int no_of_hosts = 0, timeout, i, j, count = 0; +u_int pci_maddr = 0; +struct pci_dev *pdev = NULL; + + tmpt->proc_dir = &proc_scsi_iph5526; + if (pci_present() == 0) { + printk("iph5526: PCI not present\n"); + return 0; + } + + for (i = 0; i <= MAX_FC_CARDS; i++) + fc[i] = NULL; + + for (i = 0; i < clone_list[i].vendor_id != 0; i++) + while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) { + unsigned short pci_command; + if (count < MAX_FC_CARDS) { + fc[count] = kmalloc(sizeof(struct fc_info), GFP_ATOMIC); + if (fc[count] == NULL) { + printk("iph5526.c: Unable to register card # %d\n", count + 1); + return no_of_hosts; + } + memset(fc[count], 0, sizeof(struct fc_info)); + } + else { + printk("iph5526.c: Maximum Number of cards reached.\n"); + return no_of_hosts; + } + + fi = fc[count]; + sprintf(fi->name, "fc%d", count); + + host = scsi_register(tmpt, sizeof(struct iph5526_hostdata)); + hostdata = (struct iph5526_hostdata *)host->hostdata; + memset(hostdata, 0 , sizeof(struct iph5526_hostdata)); + for (j = 0; j < MAX_SCSI_TARGETS; j++) + hostdata->tag_ages[j] = jiffies; + hostdata->fi = fi; + fi->host = host; + //host->max_id = MAX_SCSI_TARGETS; + host->max_id = 5; + host->hostt->use_new_eh_code = 1; + host->this_id = tmpt->this_id; + + pci_maddr = pdev->resource[0].start; + if ( (pdev->resource[0].flags & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { + printk("iph5526.c : Cannot find proper PCI device base address.\n"); + scsi_unregister(host); + kfree(fc[count]); + fc[count] = NULL; + continue; + } + + DPRINTK("pci_maddr = %x", pci_maddr); + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); + + pci_irq_line = pdev->irq; + printk("iph5526.c: PCI BIOS reports %s at i/o %#x, irq %d.\n", clone_list[i].name, pci_maddr, pci_irq_line); + fi->g.mem_base = ioremap(pci_maddr & PAGE_MASK, 1024); + + /* We use Memory Mapped IO. The initial space contains the + * PCI Configuration registers followed by the (i) chip + * registers followed by the Tachyon registers. + */ + /* Thatz where (i)chip maps Tachyon Address Space. + */ + fi->g.tachyon_base = (u_long)fi->g.mem_base + TACHYON_OFFSET + ( pci_maddr & ~PAGE_MASK ); + DPRINTK("fi->g.tachyon_base = %x", (u_int)fi->g.tachyon_base); + if (fi->g.mem_base == NULL) { + printk("iph5526.c : ioremap failed!!!\n"); + scsi_unregister(host); + kfree(fc[count]); + fc[count] = NULL; + continue; + } + DPRINTK("IRQ1 = %d\n", pci_irq_line); + printk(version); + fi->base_addr = (long) pdev; + + if (pci_irq_line) { + int irqval = 0; + /* Found it, get IRQ. + */ + irqval = request_irq(pci_irq_line, &tachyon_interrupt, pci_irq_line ? SA_SHIRQ : 0, fi->name, host); + if (irqval) { + printk("iph5526.c : Unable to get IRQ %d (irqval = %d).\n", pci_irq_line, irqval); + scsi_unregister(host); + kfree(fc[count]); + fc[count] = NULL; + continue; + } + host->irq = fi->irq = pci_irq_line; + pci_irq_line = 0; + fi->clone_id = clone_list[i].vendor_id; + } + + if (!initialize_register_pointers(fi) || !tachyon_init(fi)) { + printk("iph5526.c: TACHYON initialization failed for card # %d!!!\n", count + 1); + free_irq(host->irq, host); + scsi_unregister(host); + if (fi) + clean_up_memory(fi); + kfree(fc[count]); + fc[count] = NULL; + break; + } + DPRINTK1("Fibre Channel card initialized"); + /* Wait for the Link to come up and the login process + * to complete. + */ + for(timeout = jiffies + 10*HZ; (timeout > jiffies) && ((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || (fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));) + barrier(); + + count++; + no_of_hosts++; + } + DPRINTK1("no_of_hosts = %d",no_of_hosts); + + /* This is to make sure that the ACC to the PRLI comes in + * for the last ALPA. + */ + udelay(1000000); /* Ugly! Let the Gods forgive me */ + + DPRINTK1("leaving iph5526_detect\n"); + return no_of_hosts; +} + + +int iph5526_biosparam(Disk * disk, kdev_t n, int ip[]) +{ +int size = disk->capacity; + ip[0] = 64; + ip[1] = 32; + ip[2] = size >> 11; + if (ip[2] > 1024) { + ip[0] = 255; + ip[1] = 63; + ip[2] = size / (ip[0] * ip[1]); + } + return 0; +} + +int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *)) +{ +int int_required = 0; +u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND; +u_int type = TYPE_FCP | SEQUENCE_INITIATIVE; +u_int frame_class = Cmnd->target; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +struct Scsi_Host *host = Cmnd->host; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata; +struct fc_info *fi = hostdata->fi; +struct fc_node_info *q; +u_long flags; + ENTER("iph5526_queuecommand"); + + spin_lock_irqsave(&fi->fc_lock, flags); + Cmnd->scsi_done = done; + + if (Cmnd->device->tagged_supported) { + switch(Cmnd->tag) { + case SIMPLE_QUEUE_TAG: + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; + break; + case HEAD_OF_QUEUE_TAG: + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_HEAD_OF_Q; + break; + case ORDERED_QUEUE_TAG: + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED; + break; + default: + if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) { + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED; + hostdata->tag_ages[Cmnd->target] = jiffies; + } + else + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; + break; + } + } + /*else + hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED; + */ + + hostdata->cmnd.fcp_addr[3] = 0; + hostdata->cmnd.fcp_addr[2] = 0; + hostdata->cmnd.fcp_addr[1] = 0; + hostdata->cmnd.fcp_addr[0] = htons(Cmnd->lun); + + memcpy(&hostdata->cmnd.fcp_cdb, Cmnd->cmnd, Cmnd->cmd_len); + hostdata->cmnd.fcp_data_len = htonl(Cmnd->request_bufflen); + + /* Get an used OX_ID. We could have pending commands. + */ + if (get_scsi_oxid(fi)) + return 1; + fi->q.free_scsi_oxid[fi->g.scsi_oxid] = OXID_INUSE; + + /* Maintain a handler so that we can associate the done() function + * on completion of the SCSI command. + */ + hostdata->cmnd_handler[fi->g.scsi_oxid] = Cmnd; + + switch(Cmnd->cmnd[0]) { + case WRITE_6: + case WRITE_10: + case WRITE_12: + fi->g.type_of_frame = FC_SCSI_WRITE; + hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_WRITE | hostdata->cmnd.fcp_cntl); + break; + default: + fi->g.type_of_frame = FC_SCSI_READ; + hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_READ | hostdata->cmnd.fcp_cntl); + } + + memcpy(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx], &(hostdata->cmnd), sizeof(fcp_cmd)); + + q = resolve_target(fi, Cmnd->target); + + if (q == NULL) { + u_int bad_id = fi->g.my_ddaa | 0xFE; + /* We transmit to an non-existant AL_PA so that the "done" + * function can be called while receiving the interrupt + * due to a Timeout for a bad AL_PA. In a PTP configuration, + * the int_required field is set, since there is no notion + * of AL_PAs. This approach sucks, but works alright! + */ + if (fi->g.ptp_up == TRUE) + int_required = 1; + tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET); + spin_unlock_irqrestore(&fi->fc_lock, flags); + DPRINTK1("Target ID %x not present", Cmnd->target); + return 0; + } + if (q->login == LOGIN_COMPLETED) { + if (add_to_sest(fi, Cmnd, q)) { + DPRINTK1("add_to_sest() failed."); + spin_unlock_irqrestore(&fi->fc_lock, flags); + return 0; + } + tx_exchange(fi, (char *)(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx]), sizeof(fcp_cmd), r_ctl, type, q->d_id, q->mtu, int_required, ox_id, frame_class << 16); + update_FCP_CMND_indx(fi); + } + spin_unlock_irqrestore(&fi->fc_lock, flags); + /* If q != NULL, then we have a SCSI Target. + * If q->login != LOGIN_COMPLETED, then that device could be + * offline temporarily. So we let the command to time-out. + */ + LEAVE("iph5526_queuecommand"); + return 0; +} + +int iph5526_abort(Scsi_Cmnd *Cmnd) +{ +struct Scsi_Host *host = Cmnd->host; +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata; +struct fc_info *fi = hostdata->fi; +struct fc_node_info *q; +u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND; +u_int type = TYPE_FCP | SEQUENCE_INITIATIVE; +u_short ox_id = OX_ID_FIRST_SEQUENCE; +int int_required = 1, i, abort_status = FALSE; +u_long flags; + + ENTER("iph5526_abort"); + + spin_lock_irqsave(&fi->fc_lock, flags); + + q = resolve_target(fi, Cmnd->target); + if (q == NULL) { + u_int bad_id = fi->g.my_ddaa | 0xFE; + /* This should not happen as we should always be able to + * resolve a target id. But, jus in case... + * We transmit to an non-existant AL_PA so that the done + * function can be called while receiving the interrupt + * for a bad AL_PA. + */ + DPRINTK1("Unresolved Target ID!"); + tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET); + DPRINTK1("Target ID %x not present", Cmnd->target); + spin_unlock_irqrestore(&fi->fc_lock, flags); + return FAILED; + } + + /* If q != NULL, then we have a SCSI Target. If + * q->login != LOGIN_COMPLETED, then that device could + * be offline temporarily. So we let the command to time-out. + */ + + /* Get the OX_ID for the Command to be aborted. + */ + for (i = 0; i <= MAX_SCSI_XID; i++) { + if (hostdata->cmnd_handler[i] == Cmnd) { + hostdata->cmnd_handler[i] = NULL; + ox_id = i; + break; + } + } + if (i > MAX_SCSI_XID) { + T_MSG("Command could not be resolved to OX_ID"); + spin_unlock_irqrestore(&fi->fc_lock, flags); + return FAILED; + } + + switch(Cmnd->cmnd[0]) { + case WRITE_6: + case WRITE_10: + case WRITE_12: + break; + default: + ox_id |= SCSI_READ_BIT; + } + abort_status = abort_exchange(fi, ox_id); + + if ((q->login == LOGIN_COMPLETED) && (abort_status == TRUE)) { + /* Then, transmit an ABTS to the target. The rest + * is done when the BA_ACC is received for the ABTS. + */ + tx_abts(fi, q->d_id, ox_id); + } + else { + u_int STE_bit; + u_short x_id; + /* Invalidate resources for that Exchange. + */ + x_id = ox_id & MAX_SCSI_XID; + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + if (STE_bit & SEST_V) { + *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV); + invalidate_SEST_entry(fi, ox_id); + } + } + + LEAVE("iph5526_abort"); + spin_unlock_irqrestore(&fi->fc_lock, flags); + return SUCCESS; +} + +static int abort_exchange(struct fc_info *fi, u_short ox_id) +{ +u_short x_id; +volatile u_int flush_SEST, STE_bit; + x_id = ox_id & MAX_SCSI_XID; + DPRINTK1("Aborting Exchange %x", ox_id); + + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + /* Is the Exchange still active?. + */ + if (STE_bit & SEST_V) { + if (ox_id & SCSI_READ_BIT) { + /* If the Exchange to be aborted is Inbound, + * Flush the SEST Entry from Tachyon's Cache. + */ + *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV); + flush_tachyon_cache(fi, ox_id); + flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg); + while ((flush_SEST & 0x80000000) != 0) + flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg); + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + while ((STE_bit & 0x80000000) != 0) + STE_bit = ntohl(*fi->q.ptr_sest[x_id]); + flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg); + invalidate_SEST_entry(fi, ox_id); + } + else { + int i; + u_int *ptr_edb; + /* For In-Order Reassembly, the following is done: + * First, write zero as the buffer length in the EDB. + */ + ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7))); + for (i = 0; i < EDB_LEN; i++) + if (fi->q.ptr_edb[i] == ptr_edb) + break; + if (i < EDB_LEN) + *ptr_edb = *ptr_edb & 0x0000FFFF; + else + T_MSG("EDB not found while clearing in abort_exchange()"); + } + DPRINTK1("Exchange %x invalidated", ox_id); + return TRUE; + } + else { + DPRINTK1("SEST Entry for exchange %x not valid", ox_id); + return FALSE; + } +} + +static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id) +{ +volatile u_int tachyon_status; + if (fi->g.loop_up == TRUE) { + writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg); + /* Make sure that the Inbound FIFO is empty. + */ + do { + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + udelay(200); + }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0); + /* Ok. Go ahead and flushhhhhhhhh! + */ + writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg); + writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg); + return; + } + if (fi->g.ptp_up == TRUE) { + take_tachyon_offline(fi); + /* Make sure that the Inbound FIFO is empty. + */ + do { + tachyon_status = readl(fi->t_r.ptr_tach_status_reg); + udelay(200); + }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0); + writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg); + /* Write the Initialize command to the FM Control reg. + */ + fi->g.n_port_try = TRUE; + DPRINTK1("In abort_exchange, TACHYON initializing as N_Port...\n"); + writel(INITIALIZE, fi->t_r.ptr_fm_control_reg); + } +} + +static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target) +{ +struct fc_node_info *temp = fi->node_info_list; + while(temp != NULL) + if (temp->target_id == target) { + if ((temp->scsi == TARGET) && (temp->login == LOGIN_COMPLETED)) + return temp; + else { + if (temp->login != LOGIN_COMPLETED) { + /* The Target is not currently logged in. + * It could be a Target on the Local Loop or + * on a Remote Loop connected through a switch. + * In either case, we will know whenever the Target + * comes On-Line again. We let the command to + * time-out so that it gets retried. + */ + T_MSG("Target %d not logged in.", temp->target_id); + tx_logi(fi, ELS_PLOGI, temp->d_id); + return temp; + } + else { + if (temp->scsi != TARGET) { + /* For some reason, we did not get a response to + * PRLI. Letz try it again... + */ + DPRINTK1("Node not PRLIied. Txing PRLI..."); + tx_prli(fi, ELS_PRLI, temp->d_id, OX_ID_FIRST_SEQUENCE); + } + } + return temp; + } + } + else + temp = temp->next; + return NULL; +} + +static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni) +{ +/* we have at least 1 buffer, the terminator */ +int no_of_sdb_buffers = 1, i; +int no_of_edb_buffers = 0; +u_int *req_buffer = (u_int *)Cmnd->request_buffer; +u_int *ptr_sdb = NULL; +struct scatterlist *sl1, *sl2 = NULL; +int no_of_sg = 0; + + switch(fi->g.type_of_frame) { + case FC_SCSI_READ: + fi->g.inb_sest_entry.flags_and_byte_offset = htonl(INB_SEST_VED); + fi->g.inb_sest_entry.byte_count = 0; + fi->g.inb_sest_entry.no_of_recvd_frames = 0; + fi->g.inb_sest_entry.no_of_expected_frames = 0; + fi->g.inb_sest_entry.last_fctl = 0; + + if (Cmnd->use_sg) { + no_of_sg = Cmnd->use_sg; + sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer; + for (i = 0; i < no_of_sg; i++) { + no_of_sdb_buffers += sl1->length / SEST_BUFFER_SIZE; + if (sl1->length % SEST_BUFFER_SIZE) + no_of_sdb_buffers++; + sl1++; + } + } + else { + no_of_sdb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE; + if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) + no_of_sdb_buffers++; + } /* if !use_sg */ + + /* We are working with the premise that at the max we would + * get a scatter-gather buffer containing 63 buffers + * of size 1024 bytes each. Is it a _bad_ assumption? + */ + if (no_of_sdb_buffers > 512) { + T_MSG("Number of SDB buffers needed = %d", no_of_sdb_buffers); + T_MSG("Disable Scatter-Gather!!!"); + return 1; + } + + + /* Store it in the sdb_table so that we can retrieve that + * free up the memory when the Read Command completes. + */ + if (get_free_SDB(fi)) + return 1; + ptr_sdb = fi->q.ptr_sdb_slot[fi->q.sdb_indx]; + fi->q.sdb_slot_status[fi->q.sdb_indx] = SDB_BUSY; + fi->g.inb_sest_entry.sdb_address = htonl(virt_to_bus(ptr_sdb)); + + if (Cmnd->use_sg) { + int count = 0, j; + for(i = 0; i < no_of_sg; i++) { + char *addr_ptr = sl2->address; + count = sl2->length / SEST_BUFFER_SIZE; + if (sl2->length % SEST_BUFFER_SIZE) + count++; + for (j = 0; j < count; j++) { + *(ptr_sdb) = htonl(virt_to_bus(addr_ptr)); + addr_ptr += SEST_BUFFER_SIZE; + ptr_sdb++; + } + count = 0; + sl2++; + } + } + else { + for (i = 0; i < no_of_sdb_buffers - 1; i++) { + *(ptr_sdb) = htonl(virt_to_bus(req_buffer)); + req_buffer += SEST_BUFFER_SIZE/4; + ptr_sdb++; + } + } + *(ptr_sdb) = htonl(0x1); /* Terminator */ + + /* The scratch pad is used to hold the index into the SDB. + */ + fi->g.inb_sest_entry.scratch_pad = fi->q.sdb_indx; + fi->g.inb_sest_entry.expected_ro = 0; + fi->g.inb_sest_entry.buffer_index = 0; + fi->g.inb_sest_entry.buffer_offset = 0; + memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.inb_sest_entry, sizeof(INB_SEST_ENTRY)); + break; + case FC_SCSI_WRITE: + fi->g.outb_sest_entry.flags_and_did = htonl(OUTB_SEST_VED | ni->d_id); + fi->g.outb_sest_entry.max_frame_len = htons(ni->mtu << 4); + fi->g.outb_sest_entry.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP); + fi->g.outb_sest_entry.total_seq_length = INV_SEQ_LEN; + fi->g.outb_sest_entry.link = htons(OUTB_SEST_LINK); + fi->g.outb_sest_entry.transaction_id = htonl(fi->g.scsi_oxid); + fi->g.outb_sest_entry.seq_id = fi->g.seq_id; + fi->g.outb_sest_entry.reserved = 0x0; + fi->g.outb_sest_entry.header_length = htons(TACHYON_HEADER_LEN); + + { + u_char df_ctl = 0; + u_short rx_id = RX_ID_FIRST_SEQUENCE; + u_int r_ctl = FC4_DEVICE_DATA | SOLICITED_DATA; + u_int type = TYPE_FCP | SEQUENCE_INITIATIVE; + /* Multi Frame Sequence ? If yes, set RO bit. + */ + if (Cmnd->request_bufflen > ni->mtu) + type |= RELATIVE_OFF_PRESENT; + build_tachyon_header(fi, fi->g.my_id, r_ctl, ni->d_id, type, fi->g.seq_id, df_ctl, fi->g.scsi_oxid, rx_id, NULL); + if (get_free_header(fi) || get_free_EDB(fi)) + return 1; + memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN); + fi->g.outb_sest_entry.header_address = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx])); + update_tachyon_header_indx(fi); + } + + if (Cmnd->use_sg) { + no_of_sg = Cmnd->use_sg; + sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer; + for (i = 0; i < no_of_sg; i++) { + no_of_edb_buffers += sl1->length / SEST_BUFFER_SIZE; + if (sl1->length % SEST_BUFFER_SIZE) + no_of_edb_buffers++; + sl1++; + } + } + else { + no_of_edb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE; + if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) + no_of_edb_buffers++; + } /* if !use_sg */ + + + /* We need "no_of_edb_buffers" _contiguous_ EDBs + * that are FREE. Check for that first. + */ + for (i = 0; i < no_of_edb_buffers; i++) { + int j; + if ((fi->q.edb_buffer_indx + no_of_edb_buffers) >= EDB_LEN) + fi->q.edb_buffer_indx = 0; + if (fi->q.free_edb_list[fi->q.edb_buffer_indx + i] != EDB_FREE) { + for (j = 0; j < i; j++) + update_EDB_indx(fi); + if (get_free_EDB(fi)) + return 1; + i = 0; + } + } + + /* We got enuff FREE EDBs. + */ + if (Cmnd->use_sg) { + fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx])); + sl1 = (struct scatterlist *)Cmnd->request_buffer; + for(i = 0; i < no_of_sg; i++) { + int count = 0, j; + count = sl1->length / SEST_BUFFER_SIZE; + for (j = 0; j < count; j++) { + build_EDB(fi, (char *)sl1->address, 0, SEST_BUFFER_SIZE); + memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB)); + /* Mark this EDB as being in use */ + fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY; + /* We have already made sure that we have enuff + * free EDBs that are contiguous. So this is + * safe. + */ + update_EDB_indx(fi); + sl1->address += SEST_BUFFER_SIZE; + } + /* Just in case itz not a multiple of + * SEST_BUFFER_SIZE bytes. + */ + if (sl1->length % SEST_BUFFER_SIZE) { + build_EDB(fi, (char *)sl1->address, 0, sl1->length % SEST_BUFFER_SIZE); + memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB)); + fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY; + update_EDB_indx(fi); + } + sl1++; + } + /* The last EDB is special. It needs the "end bit" to + * be set. + */ + *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | ntohs(EDB_END); + } + else { + int count = 0, j; + fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx])); + count = Cmnd->request_bufflen / SEST_BUFFER_SIZE; + for (j = 0; j < count; j++) { + build_EDB(fi, (char *)req_buffer, 0, SEST_BUFFER_SIZE); + memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB)); + /* Mark this EDB as being in use */ + fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY; + /* We have already made sure that we have enuff + * free EDBs that are contiguous. So this is + * safe. + */ + update_EDB_indx(fi); + req_buffer += SEST_BUFFER_SIZE; + } + /* Just in case itz not a multiple of + * SEST_BUFFER_SIZE bytes. + */ + if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) { + build_EDB(fi, (char *)req_buffer, EDB_END, Cmnd->request_bufflen % SEST_BUFFER_SIZE); + memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB)); + fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY; + update_EDB_indx(fi); + } + else { + /* Mark the last EDB as the "end edb". + */ + *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | htons(EDB_END); + } + } + + /* Finally we have something to send!. + */ + memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.outb_sest_entry, sizeof(OUTB_SEST_ENTRY)); + break; + } + return 0; +} + +static void update_FCP_CMND_indx(struct fc_info *fi) +{ + fi->q.fcp_cmnd_indx++; + if (fi->q.fcp_cmnd_indx == NO_OF_FCP_CMNDS) + fi->q.fcp_cmnd_indx = 0; +} + +static int get_scsi_oxid(struct fc_info *fi) +{ +u_short initial_oxid = fi->g.scsi_oxid; + /* Check if the OX_ID is in use. + * We could have an outstanding SCSI command. + */ + while (fi->q.free_scsi_oxid[fi->g.scsi_oxid] != OXID_AVAILABLE) { + update_scsi_oxid(fi); + if (fi->g.scsi_oxid == initial_oxid) { + T_MSG("No free OX_IDs avaliable") + reset_tachyon(fi, SOFTWARE_RESET); + return 1; + } + } + return 0; +} + +static void update_scsi_oxid(struct fc_info *fi) +{ + fi->g.scsi_oxid++; + if (fi->g.scsi_oxid == (MAX_SCSI_XID + 1)) + fi->g.scsi_oxid = 0; +} + +static int get_free_SDB(struct fc_info *fi) +{ +unsigned int initial_indx = fi->q.sdb_indx; + /* Check if the SDB is in use. + * We could have an outstanding SCSI Read command. + * We should find a free slot as we can queue a + * maximum of 32 SCSI commands only. + */ + while (fi->q.sdb_slot_status[fi->q.sdb_indx] != SDB_FREE) { + update_SDB_indx(fi); + if (fi->q.sdb_indx == initial_indx) { + T_MSG("No free SDB buffers avaliable") + reset_tachyon(fi, SOFTWARE_RESET); + return 1; + } + } + return 0; +} + +static void update_SDB_indx(struct fc_info *fi) +{ + fi->q.sdb_indx++; + if (fi->q.sdb_indx == NO_OF_SDB_ENTRIES) + fi->q.sdb_indx = 0; +} + +int iph5526_release(struct Scsi_Host *host) +{ +struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata; +struct fc_info *fi = hostdata->fi; + free_irq(host->irq, host); + iounmap(fi->g.mem_base); + return 0; +} + +const char *iph5526_info(struct Scsi_Host *host) +{ +static char buf[80]; + sprintf(buf, "Interphase 5526 Fibre Channel PCI SCSI Adapter using IRQ %d\n", host->irq); + return buf; +} + +#ifdef MODULE + +#define NAMELEN 8 /* # of chars for storing dev->name */ + +static struct net_device *dev_fc[MAX_FC_CARDS]; + +static int io = 0; +static int irq = 0; +static int bad = 0; /* 0xbad = bad sig or no reset ack */ +static int scsi_registered; + + +int init_module(void) +{ +int i = 0; + + driver_template.module = &__this_module; + scsi_register_module(MODULE_SCSI_HA, &driver_template); + if (driver_template.present) + scsi_registered = TRUE; + else { + printk("iph5526: SCSI registeration failed!!!\n"); + scsi_registered = FALSE; + scsi_unregister_module(MODULE_SCSI_HA, &driver_template); + } + + while(fc[i] != NULL) { + dev_fc[i] = NULL; + dev_fc[i] = init_fcdev(dev_fc[i], 0); + if (dev_fc[i] == NULL) { + printk("iph5526.c: init_fcdev failed for card #%d\n", i+1); + break; + } + dev_fc[i]->irq = irq; + dev_fc[i]->mem_end = bad; + dev_fc[i]->base_addr = io; + dev_fc[i]->init = iph5526_probe; + dev_fc[i]->priv = fc[i]; + fc[i]->dev = dev_fc[i]; + if (register_fcdev(dev_fc[i]) != 0) { + kfree_s(dev_fc[i], sizeof(struct net_device)); + dev_fc[i] = NULL; + if (i == 0) { + printk("iph5526.c: IP registeration failed!!!\n"); + return -ENODEV; + } + } + i++; + } + if (i == 0) + return -ENODEV; + + return 0; +} + +void cleanup_module(void) +{ +int i = 0; + while(fc[i] != NULL) { + struct net_device *dev = fc[i]->dev; + void *priv = dev->priv; + fc[i]->g.dont_init = TRUE; + take_tachyon_offline(fc[i]); + unregister_fcdev(dev); + clean_up_memory(fc[i]); + if (dev->priv) + kfree(priv); + kfree(dev); + dev = NULL; + i++; + } + if (scsi_registered == TRUE) + scsi_unregister_module(MODULE_SCSI_HA, &driver_template); +} +#endif /* MODULE */ + +void clean_up_memory(struct fc_info *fi) +{ +int i,j; + ENTER("clean_up_memory"); + if (fi->q.ptr_mfsbq_base) + free_pages((u_long)bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base))), 5); + DPRINTK("after kfree2"); + for (i = 0; i < SFSBQ_LENGTH; i++) + for (j = 0; j < NO_OF_ENTRIES; j++) + if (fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j]) + kfree(fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j]); + DPRINTK("after kfree1"); + if (fi->q.ptr_ocq_base) + free_page((u_long)fi->q.ptr_ocq_base); + if (fi->q.ptr_imq_base) + free_page((u_long)fi->q.ptr_imq_base); + if (fi->q.ptr_mfsbq_base) + free_page((u_long)fi->q.ptr_mfsbq_base); + if (fi->q.ptr_sfsbq_base) + free_page((u_long)fi->q.ptr_sfsbq_base); + if (fi->q.ptr_edb_base) + free_pages((u_long)fi->q.ptr_edb_base, 5); + if (fi->q.ptr_sest_base) + free_pages((u_long)fi->q.ptr_sest_base, 5); + if (fi->q.ptr_tachyon_header_base) + free_page((u_long)fi->q.ptr_tachyon_header_base); + if (fi->q.ptr_sdb_base) + free_pages((u_long)fi->q.ptr_sdb_base, 5); + if (fi->q.ptr_fcp_cmnd_base) + free_page((u_long)fi->q.ptr_fcp_cmnd_base); + DPRINTK("after free_pages"); + if (fi->q.ptr_host_ocq_cons_indx) + kfree(fi->q.ptr_host_ocq_cons_indx); + if (fi->q.ptr_host_hpcq_cons_indx) + kfree(fi->q.ptr_host_hpcq_cons_indx); + if (fi->q.ptr_host_imq_prod_indx) + kfree(fi->q.ptr_host_imq_prod_indx); + DPRINTK("after kfree3"); + while (fi->node_info_list) { + struct fc_node_info *temp_list = fi->node_info_list; + fi->node_info_list = fi->node_info_list->next; + kfree(temp_list); + } + while (fi->ox_id_list) { + struct ox_id_els_map *temp = fi->ox_id_list; + fi->ox_id_list = fi->ox_id_list->next; + kfree(temp); + } + LEAVE("clean_up_memory"); +} + +static int initialize_register_pointers(struct fc_info *fi) +{ +ENTER("initialize_register_pointers"); +if(fi->g.tachyon_base == 0) + return -ENOMEM; + +fi->i_r.ptr_ichip_hw_control_reg = ICHIP_HW_CONTROL_REG_OFF + fi->g.tachyon_base; +fi->i_r.ptr_ichip_hw_status_reg = ICHIP_HW_STATUS_REG_OFF + fi->g.tachyon_base; +fi->i_r.ptr_ichip_hw_addr_mask_reg = ICHIP_HW_ADDR_MASK_REG_OFF + fi->g.tachyon_base; +fi->t_r.ptr_ocq_base_reg = OCQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_ocq_len_reg = OCQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_ocq_prod_indx_reg = OCQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_ocq_cons_indx_reg = OCQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_imq_base_reg = IMQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_imq_len_reg = IMQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_imq_cons_indx_reg = IMQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_imq_prod_indx_reg = IMQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_mfsbq_base_reg = MFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_mfsbq_len_reg = MFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_mfsbq_prod_reg = MFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_mfsbq_cons_reg = MFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_mfsbuff_len_reg = MFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sfsbq_base_reg = SFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sfsbq_len_reg = SFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sfsbq_prod_reg = SFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sfsbq_cons_reg = SFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sfsbuff_len_reg = SFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sest_base_reg = SEST_BASE_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_sest_len_reg = SEST_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_scsibuff_len_reg = SCSI_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_tach_config_reg = TACHYON_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_tach_control_reg = TACHYON_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_tach_status_reg = TACHYON_STATUS_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_tach_flush_oxid_reg = TACHYON_FLUSH_SEST_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_config_reg = FMGR_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_control_reg = FMGR_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_status_reg = FMGR_STATUS_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_tov_reg = FMGR_TIMER_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_wwn_hi_reg = FMGR_WWN_HI_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_wwn_low_reg = FMGR_WWN_LO_REGISTER_OFFSET + fi->g.tachyon_base; +fi->t_r.ptr_fm_rx_al_pa_reg = FMGR_RCVD_ALPA_REGISTER_OFFSET + fi->g.tachyon_base; + +LEAVE("initialize_register_pointers"); +return 1; +} + + + +/* + * Local variables: + * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c iph5526.c" + * version-control: t + * kept-new-versions: 5 + * End: + */ diff --git a/drivers/net/fc/iph5526_ip.h b/drivers/net/fc/iph5526_ip.h new file mode 100644 index 000000000..b54f727e1 --- /dev/null +++ b/drivers/net/fc/iph5526_ip.h @@ -0,0 +1,25 @@ +#ifndef IPH5526_IP_H +#define IPH5526_IP_H + +#define LLC_SNAP_LEN 0x8 + +/* Offsets into the ARP frame */ +#define ARP_OPCODE_0 (0x6 + LLC_SNAP_LEN) +#define ARP_OPCODE_1 (0x7 + LLC_SNAP_LEN) + +int iph5526_probe(struct net_device *dev); +static int fcdev_init(struct net_device *dev); +static int iph5526_open(struct net_device *dev); +static int iph5526_close(struct net_device *dev); +static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats * iph5526_get_stats(struct net_device *dev); +static int iph5526_change_mtu(struct net_device *dev, int mtu); + + +static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size); +static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb); +unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev); +static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi); +static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi); +#endif + diff --git a/drivers/net/fc/iph5526_novram.c b/drivers/net/fc/iph5526_novram.c new file mode 100644 index 000000000..d73587be0 --- /dev/null +++ b/drivers/net/fc/iph5526_novram.c @@ -0,0 +1,278 @@ +/********************************************************************** + * Reading the NVRAM on the Interphase 5526 PCI Fibre Channel Card. + * All contents in this file : courtesy Interphase Corporation. + * Special thanks to Kevin Quick, kquick@iphase.com. + **********************************************************************/ + +#define FF_MAGIC 0x4646 +#define DB_MAGIC 0x4442 +#define DL_MAGIC 0x444d + + +#define CMD_LEN 9 + +/*********** + * + * Switches and defines for header files. + * + * The following defines are used to turn on and off + * various options in the header files. Primarily useful + * for debugging. + * + ***********/ + +static const unsigned short novram_default[4] = { + FF_MAGIC, + DB_MAGIC, + DL_MAGIC, + 0 }; + + +/* + * a list of the commands that can be sent to the NOVRAM + */ + +#define NR_EXTEND 0x100 +#define NR_WRITE 0x140 +#define NR_READ 0x180 +#define NR_ERASE 0x1c0 + +#define EWDS 0x00 +#define WRAL 0x10 +#define ERAL 0x20 +#define EWEN 0x30 + +/* + * Defines for the pins on the NOVRAM + */ + +#define BIT(x) (1 << (x)) + +#define NVDI_B 31 +#define NVDI BIT(NVDI_B) +#define NVDO BIT(9) +#define NVCE BIT(30) +#define NVSK BIT(29) +#define NV_MANUAL BIT(28) + +/*********** + * + * Include files. + * + ***********/ + +#define KeStallExecutionProcessor(x) {volatile int d, p;\ + for (d=0; d<x; d++) for (p=0; p<10; p++);\ + } + + +/*********************** + * + * This define ands the value and the current config register and puts + * the result in the config register + * + ***********************/ + +#define CFG_AND(val) { volatile int t; \ + t = readl(fi->n_r.ptr_novram_hw_control_reg); \ + t &= (val); \ + writel(t, fi->n_r.ptr_novram_hw_control_reg); \ + } + +/*********************** + * + * This define ors the value and the current config register and puts + * the result in the config register + * + ***********************/ + +#define CFG_OR(val) { volatile int t; \ + t = readl(fi->n_r.ptr_novram_hw_control_reg); \ + t |= (val); \ + writel(t, fi->n_r.ptr_novram_hw_control_reg); \ + } + +/*********************** + * + * Send a command to the NOVRAM, the command is in cmd. + * + * clear CE and SK. Then assert CE. + * Clock each of the command bits out in the correct order with SK + * exit with CE still asserted + * + ***********************/ + +#define NVRAM_CMD(cmd) { int i; \ + int c = cmd; \ + CFG_AND(~(NVCE|NVSK)); \ + CFG_OR(NVCE); \ + for (i=0; i<CMD_LEN; i++) { \ + NVRAM_CLKOUT((c & (1 << (CMD_LEN - 1))) ? 1 : 0);\ + c <<= 1; } } + +/*********************** + * + * clear the CE, this must be used after each command is complete + * + ***********************/ + +#define NVRAM_CLR_CE CFG_AND(~NVCE) + +/*********************** + * + * clock the data bit in bitval out to the NOVRAM. The bitval must be + * a 1 or 0, or the clockout operation is undefined + * + ***********************/ + +#define NVRAM_CLKOUT(bitval) {\ + CFG_AND(~NVDI); \ + CFG_OR((bitval) << NVDI_B); \ + KeStallExecutionProcessor(5);\ + CFG_OR(NVSK); \ + KeStallExecutionProcessor(5);\ + CFG_AND( ~NVSK); \ + } + +/*********************** + * + * clock the data bit in and return a 1 or 0, depending on the value + * that was received from the NOVRAM + * + ***********************/ + +#define NVRAM_CLKIN(val) {\ + CFG_OR(NVSK); \ + KeStallExecutionProcessor(5);\ + CFG_AND(~NVSK); \ + KeStallExecutionProcessor(5);\ + val = (readl(fi->n_r.ptr_novram_hw_status_reg) & NVDO) ? 1 : 0; \ + } + +/*********** + * + * Function Prototypes + * + ***********/ + +static int iph5526_nr_get(struct fc_info *fi, int addr); +static void iph5526_nr_do_init(struct fc_info *fi); +static void iph5526_nr_checksum(struct fc_info *fi); + + +/******************************************************************* + * + * Local routine: iph5526_nr_do_init + * Purpose: initialize novram server + * Description: + * + * iph5526_nr_do_init reads the novram into the temporary holding place. + * A checksum is done on the area and the Magic Cookies are checked. + * If any of them are bad, the NOVRAM is initialized with the + * default values and a warning message is displayed. + * + *******************************************************************/ + +static void iph5526_nr_do_init(struct fc_info *fi) +{ + int i; + unsigned short chksum = 0; + int bad = 0; + + for (i=0; i<IPH5526_NOVRAM_SIZE; i++) { + fi->n_r.data[i] = iph5526_nr_get(fi, i); + chksum += fi->n_r.data[i]; + } + + if (chksum) + bad = 1; + + if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 4] != FF_MAGIC) + bad = 1; + if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 3] != DB_MAGIC) + bad = 1; + if (fi->n_r.data[IPH5526_NOVRAM_SIZE - 2] != DL_MAGIC) + bad = 1; + + if (bad) { + for (i=0; i<IPH5526_NOVRAM_SIZE; i++) { + if (i < (IPH5526_NOVRAM_SIZE - 4)) { + fi->n_r.data[i] = 0xffff; + } else { + fi->n_r.data[i] = novram_default[i - (IPH5526_NOVRAM_SIZE - 4)]; + } + } + iph5526_nr_checksum(fi); + } +} + + +/******************************************************************* + * + * Local routine: iph5526_nr_get + * Purpose: read a single word of NOVRAM + * Description: + * + * read the 16 bits that make up a word addr of the novram. + * The 16 bits of data that are read are returned as the return value + * + *******************************************************************/ + +static int iph5526_nr_get(struct fc_info *fi, int addr) +{ + int i; + int t; + int val = 0; + + CFG_OR(NV_MANUAL); + + /* + * read the first bit that was clocked with the falling edge of the + * the last command data clock + */ + + NVRAM_CMD(NR_READ + addr); + + /* + * Now read the rest of the bits, the next bit read is D1, then D2, + * and so on + */ + + val = 0; + for (i=0; i<16; i++) { + NVRAM_CLKIN(t); + val <<= 1; + val |= t; + } + NVRAM_CLR_CE; + + CFG_OR(NVDI); + CFG_AND(~NV_MANUAL); + + return(val); +} + + + + +/******************************************************************* + * + * Local routine: iph5526_nr_checksum + * Purpose: calculate novram checksum on fi->n_r.data + * Description: + * + * calculate a checksum for the novram on the image that is + * currently in fi->n_r.data + * + *******************************************************************/ + +static void iph5526_nr_checksum(struct fc_info *fi) +{ + int i; + unsigned short chksum = 0; + + for (i=0; i<(IPH5526_NOVRAM_SIZE - 1); i++) + chksum += fi->n_r.data[i]; + + fi->n_r.data[i] = -chksum; +} diff --git a/drivers/net/fc/iph5526_scsi.h b/drivers/net/fc/iph5526_scsi.h new file mode 100644 index 000000000..18221157b --- /dev/null +++ b/drivers/net/fc/iph5526_scsi.h @@ -0,0 +1,31 @@ +#ifndef IPH5526_SCSI_H +#define IPH5526_SCSI_H + +#define IPH5526_CAN_QUEUE 32 +#define IPH5526_SCSI_FC { \ + name: "Interphase 5526 Fibre Channel SCSI Adapter", \ + detect: iph5526_detect, \ + release: iph5526_release, \ + info: iph5526_info, \ + queuecommand: iph5526_queuecommand, \ + bios_param: iph5526_biosparam, \ + can_queue: IPH5526_CAN_QUEUE, \ + this_id: -1, \ + sg_tablesize: 255, \ + cmd_per_lun: 8, \ + use_clustering: DISABLE_CLUSTERING, \ + eh_abort_handler: iph5526_abort, \ + eh_device_reset_handler:NULL, \ + eh_bus_reset_handler: NULL, \ + eh_host_reset_handler: NULL, \ +} + +int iph5526_detect(Scsi_Host_Template *tmpt); +int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *)); +int iph5526_release(struct Scsi_Host *host); +int iph5526_abort(Scsi_Cmnd *Cmnd); +const char *iph5526_info(struct Scsi_Host *host); +int iph5526_biosparam(Disk * disk, kdev_t n, int ip[]); + +#endif + diff --git a/drivers/net/fc/tach.h b/drivers/net/fc/tach.h new file mode 100644 index 000000000..741812c5f --- /dev/null +++ b/drivers/net/fc/tach.h @@ -0,0 +1,475 @@ +/********************************************************************** + * Defines for the Tachyon Fibre Channel Controller and the Interphase + * (i)chip TPI. + *********************************************************************/ + +#ifndef _TACH_H +#define _TACH_H + +#define MY_PAGE_SIZE 4096 +#define REPLICATE 0xFF +#define MAX_NODES 127 +#define BROADCAST 0xFFFFFF +#define BROADCAST_ADDR 0xFFFFFFFFFFFF +#define LOGIN_COMPLETED 2 +#define LOGIN_ATTEMPTED 1 +#define LOGIN_NOT_ATTEMPTED 0 +#define TRUE 1 +#define FALSE 0 + +#define TACHYON_LIMIT 0x01EF +#define TACHYON_OFFSET 0x200 + +/* Offsets to the (i) chip */ +#define ICHIP_HW_CONTROL_REG_OFF (0x080 - TACHYON_OFFSET) +#define ICHIP_HW_STATUS_REG_OFF (0x084 - TACHYON_OFFSET) +#define ICHIP_HW_ADDR_MASK_REG_OFF (0x090 - TACHYON_OFFSET) + +/* (i)chip Hardware Control Register defines */ +#define ICHIP_HCR_RESET 0x01 +#define ICHIP_HCR_DERESET 0x0 +#define ICHIP_HCR_ENABLE_INTA 0x0000003E +#define ICHIP_HCR_ENABLE_INTB 0x003E0000 +#define ICHIP_HCR_IWDATA_FIFO 0x800000 + +/* (i)chip Hardware Status Register defines */ +#define ICHIP_HSR_INT_LATCH 0x02 + +/* (i)chip Hardware Address Mask Register defines */ +#define ICHIP_HAMR_BYTE_SWAP_ADDR_TR 0x08 +#define ICHIP_HAMR_BYTE_SWAP_NO_ADDR_TR 0x04 + +/* NOVRAM defines */ +#define IPH5526_NOVRAM_SIZE 64 + + +/* Offsets for the registers that correspond to the + * Qs on the Tachyon (As defined in the Tachyon Manual). + */ + +/* Outbound Command Queue (OCQ). + */ +#define OCQ_BASE_REGISTER_OFFSET 0x000 +#define OCQ_LENGTH_REGISTER_OFFSET 0x004 +#define OCQ_PRODUCER_REGISTER_OFFSET 0x008 +#define OCQ_CONSUMER_REGISTER_OFFSET 0x00C + +/* Inbound Message Queue (IMQ). + */ +#define IMQ_BASE_REGISTER_OFFSET 0x080 +#define IMQ_LENGTH_REGISTER_OFFSET 0x084 +#define IMQ_CONSUMER_REGISTER_OFFSET 0x088 +#define IMQ_PRODUCER_REGISTER_OFFSET 0x08C + +/* Multiframe Sequence Buffer Queue (MFSBQ) + */ +#define MFSBQ_BASE_REGISTER_OFFSET 0x0C0 +#define MFSBQ_LENGTH_REGISTER_OFFSET 0x0C4 +#define MFSBQ_PRODUCER_REGISTER_OFFSET 0x0C8 +#define MFSBQ_CONSUMER_REGISTER_OFFSET 0x0CC +#define MFS_LENGTH_REGISTER_OFFSET 0x0D0 + +/* Single Frame Sequence Buffer Queue (SFSBQ) + */ +#define SFSBQ_BASE_REGISTER_OFFSET 0x100 +#define SFSBQ_LENGTH_REGISTER_OFFSET 0x104 +#define SFSBQ_PRODUCER_REGISTER_OFFSET 0x108 +#define SFSBQ_CONSUMER_REGISTER_OFFSET 0x10C +#define SFS_LENGTH_REGISTER_OFFSET 0x110 + +/* SCSI Exchange State Table (SEST) + */ +#define SEST_BASE_REGISTER_OFFSET 0x140 +#define SEST_LENGTH_REGISTER_OFFSET 0x144 +#define SCSI_LENGTH_REGISTER_OFFSET 0x148 + +/* Length of the various Qs + */ +#define NO_OF_ENTRIES 8 +#define OCQ_LENGTH (MY_PAGE_SIZE/32) +#define IMQ_LENGTH (MY_PAGE_SIZE/32) +#define MFSBQ_LENGTH 8 +#define SFSBQ_LENGTH 8 +#define SEST_LENGTH MY_PAGE_SIZE + +/* Size of the various buffers. + */ +#define FRAME_SIZE 2048 +#define MFS_BUFFER_SIZE FRAME_SIZE +#define SFS_BUFFER_SIZE (FRAME_SIZE + TACHYON_HEADER_LEN) +#define SEST_BUFFER_SIZE 512 +#define TACH_HEADER_SIZE 64 +#define NO_OF_TACH_HEADERS ((MY_PAGE_SIZE)/TACH_HEADER_SIZE) + +#define NO_OF_FCP_CMNDS (MY_PAGE_SIZE/32) +#define SDB_SIZE 2048 +#define NO_OF_SDB_ENTRIES ((32*MY_PAGE_SIZE)/SDB_SIZE) + + +/* Offsets to the other Tachyon registers. + * (As defined in the Tachyon manual) + */ +#define TACHYON_CONFIG_REGISTER_OFFSET 0x184 +#define TACHYON_CONTROL_REGISTER_OFFSET 0x188 +#define TACHYON_STATUS_REGISTER_OFFSET 0x18C +#define TACHYON_FLUSH_SEST_REGISTER_OFFSET 0x190 + +/* Defines for the Tachyon Configuration register. + */ +#define SCSI_ENABLE 0x40000000 +#define WRITE_STREAM_SIZE 0x800 /* size = 16 */ +#define READ_STREAM_SIZE 0x300 /* size = 64 */ +#define PARITY_EVEN 0x2 +#define OOO_REASSEMBLY_DISABLE 0x40 + +/* Defines for the Tachyon Control register. + */ +#define SOFTWARE_RESET 0x80000000 +#define OCQ_RESET 0x4 +#define ERROR_RELEASE 0x2 + +/* Defines for the Tachyon Status register. + */ +#define RECEIVE_FIFO_EMPTY 0x10 +#define OSM_FROZEN 0x1 +#define OCQ_RESET_STATUS 0x20 +#define SCSI_FREEZE_STATUS 0x40 + + +/* Offsets to the Frame Manager registers. + */ +#define FMGR_CONFIG_REGISTER_OFFSET 0x1C0 +#define FMGR_CONTROL_REGISTER_OFFSET 0x1C4 +#define FMGR_STATUS_REGISTER_OFFSET 0x1C8 +#define FMGR_TIMER_REGISTER_OFFSET 0x1CC +#define FMGR_WWN_HI_REGISTER_OFFSET 0x1E0 +#define FMGR_WWN_LO_REGISTER_OFFSET 0x1E4 +#define FMGR_RCVD_ALPA_REGISTER_OFFSET 0x1E8 + +/* Defines for the Frame Manager Configuration register. + */ +#define BB_CREDIT 0x10000 +#define NPORT 0x8000 +#define LOOP_INIT_FABRIC_ADDRESS 0x400 +#define LOOP_INIT_PREVIOUS_ADDRESS 0x200 +#define LOOP_INIT_SOFT_ADDRESS 0x80 + +/* Defines for the Frame Manager Control register. + */ +#define HOST_CONTROL 0x02 +#define EXIT_HOST_CONTROL 0x03 +#define OFFLINE 0x05 +#define INITIALIZE 0x06 +#define CLEAR_LF 0x07 + +/* Defines for the Frame Manager Status register. + */ +#define LOOP_UP 0x80000000 +#define TRANSMIT_PARITY_ERROR 0x40000000 +#define NON_PARTICIPATING 0x20000000 +#define OUT_OF_SYNC 0x02000000 +#define LOSS_OF_SIGNAL 0x01000000 +#define NOS_OLS_RECEIVED 0x00080000 +#define LOOP_STATE_TIMEOUT 0x00040000 +#define LIPF_RECEIVED 0x00020000 +#define BAD_ALPA 0x00010000 +#define LINK_FAILURE 0x00001000 +#define ELASTIC_STORE_ERROR 0x00000400 +#define LINK_UP 0x00000200 +#define LINK_DOWN 0x00000100 +#define ARBITRATING 0x00000010 +#define ARB_WON 0x00000020 +#define OPEN 0x00000030 +#define OPENED 0x00000040 +#define TX_CLS 0x00000050 +#define RX_CLS 0x00000060 +#define TRANSFER 0x00000070 +#define INITIALIZING 0x00000080 +#define LOOP_FAIL 0x000000D0 +#define OLD_PORT 0x000000F0 +#define PORT_STATE_ACTIVE 0x0000000F +#define PORT_STATE_OFFLINE 0x00000000 +#define PORT_STATE_LF1 0x00000009 +#define PORT_STATE_LF2 0x0000000A + +/* Completion Message Types + * (defined in P.177 of the Tachyon manual) + */ +#define OUTBOUND_COMPLETION 0x000 +#define OUTBOUND_COMPLETION_I 0x100 +#define OUT_HI_PRI_COMPLETION 0x001 +#define OUT_HI_PRI_COMPLETION_I 0x101 +#define INBOUND_MFS_COMPLETION 0x102 +#define INBOUND_OOO_COMPLETION 0x003 +#define INBOUND_SFS_COMPLETION 0x104 +#define INBOUND_C1_TIMEOUT 0x105 +#define INBOUND_UNKNOWN_FRAME_I 0x106 +#define INBOUND_BUSIED_FRAME 0x006 +#define SFS_BUF_WARN 0x107 +#define MFS_BUF_WARN 0x108 +#define IMQ_BUF_WARN 0x109 +#define FRAME_MGR_INTERRUPT 0x10A +#define READ_STATUS 0x10B +#define INBOUND_SCSI_DATA_COMPLETION 0x10C +#define INBOUND_SCSI_COMMAND 0x10D +#define BAD_SCSI_FRAME 0x10E +#define INB_SCSI_STATUS_COMPLETION 0x10F + +/* One of the things that we care about when we receive an + * Outbound Completion Message (OCM). + */ +#define OCM_TIMEOUT_OR_BAD_ALPA 0x0800 + +/* Defines for the Tachyon Header structure. + */ +#define SOFI3 0x70 +#define SOFN3 0xB0 +#define EOFN 0x5 + +/* R_CTL */ +#define FC4_DEVICE_DATA 0 +#define EXTENDED_LINK_DATA 0x20000000 +#define FC4_LINK_DATA 0x30000000 +#define BASIC_LINK_DATA 0x80000000 +#define LINK_CONTROL 0xC0000000 +#define SOLICITED_DATA 0x1000000 +#define UNSOLICITED_CONTROL 0x2000000 +#define SOLICITED_CONTROL 0x3000000 +#define UNSOLICITED_DATA 0x4000000 +#define DATA_DESCRIPTOR 0x5000000 +#define UNSOLICITED_COMMAND 0x6000000 + +#define RCTL_ELS_UCTL 0x22000000 +#define RCTL_ELS_SCTL 0x23000000 +#define RCTL_BASIC_ABTS 0x81000000 +#define RCTL_BASIC_ACC 0x84000000 +#define RCTL_BASIC_RJT 0x85000000 + +/* TYPE */ +#define TYPE_BLS 0x00000000 +#define TYPE_ELS 0x01000000 +#define TYPE_FC_SERVICES 0x20000000 +#define TYPE_LLC_SNAP 0x05000000 +#define TYPE_FCP 0x08000000 + +/* F_CTL */ +#define EXCHANGE_RESPONDER 0x800000 +#define SEQUENCE_RESPONDER 0x400000 +#define FIRST_SEQUENCE 0x200000 +#define LAST_SEQUENCE 0x100000 +#define SEQUENCE_INITIATIVE 0x10000 +#define RELATIVE_OFF_PRESENT 0x8 +#define END_SEQUENCE 0x80000 + +#define TACHYON_HEADER_LEN 32 +#define NW_HEADER_LEN 16 +/* Defines for the Outbound Descriptor Block (ODB). + */ +#define ODB_CLASS_3 0xC000 +#define ODB_NO_COMP 0x400 +#define ODB_NO_INT 0x200 +#define ODB_EE_CREDIT 0xF + +/* Defines for the Extended Descriptor Block (EDB). + */ +#define EDB_LEN ((32*MY_PAGE_SIZE)/8) +#define EDB_END 0x8000 +#define EDB_FREE 0 +#define EDB_BUSY 1 + +/* Command Codes */ +#define ELS_LS_RJT 0x01000000 +#define ELS_ACC 0x02000000 +#define ELS_PLOGI 0x03000000 +#define ELS_FLOGI 0x04000000 +#define ELS_LOGO 0x05000000 +#define ELS_TPRLO 0x24000000 +#define ELS_ADISC 0x52000000 +#define ELS_PDISC 0x50000000 +#define ELS_PRLI 0x20000000 +#define ELS_PRLO 0x21000000 +#define ELS_SCR 0x62000000 +#define ELS_RSCN 0x61000000 +#define ELS_FARP_REQ 0x54000000 +#define ELS_ABTX 0x06000000 +#define ELS_ADVC 0x0D000000 +#define ELS_ECHO 0x10000000 +#define ELS_ESTC 0x0C000000 +#define ELS_ESTS 0x0B000000 +#define ELS_RCS 0x07000000 +#define ELS_RES 0x08000000 +#define ELS_RLS 0x0F000000 +#define ELS_RRQ 0x12000000 +#define ELS_RSS 0x09000000 +#define ELS_RTV 0x0E000000 +#define ELS_RSI 0x0A000000 +#define ELS_TEST 0x11000000 +#define ELS_RNC 0x53000000 +#define ELS_RVCS 0x41000000 +#define ELS_TPLS 0x23000000 +#define ELS_GAID 0x30000000 +#define ELS_FACT 0x31000000 +#define ELS_FAN 0x60000000 +#define ELS_FDACT 0x32000000 +#define ELS_NACT 0x33000000 +#define ELS_NDACT 0x34000000 +#define ELS_QoSR 0x40000000 +#define ELS_FDISC 0x51000000 + +#define ELS_NS_PLOGI 0x03FFFFFC + +/* LS_RJT reason codes. + */ +#define INV_LS_CMND_CODE 0x0001 +#define LOGICAL_ERR 0x0003 +#define LOGICAL_BUSY 0x0005 +#define PROTOCOL_ERR 0x0007 +#define UNABLE_TO_PERFORM 0x0009 +#define CMND_NOT_SUPP 0x000B + +/* LS_RJT explanation codes. + */ +#define NO_EXPLN 0x0000 +#define RECV_FIELD_SIZE 0x0700 +#define CONC_SEQ 0x0900 +#define REQ_NOT_SUPPORTED 0x2C00 +#define INV_PAYLOAD_LEN 0x2D00 + +/* Payload Length defines. + */ +#define PLOGI_LEN 116 + +#define CONCURRENT_SEQUENCES 0x01 +#define RO_INFO_CATEGORY 0xFE +#define E_D_TOV 0x07D0 /* 2 Secs */ +#define AL_TIME 0x0010 /* ~15 msec */ +#define TOV_VALUES (AL_TIME << 16) | E_D_TOV +#define RT_TOV 0x64 /* 100 msec */ +#define PTP_TOV_VALUES (RT_TOV << 16) | E_D_TOV +#define SERVICE_VALID 0x8000 +#define SEQUENCE_DELIVERY 0x0800 +#define CLASS3_CONCURRENT_SEQUENCE 0x01 +#define CLASS3_OPEN_SEQUENCE 0x01 + +/* These are retrieved from the NOVRAM. + */ +#define WORLD_WIDE_NAME_LOW fi->g.my_port_name_low +#define WORLD_WIDE_NAME_HIGH fi->g.my_port_name_high +#define N_PORT_NAME_HIGH fi->g.my_port_name_high +#define N_PORT_NAME_LOW fi->g.my_port_name_low +#define NODE_NAME_HIGH fi->g.my_node_name_high +#define NODE_NAME_LOW fi->g.my_node_name_low + +#define PORT_NAME_LEN 8 +#define NODE_NAME_LEN 8 + + +#define PH_VERSION 0x0909 + +#define LOOP_BB_CREDIT 0x00 +#define PT2PT_BB_CREDIT 0x01 +#define FLOGI_C_F 0x0800 /* Alternate BB_Credit Mgmnt */ +#define PLOGI_C_F 0x8800 /* Continuously Increasing + Alternate BB_Credit Management */ + +/* Fabric defines */ +#define DIRECTORY_SERVER 0xFFFFFC +#define FABRIC_CONTROLLER 0xFFFFFD +#define F_PORT 0xFFFFFE + +#define FLOGI_DID 0xFFFE +#define NS_PLOGI_DID 0xFFFC + +/* Fibre Channel Services defines */ +#define FCS_RFC_4 0x02170000 +#define FCS_GP_ID4 0x01A10000 +#define FCS_ACC 0x8002 +#define FCS_REJECT 0x8001 + +/* CT Header defines */ +#define FC_CT_REV 0x01000000 +#define DIRECTORY_SERVER_APP 0xFC +#define NAME_SERVICE 0x02 + +/* Port Type defines */ +#define PORT_TYPE_IP 0x05000000 +#define PORT_TYPE_NX_PORTS 0x7F000000 + +/* SCR defines */ +#define FABRIC_DETECTED_REG 0x00000001 +#define N_PORT_DETECTED_REG 0x00000002 +#define FULL_REGISTRATION 0x00000003 +#define CLEAR_REGISTRATION 0x000000FF + +/* Command structure has only one byte to address targets + */ +#define MAX_SCSI_TARGETS 0xFF + +#define FC_SCSI_READ 0x80 +#define FC_SCSI_WRITE 0x81 +#define FC_ELS 0x01 +#define FC_BLS 0x00 +#define FC_IP 0x05 +#define FC_BROADCAST 0xFF + +/* SEST defines. + */ +#define SEST_V 0x80000000 /* V = 1 */ +#define INB_SEST_VED 0xA0000000 /* V = 1, D = 1 */ +#define SEST_INV 0x7FFFFFFF +#define OUTB_SEST_VED 0x80000000 /* V = 1 */ +#define INV_SEQ_LEN 0xFFFFFFFF +#define OUTB_SEST_LINK 0xFFFF + +/* PRLI defines. + */ +#define PAGE_LEN 0x100000 /* 3rd byte - 0x10 */ +#define PRLI_LEN 0x0014 /* 20 bytes */ +#define FCP_TYPE_CODE 0x0800 /* FCP-SCSI */ +#define IMAGE_PAIR 0x2000 /* establish image pair */ +#define INITIATOR_FUNC 0x00000020 +#define TARGET_FUNC 0x00000010 +#define READ_XFER_RDY_DISABLED 0x00000002 + +#define NODE_PROCESS_LOGGED_IN 0x3 +#define NODE_NOT_PRESENT 0x2 +#define NODE_LOGGED_IN 0x1 +#define NODE_LOGGED_OUT 0x0 + +/* Defines to determine what should be returned when a SCSI frame + * times out. + */ +#define FC_SCSI_BAD_TARGET 0xFFFE0000 + +/* RSCN Address formats */ +#define PORT_ADDRESS_FORMAT 0x00 +#define AREA_ADDRESS_FORMAT 0x01 +#define DOMAIN_ADDRESS_FORMAT 0x02 + +/* Defines used to determine whether a frame transmission should + * be indicated by an interrupt or not. + */ +#define NO_COMP_AND_INT 0 +#define INT_AND_COMP_REQ 1 +#define NO_INT_COMP_REQ 2 + +/* Other junk... + */ +#define SDB_FREE 0 +#define SDB_BUSY 1 +#define MAX_PENDING_FRAMES 15 +#define RX_ID_FIRST_SEQUENCE 0xFFFF +#define OX_ID_FIRST_SEQUENCE 0xFFFF +#define NOT_SCSI_XID 0x8000 +#define MAX_SCSI_XID 0x0FFF /* X_IDs are from 0-4095 */ +#define SCSI_READ_BIT 0x4000 +#define MAX_SCSI_OXID 0x4FFF +#define OXID_AVAILABLE 0 +#define OXID_INUSE 1 +#define MAX_SEQ_ID 0xFF + +#define INITIATOR 2 +#define TARGET 1 +#define DELETE_ENTRY 1 +#define ADD_ENTRY 2 + +#endif /* _TACH_H */ diff --git a/drivers/net/fc/tach_structs.h b/drivers/net/fc/tach_structs.h new file mode 100644 index 000000000..0b7bc011e --- /dev/null +++ b/drivers/net/fc/tach_structs.h @@ -0,0 +1,428 @@ +/********************************************************************** + * iph5526.c: Structures for the Interphase 5526 PCI Fibre Channel + * IP/SCSI driver. + * Copyright (C) 1999 Vineet M Abraham <vma@iol.unh.edu> + **********************************************************************/ + +#ifndef _TACH_STRUCT_H +#define _TACH_STRUCT_H + +typedef struct { + u_short cmnd_code; + u_short payload_length; + u_short type_code; + u_short est_image_pair; + u_int originator_pa; + u_int responder_pa; + u_int service_params; +} PRLI; + +typedef struct { + u_int flags_and_byte_offset; + u_int byte_count; + u_short no_of_recvd_frames; + u_short no_of_expected_frames; + u_int last_fctl; + u_int sdb_address; + u_int scratch_pad; + u_int expected_ro; + u_short buffer_index; + u_short buffer_offset; + } INB_SEST_ENTRY; + +typedef struct { + u_int flags_and_did; + u_short max_frame_len; + u_short cntl; + u_int total_seq_length; + u_short link; + u_short rx_id; + u_int transaction_id; + u_int header_address; + u_char seq_id; + u_char reserved; + u_short header_length; + u_int edb_address; + } OUTB_SEST_ENTRY; + +typedef struct { + u_short d_naa; + u_short dest_high; + u_int dest_low; + u_short s_naa; + u_short source_high; + u_int source_low; + } NW_HEADER; + +typedef struct { + u_int resv; + u_char sof_and_eof; + u_char dest_alpa; + u_short lcr_and_time_stamp; + u_int r_ctl_and_d_id; + u_int vc_id_and_s_id; + u_int type_and_f_cntl; + u_char seq_id; + u_char df_cntl; + u_short seq_cnt; + u_short ox_id; + u_short rx_id; + u_int ro; + NW_HEADER nw_header; + } TACHYON_HEADER; + +typedef struct { + u_short service_options; + u_short initiator_ctl; + u_short recipient_ctl; + u_short recv_data_field_size; + u_short concurrent_sequences; + u_short n_port_end_to_end_credit; + u_short open_seq_per_exchange; + u_short resv; + }CLASS_OF_SERVICE; + +typedef struct { + u_int logo_cmnd; + u_char reserved; + u_char n_port_id_2; + u_char n_port_id_1; + u_char n_port_id_0; + u_int port_name_up; + u_int port_name_low; + } LOGO; + +typedef struct { + u_int ls_cmnd_code; + u_int hard_address; + u_int port_name_high; + u_int port_name_low; + u_int node_name_high; + u_int node_name_low; + u_int n_port_id; + } ADISC; + +typedef struct { + u_int cmnd_code; + u_int reason_code; + } LS_RJT; + +typedef struct { + u_int cmnd_code; + } ACC; + +typedef struct { + u_int seq_d_id; + u_int tot_len; + u_short cntl; + u_short rx_id; + u_short cs_enable; + u_short cs_seed; + u_int trans_id; + u_int hdr_addr; + u_short frame_len; + u_short hdr_len; + u_int edb_addr; + }ODB; + +typedef struct { + u_int cmnd_code; + u_int reg_function; /* in the last byte */ + } SCR; + +typedef struct { + u_int rev_in_id; + u_char fs_type; + u_char fs_subtype; + u_char options; + u_char resv1; + u_short cmnd_resp_code; + u_short max_res_size; + u_char resv2; + u_char reason_code; + u_char expln_code; + u_char vendor_unique; + } CT_HDR; + +typedef struct { + CT_HDR ct_hdr; + u_int s_id; + u_char bit_map[32]; /* 32 byte bit map */ + } RFC_4; + +typedef struct { + u_int ls_cmnd_code; + u_short fc_ph_version; + u_short buff_to_buff_credit; + u_short common_features; + u_short recv_data_field_size; + u_short n_port_total_conc_seq; + u_short rel_off_by_info_cat; + u_int ED_TOV; + u_int n_port_name_high; + u_int n_port_name_low; + u_int node_name_high; + u_int node_name_low; + CLASS_OF_SERVICE c_of_s[3]; + u_int resv[4]; + u_int vendor_version_level[4]; + }LOGIN; + +typedef struct { + CT_HDR ct_hdr; + u_int port_type; /* in the first byte */ + } GP_ID4; + +typedef struct { + u_int buf_addr; + u_short ehf; + u_short buf_len; + }EDB; + +/* (i)chip Registers */ +struct i_chip_regs { + u_int ptr_ichip_hw_control_reg; + u_int ptr_ichip_hw_status_reg; + u_int ptr_ichip_hw_addr_mask_reg; +}; + +struct iph5526_novram { + u_int ptr_novram_hw_control_reg; + u_int ptr_novram_hw_status_reg; + u_short data[IPH5526_NOVRAM_SIZE]; +}; + +/* Tachyon Registers */ +struct tachyon_regs { + u_int ptr_ocq_base_reg; + u_int ptr_ocq_len_reg; + u_int ptr_ocq_prod_indx_reg; + u_int ptr_ocq_cons_indx_reg; + + u_int ptr_imq_base_reg; + u_int ptr_imq_len_reg; + u_int ptr_imq_cons_indx_reg; + u_int ptr_imq_prod_indx_reg; + + u_int ptr_mfsbq_base_reg; + u_int ptr_mfsbq_len_reg; + u_int ptr_mfsbq_prod_reg; + u_int ptr_mfsbq_cons_reg; + u_int ptr_mfsbuff_len_reg; + + u_int ptr_sfsbq_base_reg; + u_int ptr_sfsbq_len_reg; + u_int ptr_sfsbq_prod_reg; + u_int ptr_sfsbq_cons_reg; + u_int ptr_sfsbuff_len_reg; + + u_int ptr_sest_base_reg; + u_int ptr_sest_len_reg; + u_int ptr_scsibuff_len_reg; + + u_int ptr_tach_config_reg; + u_int ptr_tach_control_reg; + u_int ptr_tach_status_reg; + u_int ptr_tach_flush_oxid_reg; + + u_int ptr_fm_config_reg; + u_int ptr_fm_control_reg; + u_int ptr_fm_status_reg; + u_int ptr_fm_tov_reg; + u_int ptr_fm_wwn_hi_reg; + u_int ptr_fm_wwn_low_reg; + u_int ptr_fm_rx_al_pa_reg; +}; + +struct globals { + u_long tachyon_base; + u_int *mem_base; + u_short ox_id; /* OX_ID used for IP and ELS frames */ + u_short scsi_oxid; /* OX_ID for SEST entry */ + u_char seq_id; + u_int my_id; + u_int my_ddaa; /* my domain and area in a fabric */ + volatile u_char loop_up; + volatile u_char ptp_up; /* we have a point-to-point link */ + volatile u_char link_up; + volatile u_char n_port_try; + volatile u_char nport_timer_set; + volatile u_char lport_timer_set; + /* Hmmm... We dont want to Initialize while closing */ + u_char dont_init; + u_int my_node_name_high; + u_int my_node_name_low; + u_int my_port_name_high; + u_int my_port_name_low; + u_char fabric_present; + u_char explore_fabric; + u_char name_server; + u_int my_mtu; + u_int *els_buffer[MAX_PENDING_FRAMES]; /* temp space for ELS frames */ + char *arp_buffer; /* temp space for ARP frames */ + u_int mfs_buffer_count; /* keep track of MFS buffers used*/ + u_char scsi_registered; + /* variables for port discovery */ + volatile u_char port_discovery; + volatile u_char perform_adisc; + u_short alpa_list_index; + u_short type_of_frame; /* Could be IP/SCSI Read/SCSI Write*/ + u_char no_of_targets; /* used to assign target_ids */ + u_long sem; /* to synchronize between IP and SCSI */ + u_char e_i; + + /* the frames */ + TACHYON_HEADER tach_header; + LOGIN login; + PRLI prli; + LOGO logo; + ADISC adisc; + LS_RJT ls_rjt; + ODB odb; + INB_SEST_ENTRY inb_sest_entry; + OUTB_SEST_ENTRY outb_sest_entry; + ACC acc; + SCR scr; + EDB edb; + RFC_4 rfc_4; + GP_ID4 gp_id4; +}; + +struct queue_variables { + /* Indices maintained in host memory. + */ + u_int *host_ocq_cons_indx, *host_hpcq_cons_indx, *host_imq_prod_indx; + u_int *ptr_host_ocq_cons_indx, *ptr_host_hpcq_cons_indx, *ptr_host_imq_prod_indx; + + /* Variables for Outbound Command Queue (OCQ). + */ + u_int *ptr_ocq_base; + u_int ocq_len, ocq_end; + u_int ocq_prod_indx; + u_int *ptr_odb[OCQ_LENGTH]; + + /* Variables for Inbound Message Queue (IMQ). + */ + u_int *ptr_imq_base; + u_int imq_len, imq_end; + u_int imq_cons_indx; + u_int imq_prod_indx; + u_int *ptr_imqe[IMQ_LENGTH]; + + u_int *ptr_mfsbq_base; + u_int mfsbq_len, mfsbq_end; + u_int mfsbq_prod_indx; + u_int mfsbq_cons_indx; + u_int mfsbuff_len, mfsbuff_end; + + u_int *ptr_sfsbq_base; + u_int sfsbq_len, sfsbq_end; + u_int sfsbq_prod_indx; + u_int sfsbq_cons_indx; + u_int sfsbuff_len, sfsbuff_end; + u_int *ptr_sfs_buffers[SFSBQ_LENGTH * NO_OF_ENTRIES]; + + /* Tables for SCSI Transactions */ + u_int *ptr_sest_base; + u_int *ptr_sest[SEST_LENGTH]; + u_char free_scsi_oxid[SEST_LENGTH]; + u_int *ptr_sdb_base; + u_int *ptr_sdb_slot[NO_OF_SDB_ENTRIES]; + u_char sdb_slot_status[NO_OF_SDB_ENTRIES]; + u_int sdb_indx; + u_int *ptr_fcp_cmnd_base; + u_int *ptr_fcp_cmnd[NO_OF_FCP_CMNDS]; + u_int fcp_cmnd_indx; + + /* Table for data to be transmitted. + */ + u_int *ptr_edb_base; + u_int *ptr_edb[EDB_LEN]; + u_int edb_buffer_indx; + volatile u_char free_edb_list[EDB_LEN]; + + /* Table of Tachyon Headers. + */ + u_int *ptr_tachyon_header[NO_OF_TACH_HEADERS]; + u_int *ptr_tachyon_header_base; + u_int tachyon_header_indx; +}; + +/* Used to match incoming ACCs to ELS requests sent out */ +struct ox_id_els_map { + u_short ox_id; + u_int els; + struct ox_id_els_map *next; +}; + + +/* Carries info about individual nodes... stores the info got at login + * time. Also maintains mapping between MAC->FC addresses + */ +struct fc_node_info { + /* Itz the WWN (8 bytes), the last 6 bytes is the MAC address */ + u_char hw_addr[PORT_NAME_LEN]; + u_char node_name[NODE_NAME_LEN]; + u_int d_id; /*real FC address, 3 bytes */ + int mtu; + /* login = 1 if login attempted + * login = 2 if login completed + */ + int login; + u_char scsi; /* = 1 if device is a SCSI Target */ + u_char target_id; + CLASS_OF_SERVICE c_of_s[3]; + struct fc_node_info *next; +}; + +struct fc_info { + char name[8]; + u_long base_addr; + int irq; + struct net_device_stats fc_stats; + struct fc_node_info *node_info_list; + int num_nodes; + struct ox_id_els_map *ox_id_list; + struct i_chip_regs i_r; + struct tachyon_regs t_r; + struct queue_variables q; + struct globals g; + struct iph5526_novram n_r; + u_short clone_id; + struct timer_list nport_timer; + struct timer_list lport_timer; + struct timer_list explore_timer; + struct timer_list display_cache_timer; + struct net_device *dev; + struct Scsi_Host *host; + spinlock_t fc_lock; +}; + +struct iph5526_hostdata { + struct fc_info *fi; + fcp_cmd cmnd; + Scsi_Cmnd *cmnd_handler[SEST_LENGTH]; + u_int tag_ages[MAX_SCSI_TARGETS]; +}; + +/* List of valid AL_PAs */ +u_char alpa_list[127] = { + 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, 0x17, + 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, 0x26, + 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, 0x3C, + 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, + 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, 0x69, + 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, 0x81, + 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, 0x9B, + 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, 0xA9, + 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, 0xC5, + 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, + 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, 0xDA, + 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF +}; + +#endif /* _TACH_STRUCT_H */ diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c index 0c51aa90b..10366f2f8 100644 --- a/drivers/net/fmv18x.c +++ b/drivers/net/fmv18x.c @@ -108,16 +108,16 @@ struct net_local { /* Index to functions, as function prototypes. */ -extern int fmv18x_probe(struct device *dev); +extern int fmv18x_probe(struct net_device *dev); -static int fmv18x_probe1(struct device *dev, short ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int fmv18x_probe1(struct net_device *dev, short ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -133,7 +133,7 @@ struct netdev_entry fmv18x_drv = {"fmv18x", fmv18x_probe1, FMV18X_IO_EXTENT, fmv18x_probe_list}; #else int __init -fmv18x_probe(struct device *dev) +fmv18x_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -163,7 +163,7 @@ fmv18x_probe(struct device *dev) that can be done is checking a few bits and then diving right into MAC address check. */ -int __init fmv18x_probe1(struct device *dev, short ioaddr) +int __init fmv18x_probe1(struct net_device *dev, short ioaddr) { char irqmap[4] = {3, 7, 10, 15}; char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; @@ -287,7 +287,7 @@ int __init fmv18x_probe1(struct device *dev, short ioaddr) } -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -326,7 +326,7 @@ static int net_open(struct device *dev) } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -420,7 +420,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -483,7 +483,7 @@ net_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -572,7 +572,7 @@ net_rx(struct device *dev) } /* The inverse routine to net_open(). */ -static int net_close(struct device *dev) +static int net_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -599,7 +599,7 @@ static int net_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -617,7 +617,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) @@ -637,7 +637,7 @@ static void set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_fmv18x = { +static struct net_device dev_fmv18x = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 9dda3006e..16dc8a976 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -53,7 +53,7 @@ typedef unsigned char byte; typedef struct sixpack_ctrl { char if_name[8]; /* "sp0\0" .. "sp99999\0" */ struct sixpack ctrl; /* 6pack things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } sixpack_ctrl_t; static sixpack_ctrl_t **sixpack_ctrls = NULL; int sixpack_maxdev = SIXP_NRUNIT; /* Can be overridden with insmod! */ @@ -327,7 +327,7 @@ static void sixpack_write_wakeup(struct tty_struct *tty) /* Encapsulate an IP datagram and kick it into a TTY queue. */ static int -sp_xmit(struct sk_buff *skb, struct device *dev) +sp_xmit(struct sk_buff *skb, struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -382,7 +382,7 @@ void sp_xmit_on_air(unsigned long channel) /* #if defined(CONFIG_6PACK) || defined(CONFIG_6PACK_MODULE) */ /* Return the frame type ID */ -static int sp_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int sp_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { #ifdef CONFIG_INET @@ -406,7 +406,7 @@ static int sp_rebuild_header(struct sk_buff *skb) /* Open the low-level part of the 6pack channel. */ static int -sp_open(struct device *dev) +sp_open(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); unsigned long len; @@ -469,7 +469,7 @@ sp_open(struct device *dev) /* Close the low-level part of the 6pack channel. */ static int -sp_close(struct device *dev) +sp_close(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -612,7 +612,7 @@ sixpack_close(struct tty_struct *tty) static struct net_device_stats * -sp_get_stats(struct device *dev) +sp_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -633,7 +633,7 @@ sp_get_stats(struct device *dev) int -sp_set_mac_address(struct device *dev, void *addr) +sp_set_mac_address(struct net_device *dev, void *addr) { int err; @@ -648,7 +648,7 @@ sp_set_mac_address(struct device *dev, void *addr) } static int -sp_set_dev_mac_address(struct device *dev, void *addr) +sp_set_dev_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa=addr; memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN); @@ -713,7 +713,7 @@ sixpack_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) } } -static int sp_open_dev(struct device *dev) +static int sp_open_dev(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); if(sp->tty==NULL) @@ -726,7 +726,7 @@ static int sp_open_dev(struct device *dev) #ifdef MODULE static int sixpack_init_ctrl_dev(void) #else /* !MODULE */ -int __init sixpack_init_ctrl_dev(struct device *dummy) +int __init sixpack_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; @@ -778,7 +778,7 @@ int __init sixpack_init_ctrl_dev(struct device *dummy) /* Initialize the 6pack driver. Called by DDI. */ int -sixpack_init(struct device *dev) +sixpack_init(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); diff --git a/drivers/net/hamradio/6pack.h b/drivers/net/hamradio/6pack.h index a5fe532f3..b929c83a6 100644 --- a/drivers/net/hamradio/6pack.h +++ b/drivers/net/hamradio/6pack.h @@ -70,7 +70,7 @@ struct sixpack { /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ /* These are pointers to the malloc()ed frame buffers. */ unsigned char *rbuff; /* receiver buffer */ @@ -128,7 +128,7 @@ struct sixpack { #define AX25_6PACK_HEADER_LEN 0 #define SIXPACK_MAGIC 0x5304 -extern int sixpack_init(struct device *dev); +extern int sixpack_init(struct net_device *dev); #endif diff --git a/drivers/net/hamradio/Config.in b/drivers/net/hamradio/Config.in index 023a4b1b6..1d45998f4 100644 --- a/drivers/net/hamradio/Config.in +++ b/drivers/net/hamradio/Config.in @@ -7,24 +7,27 @@ dep_tristate 'BPQ Ethernet driver' CONFIG_BPQETHER $CONFIG_AX25 dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25 dep_tristate 'Z8530 SCC driver' CONFIG_SCC $CONFIG_AX25 if [ "$CONFIG_SCC" != "n" ]; then - bool ' additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY - bool ' support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO + bool ' additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY + bool ' support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO fi -tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX -tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX -dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_PARPORT -dep_tristate 'BAYCOM epp driver for AX.25' CONFIG_BAYCOM_EPP $CONFIG_PARPORT +dep_tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX $CONFIG_AX25 +dep_tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX $CONFIG_AX25 +dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_PARPORT $CONFIG_AX25 +dep_tristate 'BAYCOM epp driver for AX.25' CONFIG_BAYCOM_EPP $CONFIG_PARPORT $CONFIG_AX25 -tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM +dep_tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM $CONFIG_PARPORT $CONFIG_AX25 if [ "$CONFIG_SOUNDMODEM" != "n" ]; then - bool ' soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC - bool ' soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS - bool ' soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200 - bool ' soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7 - bool ' soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8 - bool ' soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666 - bool ' soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800 - bool ' soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800 - bool ' soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600 + bool ' soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC + bool ' soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS + bool ' soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200 + bool ' soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7 + bool ' soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8 + bool ' soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666 + bool ' soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800 + bool ' soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800 + bool ' soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600 fi + +dep_tristate 'YAM driver for AX.25' CONFIG_YAM $CONFIG_AX25 + diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile index aeb14f32c..d80857838 100644 --- a/drivers/net/hamradio/Makefile +++ b/drivers/net/hamradio/Makefile @@ -11,8 +11,8 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) -L_TARGET := hamradio.a -L_OBJS := +O_TARGET := hamradio.o +O_OBJS := M_OBJS := MOD_LIST_NAME := HAM_MODULES @@ -22,7 +22,7 @@ CONFIG_HDLCDRV_BUILTIN := CONFIG_HDLCDRV_MODULE := ifeq ($(CONFIG_DMASCC),y) -L_OBJS += dmascc.o +O_OBJS += dmascc.o else ifeq ($(CONFIG_DMASCC),m) M_OBJS += dmascc.o @@ -30,7 +30,7 @@ else endif ifeq ($(CONFIG_SCC),y) -L_OBJS += scc.o +O_OBJS += scc.o else ifeq ($(CONFIG_SCC),m) M_OBJS += scc.o @@ -38,7 +38,7 @@ else endif ifeq ($(CONFIG_MKISS),y) -L_OBJS += mkiss.o +O_OBJS += mkiss.o else ifeq ($(CONFIG_MKISS),m) M_OBJS += mkiss.o @@ -46,15 +46,23 @@ else endif ifeq ($(CONFIG_6PACK),y) -L_OBJS += 6pack.o +O_OBJS += 6pack.o else ifeq ($(CONFIG_6PACK),m) M_OBJS += 6pack.o endif endif +ifeq ($(CONFIG_YAM),y) +O_OBJS += yam.o +else + ifeq ($(CONFIG_YAM),m) + M_OBJS += yam.o + endif +endif + ifeq ($(CONFIG_PI),y) -L_OBJS += pi2.o +O_OBJS += pi2.o else ifeq ($(CONFIG_PI),m) M_OBJS += pi2.o @@ -62,7 +70,7 @@ else endif ifeq ($(CONFIG_PT),y) -L_OBJS += pt.o +O_OBJS += pt.o else ifeq ($(CONFIG_PT),m) M_OBJS += pt.o @@ -70,7 +78,7 @@ else endif ifeq ($(CONFIG_BPQETHER),y) -L_OBJS += bpqether.o +O_OBJS += bpqether.o else ifeq ($(CONFIG_BPQETHER),m) M_OBJS += bpqether.o @@ -78,7 +86,7 @@ else endif ifeq ($(CONFIG_BAYCOM_SER_FDX),y) -L_OBJS += baycom_ser_fdx.o +O_OBJS += baycom_ser_fdx.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_SER_FDX),m) @@ -88,7 +96,7 @@ else endif ifeq ($(CONFIG_BAYCOM_SER_HDX),y) -L_OBJS += baycom_ser_hdx.o +O_OBJS += baycom_ser_hdx.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_SER_HDX),m) @@ -98,7 +106,7 @@ else endif ifeq ($(CONFIG_BAYCOM_PAR),y) -L_OBJS += baycom_par.o +O_OBJS += baycom_par.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_PAR),m) @@ -108,7 +116,7 @@ else endif ifeq ($(CONFIG_BAYCOM_EPP),y) -L_OBJS += baycom_epp.o +O_OBJS += baycom_epp.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_EPP),m) @@ -120,7 +128,7 @@ endif ifeq ($(CONFIG_SOUNDMODEM),y) ALL_SUB_DIRS += soundmodem SUB_DIRS += soundmodem -L_OBJS += soundmodem/soundmodem.o +O_OBJS += soundmodem/soundmodem.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_SOUNDMODEM),m) @@ -133,7 +141,7 @@ endif # If anything built-in uses the hdlcdrv, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_HDLCDRV_BUILTIN -LX_OBJS += hdlcdrv.o +OX_OBJS += hdlcdrv.o else ifdef CONFIG_HDLCDRV_MODULE MX_OBJS += hdlcdrv.o diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index d72719e5c..d4191258d 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -3,7 +3,7 @@ /* * baycom_epp.c -- baycom epp radio modem driver. * - * Copyright (C) 1998 + * Copyright (C) 1998-1999 * Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,10 @@ * 0.2 21.04.98 Massive rework by Thomas Sailer * Integrated FPGA EPP modem configuration routines * 0.3 11.05.98 Took FPGA config out and moved it into a separate program + * 0.4 26.07.99 Adapted to new lowlevel parport driver interface + * 0.5 03.08.99 adapt to Linus' new __setup/__initcall + * removed some pre-2.2 kernel compatibility cruft + * 0.6 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts * */ @@ -38,25 +42,13 @@ #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> -#include <linux/types.h> -#include <linux/ptrace.h> -#include <linux/socket.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/in.h> +#include <linux/init.h> #include <linux/string.h> +#include <linux/tqueue.h> +#include <linux/fs.h> #include <linux/parport.h> -#include <linux/bitops.h> -#include <asm/system.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/netdevice.h> +#include <asm/uaccess.h> #include <linux/if_arp.h> -//#include <net/ax25dev.h> -#include <linux/kmod.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> #include <linux/soundmodem.h> @@ -70,56 +62,6 @@ /* --------------------------------------------------------------------- */ -/* - * currently this module is supposed to support both module styles, i.e. - * the old one present up to about 2.1.9, and the new one functioning - * starting with 2.1.21. The reason is I have a kit allowing to compile - * this module also under 2.0.x which was requested by several people. - * This will go in 2.2 - */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE >= 0x20100 -#include <asm/uaccess.h> -#else -#include <asm/segment.h> -#include <linux/mm.h> - -#undef put_user -#undef get_user - -#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; }) -#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; }) - -extern inline int copy_from_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_READ, from, n); - if (i) - return i; - memcpy_fromfs(to, from, n); - return 0; -} - -extern inline int copy_to_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_WRITE, to, n); - if (i) - return i; - memcpy_tofs(to, from, n); - return 0; -} -#endif - -#if LINUX_VERSION_CODE >= 0x20123 -#include <linux/init.h> -#else -#define __init -#define __initdata -#define __initfunc(x) x -#endif - -/* --------------------------------------------------------------------- */ - #define BAYCOM_DEBUG #define BAYCOM_MAGIC 19730510 @@ -147,19 +89,14 @@ static const char paranoia_str[] = KERN_ERR /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_epp"; -static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_epp: version 0.3 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-1999 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_epp: version 0.5 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; - -static struct { - const char *mode; - int iobase; -} baycom_ports[NR_PORTS] = { { NULL, 0 }, }; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -264,7 +201,8 @@ struct baycom_state { struct { unsigned int intclk; - unsigned int divider; + unsigned int fclk; + unsigned int bps; unsigned int extmodem; unsigned int loopback; } cfg; @@ -433,7 +371,7 @@ static void inline baycom_int_freq(struct baycom_state *bc) * eppconfig_path should be setable via /proc/sys. */ -char eppconfig_path[256] = "/sbin/eppfpga"; +static char eppconfig_path[256] = "/usr/sbin/eppfpga"; static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL }; @@ -448,9 +386,10 @@ static int exec_eppfpga(void *b) int i; /* set up arguments */ - sprintf(modearg, "%sclk,%smodem,divider=%d%s,extstat", + sprintf(modearg, "%sclk,%smodem,fclk=%d,bps=%d,divider=%d%s,extstat", bc->cfg.intclk ? "int" : "ext", - bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider, + bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps, + (bc->cfg.fclk + 8 * bc->cfg.bps) / (16 * bc->cfg.bps), bc->cfg.loopback ? ",loopback" : ""); sprintf(portarg, "%ld", bc->pdev->port->base); printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); @@ -655,10 +594,11 @@ static inline unsigned short random_num(void) /* ---------------------------------------------------------------------- */ -static void transmit(struct baycom_state *bc, int cnt, unsigned char stat) +static int transmit(struct baycom_state *bc, int cnt, unsigned char stat) { struct parport *pp = bc->pdev->port; - int i; + unsigned char tmp[128]; + int i, j; if (bc->hdlctx.state == tx_tail && !(stat & EPP_PTTBIT)) bc->hdlctx.state = tx_idle; @@ -666,17 +606,17 @@ static void transmit(struct baycom_state *bc, int cnt, unsigned char stat) if (bc->hdlctx.bufcnt <= 0) encode_hdlc(bc); if (bc->hdlctx.bufcnt <= 0) - return; + return 0; if (!bc->ch_params.fulldup) { if (!(stat & EPP_DCDBIT)) { bc->hdlctx.slotcnt = bc->ch_params.slottime; - return; + return 0; } if ((--bc->hdlctx.slotcnt) > 0) - return; + return 0; bc->hdlctx.slotcnt = bc->ch_params.slottime; if ((random_num() % 256) > bc->ch_params.ppersist) - return; + return 0; } } if (bc->hdlctx.state == tx_idle && bc->hdlctx.bufcnt > 0) { @@ -692,8 +632,13 @@ static void transmit(struct baycom_state *bc, int cnt, unsigned char stat) bc->hdlctx.flags -= i; if (bc->hdlctx.flags <= 0) bc->hdlctx.state = tx_data; - for (; i > 0; i--) - parport_epp_write_data(pp, 0x7e); + memset(tmp, 0x7e, sizeof(tmp)); + while (i > 0) { + j = (i > sizeof(tmp)) ? sizeof(tmp) : i; + if (j != pp->ops->epp_write_data(pp, tmp, j, 0)) + return -1; + i -= j; + } break; case tx_data: @@ -708,8 +653,9 @@ static void transmit(struct baycom_state *bc, int cnt, unsigned char stat) i = min(cnt, bc->hdlctx.bufcnt); bc->hdlctx.bufcnt -= i; cnt -= i; - for (; i > 0; i--) - parport_epp_write_data(pp, *(bc->hdlctx.bufptr)++); + if (i != pp->ops->epp_write_data(pp, bc->hdlctx.bufptr, i, 0)) + return -1; + bc->hdlctx.bufptr += i; break; case tx_tail: @@ -722,27 +668,38 @@ static void transmit(struct baycom_state *bc, int cnt, unsigned char stat) if (i) { cnt -= i; bc->hdlctx.flags -= i; - for (; i > 0; i--) - parport_epp_write_data(pp, 0x7e); + memset(tmp, 0x7e, sizeof(tmp)); + while (i > 0) { + j = (i > sizeof(tmp)) ? sizeof(tmp) : i; + if (j != pp->ops->epp_write_data(pp, tmp, j, 0)) + return -1; + i -= j; + } break; } default: /* fall through */ if (bc->hdlctx.calibrate <= 0) - return; + return 0; i = min(cnt, bc->hdlctx.calibrate); cnt -= i; bc->hdlctx.calibrate -= i; - for (; i > 0; i--) - parport_epp_write_data(pp, 0); + memset(tmp, 0, sizeof(tmp)); + while (i > 0) { + j = (i > sizeof(tmp)) ? sizeof(tmp) : i; + if (j != pp->ops->epp_write_data(pp, tmp, j, 0)) + return -1; + i -= j; + } break; } } + return 0; } /* ---------------------------------------------------------------------- */ -static void do_rxpacket(struct device *dev) +static void do_rxpacket(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct sk_buff *skb; @@ -800,57 +757,68 @@ static void do_rxpacket(struct device *dev) goto enditer##j; \ }) -static void receive(struct device *dev, int cnt) +static int receive(struct net_device *dev, int cnt) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct parport *pp = bc->pdev->port; unsigned int bitbuf, notbitstream, bitstream, numbits, state; - unsigned char ch; + unsigned char tmp[128]; + unsigned char *cp; + int cnt2, ret = 0; numbits = bc->hdlcrx.numbits; state = bc->hdlcrx.state; bitstream = bc->hdlcrx.bitstream; bitbuf = bc->hdlcrx.bitbuf; - for (; cnt > 0; cnt--) { - ch = parport_epp_read_data(pp); - bitstream >>= 8; - bitstream |= ch << 8; - bitbuf >>= 8; - bitbuf |= ch << 8; - numbits += 8; - notbitstream = ~bitstream; - DECODEITERA(0); - DECODEITERA(1); - DECODEITERA(2); - DECODEITERA(3); - DECODEITERA(4); - DECODEITERA(5); - DECODEITERA(6); - DECODEITERA(7); - goto enddec; - DECODEITERB(0); - DECODEITERB(1); - DECODEITERB(2); - DECODEITERB(3); - DECODEITERB(4); - DECODEITERB(5); - DECODEITERB(6); - DECODEITERB(7); - enddec: - while (state && numbits >= 8) { - if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { - state = 0; - } else { - *(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits); - bc->hdlcrx.bufcnt++; - numbits -= 8; + while (cnt > 0) { + cnt2 = (cnt > sizeof(tmp)) ? sizeof(tmp) : cnt; + cnt -= cnt2; + if (cnt2 != pp->ops->epp_read_data(pp, tmp, cnt2, 0)) { + ret = -1; + break; + } + cp = tmp; + for (; cnt2 > 0; cnt2--, cp++) { + bitstream >>= 8; + bitstream |= (*cp) << 8; + bitbuf >>= 8; + bitbuf |= (*cp) << 8; + numbits += 8; + notbitstream = ~bitstream; + DECODEITERA(0); + DECODEITERA(1); + DECODEITERA(2); + DECODEITERA(3); + DECODEITERA(4); + DECODEITERA(5); + DECODEITERA(6); + DECODEITERA(7); + goto enddec; + DECODEITERB(0); + DECODEITERB(1); + DECODEITERB(2); + DECODEITERB(3); + DECODEITERB(4); + DECODEITERB(5); + DECODEITERB(6); + DECODEITERB(7); + enddec: + while (state && numbits >= 8) { + if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { + state = 0; + } else { + *(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits); + bc->hdlcrx.bufcnt++; + numbits -= 8; + } } } - } + } bc->hdlcrx.numbits = numbits; bc->hdlcrx.state = state; bc->hdlcrx.bitstream = bitstream; bc->hdlcrx.bitbuf = bitbuf; + return ret; } /* --------------------------------------------------------------------- */ @@ -865,11 +833,12 @@ static void receive(struct device *dev, int cnt) #define GETTICK(x) #endif /* __i386__ */ -static void epp_bh(struct device *dev) +static void epp_bh(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; unsigned char stat; + unsigned char tmp[2]; unsigned int time1 = 0, time2 = 0, time3 = 0; int cnt, cnt2; @@ -880,26 +849,40 @@ static void epp_bh(struct device *dev) baycom_int_freq(bc); pp = bc->pdev->port; /* update status */ - bc->stat = stat = parport_epp_read_addr(pp); + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) + goto epptimeout; + bc->stat = stat; bc->debug_vals.last_pllcorr = stat; GETTICK(time1); if (bc->modem == EPP_FPGAEXTSTATUS) { /* get input count */ - parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1); - cnt = parport_epp_read_addr(pp); - cnt |= parport_epp_read_addr(pp) << 8; + tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1; + if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1) + goto epptimeout; + if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2) + goto epptimeout; + cnt = tmp[0] | (tmp[1] << 8); cnt &= 0x7fff; /* get output count */ - parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2); - cnt2 = parport_epp_read_addr(pp); - cnt2 |= parport_epp_read_addr(pp) << 8; + tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2; + if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1) + goto epptimeout; + if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2) + goto epptimeout; + cnt2 = tmp[0] | (tmp[1] << 8); cnt2 = 16384 - (cnt2 & 0x7fff); /* return to normal */ - parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE); - transmit(bc, cnt2, stat); + tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE; + if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1) + goto epptimeout; + if (transmit(bc, cnt2, stat)) + goto epptimeout; GETTICK(time2); - receive(dev, cnt); - bc->stat = stat = parport_epp_read_addr(pp); + if (receive(dev, cnt)) + goto epptimeout; + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) + goto epptimeout; + bc->stat = stat; } else { /* try to tx */ switch (stat & (EPP_NTAEF|EPP_NTHF)) { @@ -919,7 +902,8 @@ static void epp_bh(struct device *dev) cnt = 2048 - 1025; break; } - transmit(bc, cnt, stat); + if (transmit(bc, cnt, stat)) + goto epptimeout; GETTICK(time2); /* do receiver */ while ((stat & (EPP_NRAEF|EPP_NRHF)) != EPP_NRHF) { @@ -936,9 +920,9 @@ static void epp_bh(struct device *dev) cnt = 256; break; } - receive(dev, cnt); - stat = parport_epp_read_addr(pp); - if (parport_epp_check_timeout(pp)) + if (receive(dev, cnt)) + goto epptimeout; + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) goto epptimeout; } cnt = 0; @@ -947,9 +931,11 @@ static void epp_bh(struct device *dev) else if (bc->bitrate < 100000) cnt = 128; while (cnt > 0 && stat & EPP_NREF) { - receive(dev, 1); + if (receive(dev, 1)) + goto epptimeout; cnt--; - stat = parport_epp_read_addr(pp); + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) + goto epptimeout; } } GETTICK(time3); @@ -957,8 +943,6 @@ static void epp_bh(struct device *dev) bc->debug_vals.mod_cycles = time2 - time1; bc->debug_vals.demod_cycles = time3 - time2; #endif /* BAYCOM_DEBUG */ - if (parport_epp_check_timeout(pp)) - goto epptimeout; queue_task(&bc->run_bh, &tq_timer); return; epptimeout: @@ -970,7 +954,7 @@ static void epp_bh(struct device *dev) * ===================== network driver interface ========================= */ -static int baycom_send_packet(struct sk_buff *skb, struct device *dev) +static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) { struct baycom_state *bc; @@ -983,7 +967,7 @@ static int baycom_send_packet(struct sk_buff *skb, struct device *dev) /* --------------------------------------------------------------------- */ -static int baycom_set_mac_address(struct device *dev, void *addr) +static int baycom_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -994,7 +978,7 @@ static int baycom_set_mac_address(struct device *dev, void *addr) /* --------------------------------------------------------------------- */ -static struct net_device_stats *baycom_get_stats(struct device *dev) +static struct net_device_stats *baycom_get_stats(struct net_device *dev) { struct baycom_state *bc; @@ -1011,7 +995,7 @@ static struct net_device_stats *baycom_get_stats(struct device *dev) static void epp_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct baycom_state *bc; baycom_paranoia_check_void(dev, "epp_wakeup"); @@ -1032,7 +1016,7 @@ static void epp_wakeup(void *handle) * there is non-reboot way to recover if something goes wrong. */ -static int epp_open(struct device *dev) +static int epp_open(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; @@ -1040,6 +1024,7 @@ static int epp_open(struct device *dev) 0, 0, (void *)(void *)epp_bh, dev }; unsigned int i, j; + unsigned char tmp[128]; unsigned char stat; unsigned long tstart; @@ -1060,6 +1045,11 @@ static int epp_open(struct device *dev) return -ENXIO; } #endif + if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) { + printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n", + bc_drvname, pp->base); + return -EIO; + } memset(&bc->modem, 0, sizeof(bc->modem)); if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, epp_interrupt, PARPORT_DEV_EXCL, dev))) { @@ -1071,21 +1061,9 @@ static int epp_open(struct device *dev) parport_unregister_device(bc->pdev); return -EBUSY; } - if (!(pp->modes & (PARPORT_MODE_PCECPEPP|PARPORT_MODE_PCEPP))) { - printk(KERN_ERR "%s: parport at 0x%lx does not support any EPP mode\n", - bc_drvname, pp->base); - parport_release(bc->pdev); - parport_unregister_device(bc->pdev); - return -EIO; - } dev->irq = /*pp->irq*/ 0; bc->run_bh = run_bh; bc->bh_running = 1; - if (pp->modes & PARPORT_MODE_PCECPEPP) { - printk(KERN_INFO "%s: trying to enable EPP mode\n", bc_drvname); - parport_frob_econtrol(pp, 0xe0, 0x80); - } - /* bc->pdev->port->ops->change_mode(bc->pdev->port, PARPORT_MODE_PCEPP); not yet implemented */ bc->modem = EPP_CONVENTIONAL; if (eppconfig(bc)) printk(KERN_INFO "%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname); @@ -1093,26 +1071,33 @@ static int epp_open(struct device *dev) bc->modem = /*EPP_FPGA*/ EPP_FPGAEXTSTATUS; parport_write_control(pp, LPTCTRL_PROGRAM); /* prepare EPP mode; we aren't using interrupts */ /* reset the modem */ - parport_epp_write_addr(pp, 0); - parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE); + tmp[0] = 0; + tmp[1] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE; + if (pp->ops->epp_write_addr(pp, tmp, 2, 0) != 2) + goto epptimeout; /* autoprobe baud rate */ tstart = jiffies; i = 0; while ((signed)(jiffies-tstart-HZ/3) < 0) { - stat = parport_epp_read_addr(pp); + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) + goto epptimeout; if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) { schedule(); continue; } - for (j = 0; j < 256; j++) - parport_epp_read_data(pp); + if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128) + goto epptimeout; + if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128) + goto epptimeout; i += 256; } for (j = 0; j < 256; j++) { - stat = parport_epp_read_addr(pp); + if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) + goto epptimeout; if (!(stat & EPP_NREF)) break; - parport_epp_read_data(pp); + if (pp->ops->epp_read_data(pp, tmp, 1, 0) != 1) + goto epptimeout; i++; } tstart = jiffies - tstart; @@ -1125,7 +1110,9 @@ static int epp_open(struct device *dev) } printk(KERN_INFO "%s: autoprobed bitrate: %d int divider: %d int rate: %d\n", bc_drvname, bc->bitrate, j, bc->bitrate >> (j+2)); - parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/); + tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/; + if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1) + goto epptimeout; /* * initialise hdlc variables */ @@ -1143,21 +1130,22 @@ static int epp_open(struct device *dev) MOD_INC_USE_COUNT; return 0; -#if 0 - errreturn: + epptimeout: + printk(KERN_ERR "%s: epp timeout during bitrate probe\n", bc_drvname); + parport_write_control(pp, 0); /* reset the adapter */ parport_release(bc->pdev); parport_unregister_device(bc->pdev); return -EIO; -#endif } /* --------------------------------------------------------------------- */ -static int epp_close(struct device *dev) +static int epp_close(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; struct sk_buff *skb; + unsigned char tmp[1]; baycom_paranoia_check(dev, "epp_close", -EINVAL); if (!dev->start) @@ -1169,7 +1157,8 @@ static int epp_close(struct device *dev) dev->tbusy = 1; run_task_queue(&tq_timer); /* dequeue bottom half */ bc->stat = EPP_DCDBIT; - parport_epp_write_addr(pp, 0); + tmp[0] = 0; + pp->ops->epp_write_addr(pp, tmp, 1, 0); parport_write_control(pp, 0); /* reset the adapter */ parport_release(bc->pdev); parport_unregister_device(bc->pdev); @@ -1200,19 +1189,26 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr) bc->cfg.loopback = 0; if (strstr(modestr,"loopback")) bc->cfg.loopback = 1; - if ((cp = strstr(modestr,"divider="))) { - bc->cfg.divider = simple_strtoul(cp+8, NULL, 0); - if (bc->cfg.divider < 1) - bc->cfg.divider = 1; - if (bc->cfg.divider > 1023) - bc->cfg.divider = 1023; + if ((cp = strstr(modestr,"fclk="))) { + bc->cfg.fclk = simple_strtoul(cp+5, NULL, 0); + if (bc->cfg.fclk < 1000000) + bc->cfg.fclk = 1000000; + if (bc->cfg.fclk > 25000000) + bc->cfg.fclk = 25000000; + } + if ((cp = strstr(modestr,"bps="))) { + bc->cfg.bps = simple_strtoul(cp+4, NULL, 0); + if (bc->cfg.bps < 1000) + bc->cfg.bps = 1000; + if (bc->cfg.bps > 1500000) + bc->cfg.bps = 1500000; } return 0; } /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct baycom_state *bc; struct baycom_ioctl bi; @@ -1316,9 +1312,9 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd) break; case HDLCDRVCTL_GETMODE: - sprintf(hi.data.modename, "%sclk,%smodem,divider=%d%s", + sprintf(hi.data.modename, "%sclk,%smodem,fclk=%d,bps=%d%s", bc->cfg.intclk ? "int" : "ext", - bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider, + bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps, bc->cfg.loopback ? ",loopback" : ""); break; @@ -1351,7 +1347,7 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd) * If dev->base_addr == 2, allocate space for the device and return success * (detachable devices only). */ -static int baycom_probe(struct device *dev) +static int baycom_probe(struct net_device *dev) { static char ax25_bcast[AX25_ADDR_LEN] = { 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1 @@ -1415,9 +1411,25 @@ static int baycom_probe(struct device *dev) /* --------------------------------------------------------------------- */ -__initfunc(int baycom_epp_init(void)) +/* + * command line settable parameters + */ +static const char *mode[NR_PORTS] = { "", }; +static int iobase[NR_PORTS] = { 0x378, }; + +MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +MODULE_PARM_DESC(mode, "baycom operating mode"); +MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(iobase, "baycom io base address"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("Baycom epp amateur radio modem driver"); + +/* --------------------------------------------------------------------- */ + +static int __init init_baycomepp(void) { - struct device *dev; + struct net_device *dev; int i, found = 0; char set_hw = 1; struct baycom_state *bc; @@ -1428,11 +1440,11 @@ __initfunc(int baycom_epp_init(void)) */ for (i = 0; i < NR_PORTS; i++) { dev = baycom_device+i; - if (!baycom_ports[i].mode) + if (!mode[i]) set_hw = 0; if (!set_hw) - baycom_ports[i].iobase = 0; - memset(dev, 0, sizeof(struct device)); + iobase[i] = 0; + memset(dev, 0, sizeof(struct net_device)); if (!(bc = dev->priv = kmalloc(sizeof(struct baycom_state), GFP_KERNEL))) return -ENOMEM; /* @@ -1441,6 +1453,8 @@ __initfunc(int baycom_epp_init(void)) memset(bc, 0, sizeof(struct baycom_state)); bc->magic = BAYCOM_MAGIC; sprintf(bc->ifname, "bce%d", i); + bc->cfg.fclk = 19666600; + bc->cfg.bps = 9600; /* * initialize part of the device struct */ @@ -1449,7 +1463,7 @@ __initfunc(int baycom_epp_init(void)) dev->init = baycom_probe; dev->start = 0; dev->tbusy = 1; - dev->base_addr = baycom_ports[i].iobase; + dev->base_addr = iobase[i]; dev->irq = 0; dev->dma = 0; if (register_netdev(dev)) { @@ -1457,7 +1471,7 @@ __initfunc(int baycom_epp_init(void)) kfree(dev->priv); return -ENXIO; } - if (set_hw && baycom_setmode(bc, baycom_ports[i].mode)) + if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; found++; } @@ -1466,46 +1480,9 @@ __initfunc(int baycom_epp_init(void)) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -/* - * command line settable parameters - */ -static const char *mode[NR_PORTS] = { "epp", }; -static int iobase[NR_PORTS] = { 0x378, }; - -#if LINUX_VERSION_CODE >= 0x20115 - -MODULE_PARM(mode, "s"); -MODULE_PARM_DESC(mode, "baycom operating mode; epp"); -MODULE_PARM(iobase, "i"); -MODULE_PARM_DESC(iobase, "baycom io base address"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("Baycom epp amateur radio modem driver"); - -#endif - -__initfunc(int init_module(void)) -{ - int i; - - for (i = 0; (i < NR_PORTS) && (mode[i]); i++) { - baycom_ports[i].mode = mode[i]; - baycom_ports[i].iobase = iobase[i]; - } - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; - return baycom_epp_init(); -} - -/* --------------------------------------------------------------------- */ - -void cleanup_module(void) +static void __exit cleanup_baycomepp(void) { - struct device *dev; + struct net_device *dev; struct baycom_state *bc; int i; @@ -1522,28 +1499,35 @@ void cleanup_module(void) } } -#else /* MODULE */ +module_init(init_baycomepp); +module_exit(cleanup_baycomepp); + /* --------------------------------------------------------------------- */ + +#ifndef MODULE + /* - * format: baycom=io,mode - * mode: epp + * format: baycom_epp=io,mode + * mode: fpga config options */ -__initfunc(void baycom_epp_setup(char *str, int *ints)) +static int __init baycom_epp_setup(char *str) { - int i; + static unsigned __initdata nr_dev = 0; + int ints[2]; - for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++); - if ((i >= NR_PORTS) || (ints[0] < 1)) { - printk(KERN_INFO "%s: too many or invalid interface " - "specifications\n", bc_drvname); - return; - } - baycom_ports[i].mode = str; - baycom_ports[i].iobase = ints[1]; - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; + if (nr_dev >= NR_PORTS) + return 0; + str = get_options(str, 2, ints); + if (ints[0] < 1) + return 0; + mode[nr_dev] = str; + iobase[nr_dev] = ints[1]; + nr_dev++; + return 1; } +__setup("baycom_epp=", baycom_epp_setup); + #endif /* MODULE */ /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index afaed1432..9ba70b255 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c @@ -3,7 +3,7 @@ /* * baycom_par.c -- baycom par96 and picpar radio modem driver. * - * Copyright (C) 1997 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,10 +58,14 @@ * 0.3 26.04.97 init code/data tagged * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints) * 0.5 11.11.97 split into separate files for ser12/par96 + * 0.6 03.08.99 adapt to Linus' new __setup/__initcall + * removed some pre-2.2 kernel compatibility cruft + * 0.7 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts */ /*****************************************************************************/ +#include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -74,6 +78,8 @@ #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> +#include <asm/uaccess.h> +#include <linux/init.h> #include <linux/delay.h> #include <linux/errno.h> #include <linux/netdevice.h> @@ -83,56 +89,6 @@ /* --------------------------------------------------------------------- */ -/* - * currently this module is supposed to support both module styles, i.e. - * the old one present up to about 2.1.9, and the new one functioning - * starting with 2.1.21. The reason is I have a kit allowing to compile - * this module also under 2.0.x which was requested by several people. - * This will go in 2.2 - */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE >= 0x20100 -#include <asm/uaccess.h> -#else -#include <asm/segment.h> -#include <linux/mm.h> - -#undef put_user -#undef get_user - -#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; }) -#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; }) - -extern __inline__ int copy_from_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_READ, from, n); - if (i) - return i; - memcpy_fromfs(to, from, n); - return 0; -} - -extern __inline__ int copy_to_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_WRITE, to, n); - if (i) - return i; - memcpy_tofs(to, from, n); - return 0; -} -#endif - -#if LINUX_VERSION_CODE >= 0x20123 -#include <linux/init.h> -#else -#define __init -#define __initdata -#define __initfunc(x) x -#endif - -/* --------------------------------------------------------------------- */ - #define BAYCOM_DEBUG /* @@ -143,19 +99,14 @@ extern __inline__ int copy_to_user(void *to, const void *from, unsigned long n) /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_par"; -static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1997 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_par: version 0.5 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_par: version 0.6 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; - -static struct { - const char *mode; - int iobase; -} baycom_ports[NR_PORTS] = { { NULL, 0 }, }; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -252,7 +203,7 @@ static void __inline__ baycom_int_freq(struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static __inline__ void par96_tx(struct device *dev, struct baycom_state *bc) +static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data = hdlcdrv_getbits(&bc->hdrv); @@ -275,7 +226,7 @@ static __inline__ void par96_tx(struct device *dev, struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static __inline__ void par96_rx(struct device *dev, struct baycom_state *bc) +static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data, mask, mask2, descx; @@ -329,7 +280,7 @@ static __inline__ void par96_rx(struct device *dev, struct baycom_state *bc) static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC) @@ -359,7 +310,7 @@ static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) static void par96_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct baycom_state *bc = (struct baycom_state *)dev->priv; printk(KERN_DEBUG "baycom_par: %s: why am I being woken up?\n", dev->name); @@ -369,7 +320,7 @@ static void par96_wakeup(void *handle) /* --------------------------------------------------------------------- */ -static int par96_open(struct device *dev) +static int par96_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct parport *pp = parport_enumerate(); @@ -386,6 +337,10 @@ static int par96_open(struct device *dev) printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base); return -ENXIO; } + if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) { + printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base); + return -ENXIO; + } memset(&bc->modem, 0, sizeof(bc->modem)); bc->hdrv.par.bitrate = 9600; if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, @@ -413,7 +368,7 @@ static int par96_open(struct device *dev) /* --------------------------------------------------------------------- */ -static int par96_close(struct device *dev) +static int par96_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -437,7 +392,7 @@ static int par96_close(struct device *dev) * ===================== hdlcdrv driver interface ========================= */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -465,7 +420,7 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr) /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -533,32 +488,46 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, /* --------------------------------------------------------------------- */ -int __init baycom_par_init(void) +/* + * command line settable parameters + */ +static const char *mode[NR_PORTS] = { "picpar", }; +static int iobase[NR_PORTS] = { 0x378, }; + +MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar"); +MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(iobase, "baycom io base address"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("Baycom par96 and picpar amateur radio modem driver"); + +/* --------------------------------------------------------------------- */ + +static int __init init_baycompar(void) { int i, j, found = 0; char set_hw = 1; struct baycom_state *bc; char ifname[HDLCDRV_IFNAMELEN]; - printk(bc_drvinfo); /* * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcp%d", i); - if (!baycom_ports[i].mode) + if (!mode[i]) set_hw = 0; if (!set_hw) - baycom_ports[i].iobase = 0; - j = hdlcdrv_register_hdlcdrv(dev, &par96_ops, - sizeof(struct baycom_state), - ifname, baycom_ports[i].iobase, 0, 0); + iobase[i] = 0; + j = hdlcdrv_register_hdlcdrv(dev, &par96_ops, sizeof(struct baycom_state), + ifname, iobase[i], 0, 0); if (!j) { bc = (struct baycom_state *)dev->priv; - if (set_hw && baycom_setmode(bc, baycom_ports[i].mode)) + if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; found++; } else { @@ -571,49 +540,12 @@ int __init baycom_par_init(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -/* - * command line settable parameters - */ -static const char *mode[NR_PORTS] = { "picpar", }; -static int iobase[NR_PORTS] = { 0x378, }; - -#if LINUX_VERSION_CODE >= 0x20115 - -MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); -MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar"); -MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(iobase, "baycom io base address"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("Baycom par96 and picpar amateur radio modem driver"); - -#endif - -int __init init_module(void) -{ - int i; - - for (i = 0; (i < NR_PORTS) && (mode[i]); i++) { - baycom_ports[i].mode = mode[i]; - baycom_ports[i].iobase = iobase[i]; - } - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; - return baycom_par_init(); -} - -/* --------------------------------------------------------------------- */ - -void cleanup_module(void) +static void __exit cleanup_baycompar(void) { int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { @@ -626,28 +558,35 @@ void cleanup_module(void) } } -#else /* MODULE */ +module_init(init_baycompar); +module_exit(cleanup_baycompar); + /* --------------------------------------------------------------------- */ + +#ifndef MODULE + /* * format: baycom_par=io,mode * mode: par96,picpar */ -void __init baycom_par_setup(char *str, int *ints) +static int __init baycom_par_setup(char *str) { - int i; - - for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++); - if ((i >= NR_PORTS) || (ints[0] < 1)) { - printk(KERN_INFO "%s: too many or invalid interface " - "specifications\n", bc_drvname); - return; - } - baycom_ports[i].mode = str; - baycom_ports[i].iobase = ints[1]; - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; + static unsigned __initdata nr_dev = 0; + int ints[2]; + + if (nr_dev >= NR_PORTS) + return 0; + str = get_options(str, 2, ints); + if (ints[0] < 1) + return 0; + mode[nr_dev] = str; + iobase[nr_dev] = ints[1]; + nr_dev++; + return 1; } +__setup("baycom_par=", baycom_par_setup); + #endif /* MODULE */ /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 216855a4c..9c6e69cf6 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -3,7 +3,7 @@ /* * baycom_ser_fdx.c -- baycom ser12 fullduplex radio modem driver. * - * Copyright (C) 1997-1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,7 +45,10 @@ * * Command line options (insmod command line) * - * mode * enables software DCD. + * mode ser# hardware DCD + * ser#* software DCD + * ser#+ hardware DCD, inverted signal at DCD pin + * '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD' * iobase base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8 * baud baud rate (between 300 and 4800) * irq interrupt line of the port; common values are 4,3 @@ -60,56 +63,37 @@ * 0.6 24.01.98 Thorsten Kranzkowski, dl8bcu and Thomas Sailer: * reduced interrupt load in transmit case * reworked receiver + * 0.7 03.08.99 adapt to Linus' new __setup/__initcall + * 0.8 10.08.99 use module_init/module_exit */ /*****************************************************************************/ +#include <linux/version.h> #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/interrupt.h> #include <linux/ioport.h> -#include <linux/in.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/bitops.h> #include <asm/uaccess.h> -#include <asm/system.h> #include <asm/io.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/netdevice.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> -#include <linux/version.h> /* --------------------------------------------------------------------- */ #define BAYCOM_DEBUG -/* - * modem options; bit mask - */ -#define BAYCOM_OPTIONS_SOFTDCD 1 - /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_ser_fdx"; -static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1997-1998 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_ser_fdx: version 0.6 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_ser_fdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; - -static struct { - char *mode; - int iobase, irq, baud; -} baycom_ports[NR_PORTS] = { { NULL, 0, 0 }, }; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -137,7 +121,7 @@ struct baycom_state { struct hdlcdrv_state hdrv; unsigned int baud, baud_us, baud_arbdiv, baud_uartdiv, baud_dcdtimeout; - unsigned int options; + int opt_dcd; struct modem_state { unsigned char flags; @@ -196,7 +180,7 @@ static void inline baycom_int_freq(struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static inline void ser12_set_divisor(struct device *dev, +static inline void ser12_set_divisor(struct net_device *dev, unsigned int divisor) { outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */ @@ -243,7 +227,7 @@ extern inline unsigned int hweight8(unsigned int w) /* --------------------------------------------------------------------- */ -static __inline__ void ser12_rx(struct device *dev, struct baycom_state *bc, struct timeval *tv, unsigned char curs) +static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc, struct timeval *tv, unsigned char curs) { int timediff; int bdus8 = bc->baud_us >> 3; @@ -266,7 +250,7 @@ static __inline__ void ser12_rx(struct device *dev, struct baycom_state *bc, str bc->modem.shreg >>= 1; } if (bc->modem.ser12.dcd_time <= 0) { - if (bc->options & BAYCOM_OPTIONS_SOFTDCD) + if (!bc->opt_dcd) hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + bc->modem.ser12.dcd_sum1 + bc->modem.ser12.dcd_sum2) < 0); @@ -300,7 +284,7 @@ static __inline__ void ser12_rx(struct device *dev, struct baycom_state *bc, str static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; struct timeval tv; unsigned char iir, msr; @@ -315,8 +299,8 @@ static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) do_gettimeofday(&tv); msr = inb(MSR(dev->base_addr)); /* delta DCD */ - if ((msr & 8) && !(bc->options & BAYCOM_OPTIONS_SOFTDCD)) - hdlcdrv_setdcd(&bc->hdrv, !(msr & 0x80)); + if ((msr & 8) && bc->opt_dcd) + hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80)); do { switch (iir & 6) { case 6: @@ -349,8 +333,8 @@ static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) default: msr = inb(MSR(dev->base_addr)); /* delta DCD */ - if ((msr & 8) && !(bc->options & BAYCOM_OPTIONS_SOFTDCD)) - hdlcdrv_setdcd(&bc->hdrv, !(msr & 0x80)); + if ((msr & 8) && bc->opt_dcd) + hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80)); break; } iir = inb(IIR(dev->base_addr)); @@ -424,7 +408,7 @@ static enum uart ser12_check_uart(unsigned int iobase) /* --------------------------------------------------------------------- */ -static int ser12_open(struct device *dev) +static int ser12_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; enum uart u; @@ -470,16 +454,15 @@ static int ser12_open(struct device *dev) */ outb(0x00, THR(dev->base_addr)); hdlcdrv_setdcd(&bc->hdrv, 0); - printk(KERN_INFO "%s: ser_fdx at iobase 0x%lx irq %u options " - "0x%x baud %u uart %s\n", bc_drvname, dev->base_addr, dev->irq, - bc->options, bc->baud, uart_str[u]); + printk(KERN_INFO "%s: ser_fdx at iobase 0x%lx irq %u baud %u uart %s\n", + bc_drvname, dev->base_addr, dev->irq, bc->baud, uart_str[u]); MOD_INC_USE_COUNT; return 0; } /* --------------------------------------------------------------------- */ -static int ser12_close(struct device *dev) +static int ser12_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -505,7 +488,7 @@ static int ser12_close(struct device *dev) /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -529,13 +512,18 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr) if (baud >= 3 && baud <= 48) bc->baud = baud*100; } - bc->options = !!strchr(modestr, '*'); + if (strchr(modestr, '*')) + bc->opt_dcd = 0; + else if (strchr(modestr, '+')) + bc->opt_dcd = -1; + else + bc->opt_dcd = 1; return 0; } /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -559,8 +547,8 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, case HDLCDRVCTL_GETMODE: sprintf(hi->data.modename, "ser%u", bc->baud / 100); - if (bc->options & 1) - strcat(hi->data.modename, "*"); + if (bc->opt_dcd <= 0) + strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : "+"); if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) return -EFAULT; return 0; @@ -605,7 +593,29 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, /* --------------------------------------------------------------------- */ -int __init baycom_ser_fdx_init(void) +/* + * command line settable parameters + */ +static char *mode[NR_PORTS] = { "ser12*", }; +static int iobase[NR_PORTS] = { 0x3f8, }; +static int irq[NR_PORTS] = { 4, }; +static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 }; + +MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD"); +MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(iobase, "baycom io base address"); +MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(irq, "baycom irq number"); +MODULE_PARM(baud, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("Baycom ser12 full duplex amateur radio modem driver"); + +/* --------------------------------------------------------------------- */ + +static int __init init_baycomserfdx(void) { int i, j, found = 0; char set_hw = 1; @@ -618,22 +628,20 @@ int __init baycom_ser_fdx_init(void) * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcsf%d", i); - if (!baycom_ports[i].mode) + if (!mode[i]) set_hw = 0; if (!set_hw) - baycom_ports[i].iobase = baycom_ports[i].irq = 0; - j = hdlcdrv_register_hdlcdrv(dev, &ser12_ops, - sizeof(struct baycom_state), - ifname, baycom_ports[i].iobase, - baycom_ports[i].irq, 0); + iobase[i] = irq[i] = 0; + j = hdlcdrv_register_hdlcdrv(dev, &ser12_ops, sizeof(struct baycom_state), + ifname, iobase[i], irq[i], 0); if (!j) { bc = (struct baycom_state *)dev->priv; - if (set_hw && baycom_setmode(bc, baycom_ports[i].mode)) + if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; - bc->baud = baycom_ports[i].baud; + bc->baud = baud[i]; found++; } else { printk(KERN_WARNING "%s: cannot register net device\n", @@ -645,57 +653,12 @@ int __init baycom_ser_fdx_init(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -/* - * command line settable parameters - */ -static char *mode[NR_PORTS] = { "ser12*", }; -static int iobase[NR_PORTS] = { 0x3f8, }; -static int irq[NR_PORTS] = { 4, }; -static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 }; - -#if LINUX_VERSION_CODE >= 0x20115 - -MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); -MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD"); -MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(iobase, "baycom io base address"); -MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(irq, "baycom irq number"); -MODULE_PARM(baud, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("Baycom ser12 full duplex amateur radio modem driver"); - -#endif - -int __init init_module(void) -{ - int i; - - for (i = 0; (i < NR_PORTS) && (mode[i]); i++) { - baycom_ports[i].mode = mode[i]; - baycom_ports[i].iobase = iobase[i]; - baycom_ports[i].irq = irq[i]; - baycom_ports[i].baud = baud[i]; - } - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; - return baycom_ser_fdx_init(); -} - -/* --------------------------------------------------------------------- */ - -void cleanup_module(void) +static void __exit cleanup_baycomserfdx(void) { int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { @@ -708,34 +671,41 @@ void cleanup_module(void) } } -#else /* MODULE */ +module_init(init_baycomserfdx); +module_exit(cleanup_baycomserfdx); + /* --------------------------------------------------------------------- */ + +#ifndef MODULE + /* * format: baycom_ser_fdx=io,irq,mode - * mode: [*] - * * indicates sofware DCD + * mode: ser# hardware DCD + * ser#* software DCD + * ser#+ hardware DCD, inverted signal at DCD pin + * '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD' */ -void __init baycom_ser_fdx_setup(char *str, int *ints) +static int __init baycom_ser_fdx_setup(char *str) { - int i; - - for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++); - if ((i >= NR_PORTS) || (ints[0] < 2)) { - printk(KERN_INFO "%s: too many or invalid interface " - "specifications\n", bc_drvname); - return; - } - baycom_ports[i].mode = str; - baycom_ports[i].iobase = ints[1]; - baycom_ports[i].irq = ints[2]; + static unsigned nr_dev = 0; + int ints[4]; + + if (nr_dev >= NR_PORTS) + return 0; + str = get_options(str, 4, ints); + if (ints[0] < 2) + return 0; + mode[nr_dev] = str; + iobase[nr_dev] = ints[1]; + irq[nr_dev] = ints[2]; if (ints[0] >= 3) - baycom_ports[i].baud = ints[3]; - else - baycom_ports[i].baud = 1200; - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; + baud[nr_dev] = ints[3]; + nr_dev++; + return 1; } +__setup("baycom_ser_fdx=", baycom_ser_fdx_setup); + #endif /* MODULE */ /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index 20681a134..c44395f84 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c @@ -3,7 +3,7 @@ /* * baycom_ser_hdx.c -- baycom ser12 halfduplex radio modem driver. * - * Copyright (C) 1997 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +37,11 @@ * * Command line options (insmod command line) * - * mode * enables software DCD. + * mode ser12 hardware DCD + * ser12* software DCD + * ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware + * mutes audio input to the modem + * ser12+ hardware DCD, inverted signal at DCD pin * iobase base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8 * irq interrupt line of the port; common values are 4,3 * @@ -49,56 +53,37 @@ * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints) * 0.5 11.11.97 ser12/par96 split into separate files * 0.6 14.04.98 cleanups + * 0.7 03.08.99 adapt to Linus' new __setup/__initcall + * 0.8 10.08.99 use module_init/module_exit */ /*****************************************************************************/ +#include <linux/version.h> #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/interrupt.h> #include <linux/ioport.h> -#include <linux/in.h> #include <linux/string.h> #include <linux/init.h> #include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/bitops.h> #include <asm/io.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/netdevice.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> -#include <linux/version.h> /* --------------------------------------------------------------------- */ #define BAYCOM_DEBUG -/* - * modem options; bit mask - */ -#define BAYCOM_OPTIONS_SOFTDCD 1 - /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_ser_hdx"; -static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1997-1998 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_ser_hdx: version 0.6 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_ser_hdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; - -static struct { - char *mode; - int iobase, irq; -} baycom_ports[NR_PORTS] = { { NULL, 0, 0 }, }; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -125,7 +110,7 @@ static struct { struct baycom_state { struct hdlcdrv_state hdrv; - unsigned int options; + int opt_dcd; struct modem_state { short arb_divider; @@ -184,7 +169,7 @@ static void inline baycom_int_freq(struct baycom_state *bc) * ===================== SER12 specific routines ========================= */ -static void inline ser12_set_divisor(struct device *dev, +static void inline ser12_set_divisor(struct net_device *dev, unsigned char divisor) { outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */ @@ -210,12 +195,11 @@ static void inline ser12_set_divisor(struct device *dev, /* * must call the TX arbitrator every 10ms */ -#define SER12_ARB_DIVIDER(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \ - 36 : 24) -#define SER12_DCD_INTERVAL(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \ - 240 : 12) +#define SER12_ARB_DIVIDER(bc) (bc->opt_dcd ? 24 : 36) + +#define SER12_DCD_INTERVAL(bc) (bc->opt_dcd ? 12 : 240) -static inline void ser12_tx(struct device *dev, struct baycom_state *bc) +static inline void ser12_tx(struct net_device *dev, struct baycom_state *bc) { /* one interrupt per channel bit */ ser12_set_divisor(dev, 12); @@ -233,7 +217,7 @@ static inline void ser12_tx(struct device *dev, struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static inline void ser12_rx(struct device *dev, struct baycom_state *bc) +static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc) { unsigned char cur_s; /* @@ -245,7 +229,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc) (cur_s != bc->modem.ser12.last_sample); bc->modem.ser12.last_sample = cur_s; if(bc->modem.ser12.dcd_shreg & 1) { - if (bc->options & BAYCOM_OPTIONS_SOFTDCD) { + if (!bc->opt_dcd) { unsigned int dcdspos, dcdsneg; dcdspos = dcdsneg = 0; @@ -271,7 +255,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc) bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc); } bc->modem.ser12.dcd_time--; - if (bc->options & BAYCOM_OPTIONS_SOFTDCD) { + if (!bc->opt_dcd) { /* * PLL code for the improved software DCD algorithm */ @@ -375,9 +359,12 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc) bc->modem.shreg = 0x10000; } if(!bc->modem.ser12.dcd_time) { - hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + - bc->modem.ser12.dcd_sum1 + - bc->modem.ser12.dcd_sum2) < 0); + if (bc->opt_dcd & 1) + hdlcdrv_setdcd(&bc->hdrv, !((inb(MSR(dev->base_addr)) ^ bc->opt_dcd) & 0x80)); + else + hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + + bc->modem.ser12.dcd_sum1 + + bc->modem.ser12.dcd_sum2) < 0); bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1; bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0; /* offset to ensure DCD off on silent input */ @@ -391,7 +378,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc) static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; unsigned char iir; @@ -482,7 +469,7 @@ static enum uart ser12_check_uart(unsigned int iobase) /* --------------------------------------------------------------------- */ -static int ser12_open(struct device *dev) +static int ser12_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; enum uart u; @@ -514,17 +501,16 @@ static int ser12_open(struct device *dev) * we get exactly (hopefully) 2 or 3 interrupts per radio symbol, * depending on the usage of the software DCD routine */ - ser12_set_divisor(dev, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6); - printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u options " - "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq, - bc->options, uart_str[u]); + ser12_set_divisor(dev, bc->opt_dcd ? 6 : 4); + printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u uart %s\n", + bc_drvname, dev->base_addr, dev->irq, uart_str[u]); MOD_INC_USE_COUNT; return 0; } /* --------------------------------------------------------------------- */ -static int ser12_close(struct device *dev) +static int ser12_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -550,7 +536,7 @@ static int ser12_close(struct device *dev) /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -567,13 +553,20 @@ static struct hdlcdrv_ops ser12_ops = { static int baycom_setmode(struct baycom_state *bc, const char *modestr) { - bc->options = !!strchr(modestr, '*'); + if (strchr(modestr, '*')) + bc->opt_dcd = 0; + else if (strchr(modestr, '+')) + bc->opt_dcd = -1; + else if (strchr(modestr, '@')) + bc->opt_dcd = -2; + else + bc->opt_dcd = 1; return 0; } /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -597,8 +590,8 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, case HDLCDRVCTL_GETMODE: strcpy(hi->data.modename, "ser12"); - if (bc->options & 1) - strcat(hi->data.modename, "*"); + if (bc->opt_dcd <= 0) + strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : (bc->opt_dcd == -2) ? "@" : "+"); if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) return -EFAULT; return 0; @@ -643,7 +636,26 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr, /* --------------------------------------------------------------------- */ -int __init baycom_ser_hdx_init(void) +/* + * command line settable parameters + */ +static char *mode[NR_PORTS] = { "ser12*", }; +static int iobase[NR_PORTS] = { 0x3f8, }; +static int irq[NR_PORTS] = { 4, }; + +MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD"); +MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(iobase, "baycom io base address"); +MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(irq, "baycom irq number"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("Baycom ser12 half duplex amateur radio modem driver"); + +/* --------------------------------------------------------------------- */ + +static int __init init_baycomserhdx(void) { int i, j, found = 0; char set_hw = 1; @@ -656,20 +668,18 @@ int __init baycom_ser_hdx_init(void) * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcsh%d", i); - if (!baycom_ports[i].mode) + if (!mode[i]) set_hw = 0; if (!set_hw) - baycom_ports[i].iobase = baycom_ports[i].irq = 0; - j = hdlcdrv_register_hdlcdrv(dev, &ser12_ops, - sizeof(struct baycom_state), - ifname, baycom_ports[i].iobase, - baycom_ports[i].irq, 0); + iobase[i] = irq[i] = 0; + j = hdlcdrv_register_hdlcdrv(dev, &ser12_ops, sizeof(struct baycom_state), + ifname, iobase[i], irq[i], 0); if (!j) { bc = (struct baycom_state *)dev->priv; - if (set_hw && baycom_setmode(bc, baycom_ports[i].mode)) + if (set_hw && baycom_setmode(bc, mode[i])) set_hw = 0; found++; } else { @@ -682,53 +692,12 @@ int __init baycom_ser_hdx_init(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -/* - * command line settable parameters - */ -static char *mode[NR_PORTS] = { "ser12*", }; -static int iobase[NR_PORTS] = { 0x3f8, }; -static int irq[NR_PORTS] = { 4, }; - -#if LINUX_VERSION_CODE >= 0x20115 - -MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); -MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD"); -MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(iobase, "baycom io base address"); -MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i"); -MODULE_PARM_DESC(irq, "baycom irq number"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("Baycom ser12 half duplex amateur radio modem driver"); - -#endif - -int __init init_module(void) -{ - int i; - - for (i = 0; (i < NR_PORTS) && (mode[i]); i++) { - baycom_ports[i].mode = mode[i]; - baycom_ports[i].iobase = iobase[i]; - baycom_ports[i].irq = irq[i]; - } - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; - return baycom_ser_hdx_init(); -} - -/* --------------------------------------------------------------------- */ - -void cleanup_module(void) +static void __exit cleanup_baycomserhdx(void) { int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { @@ -741,30 +710,40 @@ void cleanup_module(void) } } -#else /* MODULE */ +module_init(init_baycomserhdx); +module_exit(cleanup_baycomserhdx); + /* --------------------------------------------------------------------- */ + +#ifndef MODULE + /* - * format: baycom_ser_=io,irq,mode - * mode: [*] - * * indicates sofware DCD + * format: baycom_ser_hdx=io,irq,mode + * mode: ser12 hardware DCD + * ser12* software DCD + * ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware + * mutes audio input to the modem + * ser12+ hardware DCD, inverted signal at DCD pin */ -void __init baycom_ser_hdx_setup(char *str, int *ints) +static int __init baycom_ser_hdx_setup(char *str) { - int i; + static unsigned nr_dev = 0; + int ints[3]; - for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++); - if ((i >= NR_PORTS) || (ints[0] < 2)) { - printk(KERN_INFO "%s: too many or invalid interface " - "specifications\n", bc_drvname); - return; - } - baycom_ports[i].mode = str; - baycom_ports[i].iobase = ints[1]; - baycom_ports[i].irq = ints[2]; - if (i < NR_PORTS-1) - baycom_ports[i+1].mode = NULL; + if (nr_dev >= NR_PORTS) + return 0; + str = get_options(str, 3, ints); + if (ints[0] < 2) + return 0; + mode[nr_dev] = str; + iobase[nr_dev] = ints[1]; + irq[nr_dev] = ints[2]; + nr_dev++; + return 1; } +__setup("baycom_ser_hdx=", baycom_ser_hdx_setup); + #endif /* MODULE */ /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 18a7bce23..088eaa68e 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -76,7 +76,7 @@ #include <linux/notifier.h> #include <linux/proc_fs.h> #include <linux/stat.h> -#include <linux/firewall.h> +#include <linux/netfilter.h> #include <linux/module.h> #include <linux/init.h> #include <linux/rtnetlink.h> @@ -95,7 +95,7 @@ static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; static char bpq_eth_addr[6]; -static int bpq_rcv(struct sk_buff *, struct device *, struct packet_type *); +static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *); static int bpq_device_event(struct notifier_block *, unsigned long, void *); static char *bpq_print_ethaddr(unsigned char *); @@ -118,8 +118,8 @@ static struct notifier_block bpq_dev_notifier = { static struct bpqdev { struct bpqdev *next; char ethname[14]; /* ether device name */ - struct device *ethdev; /* link to ethernet device */ - struct device axdev; /* bpq device (bpq#) */ + struct net_device *ethdev; /* link to ethernet device */ + struct net_device axdev; /* bpq device (bpq#) */ struct net_device_stats stats; /* some statistics */ char dest_addr[6]; /* ether destination address */ char acpt_addr[6]; /* accept ether frames from this address only */ @@ -132,7 +132,7 @@ static struct bpqdev { /* * Get the ethernet device for a BPQ device */ -static __inline__ struct device *bpq_get_ether_dev(struct device *dev) +static __inline__ struct net_device *bpq_get_ether_dev(struct net_device *dev) { struct bpqdev *bpq; @@ -144,7 +144,7 @@ static __inline__ struct device *bpq_get_ether_dev(struct device *dev) /* * Get the BPQ device for the ethernet device */ -static __inline__ struct device *bpq_get_ax25_dev(struct device *dev) +static __inline__ struct net_device *bpq_get_ax25_dev(struct net_device *dev) { struct bpqdev *bpq; @@ -155,7 +155,7 @@ static __inline__ struct device *bpq_get_ax25_dev(struct device *dev) return NULL; } -static __inline__ int dev_is_ethdev(struct device *dev) +static __inline__ int dev_is_ethdev(struct net_device *dev) { return ( dev->type == ARPHRD_ETHER @@ -167,7 +167,7 @@ static __inline__ int dev_is_ethdev(struct device *dev) * Sanity check: remove all devices that ceased to exists and * return '1' if the given BPQ device was affected. */ -static int bpq_check_devices(struct device *dev) +static int bpq_check_devices(struct net_device *dev) { struct bpqdev *bpq, *bpq_prev; int result = 0; @@ -211,7 +211,7 @@ static int bpq_check_devices(struct device *dev) /* * Receive an AX.25 frame via an ethernet interface. */ -static int bpq_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype) +static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) { int len; char * ptr; @@ -264,7 +264,7 @@ static int bpq_rcv(struct sk_buff *skb, struct device *dev, struct packet_type * /* * Send an AX.25 frame via an ethernet interface */ -static int bpq_xmit(struct sk_buff *skb, struct device *dev) +static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *newskb; unsigned char *ptr; @@ -331,7 +331,7 @@ static int bpq_xmit(struct sk_buff *skb, struct device *dev) /* * Statistics */ -static struct net_device_stats *bpq_get_stats(struct device *dev) +static struct net_device_stats *bpq_get_stats(struct net_device *dev) { struct bpqdev *bpq; @@ -343,7 +343,7 @@ static struct net_device_stats *bpq_get_stats(struct device *dev) /* * Set AX.25 callsign */ -static int bpq_set_mac_address(struct device *dev, void *addr) +static int bpq_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -359,7 +359,7 @@ static int bpq_set_mac_address(struct device *dev, void *addr) * source ethernet address (broadcast * or multicast: accept all) */ -static int bpq_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int err; struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data; @@ -403,7 +403,7 @@ static int bpq_ioctl(struct device *dev, struct ifreq *ifr, int cmd) /* * open/close a device */ -static int bpq_open(struct device *dev) +static int bpq_open(struct net_device *dev) { if (bpq_check_devices(dev)) return -ENODEV; /* oops, it's gone */ @@ -416,7 +416,7 @@ static int bpq_open(struct device *dev) return 0; } -static int bpq_close(struct device *dev) +static int bpq_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -429,7 +429,7 @@ static int bpq_close(struct device *dev) /* * currently unused */ -static int bpq_dev_init(struct device *dev) +static int bpq_dev_init(struct net_device *dev) { return 0; } @@ -498,7 +498,7 @@ int bpq_get_info(char *buffer, char **start, off_t offset, int length, int dummy /* * Setup a new device. */ -static int bpq_new_device(struct device *dev) +static int bpq_new_device(struct net_device *dev) { int k; unsigned char *buf; @@ -521,11 +521,11 @@ static int bpq_new_device(struct device *dev) buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXBPQDEV; k++) { - struct device *odev; + struct net_device *odev; sprintf(buf, "bpq%d", k); - if ((odev = dev_get(buf)) == NULL || bpq_check_devices(odev)) + if ((odev = __dev_get_by_name(buf)) == NULL || bpq_check_devices(odev)) break; } @@ -589,7 +589,7 @@ static int bpq_new_device(struct device *dev) */ static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr) { - struct device *dev = (struct device *)ptr; + struct net_device *dev = (struct net_device *)ptr; if (!dev_is_ethdev(dev)) return NOTIFY_DONE; @@ -623,7 +623,7 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi */ int __init bpq_init(void) { - struct device *dev; + struct net_device *dev; bpq_packet_type.type = htons(ETH_P_BPQ); dev_add_pack(&bpq_packet_type); diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 2d3935117..afba5cb14 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -71,12 +71,12 @@ #define RXFIFOH 0x08 #define TXFIFOE 0x20 -static int dmascc_dev_init(struct device *dev) +static int dmascc_dev_init(struct net_device *dev) { return 0; } -static void dev_init_buffers(struct device *dev) +static void dev_init_buffers(struct net_device *dev) { int i; @@ -239,7 +239,7 @@ struct scc_info { int scc_base; int tmr_base; int twin_serial_cfg; - struct device dev[2]; + struct net_device dev[2]; struct scc_priv priv[2]; struct scc_info *next; }; @@ -252,21 +252,21 @@ static int setup_adapter(int io, int h, int n) __init; static inline void write_scc(int ctl, int reg, int val); static inline int read_scc(int ctl, int reg); -static int scc_open(struct device *dev); -static int scc_close(struct device *dev); -static int scc_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int scc_send_packet(struct sk_buff *skb, struct device *dev); -static struct enet_statistics *scc_get_stats(struct device *dev); -static int scc_set_mac_address(struct device *dev, void *sa); +static int scc_open(struct net_device *dev); +static int scc_close(struct net_device *dev); +static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int scc_send_packet(struct sk_buff *skb, struct net_device *dev); +static struct enet_statistics *scc_get_stats(struct net_device *dev); +static int scc_set_mac_address(struct net_device *dev, void *sa); static void scc_isr(int irq, void *dev_id, struct pt_regs * regs); static inline void z8530_isr(struct scc_info *info); -static void rx_isr(struct device *dev); -static void special_condition(struct device *dev, int rc); +static void rx_isr(struct net_device *dev); +static void special_condition(struct net_device *dev, int rc); static void rx_bh(void *arg); -static void tx_isr(struct device *dev); -static void es_isr(struct device *dev); -static void tm_isr(struct device *dev); -static inline void delay(struct device *dev, int t); +static void tx_isr(struct net_device *dev); +static void es_isr(struct net_device *dev); +static void tm_isr(struct net_device *dev); +static inline void delay(struct net_device *dev, int t); static inline unsigned char random(void); @@ -457,7 +457,7 @@ int __init setup_adapter(int io, int h, int n) { int i, irq, chip; struct scc_info *info; - struct device *dev; + struct net_device *dev; struct scc_priv *priv; unsigned long time; unsigned int irqs; @@ -623,7 +623,7 @@ static inline int read_scc(int ctl, int reg) } -static int scc_open(struct device *dev) +static int scc_open(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -740,7 +740,7 @@ static int scc_open(struct device *dev) } -static int scc_close(struct device *dev) +static int scc_close(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -772,7 +772,7 @@ static int scc_close(struct device *dev) } -static int scc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int rc; struct scc_priv *priv = dev->priv; @@ -797,7 +797,7 @@ static int scc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) } -static int scc_send_packet(struct sk_buff *skb, struct device *dev) +static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -851,7 +851,7 @@ static int scc_send_packet(struct sk_buff *skb, struct device *dev) } -static struct enet_statistics *scc_get_stats(struct device *dev) +static struct enet_statistics *scc_get_stats(struct net_device *dev) { struct scc_priv *priv = dev->priv; @@ -859,7 +859,7 @@ static struct enet_statistics *scc_get_stats(struct device *dev) } -static int scc_set_mac_address(struct device *dev, void *sa) +static int scc_set_mac_address(struct net_device *dev, void *sa) { memcpy(dev->dev_addr, ((struct sockaddr *)sa)->sa_data, dev->addr_len); return 0; @@ -934,7 +934,7 @@ static inline void z8530_isr(struct scc_info *info) } -static void rx_isr(struct device *dev) +static void rx_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; int cmd = priv->cmd; @@ -961,7 +961,7 @@ static void rx_isr(struct device *dev) } -static void special_condition(struct device *dev, int rc) +static void special_condition(struct net_device *dev, int rc) { struct scc_priv *priv = dev->priv; int cb, cmd = priv->cmd; @@ -1032,7 +1032,7 @@ static void special_condition(struct device *dev, int rc) static void rx_bh(void *arg) { - struct device *dev = arg; + struct net_device *dev = arg; struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; int cmd = priv->cmd; @@ -1081,7 +1081,7 @@ static void rx_bh(void *arg) } -static void tx_isr(struct device *dev) +static void tx_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; int cmd = priv->cmd; @@ -1103,7 +1103,7 @@ static void tx_isr(struct device *dev) } -static void es_isr(struct device *dev) +static void es_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -1261,7 +1261,7 @@ static void es_isr(struct device *dev) } -static void tm_isr(struct device *dev) +static void tm_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -1326,7 +1326,7 @@ static void tm_isr(struct device *dev) } -static inline void delay(struct device *dev, int t) +static inline void delay(struct net_device *dev, int t) { struct scc_priv *priv = dev->priv; int tmr = priv->tmr; diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 9558b9763..67a835b02 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -3,7 +3,7 @@ /* * hdlcdrv.c -- HDLC packet radio network driver. * - * Copyright (C) 1996-1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,6 +36,7 @@ * 0.5 30.07.97 made HDLC buffers bigger (solves a problem with the * soundmodem driver) * 0.6 05.04.98 add spinlocks + * 0.7 03.08.99 removed some old compatibility cruft */ /*****************************************************************************/ @@ -203,7 +204,7 @@ static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits, return added; } -static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s) +static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s) { struct sk_buff *skb; int pkt_len; @@ -230,7 +231,7 @@ static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s) s->stats.rx_packets++; } -void hdlcdrv_receiver(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s) { int i; unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word; @@ -327,7 +328,7 @@ static void inline do_kiss_params(struct hdlcdrv_state *s, /* ---------------------------------------------------------------------- */ -void hdlcdrv_transmitter(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s) { unsigned int mask1, mask2, mask3; int i; @@ -429,7 +430,7 @@ void hdlcdrv_transmitter(struct device *dev, struct hdlcdrv_state *s) /* ---------------------------------------------------------------------- */ -static void start_tx(struct device *dev, struct hdlcdrv_state *s) +static void start_tx(struct net_device *dev, struct hdlcdrv_state *s) { s->hdlctx.tx_state = 0; s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay); @@ -451,7 +452,7 @@ static inline unsigned short random_num(void) /* ---------------------------------------------------------------------- */ -void hdlcdrv_arbitrate(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s) { if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || skb_queue_empty(&s->send_queue)) @@ -477,7 +478,7 @@ void hdlcdrv_arbitrate(struct device *dev, struct hdlcdrv_state *s) * ===================== network driver interface ========================= */ -static inline int hdlcdrv_paranoia_check(struct device *dev, +static inline int hdlcdrv_paranoia_check(struct net_device *dev, const char *routine) { if (!dev || !dev->priv || @@ -491,7 +492,7 @@ static inline int hdlcdrv_paranoia_check(struct device *dev, /* --------------------------------------------------------------------- */ -static int hdlcdrv_send_packet(struct sk_buff *skb, struct device *dev) +static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev) { struct hdlcdrv_state *sm; @@ -505,7 +506,7 @@ static int hdlcdrv_send_packet(struct sk_buff *skb, struct device *dev) /* --------------------------------------------------------------------- */ -static int hdlcdrv_set_mac_address(struct device *dev, void *addr) +static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -516,11 +517,7 @@ static int hdlcdrv_set_mac_address(struct device *dev, void *addr) /* --------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= 0x20119 -static struct net_device_stats *hdlcdrv_get_stats(struct device *dev) -#else -static struct enet_statistics *hdlcdrv_get_stats(struct device *dev) -#endif +static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev) { struct hdlcdrv_state *sm; @@ -544,7 +541,7 @@ static struct enet_statistics *hdlcdrv_get_stats(struct device *dev) * there is non-reboot way to recover if something goes wrong. */ -static int hdlcdrv_open(struct device *dev) +static int hdlcdrv_open(struct net_device *dev) { struct hdlcdrv_state *s; int i; @@ -592,7 +589,7 @@ static int hdlcdrv_open(struct device *dev) * The inverse routine to hdlcdrv_open(). */ -static int hdlcdrv_close(struct device *dev) +static int hdlcdrv_close(struct net_device *dev) { struct hdlcdrv_state *s; struct sk_buff *skb; @@ -617,7 +614,7 @@ static int hdlcdrv_close(struct device *dev) /* --------------------------------------------------------------------- */ -static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct hdlcdrv_state *s; struct hdlcdrv_ioctl bi; @@ -695,9 +692,6 @@ static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd) bi.data.ocs.ptt = hdlcdrv_ptt(s); bi.data.ocs.dcd = s->hdlcrx.dcd; bi.data.ocs.ptt_keyed = s->ptt_keyed; -#if LINUX_VERSION_CODE < 0x20100 - bi.data.ocs.stats = s->stats; -#endif break; case HDLCDRVCTL_CALIBRATE: @@ -755,7 +749,7 @@ static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd) * If dev->base_addr == 2, allocate space for the device and return success * (detachable devices only). */ -static int hdlcdrv_probe(struct device *dev) +static int hdlcdrv_probe(struct net_device *dev) { const struct hdlcdrv_channel_params dflt_ch_params = { 20, 2, 10, 40, 0 @@ -836,7 +830,7 @@ static int hdlcdrv_probe(struct device *dev) /* --------------------------------------------------------------------- */ -int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops, +int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops, unsigned int privsize, char *ifname, unsigned int baseaddr, unsigned int irq, unsigned int dma) @@ -847,7 +841,7 @@ int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops, return -EACCES; if (privsize < sizeof(struct hdlcdrv_state)) privsize = sizeof(struct hdlcdrv_state); - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); if (!(s = dev->priv = kmalloc(privsize, GFP_KERNEL))) return -ENOMEM; /* @@ -880,7 +874,7 @@ int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops, /* --------------------------------------------------------------------- */ -int hdlcdrv_unregister_hdlcdrv(struct device *dev) +int hdlcdrv_unregister_hdlcdrv(struct net_device *dev) { struct hdlcdrv_state *s; @@ -900,48 +894,25 @@ int hdlcdrv_unregister_hdlcdrv(struct device *dev) /* --------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= 0x20115 - EXPORT_SYMBOL(hdlcdrv_receiver); EXPORT_SYMBOL(hdlcdrv_transmitter); EXPORT_SYMBOL(hdlcdrv_arbitrate); EXPORT_SYMBOL(hdlcdrv_register_hdlcdrv); EXPORT_SYMBOL(hdlcdrv_unregister_hdlcdrv); -#else - -static struct symbol_table hdlcdrv_syms = { -#include <linux/symtab_begin.h> - X(hdlcdrv_receiver), - X(hdlcdrv_transmitter), - X(hdlcdrv_arbitrate), - X(hdlcdrv_register_hdlcdrv), - X(hdlcdrv_unregister_hdlcdrv), -#include <linux/symtab_end.h> -}; - -#endif - /* --------------------------------------------------------------------- */ #ifdef MODULE -#if LINUX_VERSION_CODE >= 0x20115 - MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder"); -#endif - /* --------------------------------------------------------------------- */ int __init init_module(void) { printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n"); - printk(KERN_INFO "hdlcdrv: version 0.6 compiled " __TIME__ " " __DATE__ "\n"); -#if LINUX_VERSION_CODE < 0x20115 - register_symtab(&hdlcdrv_syms); -#endif + printk(KERN_INFO "hdlcdrv: version 0.7 compiled " __TIME__ " " __DATE__ "\n"); return 0; } diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 796b019e4..0e819d973 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -75,7 +75,7 @@ struct mkiss_channel { typedef struct ax25_ctrl { char if_name[8]; /* "ax0\0" .. "ax99999\0" */ struct ax_disp ctrl; /* */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } ax25_ctrl_t; static ax25_ctrl_t **ax25_ctrls = NULL; @@ -90,7 +90,7 @@ static struct termios *mkiss_termios[NR_MKISS]; static struct termios *mkiss_termios_locked[NR_MKISS]; struct mkiss_channel MKISS_Info[NR_MKISS]; -static int ax25_init(struct device *); +static int ax25_init(struct net_device *); static int mkiss_init(void); static int mkiss_write(struct tty_struct *, int, const unsigned char *, int); static int kiss_esc(unsigned char *, unsigned char *, int); @@ -247,7 +247,7 @@ static inline void ax_free(struct ax_disp *ax) static void ax_changedmtu(struct ax_disp *ax) { - struct device *dev = ax->dev; + struct net_device *dev = ax->dev; unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; int len; unsigned long flags; @@ -460,7 +460,7 @@ static void ax25_write_wakeup(struct tty_struct *tty) } /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ -static int ax_xmit(struct sk_buff *skb, struct device *dev) +static int ax_xmit(struct sk_buff *skb, struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; struct mkiss_channel *mkiss = ax->tty->driver_data; @@ -523,7 +523,7 @@ static int ax_xmit(struct sk_buff *skb, struct device *dev) #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) /* Return the frame type ID */ -static int ax_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { #ifdef CONFIG_INET @@ -546,7 +546,7 @@ static int ax_rebuild_header(struct sk_buff *skb) #endif /* CONFIG_{AX25,AX25_MODULE} */ /* Open the low-level part of the AX25 channel. Easy! */ -static int ax_open(struct device *dev) +static int ax_open(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; unsigned long len; @@ -600,7 +600,7 @@ norbuff: /* Close the low-level part of the AX25 channel. Easy! */ -static int ax_close(struct device *dev) +static int ax_close(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -737,7 +737,7 @@ static void ax25_close(struct tty_struct *tty) } -static struct net_device_stats *ax_get_stats(struct device *dev) +static struct net_device_stats *ax_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -873,14 +873,14 @@ static void kiss_unesc(struct ax_disp *ax, unsigned char s) } -int ax_set_mac_address(struct device *dev, void *addr) +int ax_set_mac_address(struct net_device *dev, void *addr) { if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN)) return -EFAULT; return 0; } -static int ax_set_dev_mac_address(struct device *dev, void *addr) +static int ax_set_dev_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = addr; @@ -926,7 +926,7 @@ static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void *ar } } -static int ax_open_dev(struct device *dev) +static int ax_open_dev(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -986,7 +986,7 @@ int __init mkiss_init_ctrl_dev(void) /* Initialize the driver. Called by network startup. */ -static int ax25_init(struct device *dev) +static int ax25_init(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; diff --git a/drivers/net/hamradio/mkiss.h b/drivers/net/hamradio/mkiss.h index e1531b728..c24c27819 100644 --- a/drivers/net/hamradio/mkiss.h +++ b/drivers/net/hamradio/mkiss.h @@ -18,7 +18,7 @@ struct ax_disp { /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ struct ax_disp *mkiss; /* mkiss txport if mkiss channel*/ /* These are pointers to the malloc()ed frame buffers. */ diff --git a/drivers/net/hamradio/pi2.c b/drivers/net/hamradio/pi2.c index f036c5eb8..b52a254c8 100644 --- a/drivers/net/hamradio/pi2.c +++ b/drivers/net/hamradio/pi2.c @@ -130,9 +130,9 @@ struct mbuf { * PI device declarations. */ -static int pi0_preprobe(struct device *dev){return 0;} /* Dummy probe function */ -static struct device pi0a = { "pi0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; -static struct device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; +static int pi0_preprobe(struct net_device *dev){return 0;} /* Dummy probe function */ +static struct net_device pi0a = { "pi0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; +static struct net_device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; /* The number of low I/O ports used by the card. */ @@ -141,18 +141,18 @@ static struct device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_prepr /* Index to functions, as function prototypes. */ -static int pi_probe(struct device *dev, int card_type); -static int pi_open(struct device *dev); -static int pi_send_packet(struct sk_buff *skb, struct device *dev); +static int pi_probe(struct net_device *dev, int card_type); +static int pi_open(struct net_device *dev); +static int pi_send_packet(struct sk_buff *skb, struct net_device *dev); static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs); -static int pi_close(struct device *dev); -static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *pi_get_stats(struct device *dev); +static int pi_close(struct net_device *dev); +static int pi_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *pi_get_stats(struct net_device *dev); static void rts(struct pi_local *lp, int x); -static void b_rxint(struct device *dev, struct pi_local *lp); +static void b_rxint(struct net_device *dev, struct pi_local *lp); static void b_txint(struct pi_local *lp); static void b_exint(struct pi_local *lp); -static void a_rxint(struct device *dev, struct pi_local *lp); +static void a_rxint(struct net_device *dev, struct pi_local *lp); static void a_txint(struct pi_local *lp); static void a_exint(struct pi_local *lp); static char *get_dma_buffer(unsigned long *mem_ptr); @@ -493,7 +493,7 @@ static void a_exint(struct pi_local *lp) /* Receive interrupt handler for the A channel */ -static void a_rxint(struct device *dev, struct pi_local *lp) +static void a_rxint(struct net_device *dev, struct pi_local *lp) { unsigned long flags; int cmd; @@ -568,7 +568,7 @@ static void a_rxint(struct device *dev, struct pi_local *lp) restore_flags(flags); } -static void b_rxint(struct device *dev, struct pi_local *lp) +static void b_rxint(struct net_device *dev, struct pi_local *lp) { unsigned long flags; int cmd; @@ -1063,7 +1063,7 @@ static void rts(struct pi_local *lp, int x) } } -static void scc_init(struct device *dev) +static void scc_init(struct net_device *dev) { unsigned long flags; struct pi_local *lp = (struct pi_local *) dev->priv; @@ -1165,7 +1165,7 @@ static void scc_init(struct device *dev) restore_flags(flags); } -static void chipset_init(struct device *dev) +static void chipset_init(struct net_device *dev) { int cardbase; unsigned long flags; @@ -1251,7 +1251,7 @@ static int valid_dma_page(unsigned long addr, unsigned long dev_buffsize) return 0; } -static int pi_set_mac_address(struct device *dev, void *addr) +static int pi_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); /* addr is an AX.25 shifted ASCII */ @@ -1274,7 +1274,7 @@ get_dma_buffer(unsigned long *mem_ptr) return (ret); } -static int pi_probe(struct device *dev, int card_type) +static int pi_probe(struct net_device *dev, int card_type) { short ioaddr; struct pi_local *lp; @@ -1423,7 +1423,7 @@ static int pi_probe(struct device *dev, int card_type) registers that "should" only need to be set once at boot, so that there is non-reboot way to recover if something goes wrong. */ -static int pi_open(struct device *dev) +static int pi_open(struct net_device *dev) { unsigned long flags; static first_time = 1; @@ -1464,7 +1464,7 @@ static int pi_open(struct device *dev) return 0; } -static int pi_send_packet(struct sk_buff *skb, struct device *dev) +static int pi_send_packet(struct sk_buff *skb, struct net_device *dev) { struct pi_local *lp = (struct pi_local *) dev->priv; @@ -1531,7 +1531,7 @@ static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs) } /* The inverse routine to pi_open(). */ -static int pi_close(struct device *dev) +static int pi_close(struct net_device *dev) { unsigned long flags; struct pi_local *lp; @@ -1562,7 +1562,7 @@ static int pi_close(struct device *dev) return 0; } -static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int pi_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { unsigned long flags; struct pi_req rq; @@ -1643,7 +1643,7 @@ static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *pi_get_stats(struct device *dev) +static struct net_device_stats *pi_get_stats(struct net_device *dev) { struct pi_local *lp = (struct pi_local *) dev->priv; diff --git a/drivers/net/hamradio/pt.c b/drivers/net/hamradio/pt.c index 4a7604e96..59762edd7 100644 --- a/drivers/net/hamradio/pt.c +++ b/drivers/net/hamradio/pt.c @@ -105,9 +105,9 @@ struct mbuf { /* * The actual PT devices we will use */ -static int pt0_preprobe(struct device *dev) {return 0;} /* Dummy probe function */ -static struct device pt0a = { "pt0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; -static struct device pt0b = { "pt0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; +static int pt0_preprobe(struct net_device *dev) {return 0;} /* Dummy probe function */ +static struct net_device pt0a = { "pt0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; +static struct net_device pt0b = { "pt0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; /* Ok, they shouldn't be here, but both channels share them */ /* The Images of the Serial and DMA config registers */ @@ -119,15 +119,15 @@ static unsigned char pt_dmacfg = 0; /* Index to functions, as function prototypes. */ -static int pt_probe(struct device *dev); -static int pt_open(struct device *dev); -static int pt_send_packet(struct sk_buff *skb, struct device *dev); +static int pt_probe(struct net_device *dev); +static int pt_open(struct net_device *dev); +static int pt_send_packet(struct sk_buff *skb, struct net_device *dev); static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int pt_close(struct device *dev); -static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *pt_get_stats(struct device *dev); +static int pt_close(struct net_device *dev); +static int pt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *pt_get_stats(struct net_device *dev); static void pt_rts(struct pt_local *lp, int x); -static void pt_rxisr(struct device *dev); +static void pt_rxisr(struct net_device *dev); static void pt_txisr(struct pt_local *lp); static void pt_exisr(struct pt_local *lp); static void pt_tmrisr(struct pt_local *lp); @@ -135,7 +135,7 @@ static char *get_dma_buffer(unsigned long *mem_ptr); static int valid_dma_page(unsigned long addr, unsigned long dev_buffsize); static int hw_probe(int ioaddr); static void tdelay(struct pt_local *lp, int time); -static void chipset_init(struct device *dev); +static void chipset_init(struct net_device *dev); static char ax25_bcast[7] = {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1}; @@ -179,7 +179,7 @@ static void hardware_send_packet(struct pt_local *lp, struct sk_buff *skb) char kickflag; unsigned long flags; char *ptr; - struct device *dev; + struct net_device *dev; /* First, let's see if this packet is actually a KISS packet */ ptr = skb->data; @@ -322,7 +322,7 @@ static void setup_tx_dma(struct pt_local *lp, int length) * This sets up all the registers in the SCC for the given channel * based upon tsync_hwint() */ -static void scc_init(struct device *dev) +static void scc_init(struct net_device *dev) { unsigned long flags; struct pt_local *lp = (struct pt_local*) dev->priv; @@ -443,7 +443,7 @@ static void scc_init(struct device *dev) } /* scc_init() */ /* Resets the given channel and whole SCC if both channels off */ -static void chipset_init(struct device *dev) +static void chipset_init(struct net_device *dev) { struct pt_local *lp = (struct pt_local*) dev->priv; @@ -699,7 +699,7 @@ static int valid_dma_page(unsigned long addr, unsigned long dev_bufsize) return 0; } -static int pt_set_mac_address(struct device *dev, void *addr) +static int pt_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); /* addr is an AX.25 shifted ASCII */ @@ -726,7 +726,7 @@ static char * get_dma_buffer(unsigned long *mem_ptr) /* * Sets up all the structures for the PT device */ -static int pt_probe(struct device *dev) +static int pt_probe(struct net_device *dev) { short ioaddr; struct pt_local *lp; @@ -878,7 +878,7 @@ static int pt_probe(struct device *dev) * a non-reboot way to recover if something goes wrong. * derived from last half of tsync_attach() */ -static int pt_open(struct device *dev) +static int pt_open(struct net_device *dev) { unsigned long flags; struct pt_local *lp = dev->priv; @@ -928,7 +928,7 @@ static int pt_open(struct device *dev) return 0; } /* pt_open() */ -static int pt_send_packet(struct sk_buff *skb, struct device *dev) +static int pt_send_packet(struct sk_buff *skb, struct net_device *dev) { struct pt_local *lp = (struct pt_local *) dev->priv; @@ -944,7 +944,7 @@ static int pt_send_packet(struct sk_buff *skb, struct device *dev) /* The inverse routine to pt_open() */ -static int pt_close(struct device *dev) +static int pt_close(struct net_device *dev) { unsigned long flags; struct pt_local *lp = dev->priv; @@ -980,7 +980,7 @@ static int pt_close(struct device *dev) } /* pt_close() */ -static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int pt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { unsigned long flags; struct pt_req rq; @@ -1064,7 +1064,7 @@ static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd) * This may be called with the card open or closed. */ -static struct net_device_stats *pt_get_stats(struct device *dev) +static struct net_device_stats *pt_get_stats(struct net_device *dev) { struct pt_local *lp = (struct pt_local *) dev->priv; return &lp->stats; @@ -1219,7 +1219,7 @@ static void pt_txisr(struct pt_local *lp) restore_flags(flags); } -static void pt_rxisr(struct device *dev) +static void pt_rxisr(struct net_device *dev) { struct pt_local *lp = (struct pt_local*) dev->priv; int cmd = lp->base + CTL; @@ -1432,7 +1432,7 @@ static void pt_tmrisr(struct pt_local *lp) static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* It's a tad dodgy here, but we assume pt0a until proven otherwise */ - struct device *dev = &pt0a; + struct net_device *dev = &pt0a; struct pt_local *lp = dev->priv; unsigned char intreg; unsigned char st; diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 0f803139a..f93f3d261 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -210,15 +210,15 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs *regs); static void scc_init_timer(struct scc_channel *scc); static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev); -static int scc_net_init(struct device *dev); -static int scc_net_open(struct device *dev); -static int scc_net_close(struct device *dev); +static int scc_net_init(struct net_device *dev); +static int scc_net_open(struct net_device *dev); +static int scc_net_close(struct net_device *dev); static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb); -static int scc_net_tx(struct sk_buff *skb, struct device *dev); -static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int scc_net_set_mac_address(struct device *dev, void *addr); -static int scc_net_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); -static struct net_device_stats * scc_net_get_stats(struct device *dev); +static int scc_net_tx(struct sk_buff *skb, struct net_device *dev); +static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int scc_net_set_mac_address(struct net_device *dev, void *addr); +static int scc_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); +static struct net_device_stats * scc_net_get_stats(struct net_device *dev); static unsigned char *SCC_DriverName = "scc"; @@ -1569,7 +1569,7 @@ static void z8530_init(void) static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev) { unsigned char *buf; - struct device *dev; + struct net_device *dev; if (dev_get(name) != NULL) { @@ -1577,11 +1577,11 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev return -EEXIST; } - if ((scc->dev = (struct device *) kmalloc(sizeof(struct device), GFP_KERNEL)) == NULL) + if ((scc->dev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) return -ENOMEM; dev = scc->dev; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); buf = (unsigned char *) kmalloc(10, GFP_KERNEL); strcpy(buf, name); @@ -1612,7 +1612,7 @@ static unsigned char ax25_nocall[AX25_ADDR_LEN] = /* ----> Initialize device <----- */ -static int scc_net_init(struct device *dev) +static int scc_net_init(struct net_device *dev) { dev_init_buffers(dev); @@ -1643,7 +1643,7 @@ static int scc_net_init(struct device *dev) /* ----> open network device <---- */ -static int scc_net_open(struct device *dev) +static int scc_net_open(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; @@ -1668,7 +1668,7 @@ static int scc_net_open(struct device *dev) /* ----> close network device <---- */ -static int scc_net_close(struct device *dev) +static int scc_net_close(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; @@ -1721,7 +1721,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb) /* ----> transmit frame <---- */ -static int scc_net_tx(struct sk_buff *skb, struct device *dev) +static int scc_net_tx(struct sk_buff *skb, struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; @@ -1799,7 +1799,7 @@ static int scc_net_tx(struct sk_buff *skb, struct device *dev) * SIOCSCCCAL - send calib. pattern arg: (struct scc_calibrate *) arg */ -static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct scc_kiss_cmd kiss_cmd; struct scc_mem_config memcfg; @@ -2031,7 +2031,7 @@ static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) /* ----> set interface callsign <---- */ -static int scc_net_set_mac_address(struct device *dev, void *addr) +static int scc_net_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *) addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); @@ -2040,7 +2040,7 @@ static int scc_net_set_mac_address(struct device *dev, void *addr) /* ----> "hard" header <---- */ -static int scc_net_header(struct sk_buff *skb, struct device *dev, +static int scc_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { return ax25_encapsulate(skb, dev, type, daddr, saddr, len); @@ -2048,7 +2048,7 @@ static int scc_net_header(struct sk_buff *skb, struct device *dev, /* ----> get statistics <---- */ -static struct net_device_stats *scc_net_get_stats(struct device *dev) +static struct net_device_stats *scc_net_get_stats(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; diff --git a/drivers/net/hamradio/soundmodem/sm.c b/drivers/net/hamradio/soundmodem/sm.c index 193ffeae2..99d9061f9 100644 --- a/drivers/net/hamradio/soundmodem/sm.c +++ b/drivers/net/hamradio/soundmodem/sm.c @@ -3,7 +3,7 @@ /* * sm.c -- soundcard radio modem driver. * - * Copyright (C) 1996-1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,34 +41,30 @@ * 0.6 16.04.97 init code/data tagged * 0.7 30.07.97 fixed halfduplex interrupt handlers/hotfix for CS423X * 0.8 14.04.98 cleanups + * 0.9 03.08.99 adapt to Linus' new __setup/__initcall + * use parport lowlevel drivers instead of directly writing to a parallel port + * removed some pre-2.2 kernel compatibility cruft + * 0.10 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts */ /*****************************************************************************/ #include <linux/config.h> +#include <linux/version.h> #include <linux/module.h> -#include <linux/ptrace.h> -#include <linux/types.h> -#include <linux/fcntl.h> #include <linux/ioport.h> -#include <linux/net.h> -#include <linux/in.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/parport.h> #include <asm/uaccess.h> -#include <asm/system.h> #include <asm/io.h> -#include <asm/bitops.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/version.h> #include "sm.h" /* --------------------------------------------------------------------- */ /*static*/ const char sm_drvname[] = "soundmodem"; -static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1998 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "soundmodem: version 0.8 compiled " __TIME__ " " __DATE__ "\n"; +static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "soundmodem: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -146,16 +142,7 @@ static const struct hardware_info *sm_hardware_table[] = { #define NR_PORTS 4 -/* --------------------------------------------------------------------- */ - -static struct device sm_device[NR_PORTS]; - -static struct { - char *mode; - int iobase, irq, dma, dma2, seriobase, pariobase, midiiobase; -} sm_ports[NR_PORTS] = { - { NULL, -1, 0, 0, 0, -1, -1, -1 }, -}; +static struct net_device sm_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -174,13 +161,6 @@ static struct { #define SER_EXTENT 8 -#define LPT_DATA(iobase) (iobase+0) -#define LPT_STATUS(iobase) (iobase+1) -#define LPT_CONTROL(iobase) (iobase+2) -#define LPT_IRQ_ENABLE 0x10 - -#define LPT_EXTENT 3 - #define MIDI_DATA(iobase) (iobase) #define MIDI_STATUS(iobase) (iobase+1) #define MIDI_READ_FULL 0x80 /* attention: negative logic!! */ @@ -202,47 +182,10 @@ static struct { #define SP_PAR 2 #define SP_MIDI 4 -/* --------------------------------------------------------------------- */ /* * ===================== port checking routines ======================== */ -/* - * returns 0 if ok and != 0 on error; - * the same behaviour as par96_check_lpt in baycom.c - */ - -/* - * returns 0 if ok and != 0 on error; - * the same behaviour as par96_check_lpt in baycom.c - */ - -static int check_lpt(unsigned int iobase) -{ - unsigned char b1,b2; - int i; - - if (iobase <= 0 || iobase > 0x1000-LPT_EXTENT) - return 0; - if (check_region(iobase, LPT_EXTENT)) - return 0; - b1 = inb(LPT_DATA(iobase)); - b2 = inb(LPT_CONTROL(iobase)); - outb(0xaa, LPT_DATA(iobase)); - i = inb(LPT_DATA(iobase)) == 0xaa; - outb(0x55, LPT_DATA(iobase)); - i &= inb(LPT_DATA(iobase)) == 0x55; - outb(0x0a, LPT_CONTROL(iobase)); - i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x0a; - outb(0x05, LPT_CONTROL(iobase)); - i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x05; - outb(b1, LPT_DATA(iobase)); - outb(b2, LPT_CONTROL(iobase)); - return !i; -} - -/* --------------------------------------------------------------------- */ - enum uart { c_uart_unknown, c_uart_8250, c_uart_16450, c_uart_16550, c_uart_16550A}; static const char *uart_str[] = @@ -326,12 +269,10 @@ void sm_output_status(struct sm_state *sm) outb(dcd | (ptt << 1), UART_MCR(sm->hdrv.ptt_out.seriobase)); outb(0x40 & (-ptt), UART_LCR(sm->hdrv.ptt_out.seriobase)); } - if (sm->hdrv.ptt_out.flags & SP_PAR) { - outb(ptt | (dcd << 1), LPT_DATA(sm->hdrv.ptt_out.pariobase)); - } - if (sm->hdrv.ptt_out.flags & SP_MIDI && hdlcdrv_ptt(&sm->hdrv)) { + if (sm->hdrv.ptt_out.flags & SP_PAR && sm->pardev && sm->pardev->port) + parport_write_data(sm->pardev->port, ptt | (dcd << 1)); + if (sm->hdrv.ptt_out.flags & SP_MIDI && hdlcdrv_ptt(&sm->hdrv)) outb(0, MIDI_DATA(sm->hdrv.ptt_out.midiiobase)); - } } /* --------------------------------------------------------------------- */ @@ -339,6 +280,7 @@ void sm_output_status(struct sm_state *sm) static void sm_output_open(struct sm_state *sm) { enum uart u = c_uart_unknown; + struct parport *pp = NULL; sm->hdrv.ptt_out.flags = 0; if (sm->hdrv.ptt_out.seriobase > 0 && @@ -353,11 +295,29 @@ static void sm_output_open(struct sm_state *sm) outb(1, UART_DLL(sm->hdrv.ptt_out.seriobase)); /* as fast as possible */ /* LCR and MCR set by output_status */ } - if (sm->hdrv.ptt_out.pariobase > 0 && - sm->hdrv.ptt_out.pariobase <= 0x1000-LPT_EXTENT && - !check_lpt(sm->hdrv.ptt_out.pariobase)) { - sm->hdrv.ptt_out.flags |= SP_PAR; - request_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT, "sm par ptt"); + sm->pardev = NULL; + if (sm->hdrv.ptt_out.pariobase > 0) { + pp = parport_enumerate(); + while (pp && pp->base != sm->hdrv.ptt_out.pariobase) + pp = pp->next; + if (!pp) + printk(KERN_WARNING "%s: parport at address 0x%x not found\n", sm_drvname, sm->hdrv.ptt_out.pariobase); + else if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) + printk(KERN_WARNING "%s: parport at address 0x%x cannot be used\n", sm_drvname, sm->hdrv.ptt_out.pariobase); + else { + sm->pardev = parport_register_device(pp, sm->hdrv.ifname, NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!sm->pardev) { + pp = NULL; + printk(KERN_WARNING "%s: cannot register parport device (address 0x%x)\n", sm_drvname, sm->hdrv.ptt_out.pariobase); + } else { + if (parport_claim(sm->pardev)) { + parport_unregister_device(sm->pardev); + sm->pardev = NULL; + printk(KERN_WARNING "%s: cannot claim parport at address 0x%x\n", sm_drvname, sm->hdrv.ptt_out.pariobase); + } else + sm->hdrv.ptt_out.flags |= SP_PAR; + } + } } if (sm->hdrv.ptt_out.midiiobase > 0 && sm->hdrv.ptt_out.midiiobase <= 0x1000-MIDI_EXTENT && @@ -390,8 +350,10 @@ static void sm_output_close(struct sm_state *sm) sm_output_status(sm); if (sm->hdrv.ptt_out.flags & SP_SER) release_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT); - if (sm->hdrv.ptt_out.flags & SP_PAR) - release_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT); + if (sm->hdrv.ptt_out.flags & SP_PAR && sm->pardev) { + parport_release(sm->pardev); + parport_unregister_device(sm->pardev); + } if (sm->hdrv.ptt_out.flags & SP_MIDI) release_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT); sm->hdrv.ptt_out.flags = 0; @@ -399,9 +361,9 @@ static void sm_output_close(struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int sm_open(struct device *dev); -static int sm_close(struct device *dev); -static int sm_ioctl(struct device *dev, struct ifreq *ifr, +static int sm_open(struct net_device *dev); +static int sm_close(struct net_device *dev); +static int sm_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -412,7 +374,7 @@ static const struct hdlcdrv_ops sm_ops = { /* --------------------------------------------------------------------- */ -static int sm_open(struct device *dev) +static int sm_open(struct net_device *dev) { struct sm_state *sm; int err; @@ -440,7 +402,7 @@ static int sm_open(struct device *dev) /* --------------------------------------------------------------------- */ -static int sm_close(struct device *dev) +static int sm_close(struct net_device *dev) { struct sm_state *sm; int err = -ENODEV; @@ -464,7 +426,7 @@ static int sm_close(struct device *dev) /* --------------------------------------------------------------------- */ -static int sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, ':'); const struct hardware_info **hwp = sm_hardware_table; @@ -493,7 +455,7 @@ static int sethw(struct device *dev, struct sm_state *sm, char *mode) /* --------------------------------------------------------------------- */ -static int sm_ioctl(struct device *dev, struct ifreq *ifr, +static int sm_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_state *sm; @@ -639,11 +601,41 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr, /* --------------------------------------------------------------------- */ -#ifdef MODULE -static int __init sm_init(void) -#else /* MODULE */ -int __init sm_init(void) -#endif /* MODULE */ +/* + * command line settable parameters + */ +static char *mode[NR_PORTS] = { [0 ... NR_PORTS-1] = NULL }; +static int iobase[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 }; +static int irq[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 }; +static int dma[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 }; +static int dma2[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 }; +static int serio[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 }; +static int pario[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 }; +static int midiio[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 }; + +MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +MODULE_PARM_DESC(mode, "soundmodem operating mode; eg. sbc:afsk1200 or wss:fsk9600"); +MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(iobase, "soundmodem base address"); +MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(irq, "soundmodem interrupt"); +MODULE_PARM(dma, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(dma, "soundmodem dma channel"); +MODULE_PARM(dma2, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(dma2, "soundmodem 2nd dma channel; full duplex only"); +MODULE_PARM(serio, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(serio, "soundmodem PTT output on serial port"); +MODULE_PARM(pario, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(pario, "soundmodem PTT output on parallel port"); +MODULE_PARM(midiio, "1-" __MODULE_STRING(NR_PORTS) "i"); +MODULE_PARM_DESC(midiio, "soundmodem PTT output on midi port"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("Soundcard amateur radio modem driver"); + +/* --------------------------------------------------------------------- */ + +static int __init init_soundmodem(void) { int i, j, found = 0; char set_hw = 1; @@ -655,28 +647,42 @@ int __init sm_init(void) * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = sm_device+i; + struct net_device *dev = sm_device+i; sprintf(ifname, "sm%d", i); - if (!sm_ports[i].mode) + if (!mode[i]) set_hw = 0; + else { + if (!strncmp(mode[i], "sbc", 3)) { + if (iobase[i] == -1) + iobase[i] = 0x220; + if (irq[i] == -1) + irq[i] = 5; + if (dma[i] == -1) + dma[i] = 1; + } else { + if (iobase[i] == -1) + iobase[i] = 0x530; + if (irq[i] == -1) + irq[i] = 11; + if (dma[i] == -1) + dma[i] = 1; + } + } if (!set_hw) - sm_ports[i].iobase = sm_ports[i].irq = 0; - j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state), - ifname, sm_ports[i].iobase, - sm_ports[i].irq, sm_ports[i].dma); + iobase[i] = irq[i] = 0; + j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state), ifname, iobase[i], irq[i], dma[i]); if (!j) { sm = (struct sm_state *)dev->priv; - sm->hdrv.ptt_out.dma2 = sm_ports[i].dma2; - sm->hdrv.ptt_out.seriobase = sm_ports[i].seriobase; - sm->hdrv.ptt_out.pariobase = sm_ports[i].pariobase; - sm->hdrv.ptt_out.midiiobase = sm_ports[i].midiiobase; - if (set_hw && sethw(dev, sm, sm_ports[i].mode)) + sm->hdrv.ptt_out.dma2 = dma2[i]; + sm->hdrv.ptt_out.seriobase = serio[i]; + sm->hdrv.ptt_out.pariobase = pario[i]; + sm->hdrv.ptt_out.midiiobase = midiio[i]; + if (set_hw && sethw(dev, sm, mode[i])) set_hw = 0; found++; } else { - printk(KERN_WARNING "%s: cannot register net device\n", - sm_drvname); + printk(KERN_WARNING "%s: cannot register net device\n", sm_drvname); } } if (!found) @@ -684,79 +690,14 @@ int __init sm_init(void) return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -/* - * command line settable parameters - */ -static char *mode = NULL; -static int iobase = -1; -static int irq = -1; -static int dma = -1; -static int dma2 = -1; -static int serio = 0; -static int pario = 0; -static int midiio = 0; - -#if LINUX_VERSION_CODE >= 0x20115 - -MODULE_PARM(mode, "s"); -MODULE_PARM_DESC(mode, "soundmodem operating mode; eg. sbc:afsk1200 or wss:fsk9600"); -MODULE_PARM(iobase, "i"); -MODULE_PARM_DESC(iobase, "soundmodem base address"); -MODULE_PARM(irq, "i"); -MODULE_PARM_DESC(irq, "soundmodem interrupt"); -MODULE_PARM(dma, "i"); -MODULE_PARM_DESC(dma, "soundmodem dma channel"); -MODULE_PARM(dma2, "i"); -MODULE_PARM_DESC(dma2, "soundmodem 2nd dma channel; full duplex only"); -MODULE_PARM(serio, "i"); -MODULE_PARM_DESC(serio, "soundmodem PTT output on serial port"); -MODULE_PARM(pario, "i"); -MODULE_PARM_DESC(pario, "soundmodem PTT output on parallel port"); -MODULE_PARM(midiio, "i"); -MODULE_PARM_DESC(midiio, "soundmodem PTT output on midi port"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("Soundcard amateur radio modem driver"); - -#endif - -int __init init_module(void) -{ - if (mode) { - if (iobase == -1) - iobase = (!strncmp(mode, "sbc", 3)) ? 0x220 : 0x530; - if (irq == -1) - irq = (!strncmp(mode, "sbc", 3)) ? 5 : 11; - if (dma == -1) - dma = 1; - } - sm_ports[0].mode = mode; - sm_ports[0].iobase = iobase; - sm_ports[0].irq = irq; - sm_ports[0].dma = dma; - sm_ports[0].dma2 = dma2; - sm_ports[0].seriobase = serio; - sm_ports[0].pariobase = pario; - sm_ports[0].midiiobase = midiio; - sm_ports[1].mode = NULL; - - return sm_init(); -} - -/* --------------------------------------------------------------------- */ - -void cleanup_module(void) +static void __exit cleanup_soundmodem(void) { int i; printk(KERN_INFO "sm: cleanup_module called\n"); for(i = 0; i < NR_PORTS; i++) { - struct device *dev = sm_device+i; + struct net_device *dev = sm_device+i; struct sm_state *sm = (struct sm_state *)dev->priv; if (sm) { @@ -769,36 +710,48 @@ void cleanup_module(void) } } -#else /* MODULE */ +module_init(init_soundmodem); +module_exit(cleanup_soundmodem); + /* --------------------------------------------------------------------- */ + +#ifndef MODULE + /* - * format: sm=io,irq,dma[,dma2[,serio[,pario]]],mode + * format: soundmodem=io,irq,dma[,dma2[,serio[,pario]]],mode * mode: hw:modem * hw: sbc, wss, wssfdx * modem: afsk1200, fsk9600 */ -void __init sm_setup(char *str, int *ints) +static int __init sm_setup(char *str) { - int i; + static unsigned __initdata nr_dev = 0; + int ints[8]; - for (i = 0; (i < NR_PORTS) && (sm_ports[i].mode); i++); - if ((i >= NR_PORTS) || (ints[0] < 3)) { - printk(KERN_INFO "%s: too many or invalid interface " - "specifications\n", sm_drvname); - return; - } - sm_ports[i].mode = str; - sm_ports[i].iobase = ints[1]; - sm_ports[i].irq = ints[2]; - sm_ports[i].dma = ints[3]; - sm_ports[i].dma2 = (ints[0] >= 4) ? ints[4] : 0; - sm_ports[i].seriobase = (ints[0] >= 5) ? ints[5] : 0; - sm_ports[i].pariobase = (ints[0] >= 6) ? ints[6] : 0; - sm_ports[i].midiiobase = (ints[0] >= 7) ? ints[7] : 0; - if (i < NR_PORTS-1) - sm_ports[i+1].mode = NULL; + if (nr_dev >= NR_PORTS) + return 0; + str = get_options(str, 8, ints); + mode[nr_dev] = str; + if (ints[0] >= 1) + iobase[nr_dev] = ints[1]; + if (ints[0] >= 2) + irq[nr_dev] = ints[2]; + if (ints[0] >= 3) + dma[nr_dev] = ints[3]; + if (ints[0] >= 4) + dma2[nr_dev] = ints[4]; + if (ints[0] >= 5) + serio[nr_dev] = ints[5]; + if (ints[0] >= 6) + pario[nr_dev] = ints[6]; + if (ints[0] >= 7) + midiio[nr_dev] = ints[7]; + nr_dev++; + return 1; } +__setup("soundmodem=", sm_setup); + #endif /* MODULE */ /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/soundmodem/sm.h b/drivers/net/hamradio/soundmodem/sm.h index 68799e20e..4608b3650 100644 --- a/drivers/net/hamradio/soundmodem/sm.h +++ b/drivers/net/hamradio/soundmodem/sm.h @@ -3,7 +3,7 @@ /* * sm.h -- soundcard radio modem driver internal header. * - * Copyright (C) 1996-1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,6 +34,7 @@ #include <linux/soundmodem.h> #include <asm/processor.h> #include <linux/bitops.h> +#include <linux/parport.h> #define SM_DEBUG @@ -50,6 +51,8 @@ struct sm_state { const struct hardware_info *hwdrv; + struct pardevice *pardev; + /* * Hardware (soundcard) access routines state */ @@ -138,11 +141,11 @@ struct hardware_info { /* * mode specific open/close */ - int (*open)(struct device *, struct sm_state *); - int (*close)(struct device *, struct sm_state *); - int (*ioctl)(struct device *, struct sm_state *, struct ifreq *, + int (*open)(struct net_device *, struct sm_state *); + int (*close)(struct net_device *, struct sm_state *); + int (*ioctl)(struct net_device *, struct sm_state *, struct ifreq *, struct hdlcdrv_ioctl *, int); - int (*sethw)(struct device *, struct sm_state *, char *); + int (*sethw)(struct net_device *, struct sm_state *, char *); }; /* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/soundmodem/sm_sbc.c b/drivers/net/hamradio/soundmodem/sm_sbc.c index e66a2e5cb..efc2a3295 100644 --- a/drivers/net/hamradio/soundmodem/sm_sbc.c +++ b/drivers/net/hamradio/soundmodem/sm_sbc.c @@ -140,7 +140,7 @@ struct sc_state_sbc { /* --------------------------------------------------------------------- */ -static int inline reset_dsp(struct device *dev) +static int inline reset_dsp(struct net_device *dev) { int i; @@ -156,7 +156,7 @@ static int inline reset_dsp(struct device *dev) /* --------------------------------------------------------------------- */ -static void inline write_dsp(struct device *dev, unsigned char data) +static void inline write_dsp(struct net_device *dev, unsigned char data) { int i; @@ -169,7 +169,7 @@ static void inline write_dsp(struct device *dev, unsigned char data) /* --------------------------------------------------------------------- */ -static int inline read_dsp(struct device *dev, unsigned char *data) +static int inline read_dsp(struct net_device *dev, unsigned char *data) { int i; @@ -185,7 +185,7 @@ static int inline read_dsp(struct device *dev, unsigned char *data) /* --------------------------------------------------------------------- */ -static int config_resources(struct device *dev, struct sm_state *sm, int fdx) +static int config_resources(struct net_device *dev, struct sm_state *sm, int fdx) { unsigned char irqreg = 0, dmareg = 0, realirq, realdma; unsigned long flags; @@ -266,21 +266,21 @@ static int config_resources(struct device *dev, struct sm_state *sm, int fdx) /* --------------------------------------------------------------------- */ -static void inline sbc_int_ack_8bit(struct device *dev) +static void inline sbc_int_ack_8bit(struct net_device *dev) { inb(DSP_DATA_AVAIL(dev->base_addr)); } /* --------------------------------------------------------------------- */ -static void inline sbc_int_ack_16bit(struct device *dev) +static void inline sbc_int_ack_16bit(struct net_device *dev) { inb(DSP_INTACK_16BIT(dev->base_addr)); } /* --------------------------------------------------------------------- */ -static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send) +static void setup_dma_dsp(struct net_device *dev, struct sm_state *sm, int send) { unsigned long flags; static const unsigned char sbcmode[2][2] = { @@ -323,7 +323,7 @@ static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send) static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned int curfrag; @@ -364,7 +364,7 @@ static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static int sbc_open(struct device *dev, struct sm_state *sm) +static int sbc_open(struct net_device *dev, struct sm_state *sm) { int err; unsigned int dmasz, u; @@ -449,7 +449,7 @@ static int sbc_open(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int sbc_close(struct device *dev, struct sm_state *sm) +static int sbc_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -467,7 +467,7 @@ static int sbc_close(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sbc_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -524,7 +524,7 @@ static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode) /* --------------------------------------------------------------------- */ -static int sbc_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int sbc_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_ioctl bi; @@ -619,7 +619,7 @@ const struct hardware_info sm_hw_sbc = { /* --------------------------------------------------------------------- */ -static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm) +static void setup_dma_fdx_dsp(struct net_device *dev, struct sm_state *sm) { unsigned long flags; unsigned int isamps, osamps; @@ -684,7 +684,7 @@ static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm) static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned char intsrc, pbint = 0, captint = 0; unsigned int ocfrag, icfrag; @@ -747,7 +747,7 @@ static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static int sbcfdx_open(struct device *dev, struct sm_state *sm) +static int sbcfdx_open(struct net_device *dev, struct sm_state *sm) { int err; @@ -830,7 +830,7 @@ static int sbcfdx_open(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int sbcfdx_close(struct device *dev, struct sm_state *sm) +static int sbcfdx_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -851,7 +851,7 @@ static int sbcfdx_close(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sbcfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -917,7 +917,7 @@ static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) /* --------------------------------------------------------------------- */ -static int sbcfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int sbcfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { if (cmd != SIOCDEVPRIVATE) diff --git a/drivers/net/hamradio/soundmodem/sm_wss.c b/drivers/net/hamradio/soundmodem/sm_wss.c index a089544d2..f1dc3744e 100644 --- a/drivers/net/hamradio/soundmodem/sm_wss.c +++ b/drivers/net/hamradio/soundmodem/sm_wss.c @@ -102,7 +102,7 @@ struct sc_state_wss { /* --------------------------------------------------------------------- */ -static void write_codec(struct device *dev, unsigned char idx, +static void write_codec(struct net_device *dev, unsigned char idx, unsigned char data) { int timeout = 900000; @@ -117,7 +117,7 @@ static void write_codec(struct device *dev, unsigned char idx, /* --------------------------------------------------------------------- */ -static unsigned char read_codec(struct device *dev, unsigned char idx) +static unsigned char read_codec(struct net_device *dev, unsigned char idx) { int timeout = 900000; @@ -130,7 +130,7 @@ static unsigned char read_codec(struct device *dev, unsigned char idx) /* --------------------------------------------------------------------- */ -extern void inline wss_ack_int(struct device *dev) +extern void inline wss_ack_int(struct net_device *dev) { outb(0, WSS_CODEC_STATUS(dev->base_addr)); } @@ -154,7 +154,7 @@ static int wss_srate_index(int srate) /* --------------------------------------------------------------------- */ -static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm, unsigned char fmt, +static int wss_set_codec_fmt(struct net_device *dev, struct sm_state *sm, unsigned char fmt, unsigned char fmt2, char fdx, char fullcalib) { unsigned long time; @@ -202,7 +202,7 @@ static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm, unsigned c /* --------------------------------------------------------------------- */ -static int wss_init_codec(struct device *dev, struct sm_state *sm, char fdx, +static int wss_init_codec(struct net_device *dev, struct sm_state *sm, char fdx, unsigned char src_l, unsigned char src_r, int igain_l, int igain_r, int ogain_l, int ogain_r) @@ -341,7 +341,7 @@ static int wss_init_codec(struct device *dev, struct sm_state *sm, char fdx, /* --------------------------------------------------------------------- */ -static void setup_dma_wss(struct device *dev, struct sm_state *sm, int send) +static void setup_dma_wss(struct net_device *dev, struct sm_state *sm, int send) { unsigned long flags; static const unsigned char codecmode[2] = { 0x0e, 0x0d }; @@ -383,7 +383,7 @@ static void setup_dma_wss(struct device *dev, struct sm_state *sm, int send) static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned int curfrag; unsigned int nums; @@ -426,7 +426,7 @@ static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static int wss_open(struct device *dev, struct sm_state *sm) +static int wss_open(struct net_device *dev, struct sm_state *sm) { unsigned int dmasz, u; @@ -484,7 +484,7 @@ static int wss_open(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int wss_close(struct device *dev, struct sm_state *sm) +static int wss_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -502,7 +502,7 @@ static int wss_close(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int wss_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int wss_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -600,7 +600,7 @@ static int wss_sethw(struct device *dev, struct sm_state *sm, char *mode) /* --------------------------------------------------------------------- */ -static int wss_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int wss_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_ioctl bi; @@ -665,7 +665,7 @@ const struct hardware_info sm_hw_wss = { /* --------------------------------------------------------------------- */ -static void setup_fdx_dma_wss(struct device *dev, struct sm_state *sm) +static void setup_fdx_dma_wss(struct net_device *dev, struct sm_state *sm) { unsigned long flags; unsigned char oldcodecmode, codecdma; @@ -703,7 +703,7 @@ static void setup_fdx_dma_wss(struct device *dev, struct sm_state *sm) static void wssfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned long flags; unsigned char cry_int_src; @@ -781,7 +781,7 @@ static void wssfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static int wssfdx_open(struct device *dev, struct sm_state *sm) +static int wssfdx_open(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm || !sm->mode_rx || !sm->mode_tx) return -ENXIO; @@ -840,7 +840,7 @@ static int wssfdx_open(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int wssfdx_close(struct device *dev, struct sm_state *sm) +static int wssfdx_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -861,7 +861,7 @@ static int wssfdx_close(struct device *dev, struct sm_state *sm) /* --------------------------------------------------------------------- */ -static int wssfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int wssfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -938,7 +938,7 @@ static int wssfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) /* --------------------------------------------------------------------- */ -static int wssfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int wssfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { if (cmd != SIOCDEVPRIVATE) diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c new file mode 100644 index 000000000..2c468c8c1 --- /dev/null +++ b/drivers/net/hamradio/yam.c @@ -0,0 +1,1302 @@ +/*****************************************************************************/ + +/* + * yam.c -- YAM radio modem driver. + * + * Copyright (C) 1998 Frederic Rible F1OAT (frible@teaser.fr) + * Adapted from baycom.c driver written by Thomas Sailer (sailer@ife.ee.ethz.ch) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Please note that the GPL allows you to use the driver, NOT the radio. + * In order to use the radio, you need a license from the communications + * authority of your country. + * + * + * History: + * 0.0 F1OAT 06.06.98 Begin of work with baycom.c source code V 0.3 + * 0.1 F1OAT 07.06.98 Add timer polling routine for channel arbitration + * 0.2 F6FBB 08.06.98 Added delay after FPGA programming + * 0.3 F6FBB 29.07.98 Delayed PTT implementation for dupmode=2 + * 0.4 F6FBB 30.07.98 Added TxTail, Slottime and Persistance + * 0.5 F6FBB 01.08.98 Shared IRQs, /proc/net and network statistics + * 0.6 F6FBB 25.08.98 Added 1200Bds format + * 0.7 F6FBB 12.09.98 Added to the kernel configuration + * 0.8 F6FBB 14.10.98 Fixed slottime/persistance timing bug + */ + +/*****************************************************************************/ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/net.h> +#include <linux/in.h> +#include <linux/if.h> +#include <linux/malloc.h> +#include <linux/errno.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/system.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <linux/netdevice.h> +#include <linux/if_arp.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) +/* prototypes for ax25_encapsulate and ax25_rebuild_header */ +#include <net/ax25.h> +#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ + +/* make genksyms happy */ +#include <linux/ip.h> +#include <linux/udp.h> +#include <linux/tcp.h> + +#include <linux/kernel.h> +#include <linux/proc_fs.h> + +#include <linux/yam.h> +#include "yam9600.h" +#include "yam1200.h" + +/* --------------------------------------------------------------------- */ + +/* + * currently this module is supposed to support both module styles, i.e. + * the old one present up to about 2.1.9, and the new one functioning + * starting with 2.1.21. The reason is I have a kit allowing to compile + * this module also under 2.0.x which was requested by several people. + * This will go in 2.2 + */ +#include <linux/version.h> + +#if LINUX_VERSION_CODE >= 0x20100 +#include <asm/uaccess.h> +#else +#include <asm/segment.h> +#include <linux/mm.h> + +#undef put_user +#undef get_user + +#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; }) +#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; }) + +extern inline int copy_from_user(void *to, const void *from, unsigned long n) +{ + int i = verify_area(VERIFY_READ, from, n); + if (i) + return i; + memcpy_fromfs(to, from, n); + return 0; +} + +extern inline int copy_to_user(void *to, const void *from, unsigned long n) +{ + int i = verify_area(VERIFY_WRITE, to, n); + if (i) + return i; + memcpy_tofs(to, from, n); + return 0; +} +#endif + +#if LINUX_VERSION_CODE < 0x20115 +extern __inline__ void dev_init_buffers(struct net_device *dev) +{ + int i; + for (i = 0; i < DEV_NUMBUFFS; i++) { + skb_queue_head_init(&dev->buffs[i]); + } +} +#endif + +#if LINUX_VERSION_CODE >= 0x20123 +#include <linux/init.h> +#else +#define __init +#define __initdata +#endif + +/* --------------------------------------------------------------------- */ + +static const char yam_drvname[] = "yam"; +static const char yam_drvinfo[] = KERN_INFO "YAM driver version 0.8 by F1OAT/F6FBB\n"; + +/* --------------------------------------------------------------------- */ + +#define YAM_9600 1 +#define YAM_1200 2 + +#define NR_PORTS 4 +#define YAM_MAGIC 0xF10A7654 + +/* Transmitter states */ + +#define TX_OFF 0 +#define TX_HEAD 1 +#define TX_DATA 2 +#define TX_CRC1 3 +#define TX_CRC2 4 +#define TX_TAIL 5 + +#define YAM_MAX_FRAME 1024 + +#define DEFAULT_BITRATE 9600 /* bps */ +#define DEFAULT_HOLDD 10 /* sec */ +#define DEFAULT_TXD 300 /* ms */ +#define DEFAULT_TXTAIL 10 /* ms */ +#define DEFAULT_SLOT 100 /* ms */ +#define DEFAULT_PERS 64 /* 0->255 */ + +struct yam_port { + int magic; + int bitrate; + int baudrate; + int iobase; + int irq; + int dupmode; + char name[16]; + + struct net_device dev; + + /* Stats section */ + +#if LINUX_VERSION_CODE < 0x20119 + struct enet_statistics stats; +#else + struct net_device_stats stats; +#endif + int nb_rxint; + int nb_mdint; + + /* Parameters section */ + + int txd; /* tx delay */ + int holdd; /* duplex ptt delay */ + int txtail; /* txtail delay */ + int slot; /* slottime */ + int pers; /* persistence */ + + /* Tx section */ + + int tx_state; + int tx_count; + int slotcnt; + unsigned char tx_buf[YAM_MAX_FRAME]; + int tx_len; + int tx_crcl, tx_crch; + struct sk_buff_head send_queue; /* Packets awaiting transmission */ + + /* Rx section */ + + int dcd; + unsigned char rx_buf[YAM_MAX_FRAME]; + int rx_len; + int rx_crcl, rx_crch; +}; + +struct yam_mcs { + unsigned char bits[YAM_FPGA_SIZE]; + int bitrate; + struct yam_mcs *next; +}; + +static struct yam_port yam_ports[NR_PORTS]; + +static struct yam_mcs *yam_data = NULL; + +static unsigned irqs[16]; + +static char ax25_bcast[7] = +{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1}; +static char ax25_test[7] = +{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1}; + +static struct timer_list yam_timer; + +/* --------------------------------------------------------------------- */ + +#define RBR(iobase) (iobase+0) +#define THR(iobase) (iobase+0) +#define IER(iobase) (iobase+1) +#define IIR(iobase) (iobase+2) +#define FCR(iobase) (iobase+2) +#define LCR(iobase) (iobase+3) +#define MCR(iobase) (iobase+4) +#define LSR(iobase) (iobase+5) +#define MSR(iobase) (iobase+6) +#define SCR(iobase) (iobase+7) +#define DLL(iobase) (iobase+0) +#define DLM(iobase) (iobase+1) + +#define YAM_EXTENT 8 + +/* Interrupt Identification Register Bit Masks */ +#define IIR_NOPEND 1 +#define IIR_MSR 0 +#define IIR_TX 2 +#define IIR_RX 4 +#define IIR_LSR 6 +#define IIR_TIMEOUT 12 /* Fifo mode only */ + +#define IIR_MASK 0x0F + +/* Interrupt Enable Register Bit Masks */ +#define IER_RX 1 /* enable rx interrupt */ +#define IER_TX 2 /* enable tx interrupt */ +#define IER_LSR 4 /* enable line status interrupts */ +#define IER_MSR 8 /* enable modem status interrupts */ + +/* Modem Control Register Bit Masks */ +#define MCR_DTR 0x01 /* DTR output */ +#define MCR_RTS 0x02 /* RTS output */ +#define MCR_OUT1 0x04 /* OUT1 output (not accessible in RS232) */ +#define MCR_OUT2 0x08 /* Master Interrupt enable (must be set on PCs) */ +#define MCR_LOOP 0x10 /* Loopback enable */ + +/* Modem Status Register Bit Masks */ +#define MSR_DCTS 0x01 /* Delta CTS input */ +#define MSR_DDSR 0x02 /* Delta DSR */ +#define MSR_DRIN 0x04 /* Delta RI */ +#define MSR_DDCD 0x08 /* Delta DCD */ +#define MSR_CTS 0x10 /* CTS input */ +#define MSR_DSR 0x20 /* DSR input */ +#define MSR_RING 0x40 /* RI input */ +#define MSR_DCD 0x80 /* DCD input */ + +/* line status register bit mask */ +#define LSR_RXC 0x01 +#define LSR_OE 0x02 +#define LSR_PE 0x04 +#define LSR_FE 0x08 +#define LSR_BREAK 0x10 +#define LSR_THRE 0x20 +#define LSR_TSRE 0x40 + +/* Line Control Register Bit Masks */ +#define LCR_DLAB 0x80 +#define LCR_BREAK 0x40 +#define LCR_PZERO 0x28 +#define LCR_PEVEN 0x18 +#define LCR_PODD 0x08 +#define LCR_STOP1 0x00 +#define LCR_STOP2 0x04 +#define LCR_BIT5 0x00 +#define LCR_BIT6 0x02 +#define LCR_BIT7 0x01 +#define LCR_BIT8 0x03 + +/* YAM Modem <-> UART Port mapping */ + +#define TX_RDY MSR_DCTS /* transmitter ready to send */ +#define RX_DCD MSR_DCD /* carrier detect */ +#define RX_FLAG MSR_RING /* hdlc flag received */ +#define FPGA_DONE MSR_DSR /* FPGA is configured */ +#define PTT_ON (MCR_RTS|MCR_OUT2) /* activate PTT */ +#define PTT_OFF (MCR_DTR|MCR_OUT2) /* release PTT */ + +#define ENABLE_RXINT IER_RX /* enable uart rx interrupt during rx */ +#define ENABLE_TXINT IER_MSR /* enable uart ms interrupt during tx */ +#define ENABLE_RTXINT (IER_RX|IER_MSR) /* full duplex operations */ + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/************************************************************************* +* CRC Tables +************************************************************************/ + +static const unsigned char chktabl[256] = +{0x00, 0x89, 0x12, 0x9b, 0x24, 0xad, 0x36, 0xbf, 0x48, 0xc1, 0x5a, 0xd3, 0x6c, 0xe5, 0x7e, + 0xf7, 0x81, 0x08, 0x93, 0x1a, 0xa5, 0x2c, 0xb7, 0x3e, 0xc9, 0x40, 0xdb, 0x52, 0xed, 0x64, + 0xff, 0x76, 0x02, 0x8b, 0x10, 0x99, 0x26, 0xaf, 0x34, 0xbd, 0x4a, 0xc3, 0x58, 0xd1, 0x6e, + 0xe7, 0x7c, 0xf5, 0x83, 0x0a, 0x91, 0x18, 0xa7, 0x2e, 0xb5, 0x3c, 0xcb, 0x42, 0xd9, 0x50, + 0xef, 0x66, 0xfd, 0x74, 0x04, 0x8d, 0x16, 0x9f, 0x20, 0xa9, 0x32, 0xbb, 0x4c, 0xc5, 0x5e, + 0xd7, 0x68, 0xe1, 0x7a, 0xf3, 0x85, 0x0c, 0x97, 0x1e, 0xa1, 0x28, 0xb3, 0x3a, 0xcd, 0x44, + 0xdf, 0x56, 0xe9, 0x60, 0xfb, 0x72, 0x06, 0x8f, 0x14, 0x9d, 0x22, 0xab, 0x30, 0xb9, 0x4e, + 0xc7, 0x5c, 0xd5, 0x6a, 0xe3, 0x78, 0xf1, 0x87, 0x0e, 0x95, 0x1c, 0xa3, 0x2a, 0xb1, 0x38, + 0xcf, 0x46, 0xdd, 0x54, 0xeb, 0x62, 0xf9, 0x70, 0x08, 0x81, 0x1a, 0x93, 0x2c, 0xa5, 0x3e, + 0xb7, 0x40, 0xc9, 0x52, 0xdb, 0x64, 0xed, 0x76, 0xff, 0x89, 0x00, 0x9b, 0x12, 0xad, 0x24, + 0xbf, 0x36, 0xc1, 0x48, 0xd3, 0x5a, 0xe5, 0x6c, 0xf7, 0x7e, 0x0a, 0x83, 0x18, 0x91, 0x2e, + 0xa7, 0x3c, 0xb5, 0x42, 0xcb, 0x50, 0xd9, 0x66, 0xef, 0x74, 0xfd, 0x8b, 0x02, 0x99, 0x10, + 0xaf, 0x26, 0xbd, 0x34, 0xc3, 0x4a, 0xd1, 0x58, 0xe7, 0x6e, 0xf5, 0x7c, 0x0c, 0x85, 0x1e, + 0x97, 0x28, 0xa1, 0x3a, 0xb3, 0x44, 0xcd, 0x56, 0xdf, 0x60, 0xe9, 0x72, 0xfb, 0x8d, 0x04, + 0x9f, 0x16, 0xa9, 0x20, 0xbb, 0x32, 0xc5, 0x4c, 0xd7, 0x5e, 0xe1, 0x68, 0xf3, 0x7a, 0x0e, + 0x87, 0x1c, 0x95, 0x2a, 0xa3, 0x38, 0xb1, 0x46, 0xcf, 0x54, 0xdd, 0x62, 0xeb, 0x70, 0xf9, + 0x8f, 0x06, 0x9d, 0x14, 0xab, 0x22, 0xb9, 0x30, 0xc7, 0x4e, 0xd5, 0x5c, 0xe3, 0x6a, 0xf1, + 0x78}; +static const unsigned char chktabh[256] = +{0x00, 0x11, 0x23, 0x32, 0x46, 0x57, 0x65, 0x74, 0x8c, 0x9d, 0xaf, 0xbe, 0xca, 0xdb, 0xe9, + 0xf8, 0x10, 0x01, 0x33, 0x22, 0x56, 0x47, 0x75, 0x64, 0x9c, 0x8d, 0xbf, 0xae, 0xda, 0xcb, + 0xf9, 0xe8, 0x21, 0x30, 0x02, 0x13, 0x67, 0x76, 0x44, 0x55, 0xad, 0xbc, 0x8e, 0x9f, 0xeb, + 0xfa, 0xc8, 0xd9, 0x31, 0x20, 0x12, 0x03, 0x77, 0x66, 0x54, 0x45, 0xbd, 0xac, 0x9e, 0x8f, + 0xfb, 0xea, 0xd8, 0xc9, 0x42, 0x53, 0x61, 0x70, 0x04, 0x15, 0x27, 0x36, 0xce, 0xdf, 0xed, + 0xfc, 0x88, 0x99, 0xab, 0xba, 0x52, 0x43, 0x71, 0x60, 0x14, 0x05, 0x37, 0x26, 0xde, 0xcf, + 0xfd, 0xec, 0x98, 0x89, 0xbb, 0xaa, 0x63, 0x72, 0x40, 0x51, 0x25, 0x34, 0x06, 0x17, 0xef, + 0xfe, 0xcc, 0xdd, 0xa9, 0xb8, 0x8a, 0x9b, 0x73, 0x62, 0x50, 0x41, 0x35, 0x24, 0x16, 0x07, + 0xff, 0xee, 0xdc, 0xcd, 0xb9, 0xa8, 0x9a, 0x8b, 0x84, 0x95, 0xa7, 0xb6, 0xc2, 0xd3, 0xe1, + 0xf0, 0x08, 0x19, 0x2b, 0x3a, 0x4e, 0x5f, 0x6d, 0x7c, 0x94, 0x85, 0xb7, 0xa6, 0xd2, 0xc3, + 0xf1, 0xe0, 0x18, 0x09, 0x3b, 0x2a, 0x5e, 0x4f, 0x7d, 0x6c, 0xa5, 0xb4, 0x86, 0x97, 0xe3, + 0xf2, 0xc0, 0xd1, 0x29, 0x38, 0x0a, 0x1b, 0x6f, 0x7e, 0x4c, 0x5d, 0xb5, 0xa4, 0x96, 0x87, + 0xf3, 0xe2, 0xd0, 0xc1, 0x39, 0x28, 0x1a, 0x0b, 0x7f, 0x6e, 0x5c, 0x4d, 0xc6, 0xd7, 0xe5, + 0xf4, 0x80, 0x91, 0xa3, 0xb2, 0x4a, 0x5b, 0x69, 0x78, 0x0c, 0x1d, 0x2f, 0x3e, 0xd6, 0xc7, + 0xf5, 0xe4, 0x90, 0x81, 0xb3, 0xa2, 0x5a, 0x4b, 0x79, 0x68, 0x1c, 0x0d, 0x3f, 0x2e, 0xe7, + 0xf6, 0xc4, 0xd5, 0xa1, 0xb0, 0x82, 0x93, 0x6b, 0x7a, 0x48, 0x59, 0x2d, 0x3c, 0x0e, 0x1f, + 0xf7, 0xe6, 0xd4, 0xc5, 0xb1, 0xa0, 0x92, 0x83, 0x7b, 0x6a, 0x58, 0x49, 0x3d, 0x2c, 0x1e, + 0x0f}; + +/************************************************************************* +* FPGA functions +************************************************************************/ + +static void delay(int ms) +{ + unsigned long timeout = jiffies + ((ms * HZ) / 1000); + while (jiffies < timeout); +} + +/* + * reset FPGA + */ + +static void fpga_reset(int iobase) +{ + outb(0, IER(iobase)); + outb(LCR_DLAB | LCR_BIT5, LCR(iobase)); + outb(1, DLL(iobase)); + outb(0, DLM(iobase)); + + outb(LCR_BIT5, LCR(iobase)); + inb(LSR(iobase)); + inb(MSR(iobase)); + /* turn off FPGA supply voltage */ + outb(MCR_OUT1 | MCR_OUT2, MCR(iobase)); + delay(100); + /* turn on FPGA supply voltage again */ + outb(MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2, MCR(iobase)); + delay(100); +} + +/* + * send one byte to FPGA + */ + +static int fpga_write(int iobase, unsigned char wrd) +{ + unsigned char bit; + int k; + unsigned long timeout = jiffies + HZ / 10; + + for (k = 0; k < 8; k++) { + bit = (wrd & 0x80) ? (MCR_RTS | MCR_DTR) : MCR_DTR; + outb(bit | MCR_OUT1 | MCR_OUT2, MCR(iobase)); + wrd <<= 1; + outb(0xfc, THR(iobase)); + while ((inb(LSR(iobase)) & LSR_TSRE) == 0) + if (jiffies > timeout) + return -1; + } + + return 0; +} + +#ifdef MODULE +static void free_mcs(void) +{ + struct yam_mcs *p; + + while (yam_data) { + p = yam_data; + yam_data = yam_data->next; + kfree(p); + } +} +#endif + +static unsigned char * + add_mcs(unsigned char *bits, int bitrate) +{ + struct yam_mcs *p; + + /* If it already exists, replace the bit data */ + p = yam_data; + while (p) { + if (p->bitrate == bitrate) { + memcpy(p->bits, bits, YAM_FPGA_SIZE); + return p->bits; + } + p = p->next; + } + + /* Allocate a new mcs */ + p = kmalloc(sizeof(struct yam_mcs), GFP_ATOMIC); + if (p == NULL) { + printk(KERN_WARNING "YAM: no memory to allocate mcs\n"); + return NULL; + } + memcpy(p->bits, bits, YAM_FPGA_SIZE); + p->bitrate = bitrate; + p->next = yam_data; + yam_data = p; + + return p->bits; +} + +static unsigned char *get_mcs(int bitrate) +{ + struct yam_mcs *p; + + p = yam_data; + while (p) { + if (p->bitrate == bitrate) + return p->bits; + p = p->next; + } + + /* Load predefined mcs data */ + switch (bitrate) { + case 1200: + return add_mcs(bits_1200, bitrate); + default: + return add_mcs(bits_9600, bitrate); + } +} + +/* + * download bitstream to FPGA + * data is contained in bits[] array in fpgaconf.h + */ + +static int fpga_download(int iobase, int bitrate) +{ + int i, rc; + unsigned char *pbits; + + pbits = get_mcs(bitrate); + if (pbits == NULL) + return -1; + + fpga_reset(iobase); + for (i = 0; i < YAM_FPGA_SIZE; i++) { + if (fpga_write(iobase, pbits[i])) { + printk("yam: error in write cycle\n"); + return -1; /* write... */ + } + } + + fpga_write(iobase, 0xFF); + rc = inb(MSR(iobase)); /* check DONE signal */ + + /* Needed for some hardwares */ + delay(50); + + return (rc & MSR_DSR) ? 0 : -1; +} + + +/************************************************************************ +* Serial port init +************************************************************************/ + +static void yam_set_uart(struct net_device *dev) +{ + struct yam_port *yp = (struct yam_port *) dev->priv; + int divisor = 115200 / yp->baudrate; + + outb(0, IER(dev->base_addr)); + outb(LCR_DLAB | LCR_BIT8, LCR(dev->base_addr)); + outb(divisor, DLL(dev->base_addr)); + outb(0, DLM(dev->base_addr)); + outb(LCR_BIT8, LCR(dev->base_addr)); + outb(PTT_OFF, MCR(dev->base_addr)); + outb(0x00, FCR(dev->base_addr)); + + /* Flush pending irq */ + + inb(RBR(dev->base_addr)); + inb(MSR(dev->base_addr)); + + /* Enable rx irq */ + + outb(ENABLE_RTXINT, IER(dev->base_addr)); +} + + +/* --------------------------------------------------------------------- */ + +enum uart { + c_uart_unknown, c_uart_8250, + c_uart_16450, c_uart_16550, c_uart_16550A +}; + +static const char *uart_str[] = +{"unknown", "8250", "16450", "16550", "16550A"}; + +static enum uart yam_check_uart(unsigned int iobase) +{ + unsigned char b1, b2, b3; + enum uart u; + enum uart uart_tab[] = + {c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A}; + + b1 = inb(MCR(iobase)); + outb(b1 | 0x10, MCR(iobase)); /* loopback mode */ + b2 = inb(MSR(iobase)); + outb(0x1a, MCR(iobase)); + b3 = inb(MSR(iobase)) & 0xf0; + outb(b1, MCR(iobase)); /* restore old values */ + outb(b2, MSR(iobase)); + if (b3 != 0x90) + return c_uart_unknown; + inb(RBR(iobase)); + inb(RBR(iobase)); + outb(0x01, FCR(iobase)); /* enable FIFOs */ + u = uart_tab[(inb(IIR(iobase)) >> 6) & 3]; + if (u == c_uart_16450) { + outb(0x5a, SCR(iobase)); + b1 = inb(SCR(iobase)); + outb(0xa5, SCR(iobase)); + b2 = inb(SCR(iobase)); + if ((b1 != 0x5a) || (b2 != 0xa5)) + u = c_uart_8250; + } + return u; +} + +/****************************************************************************** +* Rx Section +******************************************************************************/ +static void inline + yam_rx_flag(struct net_device *dev, struct yam_port *yp) +{ + if (yp->dcd && yp->rx_len >= 3 && yp->rx_len < YAM_MAX_FRAME) { + int pkt_len = yp->rx_len - 2 + 1; /* -CRC + kiss */ + struct sk_buff *skb; + + if ((yp->rx_crch & yp->rx_crcl) != 0xFF) { + /* Bad crc */ + } else { + if (!(skb = dev_alloc_skb(pkt_len))) { + printk("%s: memory squeeze, dropping packet\n", dev->name); + ++yp->stats.rx_dropped; + } else { + unsigned char *cp; + skb->dev = dev; + cp = skb_put(skb, pkt_len); + *cp++ = 0; /* KISS kludge */ + memcpy(cp, yp->rx_buf, pkt_len - 1); + skb->protocol = htons(ETH_P_AX25); + skb->mac.raw = skb->data; + netif_rx(skb); + ++yp->stats.rx_packets; + } + } + } + yp->rx_len = 0; + yp->rx_crcl = 0x21; + yp->rx_crch = 0xf3; +} + +static void inline + yam_rx_byte(struct net_device *dev, struct yam_port *yp, unsigned char rxb) +{ + if (yp->rx_len < YAM_MAX_FRAME) { + unsigned char c = yp->rx_crcl; + yp->rx_crcl = (chktabl[c] ^ yp->rx_crch); + yp->rx_crch = (chktabh[c] ^ rxb); + yp->rx_buf[yp->rx_len++] = rxb; + } +} + +/******************************************************************************** +* TX Section +********************************************************************************/ + +static void ptt_on(struct net_device *dev) +{ + outb(PTT_ON, MCR(dev->base_addr)); +} + +static void ptt_off(struct net_device *dev) +{ + outb(PTT_OFF, MCR(dev->base_addr)); +} + +static int yam_send_packet(struct sk_buff *skb, struct net_device *dev) +{ + struct yam_port *yp = dev->priv; + + if (skb == NULL) { + return 0; + } + skb_queue_tail(&yp->send_queue, skb); + dev->trans_start = jiffies; + return 0; +} + +static void yam_start_tx(struct net_device *dev, struct yam_port *yp) +{ + if ((yp->tx_state == TX_TAIL) || (yp->txd == 0)) + yp->tx_count = 1; + else + yp->tx_count = (yp->bitrate * yp->txd) / 8000; + yp->tx_state = TX_HEAD; + ptt_on(dev); +} + +static unsigned short random_seed; + +static inline unsigned short random_num(void) +{ + random_seed = 28629 * random_seed + 157; + return random_seed; +} + +static void yam_arbitrate(struct net_device *dev) +{ + struct yam_port *yp = dev->priv; + + if (!yp || yp->magic != YAM_MAGIC + || yp->tx_state != TX_OFF || skb_queue_empty(&yp->send_queue)) { + return; + } + /* tx_state is TX_OFF and there is data to send */ + + if (yp->dupmode) { + /* Full duplex mode, don't wait */ + yam_start_tx(dev, yp); + return; + } + if (yp->dcd) { + /* DCD on, wait slotime ... */ + yp->slotcnt = yp->slot / 10; + return; + } + /* Is slottime passed ? */ + if ((--yp->slotcnt) > 0) + return; + + yp->slotcnt = yp->slot / 10; + + /* is random > persist ? */ + if ((random_num() % 256) > yp->pers) + return; + + yam_start_tx(dev, yp); +} + +static void yam_dotimer(unsigned long dummy) +{ + int i; + + for (i = 0; i < NR_PORTS; i++) { + struct net_device *dev = &yam_ports[i].dev; + if (dev->start) + yam_arbitrate(dev); + } + yam_timer.expires = jiffies + HZ / 100; + add_timer(&yam_timer); +} + +static void yam_tx_byte(struct net_device *dev, struct yam_port *yp) +{ + struct sk_buff *skb; + unsigned char b, temp; + + switch (yp->tx_state) { + case TX_OFF: + break; + case TX_HEAD: + if (--yp->tx_count <= 0) { + if (!(skb = skb_dequeue(&yp->send_queue))) { + ptt_off(dev); + yp->tx_state = TX_OFF; + break; + } + yp->tx_state = TX_DATA; + if (skb->data[0] != 0) { +/* do_kiss_params(s, skb->data, skb->len); */ + dev_kfree_skb(skb); + break; + } + yp->tx_len = skb->len - 1; /* strip KISS byte */ + if (yp->tx_len >= YAM_MAX_FRAME || yp->tx_len < 2) { + dev_kfree_skb(skb); + break; + } + memcpy(yp->tx_buf, skb->data + 1, yp->tx_len); + dev_kfree_skb(skb); + yp->tx_count = 0; + yp->tx_crcl = 0x21; + yp->tx_crch = 0xf3; + yp->tx_state = TX_DATA; + } + break; + case TX_DATA: + b = yp->tx_buf[yp->tx_count++]; + outb(b, THR(dev->base_addr)); + temp = yp->tx_crcl; + yp->tx_crcl = chktabl[temp] ^ yp->tx_crch; + yp->tx_crch = chktabh[temp] ^ b; + if (yp->tx_count >= yp->tx_len) { + yp->tx_state = TX_CRC1; + } + break; + case TX_CRC1: + yp->tx_crch = chktabl[yp->tx_crcl] ^ yp->tx_crch; + yp->tx_crcl = chktabh[yp->tx_crcl] ^ chktabl[yp->tx_crch] ^ 0xff; + outb(yp->tx_crcl, THR(dev->base_addr)); + yp->tx_state = TX_CRC2; + break; + case TX_CRC2: + outb(chktabh[yp->tx_crch] ^ 0xFF, THR(dev->base_addr)); + if (skb_queue_empty(&yp->send_queue)) { + yp->tx_count = (yp->bitrate * yp->txtail) / 8000; + if (yp->dupmode == 2) + yp->tx_count += (yp->bitrate * yp->holdd) / 8; + if (yp->tx_count == 0) + yp->tx_count = 1; + yp->tx_state = TX_TAIL; + } else { + yp->tx_count = 1; + yp->tx_state = TX_HEAD; + } + ++yp->stats.tx_packets; + break; + case TX_TAIL: + if (--yp->tx_count <= 0) { + yp->tx_state = TX_OFF; + ptt_off(dev); + } + break; + } +} + +/*********************************************************************************** +* ISR routine +************************************************************************************/ + +static void yam_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev; + struct yam_port *yp; + unsigned char iir; + int counter = 100; + int i; + + sti(); + + for (i = 0; i < NR_PORTS; i++) { + yp = &yam_ports[i]; + dev = &yp->dev; + + if (!dev->start) + continue; + + while ((iir = IIR_MASK & inb(IIR(dev->base_addr))) != IIR_NOPEND) { + unsigned char msr = inb(MSR(dev->base_addr)); + unsigned char lsr = inb(LSR(dev->base_addr)); + unsigned char rxb; + + if (lsr & LSR_OE) + ++yp->stats.rx_fifo_errors; + + yp->dcd = (msr & RX_DCD) ? 1 : 0; + + if (--counter <= 0) { + printk("%s: too many irq iir=%d\n", dev->name, iir); + return; + } + if (msr & TX_RDY) { + ++yp->nb_mdint; + yam_tx_byte(dev, yp); + } + if (lsr & LSR_RXC) { + ++yp->nb_rxint; + rxb = inb(RBR(dev->base_addr)); + if (msr & RX_FLAG) + yam_rx_flag(dev, yp); + else + yam_rx_byte(dev, yp, rxb); + } + } + } +} + +static int yam_net_get_info(char *buffer, char **start, off_t offset, int length, int dummy) +{ + int len = 0; + int i; + off_t pos = 0; + off_t begin = 0; + + cli(); + + for (i = 0; i < NR_PORTS; i++) { + if (yam_ports[i].iobase == 0 || yam_ports[i].irq == 0) + continue; + len += sprintf(buffer + len, "Device %s\n", yam_ports[i].name); + len += sprintf(buffer + len, " Up %d\n", yam_ports[i].dev.start); + len += sprintf(buffer + len, " Speed %u\n", yam_ports[i].bitrate); + len += sprintf(buffer + len, " IoBase 0x%x\n", yam_ports[i].iobase); + len += sprintf(buffer + len, " BaudRate %u\n", yam_ports[i].baudrate); + len += sprintf(buffer + len, " IRQ %u\n", yam_ports[i].irq); + len += sprintf(buffer + len, " TxState %u\n", yam_ports[i].tx_state); + len += sprintf(buffer + len, " Duplex %u\n", yam_ports[i].dupmode); + len += sprintf(buffer + len, " HoldDly %u\n", yam_ports[i].holdd); + len += sprintf(buffer + len, " TxDelay %u\n", yam_ports[i].txd); + len += sprintf(buffer + len, " TxTail %u\n", yam_ports[i].txtail); + len += sprintf(buffer + len, " SlotTime %u\n", yam_ports[i].slot); + len += sprintf(buffer + len, " Persist %u\n", yam_ports[i].pers); + len += sprintf(buffer + len, " TxFrames %lu\n", yam_ports[i].stats.tx_packets); + len += sprintf(buffer + len, " RxFrames %lu\n", yam_ports[i].stats.rx_packets); + len += sprintf(buffer + len, " TxInt %u\n", yam_ports[i].nb_mdint); + len += sprintf(buffer + len, " RxInt %u\n", yam_ports[i].nb_rxint); + len += sprintf(buffer + len, " RxOver %lu\n", yam_ports[i].stats.rx_fifo_errors); + len += sprintf(buffer + len, "\n"); + + pos = begin + len; + + if (pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) + break; + } + + sti(); + + *start = buffer + (offset - begin); + len -= (offset - begin); + + if (len > length) + len = length; + + return len; +} + +#ifdef CONFIG_INET + +#ifndef PROC_NET_YAM +#define PROC_NET_YAM (PROC_NET_LAST+10) /* Sorry again... */ +#endif + +#ifdef CONFIG_PROC_FS +struct proc_dir_entry yam_proc_dir_entry = +{ + PROC_NET_YAM, 3, "yam", S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, yam_net_get_info +}; + +#define yam_net_procfs_init() proc_net_register(&yam_proc_dir_entry); +#define yam_net_procfs_remove() proc_net_unregister(PROC_NET_YAM); +#else +#define yam_net_procfs_init() +#define yam_net_procfs_remove() +#endif +#else +#define yam_net_procfs_init() +#define yam_net_procfs_remove() +#endif + +/* --------------------------------------------------------------------- */ + +#if LINUX_VERSION_CODE >= 0x20119 +static struct net_device_stats * + yam_get_stats(struct net_device *dev) +#else +static struct enet_statistics * + yam_get_stats(struct net_device *dev) +#endif +{ + struct yam_port *yp; + + if (!dev || !dev->priv) + return NULL; + + yp = (struct yam_port *) dev->priv; + if (yp->magic != YAM_MAGIC) + return NULL; + + /* + * Get the current statistics. This may be called with the + * card open or closed. + */ + return &yp->stats; +} + +/* --------------------------------------------------------------------- */ + +static int yam_open(struct net_device *dev) +{ + struct yam_port *yp = (struct yam_port *) dev->priv; + enum uart u; + int i; + + printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq); + + if (!dev || !yp || !yp->bitrate) + return -ENXIO; + if (!dev->base_addr || dev->base_addr > 0x1000 - YAM_EXTENT || + dev->irq < 2 || dev->irq > 15) { + return -ENXIO; + } + if (check_region(dev->base_addr, YAM_EXTENT)) { + printk("%s: cannot 0x%lx busy\n", dev->name, dev->base_addr); + return -EACCES; + } + if ((u = yam_check_uart(dev->base_addr)) == c_uart_unknown) { + printk("%s: cannot find uart type\n", dev->name); + return -EIO; + } + if (fpga_download(dev->base_addr, yp->bitrate)) { + printk("%s: cannot init FPGA\n", dev->name); + return -EIO; + } + outb(0, IER(dev->base_addr)); + if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, NULL)) { + printk("%s: irq %d busy\n", dev->name, dev->irq); + return -EBUSY; + } + request_region(dev->base_addr, YAM_EXTENT, dev->name); + + yam_set_uart(dev); + dev->start = 1; + yp->slotcnt = yp->slot / 10; + + /* Reset overruns for all ports - FPGA programming makes overruns */ + for (i = 0; i < NR_PORTS; i++) { + inb(LSR(yam_ports[i].dev.base_addr)); + yam_ports[i].stats.rx_fifo_errors = 0; + } + + printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq, + uart_str[u]); + MOD_INC_USE_COUNT; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int yam_close(struct net_device *dev) +{ + struct sk_buff *skb; + struct yam_port *yp = (struct yam_port *) dev->priv; + + if (!dev || !yp) + return -EINVAL; + /* + * disable interrupts + */ + outb(0, IER(dev->base_addr)); + outb(1, MCR(dev->base_addr)); + /* Remove IRQ handler if last */ + free_irq(dev->irq, NULL); + release_region(dev->base_addr, YAM_EXTENT); + dev->start = 0; + dev->tbusy = 1; + while ((skb = skb_dequeue(&yp->send_queue))) + dev_kfree_skb(skb); + + printk(KERN_INFO "%s: close yam at iobase 0x%lx irq %u\n", + yam_drvname, dev->base_addr, dev->irq); + MOD_DEC_USE_COUNT; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct yam_port *yp = (struct yam_port *) dev->priv; + struct yamdrv_ioctl_cfg yi; + struct yamdrv_ioctl_mcs *ym; + int ioctl_cmd; + + if (copy_from_user(&ioctl_cmd, ifr->ifr_data, sizeof(int))) + return -EFAULT; + + if (yp == NULL || yp->magic != YAM_MAGIC) + return -EINVAL; + + if (!suser()) + return -EPERM; + + if (cmd != SIOCDEVPRIVATE) + return -EINVAL; + + switch (ioctl_cmd) { + + case SIOCYAMRESERVED: + return -EINVAL; /* unused */ + + case SIOCYAMSMCS: + if (dev->start) + return -EINVAL; /* Cannot change this parameter when up */ + ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_ATOMIC); + ym->bitrate = 9600; + if (copy_from_user(ym, ifr->ifr_data, sizeof(struct yamdrv_ioctl_mcs))) + return -EFAULT; + if (ym->bitrate > YAM_MAXBITRATE) + return -EINVAL; + add_mcs(ym->bits, ym->bitrate); + kfree(ym); + break; + + case SIOCYAMSCFG: + if (copy_from_user(&yi, ifr->ifr_data, sizeof(struct yamdrv_ioctl_cfg))) + return -EFAULT; + + if ((yi.cfg.mask & YAM_IOBASE) && dev->start) + return -EINVAL; /* Cannot change this parameter when up */ + if ((yi.cfg.mask & YAM_IRQ) && dev->start) + return -EINVAL; /* Cannot change this parameter when up */ + if ((yi.cfg.mask & YAM_BITRATE) && dev->start) + return -EINVAL; /* Cannot change this parameter when up */ + if ((yi.cfg.mask & YAM_BAUDRATE) && dev->start) + return -EINVAL; /* Cannot change this parameter when up */ + + if (yi.cfg.mask & YAM_IOBASE) { + yp->iobase = yi.cfg.iobase; + dev->base_addr = yi.cfg.iobase; + } + if (yi.cfg.mask & YAM_IRQ) { + if (yi.cfg.irq > 15) + return -EINVAL; + yp->irq = yi.cfg.irq; + dev->irq = yi.cfg.irq; + } + if (yi.cfg.mask & YAM_BITRATE) { + if (yi.cfg.bitrate > YAM_MAXBITRATE) + return -EINVAL; + yp->bitrate = yi.cfg.bitrate; + } + if (yi.cfg.mask & YAM_BAUDRATE) { + if (yi.cfg.baudrate > YAM_MAXBAUDRATE) + return -EINVAL; + yp->baudrate = yi.cfg.baudrate; + } + if (yi.cfg.mask & YAM_MODE) { + if (yi.cfg.mode > YAM_MAXMODE) + return -EINVAL; + yp->dupmode = yi.cfg.mode; + } + if (yi.cfg.mask & YAM_HOLDDLY) { + if (yi.cfg.holddly > YAM_MAXHOLDDLY) + return -EINVAL; + yp->holdd = yi.cfg.holddly; + } + if (yi.cfg.mask & YAM_TXDELAY) { + if (yi.cfg.txdelay > YAM_MAXTXDELAY) + return -EINVAL; + yp->txd = yi.cfg.txdelay; + } + if (yi.cfg.mask & YAM_TXTAIL) { + if (yi.cfg.txtail > YAM_MAXTXTAIL) + return -EINVAL; + yp->txtail = yi.cfg.txtail; + } + if (yi.cfg.mask & YAM_PERSIST) { + if (yi.cfg.persist > YAM_MAXPERSIST) + return -EINVAL; + yp->pers = yi.cfg.persist; + } + if (yi.cfg.mask & YAM_SLOTTIME) { + if (yi.cfg.slottime > YAM_MAXSLOTTIME) + return -EINVAL; + yp->slot = yi.cfg.slottime; + yp->slotcnt = yp->slot / 10; + } + break; + + case SIOCYAMGCFG: + yi.cfg.mask = 0xffffffff; + yi.cfg.iobase = yp->iobase; + yi.cfg.irq = yp->irq; + yi.cfg.bitrate = yp->bitrate; + yi.cfg.baudrate = yp->baudrate; + yi.cfg.mode = yp->dupmode; + yi.cfg.txdelay = yp->txd; + yi.cfg.holddly = yp->holdd; + yi.cfg.txtail = yp->txtail; + yi.cfg.persist = yp->pers; + yi.cfg.slottime = yp->slot; + if (copy_to_user(ifr->ifr_data, &yi, sizeof(struct yamdrv_ioctl_cfg))) + return -EFAULT; + break; + + default: + return -EINVAL; + + } + + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int yam_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *sa = (struct sockaddr *) addr; + + /* addr is an AX.25 shifted ASCII mac address */ + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int yam_probe(struct net_device *dev) +{ + struct yam_port *yp; + + if (!dev) + return -ENXIO; + + yp = (struct yam_port *) dev->priv; + + dev->open = yam_open; + dev->stop = yam_close; + dev->do_ioctl = yam_ioctl; + dev->hard_start_xmit = yam_send_packet; + dev->get_stats = yam_get_stats; + + dev_init_buffers(dev); + skb_queue_head_init(&yp->send_queue); + +#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) + dev->hard_header = ax25_encapsulate; + dev->rebuild_header = ax25_rebuild_header; +#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */ + dev->hard_header = NULL; + dev->rebuild_header = NULL; +#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ + + dev->set_mac_address = yam_set_mac_address; + + dev->type = ARPHRD_AX25; /* AF_AX25 device */ + dev->hard_header_len = 73; /* We do digipeaters now */ + dev->mtu = 256; /* AX25 is the default */ + dev->addr_len = 7; /* sizeof an ax.25 address */ + memcpy(dev->broadcast, ax25_bcast, 7); + memcpy(dev->dev_addr, ax25_test, 7); + + /* New style flags */ + dev->flags = 0; + + return 0; +} + +/* --------------------------------------------------------------------- */ + +int __init yam_init(struct net_device *dev) +{ + int i; + + printk(yam_drvinfo); + + /* Clears the IRQ table */ + memset(irqs, 0, sizeof(irqs)); + memset(yam_ports, 0, sizeof(yam_ports)); + + for (i = 0; i < NR_PORTS; i++) { + sprintf(yam_ports[i].name, "yam%d", i); + yam_ports[i].magic = YAM_MAGIC; + yam_ports[i].bitrate = DEFAULT_BITRATE; + yam_ports[i].baudrate = DEFAULT_BITRATE * 2; + yam_ports[i].iobase = 0; + yam_ports[i].irq = 0; + yam_ports[i].dupmode = 0; + yam_ports[i].holdd = DEFAULT_HOLDD; + yam_ports[i].txd = DEFAULT_TXD; + yam_ports[i].txtail = DEFAULT_TXTAIL; + yam_ports[i].slot = DEFAULT_SLOT; + yam_ports[i].pers = DEFAULT_PERS; + + dev = &yam_ports[i].dev; + + dev->priv = &yam_ports[i]; + dev->name = yam_ports[i].name; + dev->base_addr = yam_ports[i].iobase; + dev->irq = yam_ports[i].irq; + dev->init = yam_probe; + dev->if_port = 0; + dev->start = 0; + dev->tbusy = 1; + + if (register_netdev(dev)) { + printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name); + return -ENXIO; + } + } + + yam_timer.function = yam_dotimer; + yam_timer.expires = jiffies + HZ / 100; + add_timer(&yam_timer); + + yam_net_procfs_init(); + + /* do not keep this device */ + return 1; +} + +/* --------------------------------------------------------------------- */ + +#ifdef MODULE + +/* + * command line settable parameters + */ + +#if LINUX_VERSION_CODE >= 0x20115 + +MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr"); +MODULE_DESCRIPTION("Yam amateur radio modem driver"); + +#endif + +int init_module(void) +{ + int ret = yam_init(NULL); + + return (ret == 1) ? 0 : ret; +} + +/* --------------------------------------------------------------------- */ + +void cleanup_module(void) +{ + int i; + + del_timer(&yam_timer); + for (i = 0; i < NR_PORTS; i++) { + struct net_device *dev = &yam_ports[i].dev; + if (!dev->priv) + continue; + if (dev->start) + yam_close(dev); + unregister_netdev(dev); + } + free_mcs(); + yam_net_procfs_remove(); +} + +#endif /* MODULE */ +/* --------------------------------------------------------------------- */ diff --git a/drivers/net/hamradio/yam1200.h b/drivers/net/hamradio/yam1200.h new file mode 100644 index 000000000..53ca8a390 --- /dev/null +++ b/drivers/net/hamradio/yam1200.h @@ -0,0 +1,343 @@ +/* + * + * File yam1k2b5.mcs converted to h format by mcs2h + * + * (C) F6FBB 1998 + * + * Tue Aug 25 20:24:08 1998 + * + */ + +static unsigned char bits_1200[]= { +0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xf3,0xcb,0xff,0xdb,0xfc,0xf2, +0xff,0xf6,0xff,0x3c,0xbf,0xfd,0xbf,0xdf,0x6e,0x3f,0x6f,0xf1,0x7d,0xb4,0xfd,0xbf, +0xdf,0x6f,0x3f,0x6f,0xf7,0x0b,0xff,0xdb,0xfd,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff, +0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xef,0xff,0xff,0xff, +0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xbf, +0xff,0xff,0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfc,0xff,0xfe,0xff,0xff,0xff,0xf0, +0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf1,0xff,0xff,0xfe,0x7f,0xbf,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xff,0xff,0xf0,0x9f, +0xff,0xff,0xff,0xfe,0xff,0xfd,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xff, +0xff,0xff,0xfb,0xff,0xfb,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xf0,0x5f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xbf,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xfb,0xfe,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xeb, +0xff,0xff,0xff,0xfd,0xff,0xbf,0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xfb, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff, +0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xf7,0xff,0xff,0xf1,0xff,0xff,0xf7,0xbf,0xe7,0xff,0xff,0xff,0xff,0xfb, +0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdb, +0xff,0xff,0xf5,0xa5,0xfd,0x4b,0x6e,0xef,0x33,0x32,0xdd,0xd3,0x4a,0xd6,0x92,0xfe, +0xb3,0x3f,0xbd,0xf1,0xfa,0xdb,0xfe,0xf7,0xf6,0x96,0xbd,0xbd,0xff,0xbd,0xff,0xed, +0x7f,0x6b,0x7f,0xfb,0xdf,0xfe,0xfb,0xfe,0x90,0xcf,0xff,0xff,0xff,0xfe,0xbe,0xef, +0xff,0xff,0xdb,0x5f,0xf6,0xff,0xf6,0x8f,0xfd,0xa5,0xdd,0xff,0xff,0xff,0xff,0x6f, +0x7f,0xdb,0xf1,0xfc,0xbf,0xff,0x6f,0xff,0xef,0xfc,0x5b,0x5d,0xda,0xdf,0xf4,0xff, +0xf2,0xff,0xfd,0xbf,0xff,0xff,0xff,0xd0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff, +0xff,0xfb,0xef,0xb7,0xfc,0x33,0xff,0xfb,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0, +0x0f,0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x72,0x0f,0xf1,0x6f,0xff,0xfe,0x94,0x3f, +0xff,0xff,0xff,0x7b,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf0, +0xf7,0xef,0xb7,0xfc,0x33,0xff,0xff,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0,0x0f, +0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x73,0x8f,0xf2,0x6f,0xff,0xfe,0x94,0x3f,0xff, +0xff,0xff,0x7d,0x9f,0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x9e, +0xff,0xfc,0xef,0xd3,0xfb,0xff,0x7f,0xf5,0x5f,0xfe,0x59,0xff,0xff,0xff,0xfc,0xf1, +0xfe,0x7f,0xff,0xff,0xfa,0x17,0xff,0xe7,0xef,0xef,0xff,0xff,0x3f,0xf1,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xfc,0xea, +0xff,0xf0,0xff,0xff,0xbf,0xf9,0x3f,0xb1,0xef,0xff,0xd7,0xff,0xfb,0xff,0xf0,0xff, +0xff,0xf3,0xff,0xdf,0xff,0x7b,0xff,0xfd,0xff,0xf6,0xff,0xbf,0xff,0xff,0xbf,0xff, +0xff,0xff,0xda,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x01,0x00,0x00,0x02,0x02, +0x02,0x02,0x00,0x40,0x40,0x40,0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x00, +0x00,0x00,0x00,0x00,0x19,0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, +0x00,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfb,0xff,0xfd,0xff, +0xff,0x7f,0xff,0xff,0xbf,0xff,0xef,0xff,0xff,0xfd,0xff,0xff,0xf1,0xff,0xdf,0xff, +0xff,0xff,0xff,0xff,0xff,0xbf,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xdf, +0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xdf,0xff,0x7f,0xff,0xff,0xff,0xff, +0xdf,0xdf,0xff,0xef,0xff,0x9e,0xef,0xff,0xff,0x7f,0xff,0xf1,0xef,0xff,0xff,0xff, +0xf7,0xfa,0xbf,0xff,0xff,0xfe,0x47,0xef,0xff,0xbd,0xf6,0xff,0xff,0xdf,0xf5,0xf0, +0xf0,0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x01,0x02,0x08, +0x16,0x00,0x00,0x00,0x80,0x00,0x01,0x02,0x00,0x80,0x01,0x0c,0x02,0x00,0x00,0x01, +0x00,0x00,0x20,0x00,0x00,0x06,0x00,0x20,0x00,0x10,0x00,0x14,0x00,0x04,0xc1,0xf0, +0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f, +0xec,0xff,0xff,0xfa,0xff,0xbf,0xff,0x6f,0xff,0xe1,0xff,0xff,0xff,0xff,0xbd,0xfe, +0x46,0xff,0xef,0x7f,0xcd,0xdf,0xff,0xff,0xfd,0xff,0xbd,0xff,0x7f,0x7f,0xf0,0x4f, +0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa4,0xbc,0xcd,0x6d,0x6b,0x6f,0x5b,0xdc,0x33, +0x5a,0xf6,0xf7,0xf6,0xb3,0x3f,0xbd,0xc1,0xfa,0x5a,0xf6,0xf6,0xb6,0xf7,0xff,0xbd, +0xbb,0x3c,0xce,0xcf,0x34,0xef,0x33,0xbb,0xcc,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff, +0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xd6,0xff,0xfd,0xfd,0xbf,0xff,0xad, +0xbf,0xf9,0x7f,0x6f,0xfc,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0xff,0xda,0xdb,0xfc, +0xdb,0xff,0x76,0x8f,0xf6,0xff,0xcd,0xab,0xfe,0xfb,0xff,0xd0,0xff,0xff,0xff,0xff, +0xfe,0xff,0x9f,0xff,0xf4,0x20,0xaf,0x6d,0x0b,0xc1,0x7b,0xff,0xff,0xff,0xcb,0xff, +0x3f,0xf0,0xef,0x7f,0x0f,0xf1,0xc3,0x3c,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0b, +0x1d,0x6a,0x64,0x05,0x6b,0x99,0x01,0xff,0xfd,0xef,0xf0,0x2f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xf4,0x00,0x2f,0xcc,0x0b,0xc3,0x7f,0xff,0xff,0xff,0x0a,0xdf,0xbf, +0xfd,0x7f,0xff,0xff,0xf1,0xc3,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x4a,0x0e, +0x96,0x64,0x02,0x97,0x99,0x10,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xfe,0x84,0xf9,0xd5,0x27,0xf1,0x7f,0xff,0xf8,0xeb,0xdf,0xf3,0xcf,0x3f, +0x1f,0xff,0xf7,0x11,0xff,0xcf,0xff,0xfe,0x67,0xff,0xff,0xff,0xff,0xc4,0xff,0xff, +0xb3,0xa1,0xff,0xf9,0xe0,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff, +0xff,0xfb,0x7f,0xe0,0xff,0xc7,0xfe,0x7f,0x3f,0xff,0xfd,0x77,0x8d,0x7f,0x0f,0xff, +0xc3,0xff,0xf1,0xbf,0x8f,0xcf,0xff,0xff,0xdd,0x7b,0xff,0xf6,0xfa,0xf7,0xff,0x40, +0x9f,0xf9,0x7f,0xd8,0xff,0xff,0xfa,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00, +0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x00,0x10, +0x00,0x01,0x00,0x10,0x20,0x20,0x00,0x00,0x10,0x00,0x04,0x01,0x05,0x00,0x00,0x00, +0x00,0x40,0x40,0x00,0x00,0x3c,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff, +0xff,0xff,0xfe,0x7f,0x7f,0xff,0xef,0xff,0xff,0xdf,0xff,0xff,0xdf,0xff,0xef,0xf7, +0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xfc,0xfd,0xff,0x7f, +0x7e,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0xff,0xff, +0xff,0xff,0xfe,0xeb,0xfd,0x6f,0xff,0xf7,0xfe,0xf5,0x7f,0xff,0xff,0x7f,0xbf,0xb1, +0xff,0xff,0x9f,0xbf,0xfb,0xff,0xfe,0xff,0xfe,0xff,0xf7,0xeb,0xdf,0xbf,0x5f,0xdd, +0xff,0xdb,0xfd,0xd0,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x00,0x42,0x00, +0x00,0x00,0x30,0x18,0x04,0x08,0x09,0x21,0x82,0x80,0x02,0x00,0x08,0x00,0x01,0x00, +0x00,0x00,0x0c,0x20,0x10,0x00,0x11,0x00,0x44,0x84,0x00,0x20,0x20,0x84,0x80,0x00, +0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xf7,0xff,0xfb,0xdd,0xf9,0xff, +0xda,0xff,0xdc,0xdd,0xfc,0xfb,0xff,0xbf,0xfb,0x3e,0xd7,0x96,0xfe,0x61,0xf7,0xff, +0x7f,0xff,0x3f,0xfd,0xff,0xdf,0xcf,0xf7,0xdf,0xf7,0xbf,0xfd,0xff,0xfe,0xef,0xef, +0xfe,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf3,0xbd,0xfd,0x4b,0x74,0xcf, +0x73,0x5b,0xcb,0x3b,0xdf,0xfe,0xf7,0xfe,0xd3,0x75,0xac,0xa1,0xfb,0xdf,0xfe,0xf7, +0x76,0x96,0xb5,0x24,0xbd,0xa5,0xad,0x49,0x2f,0x69,0x2b,0x52,0x5b,0xbd,0xff,0xff, +0xf0,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0xff,0xcc, +0xa7,0xfb,0xad,0xff,0x7f,0x6f,0xff,0x6d,0x7f,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff, +0x6f,0xff,0xdb,0xff,0xdb,0xff,0xf6,0x97,0xf6,0xff,0xb5,0xb5,0xff,0xff,0xff,0xd0, +0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa5,0xbc,0x43,0xfc,0x7c,0x03,0xe7, +0xff,0xff,0x20,0xff,0xff,0xff,0xcc,0xfd,0x7d,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59, +0xba,0x56,0x66,0x6a,0xad,0x9a,0xa9,0x9a,0x97,0xa5,0xaa,0xbb,0xff,0xff,0xf0,0x0f, +0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xfd,0xf7,0xfd,0x43,0xff,0xfd,0x6b,0xe7,0xff, +0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0x3f,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59,0xb5, +0xa6,0x66,0x6a,0xad,0x9a,0xa9,0x99,0x6b,0x5a,0xaa,0xff,0xff,0xb7,0xf0,0x3f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x9c,0xf7,0xfd,0xd2,0x41,0xff,0xff,0xf2,0x7f, +0x8f,0xff,0xff,0x3d,0xf3,0xff,0x17,0xf1,0xff,0xff,0xff,0xff,0xff,0x7f,0xdf,0xfc, +0x8f,0x38,0xff,0xef,0x23,0xff,0xfb,0xf7,0xc8,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff, +0xff,0xfe,0xf5,0x7f,0xff,0xfd,0xff,0xe4,0xff,0xeb,0xff,0xcf,0xbf,0xfa,0xff,0xab, +0xef,0xff,0xfb,0xff,0xf3,0xfd,0x61,0xff,0xff,0xff,0xff,0xfa,0xff,0xfb,0xfd,0x0d, +0xff,0xfe,0xff,0x43,0x7f,0xfe,0xbf,0xd0,0xfd,0xff,0xfa,0xf0,0x3f,0xff,0xff,0xff, +0xfe,0xf3,0xc0,0x00,0x00,0x00,0x02,0x00,0x02,0x01,0x00,0x60,0xc0,0x40,0x00,0x00, +0x00,0x00,0x34,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x88,0x00, +0x00,0x03,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x3c,0xf0,0x3f,0xff,0xff,0xff,0xfe, +0xfd,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfd,0xff, +0xff,0xff,0xff,0xfe,0xfe,0x5f,0xff,0xff,0xcb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0, +0xff,0xff,0xfd,0xff,0xef,0xe3,0xde,0xee,0xd9,0xc5,0x93,0xff,0xff,0xfe,0xfe,0xff, +0xfb,0xee,0xfe,0xf1,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xbf,0xf7,0xff,0xff,0x7f, +0xaf,0xbd,0xdf,0xdf,0xfb,0xf3,0xf3,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x34, +0x00,0x06,0x61,0x00,0x18,0x01,0xa0,0x05,0x17,0x00,0x20,0x05,0x28,0x20,0x00,0x00, +0x05,0x00,0x41,0x00,0x00,0x40,0x00,0x09,0x00,0x01,0x20,0x86,0x82,0x08,0x40,0x03, +0x80,0x30,0x70,0x08,0x14,0x02,0xc1,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff, +0xff,0xff,0xbd,0xef,0xfb,0xff,0xff,0xfb,0x9c,0x7f,0xef,0xdf,0xff,0xbf,0xeb,0xde, +0xff,0xc1,0x7f,0xff,0xfb,0x7f,0xff,0xff,0xff,0x5f,0xff,0xff,0xff,0xdf,0xbf,0xef, +0x3f,0xf7,0x8f,0xef,0x7f,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbd, +0xdf,0xef,0x7d,0x6d,0x2b,0x5a,0x5d,0xd2,0xdf,0xf6,0x92,0xb6,0xb2,0xb3,0xac,0xa1, +0xfb,0xdf,0xfe,0xf1,0xee,0xf5,0xf6,0xbc,0x6b,0xbd,0x7d,0xaf,0x1a,0xef,0x5f,0x6b, +0xc6,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff, +0xf6,0xff,0xf6,0xb7,0xfd,0xad,0xfd,0xbf,0xf3,0x6f,0xff,0x6f,0xff,0xdb,0xd1,0xfd, +0xbf,0xff,0x6f,0xf5,0x6b,0xbc,0x5b,0x3c,0xda,0xef,0x16,0xaf,0x16,0xff,0xcd,0xab, +0xff,0x6f,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfc,0xbf,0xff,0xff, +0xff,0x6c,0x03,0x10,0xc1,0xf3,0xff,0xf3,0x3a,0xf3,0xca,0xff,0xaf,0xf1,0xff,0xff, +0xff,0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff, +0xff,0x5f,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff, +0xea,0x0f,0x50,0xc3,0xf3,0x7f,0xff,0xf3,0xf3,0xc3,0xff,0xaf,0xf1,0xff,0xff,0xff, +0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff,0xff, +0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xd7,0xff,0xff,0x5f,0xc1, +0x3f,0xf7,0x5e,0xf5,0xce,0x9e,0x5f,0x3f,0x17,0xff,0xf3,0xe1,0xff,0xff,0xff,0xff, +0xd8,0xff,0xfa,0xfe,0x67,0xff,0xfe,0xbf,0x5a,0xff,0xff,0xaf,0xf5,0xff,0xff,0xff, +0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfd,0xff,0xf7,0xff,0xfd,0x4e,0x3d, +0x3f,0xe7,0x0b,0xbf,0x8f,0xf9,0xff,0xeb,0xe3,0xff,0xe1,0xff,0xff,0xfc,0xff,0xc7, +0x9f,0xff,0x3e,0x39,0xe5,0xff,0xcf,0x9b,0xf9,0xff,0xff,0xc5,0xff,0xff,0xfa,0xf0, +0x5f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, +0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x20, +0x00,0x01,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xf0,0x4f, +0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xbf, +0x3f,0xff,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf1,0xff,0xff,0xff,0xff,0xf7,0xff,0xf7, +0xff,0xed,0xff,0xfb,0xfe,0xff,0x7f,0xff,0x7f,0xdf,0xff,0xff,0xdd,0xf0,0x3f,0xff, +0xff,0xff,0xfe,0xf0,0xff,0xff,0xf3,0xff,0xf7,0xff,0xfe,0x5f,0xff,0xf7,0xff,0xff, +0xdf,0xff,0xff,0xff,0xf7,0xfe,0x7b,0xf1,0xff,0xfd,0xfd,0xff,0xdf,0xdf,0xff,0x7d, +0x73,0xf9,0xff,0xc3,0x7e,0xfe,0xff,0xef,0xd7,0xff,0xcf,0xd0,0xf0,0x6f,0xff,0xff, +0xff,0xfe,0xf8,0x30,0x00,0x00,0x40,0x04,0x00,0x01,0x41,0x20,0x00,0x04,0x00,0x02, +0xd5,0x09,0x00,0x02,0x80,0x02,0x01,0x00,0x00,0x00,0x0a,0x04,0x00,0x07,0x00,0x01, +0x50,0x01,0x80,0x02,0x61,0x40,0x41,0x0c,0x14,0x08,0xc1,0xf0,0x9f,0xff,0xff,0xff, +0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xdf,0xcb,0x5f,0xfe,0xef,0xff,0xfe, +0xff,0x3f,0xff,0x7f,0xfd,0xc1,0xff,0xff,0x7f,0xff,0xdf,0xfd,0xfc,0xfd,0xf7,0xee, +0xff,0xff,0x4e,0xff,0xdf,0xcf,0xdb,0xeb,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0x7f, +0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff, +0xf7,0xfb,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0x7f,0xff,0xff,0xff,0x7f,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdd,0xff, +0xff,0xff,0xa5,0xff,0x6f,0x6b,0xe9,0x6f,0xda,0xca,0xfb,0xdd,0xee,0xf7,0xf6,0xb2, +0xb3,0xa4,0xa1,0x5b,0x5b,0xf6,0xd7,0xf4,0xf7,0x7b,0xbd,0xbd,0xad,0xcf,0xef,0x7f, +0x6b,0x7f,0x3b,0xdf,0xdb,0xff,0xff,0x30,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff, +0xff,0xff,0xff,0xf6,0xfe,0x96,0xff,0xfd,0xb5,0xfd,0xbf,0xad,0x7f,0xff,0x6f,0xff, +0xde,0xd1,0xad,0xad,0xe9,0xff,0xf1,0xec,0xef,0xde,0x3f,0xcb,0xff,0xf6,0xff,0x32, +0xff,0xc5,0xbd,0xff,0xff,0xff,0xd0,0xbf,0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xf4, +0x28,0xbf,0xff,0xfd,0xfb,0xd3,0xff,0xff,0x42,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3, +0xc1,0xff,0x33,0xff,0xc0,0x15,0x6b,0x70,0xff,0xf0,0xf2,0x4f,0xff,0xfc,0x3e,0x97, +0x3c,0xff,0xff,0xfd,0xef,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x78, +0xbf,0xff,0xfd,0xf3,0xef,0x55,0xff,0x7e,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3,0xc1, +0xff,0x33,0xff,0xc0,0x15,0x6f,0xff,0x0f,0xf0,0xf0,0x0f,0xff,0xfc,0x3d,0x6b,0xc3, +0xff,0xff,0xfe,0xf7,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff, +0xff,0x23,0xf8,0x7f,0xff,0x4e,0xff,0xff,0xff,0xfb,0xf9,0x17,0xff,0xf6,0xf1,0xff, +0xcf,0xef,0xff,0xff,0x13,0xdf,0xe6,0x2f,0xc7,0xff,0xff,0xe7,0xc1,0xfd,0xff,0xfe, +0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xfe,0xae,0xff, +0xff,0x7f,0x3b,0x3f,0xfc,0x7f,0xfc,0xef,0xff,0xfc,0xe2,0x7b,0xff,0xf1,0xfd,0xed, +0xef,0xff,0xff,0x35,0x73,0xff,0xff,0xfe,0xfa,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff, +0xff,0xfa,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x0c,0x04,0x01,0x40,0x40,0x00, +0x00,0x30,0x28,0x04,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00, +0x38,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xfb,0xff,0x7f, +0xff,0xff,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xdf,0xdf,0xff, +0xff,0xff,0xff,0xed,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xbf,0xbf,0xff,0xff,0xc3, +0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xfd,0xff,0xbf,0xff,0xff,0xfd,0xff,0xff, +0xff,0xff,0xff,0xfd,0x7b,0xff,0x7f,0xff,0xbd,0xff,0xf1,0xef,0xff,0xff,0xfd,0xdf, +0xfd,0xfb,0xff,0xff,0xbf,0xbe,0xff,0xcd,0x7f,0xfc,0xf7,0xf7,0x6f,0xbf,0xd8,0xf0, +0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,0x00, +0xc0,0x00,0x00,0x20,0x34,0x00,0x00,0x00,0x0c,0x81,0x00,0x20,0xa4,0x20,0x00,0x10, +0x08,0x04,0x48,0x08,0x00,0x40,0x93,0x00,0x10,0x00,0x38,0x18,0x20,0xc1,0xf0,0x3f, +0xff,0xff,0xff,0xfe,0xff,0xfb,0xff,0xff,0xb9,0xdf,0xfe,0xb3,0xff,0xff,0xe7,0xfd, +0xff,0xff,0x3b,0xff,0x7f,0xff,0xbf,0xff,0xc1,0xff,0xfc,0xff,0xff,0x3f,0x77,0xfe, +0xfe,0xcf,0xff,0xbf,0xfd,0xbf,0xff,0xfe,0xed,0xf2,0xfd,0xf7,0xff,0xf0,0x2f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xf3,0xad,0xcf,0xef,0x70,0xc9,0x73,0x3b,0xdf,0x5b,0x4a, +0xf6,0xb7,0xfe,0xd7,0xf5,0xbc,0xc1,0x33,0xca,0xd6,0xb7,0x6e,0xf7,0xfb,0xbd,0xc5, +0x24,0xcf,0x6f,0x2f,0x4d,0x2b,0xba,0x5a,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff, +0xfe,0xbf,0xff,0xff,0xff,0xff,0xf6,0xf6,0xd7,0xff,0xff,0xad,0xbd,0xff,0xff,0xff, +0xef,0xf7,0x7f,0xfc,0x5b,0xb1,0xfd,0xbd,0x75,0x6f,0xef,0x6a,0xfd,0x5b,0xfb,0xdb, +0x3a,0xbf,0x8e,0x9f,0xff,0xbf,0xfd,0xff,0x6f,0xff,0xd0,0x6f,0xff,0xff,0xff,0xfe, +0xff,0xbb,0xff,0xf0,0x3f,0xff,0xff,0xfd,0xfb,0x7f,0xde,0xff,0xff,0x5a,0xd6,0xbf, +0xd8,0x2a,0xbf,0xbf,0xf1,0xe5,0xff,0xcc,0xc0,0xa9,0x70,0xff,0xf3,0x3c,0x3c,0xfd, +0x57,0xfd,0x98,0x03,0x00,0xc3,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0x3d,0xbf,0xff,0xfd,0xfb,0xff,0xdb,0xff,0xff,0x0f,0xfc,0x3f,0xd8, +0x2a,0xbf,0xbf,0xf1,0xef,0xff,0xcc,0xc0,0x96,0xbe,0xff,0xf3,0x3f,0xff,0xfd,0x57, +0xfd,0x99,0x0f,0xff,0xc3,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xff,0xff, +0xff,0xf1,0xe7,0xff,0xff,0xf3,0x8e,0x7b,0xff,0xa8,0xff,0xdf,0x7f,0x8e,0x78,0x73, +0xff,0xf1,0x51,0x62,0xff,0xfc,0x4b,0xff,0xf3,0xff,0x7e,0xcf,0xf9,0xff,0xfd,0xff, +0xff,0x7f,0xff,0xe0,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff, +0xfb,0xfd,0xae,0xff,0xfc,0xfe,0x6f,0x3f,0xf8,0xfd,0x77,0xaf,0xfe,0x37,0xfe,0x7b, +0xff,0xb1,0x8c,0xff,0xef,0xfd,0xf8,0xe7,0xbf,0xff,0xf1,0xfe,0x3e,0xf7,0xfe,0x95, +0x3e,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00, +0x01,0x04,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x08, +0x41,0x80,0x10,0x00,0x00,0x08,0x10,0x84,0x00,0x0c,0x04,0x02,0x61,0x00,0x00,0x81, +0x00,0x00,0x00,0x00,0x3d,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff, +0xff,0xff,0x7f,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1, +0x7f,0xbf,0xf7,0x7f,0xef,0xff,0xef,0xff,0xf7,0xfd,0xff,0xff,0xfd,0x7f,0xff,0xbe, +0xdf,0xff,0xff,0xd9,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0x7f,0xfb,0xff, +0xfb,0xff,0xbf,0xff,0xf3,0x7f,0xfb,0xfd,0xeb,0x7f,0xdf,0xfa,0xff,0xde,0xf0,0xed, +0xff,0xb1,0xf7,0xf9,0x1f,0xb5,0x5b,0xfe,0x7e,0xf7,0xbe,0xfd,0x7f,0x5f,0xb5,0xf7, +0xff,0xff,0xd0,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x01,0x00,0x07,0x42,0x01, +0x00,0x6a,0x18,0x50,0x80,0x00,0x00,0x02,0x40,0x01,0x01,0x20,0x01,0x01,0x24,0x14, +0x21,0x10,0x02,0x08,0x07,0x08,0x00,0x40,0x10,0x80,0x58,0x00,0x84,0x80,0x18,0x10, +0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xff,0xdb,0xb7,0xf3, +0xdf,0x7c,0xf8,0x74,0xff,0xff,0x6f,0x7d,0x3f,0x7e,0xec,0x7f,0xc1,0xf5,0xff,0xcf, +0x6f,0x9f,0xf9,0xdf,0xbe,0xe5,0xe7,0xff,0xd7,0xf3,0xdd,0xfb,0xff,0xfc,0xff,0xbf, +0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf0,0x2f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xff,0xb4,0xcf,0xef,0x77,0x6f,0x73, +0x3a,0x4a,0x3a,0xcb,0xd4,0xf7,0x2e,0xd6,0xbd,0xbd,0xa1,0x3b,0xdf,0xd6,0xf7,0xee, +0xd3,0x35,0xbd,0xfb,0xbd,0xce,0xeb,0x2b,0x4d,0x2f,0xbb,0xda,0xff,0xff,0xfe,0xb0, +0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdf,0x5f,0x36,0xaf,0x3f,0xed,0xb7, +0xf5,0xfd,0xf3,0x2b,0xef,0x77,0xff,0xfb,0xda,0xb1,0xbd,0xa3,0x77,0x69,0x7f,0x4f, +0xff,0xdb,0xfa,0x5b,0xff,0xf2,0xfe,0xff,0x96,0xff,0xff,0xfe,0xdf,0xff,0xd0,0xaf, +0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x8f,0xfd,0x40,0x6f,0x9e,0x83,0x5a,0x0f, +0xfa,0xc3,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xd0,0x00,0xfe,0xbf,0xcd,0x3f,0xf0, +0xef,0xfc,0xc5,0x0c,0x3f,0xfd,0x68,0x0b,0xff,0xff,0xff,0xfe,0xdf,0xf0,0xff,0xff, +0xff,0xff,0xfe,0xff,0xbb,0xff,0xfd,0x85,0xff,0xd4,0x6f,0x9f,0xc3,0x5a,0x0f,0xff, +0xff,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xf0,0xfb,0xc2,0xbf,0xfc,0x00,0x37,0xef, +0xfc,0xcd,0xbc,0x3f,0xff,0x0c,0xbf,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xff,0xd9,0xf7,0xd1,0xb7,0x7e,0x7f,0xf1,0xe4,0xfd,0xff, +0xfb,0xfb,0xff,0x5f,0xff,0x7f,0xb1,0xbc,0x0f,0x67,0xeb,0xb8,0x3f,0xff,0xe2,0xff, +0xe9,0xff,0xfd,0xe3,0xff,0x3f,0x9f,0xc2,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff, +0xfe,0xf5,0x7f,0xff,0xf0,0x3f,0xbc,0xff,0xd5,0xf5,0xce,0x3f,0xfe,0xff,0xfe,0x6d, +0xff,0xf1,0xbf,0x7b,0xff,0xf1,0xfd,0xff,0x4f,0xff,0x87,0xff,0xae,0xff,0xb1,0xf8, +0xfe,0xff,0xff,0x78,0x01,0xb9,0xff,0xff,0xff,0xfa,0xf0,0x2f,0xff,0xff,0xff,0xfe, +0xf3,0xc0,0x00,0x00,0x00,0x04,0x02,0x13,0x02,0x00,0x80,0x40,0x00,0x90,0x10,0x00, +0x10,0x00,0x02,0x00,0x01,0x20,0x80,0x12,0x10,0x00,0x40,0x08,0x00,0x04,0x00,0x00, +0x02,0x00,0x01,0x40,0x00,0x80,0x00,0x00,0x3c,0xf0,0xef,0xff,0xff,0xff,0xfe,0xfd, +0x1f,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xf7,0xdf,0xf7,0xff, +0xf7,0xfb,0xeb,0xd1,0xff,0xff,0xff,0xff,0xef,0xf7,0xff,0xff,0xfb,0xff,0xfe,0xff, +0xff,0x7e,0xff,0xfb,0xff,0xff,0xff,0xdb,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf0,0xff, +0xff,0xb7,0xeb,0xf7,0xdf,0xff,0xfe,0xf5,0x6b,0xe7,0xed,0xf7,0x3e,0xec,0xff,0x54, +0xef,0x6f,0xf1,0xf5,0xaf,0x6f,0xf6,0xfd,0xff,0xdd,0x7b,0xff,0xef,0xbf,0x7f,0xff, +0xff,0xf7,0xff,0xf3,0x5f,0xf7,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00, +0x80,0x40,0x04,0x00,0x81,0x2c,0x04,0x24,0x00,0x02,0x01,0xc8,0x02,0x00,0x02,0x24, +0x00,0x01,0xb4,0x42,0xdc,0x44,0x02,0x15,0x90,0x02,0x03,0x48,0x39,0x10,0x02,0x24, +0xa0,0xba,0x00,0x00,0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +0xfe,0xfc,0xf7,0xf0,0xee,0xb6,0x5d,0xfd,0xf5,0xff,0xdb,0xf7,0x7f,0x7f,0xbe,0xff, +0xc1,0xfe,0xbf,0xfa,0xfa,0x5f,0xff,0xad,0xff,0xef,0xff,0x7f,0xdf,0x7f,0xfe,0xbf, +0xb7,0x94,0xbf,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xfb,0xb5,0xff, +0xef,0x7c,0xeb,0x2b,0x52,0x5b,0x3b,0xda,0xd4,0xf3,0x36,0x96,0xb5,0xbd,0xf1,0xfb, +0xda,0xee,0xf6,0xfe,0xd3,0x35,0xbd,0xdf,0xad,0xcf,0xef,0x7e,0xcd,0x6b,0xbb,0xdf, +0xff,0xff,0xfd,0xb0,0xef,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xd3,0x5f,0xf6, +0xff,0xf6,0xff,0xfd,0xad,0xfd,0xff,0x7f,0xef,0xff,0x6f,0x7f,0xdb,0xf1,0xa5,0xa3, +0x7f,0x6f,0x6b,0x4f,0xff,0xdb,0xfb,0xcb,0xff,0xf6,0xff,0xf4,0xd7,0xfd,0xbf,0xfe, +0xdf,0xff,0xd0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdf,0xff,0xff,0xff, +0x3f,0x7f,0xfc,0xe5,0xff,0x20,0xfe,0xff,0xff,0xdf,0x7f,0xff,0xf1,0x7f,0xff,0xfe, +0xff,0xf0,0x7c,0x3d,0x4f,0xf3,0xc3,0x3f,0xff,0xff,0x6f,0xc3,0xff,0x0f,0xff,0xff, +0xaf,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0xb7,0xe0,0x0f,0xff,0xff,0x2b, +0xff,0x7d,0xbf,0xff,0xdf,0xff,0xff,0xf8,0x9f,0x7f,0xff,0xf1,0x55,0xff,0xff,0xff, +0xfd,0x7c,0x3c,0xff,0xf3,0xc3,0x3f,0xff,0xff,0xef,0xc3,0xff,0xdf,0xff,0xff,0xff, +0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xef,0xff,0xff,0x9f,0xbf,0x7f, +0xf9,0x19,0x47,0x8e,0xe7,0x9f,0x3f,0x17,0xff,0xfc,0x81,0xc1,0x7e,0xf3,0xd9,0xf9, +0x73,0xdf,0xf4,0x7f,0xfa,0xff,0xff,0xff,0xfb,0x7f,0x77,0xc7,0xff,0xff,0xff,0xf0, +0x2f,0xff,0xff,0xff,0xfe,0xf5,0xf7,0xff,0xfb,0xff,0xf7,0x3f,0xfc,0xbf,0x3e,0x3f, +0xec,0xff,0x81,0xaf,0xfe,0x4f,0xf3,0xbb,0xff,0xf0,0x7e,0xff,0x6f,0xff,0x87,0xff, +0xbb,0xff,0xd5,0xfc,0xff,0x7f,0xfc,0x6f,0xff,0xef,0xe7,0xff,0xff,0xfa,0xf0,0x3f, +0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, +0x00,0x30,0x10,0x60,0x20,0x00,0x08,0x00,0x01,0x20,0x80,0x00,0x10,0x00,0x04,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x40,0x00,0x08,0x20,0x3c,0xf0,0x6f,0xff, +0xff,0xff,0xfe,0xf5,0xbf,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7f,0xfe,0x3f,0xff, +0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xf1,0xdf,0xdf,0xff,0xff,0xff,0x7f,0xdf,0xff, +0xfd,0xbd,0xff,0xff,0xff,0xfb,0xdf,0xff,0xff,0xff,0xff,0x5b,0xf0,0xff,0xff,0xff, +0xff,0xfe,0xf0,0xbf,0xbf,0xbf,0xff,0xf7,0xfb,0xff,0xfe,0xee,0xfa,0xff,0xff,0xff, +0x3d,0x3b,0xff,0xff,0xfe,0xfb,0xf1,0xff,0xbf,0x7b,0xff,0xff,0xef,0xff,0xbf,0xff, +0xff,0xff,0xff,0xff,0xfe,0xff,0xf7,0xef,0xff,0xfb,0xd0,0xf0,0xdf,0xff,0xff,0xff, +0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x00,0x0b,0x10,0x05,0x01,0x00,0x08,0x00,0x02, +0x01,0x01,0x00,0x00,0x10,0x01,0xc8,0x08,0x00,0x00,0x00,0x00,0x42,0x02,0x00,0x00, +0x00,0x80,0x02,0x00,0x00,0x40,0x24,0x80,0x00,0xc1,0xf0,0x3f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xf7,0xfd,0xf7,0xfa,0xef,0xee,0xf9,0xfd,0xff,0xf7,0xfe,0xbf, +0x1f,0xfd,0x9e,0xfd,0xd1,0xef,0xff,0xf7,0x7f,0x9f,0xff,0xef,0xff,0xf6,0xff,0xfe, +0xfe,0x7b,0xff,0xbd,0xff,0x7e,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff,0xff, +0xff,0xf7,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xdf,0xfd,0xff,0xff,0xdf,0xff, +0xff,0x5f,0xf1,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xef,0xff, +0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfb,0xff,0xff,0xef,0xfb,0xfd, +0xff,0xf1,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf7,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xe7,0xff, +0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0xff,0xfb,0xff,0xfb,0xf1, +0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7b,0xff,0xff,0xff,0x7f,0xff,0xf1,0xff, +0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x57,0xff,0xfe,0xbf,0xfb,0xf1,0xff,0xff, +0xfd,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xd7,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd, +0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xef,0x2f,0xf1,0x3c,0xbf,0xbc, +0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff, +0x01,0xe2,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff }; diff --git a/drivers/net/hamradio/yam9600.h b/drivers/net/hamradio/yam9600.h new file mode 100644 index 000000000..5ed1fe6ff --- /dev/null +++ b/drivers/net/hamradio/yam9600.h @@ -0,0 +1,343 @@ +/* + * + * File yam111.mcs converted to h format by mcs2h + * + * (C) F6FBB 1998 + * + * Tue Aug 25 20:23:03 1998 + * + */ + +static unsigned char bits_9600[]= { +0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xfb,0xcb,0xff,0xdb,0xfe,0xf2, +0xff,0xf6,0xff,0x9c,0xbf,0xfd,0xbf,0xef,0x2e,0x3f,0x6f,0xf1,0xfd,0xb4,0xfd,0xbf, +0xff,0x6f,0xff,0x6f,0xff,0x0b,0xff,0xdb,0xff,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff, +0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xfd,0xdf,0xff,0xff,0xff,0xf7,0xff,0xff,0xff, +0xfb,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0x7f,0xf1,0xff,0xfe,0xff,0xbf,0xbf, +0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xf0, +0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xf7, +0xff,0xff,0xf7,0xef,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0x7e,0xff,0xff, +0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0xdf, +0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xef,0xff,0xf3,0xfb,0xfe,0xff,0xf1,0xff,0xfd,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xdf,0xff,0xf0,0x7f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf5, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff, +0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xef,0xff,0x7f,0xff,0xef, +0xff,0xef,0xff,0x7f,0xef,0xf1,0xff,0xef,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0xbd,0xff,0xef,0x7f,0xef,0x7f,0xfb,0xdf,0xd3,0x5a,0xfe,0xd7,0xd6, +0xf7,0x7f,0xbd,0xf1,0xbb,0x5d,0xd6,0xf7,0xfe,0x96,0xff,0xbd,0xaf,0xad,0xbf,0xef, +0x7f,0x6b,0x7f,0xfb,0xd6,0xfe,0xf7,0xff,0x10,0xef,0xff,0xff,0xff,0xfe,0xbe,0xef, +0xff,0xff,0xdb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xbf,0xff,0x7f,0xff,0x7f, +0xdf,0xdb,0xf1,0xfd,0x35,0xff,0x6f,0xff,0x6f,0xff,0xdb,0xff,0xcb,0xff,0xf6,0xff, +0xf2,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff, +0xff,0xf1,0x24,0xf0,0xff,0xff,0xcf,0xef,0x3f,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f, +0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff,0xff, +0xf1,0x00,0xf0,0xff,0xff,0xcf,0xdf,0xff,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f,0xff, +0xff,0xff,0x7d,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfe,0x7f,0xdf,0xff,0xff,0xff,0xf1, +0xff,0xcf,0xff,0xf3,0xff,0x97,0xff,0xff,0x8f,0xe7,0xff,0xff,0xfc,0x71,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xe3,0xf7,0xef,0xff,0xff,0xfc,0x7b,0xff,0xf1,0x3f, +0xff,0xef,0xff,0xcf,0xe3,0xe3,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xbf,0xff, +0xbf,0xff,0xda,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00, +0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0x9f,0xff, +0xff,0xff,0xf7,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xdb,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xdf,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xdf,0xbf,0xf1,0xfe,0xfd,0xf7,0xff, +0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xfd,0xf2, +0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, +0x00,0x00,0x00,0x02,0x00,0x90,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x04,0x24,0x00, +0x40,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0xc0,0xf0, +0x4f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xbf,0xff,0xff,0x6f,0xff,0xdf,0xff,0xd1,0xff,0xfe,0xff,0xff,0xff,0xff, +0xff,0xff,0xdf,0xff,0xfb,0xff,0xfb,0xef,0xff,0xff,0xee,0xff,0xff,0x7f,0xf0,0xdf, +0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xad,0xff,0x69,0x2a,0xed,0x6b,0xfb,0xdf,0x3a, +0xdc,0xf4,0x96,0xee,0xb3,0x3d,0x35,0xc1,0xbb,0xdd,0xfe,0xf6,0xfe,0xd6,0xb5,0xad, +0xbf,0xa5,0xad,0x49,0x2f,0x4f,0x2b,0xda,0x5f,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff, +0xff,0xfe,0xbf,0xff,0xff,0xfb,0x5b,0xf7,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xa5, +0xf3,0x6f,0xf3,0x6e,0xfa,0x7b,0xd1,0xfd,0xb5,0x77,0x6f,0xe9,0x6f,0xff,0xdb,0xfb, +0xdb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0x3f,0xfe,0xf7,0xff,0xd0,0x4f,0xff,0xff,0xff, +0xfe,0xff,0x9f,0xff,0xff,0x0f,0xff,0xc0,0x3f,0x9c,0x03,0xff,0xff,0x8b,0xa5,0xfe, +0x80,0x3e,0xc2,0xbf,0xac,0xb1,0x24,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xa3, +0xff,0xfd,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0x0f,0xff,0xc0,0x3f,0xd4,0x6b,0xff,0xff,0xdb,0xff,0xfe,0x86, +0xbf,0xc2,0xbf,0x30,0xa1,0x24,0xff,0xff,0xff,0xff,0xcc,0xff,0x0f,0xff,0xa3,0xff, +0x05,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xfb,0xc7,0xff,0xc4,0xff,0xff,0x7f,0xff,0xec,0xfe,0x7f,0xdf,0xd8,0xb9, +0x47,0xfc,0x36,0xc1,0xdf,0xff,0xff,0xf9,0xff,0xf3,0xff,0xf7,0xff,0xfc,0xff,0xfd, +0x3f,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff, +0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xbd,0x3f,0xff,0x2b,0xfe,0x2f,0xf5,0xa3,0xfc, +0x5b,0xfe,0x61,0x9f,0x7f,0xef,0xff,0xff,0xa7,0xfb,0xff,0xff,0xfa,0xfe,0xff,0x33, +0xf1,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x24,0x04, +0x00,0x01,0x00,0x80,0x40,0x00,0x08,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x02,0x00, +0x00,0x00,0x00,0x00,0x01,0x3d,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xfd,0xbd,0xff,0xfd, +0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f,0xf6,0xef,0xbf,0xf7,0xff,0x73,0xeb, +0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xf9,0xff,0xfd,0xfe,0xff,0xff, +0xff,0xff,0xff,0xff,0xd9,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0,0xbf,0x7f,0xff,0xff, +0xff,0x7f,0xff,0xff,0xde,0xff,0xff,0xef,0xdd,0xde,0x77,0xf2,0xfb,0xed,0xe7,0xf1, +0x73,0xfd,0xfd,0xdf,0xff,0x7d,0xbe,0xdf,0xff,0xfb,0xff,0xef,0xff,0xef,0xff,0xff, +0xff,0xff,0xff,0xd0,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x02,0x00,0x22, +0x40,0xc0,0x00,0x00,0x00,0x08,0x00,0x02,0x41,0x02,0x12,0x00,0x21,0x87,0x81,0x00, +0x00,0x80,0x04,0x0b,0x28,0x01,0xb0,0x00,0x82,0x00,0x40,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff, +0xf7,0xff,0xfe,0x7f,0xed,0x79,0xff,0xde,0xeb,0x7f,0x74,0xf7,0xf7,0xe1,0xf9,0xff, +0xf6,0x5f,0x7f,0xff,0xff,0xff,0xd7,0xdb,0xef,0xff,0xbb,0xff,0xff,0xff,0xcc,0xff, +0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x3d,0xcd,0x49,0x7f,0x6f, +0x2b,0xba,0x5c,0xd2,0xda,0xf6,0xf3,0x3e,0xf7,0xff,0xbd,0xf1,0xfa,0xdf,0xfe,0xf7, +0xcc,0xf6,0xbb,0xa5,0xb3,0xad,0xbf,0x6f,0x7d,0x6f,0x6b,0xdb,0xdf,0xbd,0xff,0xfe, +0xb0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xfb,0xdb,0x57,0xf6,0xfe,0x9f,0xd5, +0xb7,0xff,0xaf,0xe5,0x3f,0xff,0xff,0x6f,0xff,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0x69, +0x6c,0xdf,0xda,0xdf,0xcb,0xff,0xf6,0xff,0x76,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0, +0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfd,0xbd,0x08,0x03,0x89,0x4f,0x5a, +0x0f,0xf0,0xff,0xf8,0xbf,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xf3, +0xfa,0xa0,0xf0,0xf2,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff, +0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xfd,0x00,0x6b,0xff,0xff,0x5a,0x0f, +0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xb3,0xf5, +0x50,0xf0,0xf0,0xff,0xff,0xff,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xbc,0xff,0xe4,0xe7,0x71,0xff,0xf9,0xc4,0xf4, +0x7f,0x7f,0xcf,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xfb,0xf7,0x73,0xbf,0x14, +0xff,0xe6,0xff,0xff,0xe1,0x7d,0xff,0xff,0xe7,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff, +0xff,0xfe,0xf5,0xff,0xff,0xfe,0xd2,0xfa,0xff,0xc4,0xf4,0x5c,0xbf,0xfa,0xff,0xff, +0xec,0x7e,0xbf,0xff,0xff,0xff,0xf1,0xff,0xff,0xef,0xff,0xff,0x6b,0xdb,0xff,0xdf, +0xf9,0xfb,0xbf,0xff,0xf1,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf0,0xbf,0xff,0xff,0xff, +0xfe,0xf3,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x00,0x80,0x00, +0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x20,0x00,0x00,0x00,0x00, +0x01,0x00,0x01,0x00,0x00,0x80,0x02,0x00,0x01,0x3c,0xf0,0x5f,0xff,0xff,0xff,0xfe, +0xfd,0xbf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0x7f,0xff,0xdf,0xff,0xef,0xff, +0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff, +0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xc3,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf0, +0xff,0xdf,0xff,0xff,0xf7,0x23,0xff,0xff,0xfd,0xff,0xef,0xff,0xfe,0x7f,0x7d,0xf7, +0xfe,0xff,0x7f,0x71,0xff,0xfb,0x7f,0xff,0xff,0xff,0x6e,0xfd,0xf7,0xfd,0xff,0xbf, +0xff,0xbf,0xf9,0xfd,0xff,0xdf,0xef,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x30, +0x40,0x01,0x00,0x83,0x00,0x00,0x00,0x0c,0x06,0x08,0x04,0x26,0x26,0x00,0x00,0x06, +0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x70,0x08,0x80,0x00,0x20,0x01,0x20, +0x00,0x02,0x00,0x30,0x00,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff, +0xff,0xff,0x7b,0x3f,0xf7,0xff,0xd7,0xfe,0xfe,0xfb,0xfe,0x3b,0xfe,0xbd,0xff,0x2f, +0xff,0x71,0xff,0xfb,0x7f,0xe7,0xff,0xf9,0xef,0xff,0xd7,0xfa,0xff,0xb7,0xbb,0xfe, +0xff,0xff,0x74,0xff,0xf7,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xb5, +0xbd,0x6f,0x7c,0xeb,0x7f,0xfb,0xdb,0xd3,0x4b,0xee,0xd6,0xf6,0xb7,0xfd,0xac,0xa1, +0xfb,0xdf,0xfe,0xf7,0xf4,0x96,0xbd,0xb4,0xc5,0xa5,0xaf,0x6f,0x69,0x4f,0x7f,0xba, +0xdb,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff, +0xf6,0xff,0xf6,0xff,0xbd,0xbf,0xa5,0xbf,0xff,0x7d,0x7f,0xef,0xff,0xfb,0xf1,0xfd, +0xbf,0xff,0x6f,0xff,0x6b,0x7a,0xdb,0xff,0xdb,0xdf,0xf6,0xfe,0xb6,0xfd,0xfd,0xbf, +0xfe,0xf7,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf4,0x2f,0xff, +0xfc,0x43,0x6b,0xff,0xff,0xff,0x0d,0xff,0xfc,0x33,0x3f,0xf0,0x5f,0xf1,0xff,0xff, +0xff,0xff,0xf9,0xde,0xf0,0x4c,0xfe,0x77,0xaf,0xff,0xff,0xef,0xff,0xf0,0xff,0xdb, +0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xfe,0xf7,0xff,0xf0,0x2f,0xff,0xfd, +0x43,0x7f,0xff,0xff,0xf1,0x0f,0xff,0xfc,0x33,0x3f,0xff,0xaf,0xf1,0xff,0xff,0xff, +0xff,0xf6,0xd7,0xff,0xbc,0xfd,0xbd,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff, +0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0xfb,0xf1, +0xbf,0xff,0xf9,0xfd,0xcf,0xf2,0x70,0xff,0x1f,0x9f,0xf3,0xf1,0xff,0xff,0xff,0xff, +0xfc,0xf7,0xff,0x13,0x9f,0xfc,0xff,0xff,0x84,0xf7,0xff,0xff,0x47,0xff,0xff,0xff, +0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xf1,0xfc,0xff,0xfe,0xfe,0x79, +0x3f,0xff,0x1d,0x46,0xcf,0xff,0xcf,0xfc,0x7b,0xff,0xf1,0xff,0xff,0xff,0xff,0xed, +0xf3,0xab,0xff,0xcb,0xff,0xf8,0xff,0xfc,0xf5,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0, +0x8f,0xff,0xff,0xff,0xfe,0xf3,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, +0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x04,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x20, +0x0c,0x00,0x00,0x04,0x01,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x01,0x3c,0xf0,0x7f, +0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfd,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff, +0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xef,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xeb, +0xff,0xdf,0xff,0xff,0xfb,0xf7,0x7f,0xff,0xfe,0xff,0xff,0xbf,0xdb,0xf0,0xff,0xff, +0xff,0xff,0xfe,0xf0,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0x7f,0xf7,0xff, +0xbf,0xbf,0xcf,0xff,0xff,0xff,0x3e,0xf1,0x7f,0xff,0xff,0xef,0xff,0xff,0xff,0xfe, +0xff,0xfd,0xff,0xbf,0xbd,0xfe,0xff,0xfb,0xf7,0xdf,0xfb,0xd0,0xf0,0x9f,0xff,0xff, +0xff,0xfe,0xf8,0x30,0x20,0x00,0x40,0x01,0x80,0xc0,0x30,0x00,0x00,0x20,0x00,0x10, +0x50,0x88,0x20,0x00,0x00,0x13,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, +0x00,0x00,0x01,0x80,0x08,0x00,0x00,0xa0,0x00,0x10,0xc1,0xf0,0xef,0xff,0xff,0xff, +0xfe,0xfd,0xef,0x7f,0xff,0xff,0xbf,0xff,0xf7,0xff,0xef,0xfb,0xfd,0x77,0xef,0xbf, +0xf7,0x7f,0xff,0xff,0xbf,0xd1,0x7f,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xaf,0xff, +0xdf,0xf7,0xfb,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff, +0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x3f,0xff,0xff,0xff,0xfe,0xdd,0xff, +0xff,0xff,0xa5,0xfd,0x6f,0x7d,0x6d,0x7f,0x52,0xdf,0x5a,0x4b,0xee,0xb6,0xee,0xf2, +0xbb,0xac,0xa1,0x5b,0x4d,0xd6,0xf7,0xfe,0xb2,0xbd,0x35,0xb5,0xb5,0xdd,0x6f,0x7f, +0xe9,0x5f,0x52,0xdf,0xbd,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff, +0xff,0xdb,0xfe,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xb5,0xbf,0xf9,0x7f,0x6f,0xff, +0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0x69,0x7f,0xdb,0xff,0xd3,0xff,0xf6,0xfe,0xf2, +0xff,0xad,0xbf,0xff,0xff,0xff,0xd0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5, +0x30,0x0f,0xff,0xff,0xfd,0x6b,0xca,0xff,0xf0,0x0f,0xd6,0xbf,0xcf,0x3f,0xff,0xff, +0xf1,0xff,0xff,0xff,0xca,0xfe,0xbf,0xff,0xf0,0x05,0xaf,0x0f,0xff,0xfc,0xf0,0xcf, +0xf0,0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0x30, +0x0f,0xff,0xff,0xfc,0x3f,0xca,0xff,0x0f,0x0f,0xd6,0xbf,0xff,0xff,0xf5,0x5f,0xf1, +0xff,0x8b,0xff,0xc3,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xfc,0xf0,0xcf,0xf0, +0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xcf,0xff, +0xff,0xbf,0x9f,0x3f,0xfe,0xfc,0xff,0x4f,0xff,0xff,0xff,0xff,0xff,0xf7,0xf1,0xff, +0xdf,0xfe,0x7e,0x3f,0x9f,0xf4,0xfc,0x7f,0xfc,0xff,0xff,0x3f,0xff,0x3f,0xfe,0x3f, +0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfb,0xff,0xfe,0xff, +0xff,0xff,0xff,0xbf,0xfb,0xff,0xf8,0xed,0xff,0x8f,0xff,0xbb,0xff,0xb1,0xf3,0xef, +0x8f,0xf7,0xff,0xff,0xdb,0xff,0xff,0xff,0xef,0xbf,0xfd,0x79,0xbf,0xbf,0xff,0xff, +0xff,0xfb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x04,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04,0x08,0x08,0x01,0x01,0x00,0x90, +0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x00,0x01, +0x3c,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0x9f,0xff,0xaf,0xdf,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff, +0xbf,0xef,0xff,0xff,0xff,0xed,0xff,0xff,0xff,0xef,0xff,0xbf,0xff,0xff,0xff,0xc3, +0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xfd,0xff,0xff,0xff,0xfb,0xff,0xbb,0xff, +0xff,0xff,0x7f,0xf6,0xff,0x7f,0xfb,0xfd,0xed,0xff,0xf1,0xff,0xfe,0x7f,0xff,0xff, +0xff,0x5f,0xff,0xf7,0xff,0x7e,0xff,0xfd,0xff,0xef,0xff,0xff,0xff,0xef,0xf0,0xf0, +0x8f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x80,0x00,0x04,0x00,0x00,0x40,0x02,0x00,0x03, +0x00,0x05,0x04,0x20,0x00,0x00,0x01,0xd0,0x00,0x81,0x00,0x20,0x04,0x04,0x00,0x00, +0x81,0x04,0x08,0x80,0x10,0x00,0xc0,0x00,0x00,0x00,0x20,0x00,0x08,0xc1,0xf0,0x6f, +0xff,0xff,0xff,0xfe,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xf3,0xfd,0xff,0xed,0xfc, +0xff,0xff,0x9f,0xfb,0xfd,0xff,0xff,0xff,0xf1,0xff,0xff,0x7f,0xfb,0x3e,0xff,0x9f, +0xff,0xff,0xff,0xff,0xfd,0xf9,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0x6f,0xff, +0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xfd,0xbd,0xff,0xef,0x7c,0xeb,0x7f,0xfb,0xdb,0xfa,0xdc, +0xee,0xf7,0xf6,0xd7,0xf5,0x2d,0xa1,0xbb,0xdd,0xee,0xf7,0x54,0xf7,0xfb,0x2c,0xb5, +0xb4,0xbd,0x6b,0x6f,0xef,0x6f,0xbb,0xdf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff, +0xfe,0xbf,0xff,0xff,0xff,0xfb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xff,0xbf,0xef, +0x6f,0xff,0x6f,0xfa,0xdb,0xf1,0xc5,0xbd,0xf5,0x6f,0xff,0x6f,0xca,0xdb,0xff,0xdb, +0xfb,0xf6,0x97,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x9f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0x7f,0xff,0xff,0xe7,0x63,0xff,0xff, +0xff,0xfc,0x77,0xdf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff, +0xc3,0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xfc,0xff,0xcf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff,0xc3, +0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xbf,0xff,0xca,0xff,0x9f,0xff,0xfa,0xb9,0xe7, +0x9f,0xf3,0x81,0xff,0xff,0xfc,0x73,0xd7,0xff,0xff,0x77,0xff,0xfd,0xff,0xfc,0xff, +0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff, +0xff,0xf7,0xde,0xff,0xfe,0x7e,0xff,0xbf,0xff,0xbf,0xf1,0xb3,0xff,0xff,0xe3,0xfb, +0xff,0xe1,0x1f,0x7f,0xff,0xf8,0x78,0xff,0xfb,0x1e,0xff,0xf7,0xfe,0xe7,0xff,0xff, +0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x04,0x00, +0x01,0x80,0x40,0x40,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, +0x80,0x00,0x00,0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xff, +0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xf7,0xf1, +0xfd,0xff,0xff,0xff,0xdf,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff, +0xff,0xff,0xff,0xdb,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xdf,0xff,0xff,0x7f, +0xff,0xff,0xff,0xbe,0xd7,0xff,0xed,0xbd,0x7e,0xbf,0xfe,0xf6,0x7f,0xbf,0x71,0xff, +0xff,0xda,0xff,0xf9,0xff,0xbf,0x7f,0xfe,0xff,0x6f,0x7f,0xff,0xff,0xff,0xff,0xff, +0x7f,0xff,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x42,0x00,0x00,0x00,0x00, +0x80,0xc1,0x00,0x00,0x90,0x00,0xc4,0x00,0x00,0x12,0x20,0x43,0x22,0x81,0x84,0x00, +0x00,0x14,0x00,0x01,0x00,0x08,0x80,0x00,0x02,0x00,0x02,0x00,0x04,0x02,0x00,0x00, +0x10,0xc1,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfd,0xff,0xff,0xdd,0xfe,0xff, +0xb6,0x76,0xe5,0xbc,0xf9,0xf7,0xaf,0x5f,0xbf,0xfc,0xdf,0xcf,0xf1,0xff,0xef,0x79, +0xff,0xbd,0xff,0xef,0xff,0xff,0xf7,0x6f,0x5f,0xff,0xff,0xfd,0xef,0xef,0xbf,0xff, +0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf0,0xff,0xff,0xff,0xff,0xfe,0xdb,0xff,0xff,0xfd,0x2d,0xff,0x69,0x2a,0xef,0x77, +0xbb,0xdd,0x5a,0xdf,0xf6,0xf6,0xd6,0xf7,0x7d,0xbd,0xd1,0xb2,0x4a,0xd6,0xb2,0xbe, +0x97,0xf5,0xbd,0xb3,0xad,0xff,0xef,0x7f,0x69,0x6b,0xfb,0xdf,0xff,0xff,0xff,0xf0, +0x2f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0x9f,0xd4,0xbf, +0xed,0xaf,0xff,0x6b,0x6f,0xf7,0xff,0xdd,0xdb,0x31,0xfd,0xbf,0xff,0x6f,0x7f,0xff, +0xff,0xdb,0xff,0xcb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x8f, +0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff, +0xa5,0xff,0xff,0xff,0xdf,0xb7,0xff,0xff,0xf1,0xff,0xff,0xff,0xf7,0xe9,0x6a,0xbf, +0xff,0xff,0xfd,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xaf,0xf0,0x4f,0xff, +0xff,0xff,0xfe,0xfe,0xdf,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff,0xa5, +0xff,0xff,0xff,0xc0,0x37,0xff,0xff,0xf1,0x99,0x8e,0xdc,0x7f,0xe9,0x6a,0xbf,0xff, +0xf0,0x0f,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xff,0x07,0xff,0xc0,0xbe,0xff,0xff,0xcf,0xef,0x9f,0xff, +0xff,0xfb,0xff,0xe7,0xff,0xff,0xa1,0xe3,0xce,0x3c,0x58,0x3f,0xf3,0xff,0xfd,0xef, +0xf9,0xff,0xff,0xf7,0xf1,0x7f,0xff,0xcb,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff, +0xfe,0xf5,0x7f,0xff,0xf0,0xff,0xfe,0xff,0xc4,0x75,0xe7,0xb9,0xff,0xff,0xff,0xef, +0xff,0xc7,0x37,0x3b,0xff,0xf0,0x13,0x9e,0x0f,0xf4,0xff,0xfe,0xfb,0xff,0xff,0xf9, +0xfc,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xef,0xff,0xff,0xff,0xfe, +0xf3,0xc0,0x01,0x00,0x00,0x02,0x00,0x02,0x22,0x00,0x00,0xc0,0x40,0x00,0x40,0x00, +0x04,0x08,0x04,0x0a,0x01,0x01,0x10,0x20,0x20,0x00,0x00,0x04,0x08,0x08,0x04,0x00, +0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x3c,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xfd, +0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0xcf,0x9d,0xff, +0xff,0xf7,0xfd,0xf1,0xff,0xff,0xff,0xee,0xbf,0xff,0xff,0xff,0xff,0xfe,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xff, +0xff,0xff,0xf7,0xf7,0xff,0xff,0xfe,0xbf,0xf7,0xff,0xff,0x5b,0xff,0xbf,0xf7,0xff, +0xfd,0x7f,0x71,0xfd,0xff,0xed,0xf7,0xfe,0xef,0xff,0xff,0x7f,0xff,0xff,0xff,0xff, +0xff,0xff,0xef,0xff,0x7f,0xff,0xd0,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf8,0x30,0x11, +0x00,0x48,0x60,0x40,0x82,0x60,0x24,0x60,0x00,0xcc,0x00,0x80,0x04,0x01,0x00,0x00, +0x14,0x01,0x0c,0x04,0x00,0x30,0x00,0x00,0x00,0x08,0x08,0x00,0x01,0x00,0xc2,0x00, +0x00,0x02,0x00,0x80,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +0xf7,0x7b,0xff,0xf3,0xeb,0xbf,0xff,0xf7,0xff,0xff,0xff,0xe7,0x5d,0x3f,0xff,0xf6, +0xd1,0xfd,0xff,0xeb,0xf7,0x3d,0xff,0xff,0xff,0x5f,0xff,0x7f,0x7f,0xf3,0xff,0xff, +0xef,0xfd,0xbf,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xb5,0xdf, +0x6f,0x7d,0x69,0x7f,0xfb,0xdf,0x52,0x5f,0xf6,0xf7,0xfe,0xf6,0xf3,0xbd,0xb1,0xda, +0xcd,0xfe,0xf6,0xee,0xd2,0xbd,0xa5,0xaf,0xbd,0xff,0x6f,0x7c,0xeb,0x2b,0xfa,0xda, +0xff,0xfe,0xdf,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6, +0xff,0xf6,0xff,0xbd,0xbf,0xcd,0xbf,0xeb,0x6f,0xf7,0x6f,0xdf,0xdb,0x51,0xfd,0xbd, +0xff,0x6f,0xff,0x6f,0xfb,0x5b,0xff,0xdb,0xff,0xf6,0xfe,0xf6,0xfd,0xfd,0xbf,0xfe, +0xf7,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfa,0x50,0xff,0xff,0xff, +0xf0,0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0xfc,0xff,0xff, +0xf7,0xdb,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff, +0xaf,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xa0,0xff,0xff,0xff,0xf0, +0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff, +0xf3,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff,0xff, +0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0x9f,0xf0,0x7f, +0xff,0xf9,0xfc,0x4f,0xf3,0xff,0x27,0xeb,0xff,0xfc,0x81,0xfc,0x7f,0xfe,0x7b,0xff, +0xf7,0xff,0x12,0x7f,0xff,0xff,0xff,0xff,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xf0, +0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xdf,0xfe,0xff,0xfc,0x7e,0x7f,0xbf, +0xff,0xff,0xaf,0xef,0xff,0xdf,0xdf,0xfb,0xff,0xf1,0xc3,0xfe,0x6f,0xf1,0xcf,0x3f, +0xfb,0xff,0xff,0xcf,0xfe,0xff,0xff,0xfe,0x7f,0xbf,0xff,0xff,0xbf,0xfa,0xf0,0xdf, +0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00, +0x20,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x02,0x80,0x00,0x02,0x3c,0xf0,0x2f,0xff, +0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xf1,0xff,0x7f,0xff,0xff,0xff,0xff,0xef,0xff, +0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x2f,0xff,0xff, +0xff,0xfe,0xf0,0xff,0xff,0xff,0xfb,0xff,0xbf,0xff,0xff,0xff,0xff,0xf7,0xbf,0xfb, +0xff,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xf7,0xbf,0xfb,0xff,0xff,0xff,0x7f,0xde,0xff, +0xff,0xff,0xff,0xff,0xff,0xed,0xf7,0xff,0xff,0x7f,0xd0,0xf0,0x3f,0xff,0xff,0xff, +0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80, +0x20,0x01,0x01,0x92,0x00,0x01,0x01,0x00,0xe0,0x1c,0x60,0x20,0x30,0x08,0x08,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xc1,0xf0,0x6f,0xff,0xff,0xff,0xfe, +0xff,0xff,0xff,0xff,0xff,0xdb,0xfe,0xff,0xff,0xdf,0xff,0xfc,0x7f,0xfb,0xbf,0xff, +0xff,0xff,0xff,0xff,0xf1,0xf6,0xff,0xf7,0x7e,0x3f,0xff,0x7f,0xff,0xff,0xff,0xf7, +0xff,0xff,0xff,0xed,0xff,0xdf,0xff,0xb7,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff, +0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xbf,0xff,0xdf, +0x57,0xef,0xf1,0xfd,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfb,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff, +0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xdf,0xff, +0xff,0xf1,0xfd,0xff,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xf7,0xfd,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff, +0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1, +0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0x6f,0xff,0xfe,0xbf,0xff,0xf1,0xff, +0xf7,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd, +0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x57,0xff,0xfd,0xbf,0xff,0xf1,0xff,0xef, +0xfe,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff, +0xde,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd, +0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xe7,0x2f,0xf1,0x3c,0xbf,0xfd, +0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff, +0x02,0x01,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff }; diff --git a/drivers/net/hostess_sv11.c b/drivers/net/hostess_sv11.c index d4f0dec2d..7b24901ce 100644 --- a/drivers/net/hostess_sv11.c +++ b/drivers/net/hostess_sv11.c @@ -73,7 +73,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) * We've been placed in the UP state */ -static int hostess_open(struct device *d) +static int hostess_open(struct net_device *d) { struct sv11_device *sv11=d->priv; int err = -1; @@ -126,7 +126,7 @@ static int hostess_open(struct device *d) return 0; } -static int hostess_close(struct device *d) +static int hostess_close(struct net_device *d) { struct sv11_device *sv11=d->priv; /* @@ -158,14 +158,14 @@ static int hostess_close(struct device *d) return 0; } -static int hostess_ioctl(struct device *d, struct ifreq *ifr, int cmd) +static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) { /* struct sv11_device *sv11=d->priv; z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *hostess_get_stats(struct device *d) +static struct enet_statistics *hostess_get_stats(struct net_device *d) { struct sv11_device *sv11=d->priv; if(sv11) @@ -178,7 +178,7 @@ static struct enet_statistics *hostess_get_stats(struct device *d) * Passed PPP frames, fire them downwind. */ -static int hostess_queue_xmit(struct sk_buff *skb, struct device *d) +static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) { struct sv11_device *sv11=d->priv; return z8530_queue_xmit(&sv11->sync.chanA, skb); @@ -194,7 +194,7 @@ static int hostess_neigh_setup(struct neighbour *n) return 0; } -static int hostess_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int hostess_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = hostess_neigh_setup; @@ -206,7 +206,7 @@ static int hostess_neigh_setup_dev(struct device *dev, struct neigh_parms *p) #else -static int return_0(struct device *d) +static int return_0(struct net_device *d) { return 0; } @@ -322,7 +322,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) sprintf(sv->name,"hdlc%d", i); if(dev_get(sv->name)==NULL) { - struct device *d=dev->chanA.netdevice; + struct net_device *d=dev->chanA.netdevice; /* * Initialise the PPP components diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index b58ba73fc..889c586fa 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -94,23 +94,23 @@ enum HP_Option { EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20, MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, }; -int hp_plus_probe(struct device *dev); -int hpp_probe1(struct device *dev, int ioaddr); +int hp_plus_probe(struct net_device *dev); +int hpp_probe1(struct net_device *dev, int ioaddr); -static void hpp_reset_8390(struct device *dev); -static int hpp_open(struct device *dev); -static int hpp_close(struct device *dev); -static void hpp_mem_block_input(struct device *dev, int count, +static void hpp_reset_8390(struct net_device *dev); +static int hpp_open(struct net_device *dev); +static int hpp_close(struct net_device *dev); +static void hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void hpp_mem_block_output(struct device *dev, int count, +static void hpp_mem_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void hpp_io_block_input(struct device *dev, int count, +static void hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void hpp_io_block_output(struct device *dev, int count, +static void hpp_io_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -123,7 +123,7 @@ struct netdev_entry hpplus_drv = {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist}; #else -int __init hp_plus_probe(struct device *dev) +int __init hp_plus_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -146,7 +146,7 @@ int __init hp_plus_probe(struct device *dev) #endif /* Do the interesting part of the probe at a single address. */ -int __init hpp_probe1(struct device *dev, int ioaddr) +int __init hpp_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char checksum = 0; @@ -258,7 +258,7 @@ int __init hpp_probe1(struct device *dev, int ioaddr) } static int -hpp_open(struct device *dev) +hpp_open(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg; @@ -287,7 +287,7 @@ hpp_open(struct device *dev) } static int -hpp_close(struct device *dev) +hpp_close(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -302,7 +302,7 @@ hpp_close(struct device *dev) } static void -hpp_reset_8390(struct device *dev) +hpp_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -329,7 +329,7 @@ hpp_reset_8390(struct device *dev) Note that transfer with the EtherTwist+ must be on word boundaries. */ static void -hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -340,7 +340,7 @@ hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page /* Block input and output, similar to the Crynwr packet driver. */ static void -hpp_io_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - NIC_OFFSET; char *buf = skb->data; @@ -354,7 +354,7 @@ hpp_io_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_ /* The corresponding shared memory versions of the above 2 functions. */ static void -hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -367,7 +367,7 @@ hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_pag } static void -hpp_mem_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -387,7 +387,7 @@ hpp_mem_block_input(struct device *dev, int count, struct sk_buff *skb, int ring /* A special note: we *must* always transfer >=16 bit words. It's always safe to round up, so we do. */ static void -hpp_io_block_output(struct device *dev, int count, +hpp_io_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -397,7 +397,7 @@ hpp_io_block_output(struct device *dev, int count, } static void -hpp_mem_block_output(struct device *dev, int count, +hpp_mem_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -416,7 +416,7 @@ hpp_mem_block_output(struct device *dev, int count, #define MAX_HPP_CARDS 4 /* Max number of HPP cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_HPP_CARDS] = { 0, }; -static struct device dev_hpp[MAX_HPP_CARDS] = { +static struct net_device dev_hpp[MAX_HPP_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -439,7 +439,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { - struct device *dev = &dev_hpp[this_dev]; + struct net_device *dev = &dev_hpp[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -468,7 +468,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { - struct device *dev = &dev_hpp[this_dev]; + struct net_device *dev = &dev_hpp[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - NIC_OFFSET; void *priv = dev->priv; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index c031cd87f..24b3e9d83 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -56,20 +56,20 @@ static unsigned int hppclan_portlist[] __initdata = #define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */ #define HP_16BSTOP_PG 0xFF /* Same, for 16 bit cards. */ -int hp_probe(struct device *dev); -int hp_probe1(struct device *dev, int ioaddr); +int hp_probe(struct net_device *dev); +int hp_probe1(struct net_device *dev, int ioaddr); -static int hp_open(struct device *dev); -static int hp_close(struct device *dev); -static void hp_reset_8390(struct device *dev); -static void hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int hp_open(struct net_device *dev); +static int hp_close(struct net_device *dev); +static void hp_reset_8390(struct net_device *dev); +static void hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void hp_block_input(struct device *dev, int count, +static void hp_block_input(struct net_device *dev, int count, struct sk_buff *skb , int ring_offset); -static void hp_block_output(struct device *dev, int count, +static void hp_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hp_init_card(struct device *dev); +static void hp_init_card(struct net_device *dev); /* The map from IRQ number to HP_CONFIGURE register setting. */ /* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ @@ -84,7 +84,7 @@ struct netdev_entry netcard_drv = {"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist}; #else -int __init hp_probe(struct device *dev) +int __init hp_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -106,7 +106,7 @@ int __init hp_probe(struct device *dev) } #endif -int __init hp_probe1(struct device *dev, int ioaddr) +int __init hp_probe1(struct net_device *dev, int ioaddr) { int i, board_id, wordmode; const char *name; @@ -215,7 +215,7 @@ int __init hp_probe1(struct device *dev, int ioaddr) } static int -hp_open(struct device *dev) +hp_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; @@ -223,7 +223,7 @@ hp_open(struct device *dev) } static int -hp_close(struct device *dev) +hp_close(struct net_device *dev) { ei_close(dev); MOD_DEC_USE_COUNT; @@ -231,7 +231,7 @@ hp_close(struct device *dev) } static void -hp_reset_8390(struct device *dev) +hp_reset_8390(struct net_device *dev) { int hp_base = dev->base_addr - NIC_OFFSET; int saved_config = inb_p(hp_base + HP_CONFIGURE); @@ -253,7 +253,7 @@ hp_reset_8390(struct device *dev) } static void -hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); @@ -280,7 +280,7 @@ hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) out through the "remote DMA" dataport. */ static void -hp_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hp_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); @@ -315,7 +315,7 @@ hp_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offs } static void -hp_block_output(struct device *dev, int count, +hp_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int nic_base = dev->base_addr; @@ -374,7 +374,7 @@ hp_block_output(struct device *dev, int count, /* This function resets the ethercard if something screws up. */ static void -hp_init_card(struct device *dev) +hp_init_card(struct net_device *dev) { int irq = dev->irq; NS8390_init(dev, 0); @@ -387,7 +387,7 @@ hp_init_card(struct device *dev) #define MAX_HP_CARDS 4 /* Max number of HP cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_HP_CARDS] = { 0, }; -static struct device dev_hp[MAX_HP_CARDS] = { +static struct net_device dev_hp[MAX_HP_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -410,7 +410,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { - struct device *dev = &dev_hp[this_dev]; + struct net_device *dev = &dev_hp[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -439,7 +439,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { - struct device *dev = &dev_hp[this_dev]; + struct net_device *dev = &dev_hp[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - NIC_OFFSET; void *priv = dev->priv; diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8535a4955..9baf82381 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -119,12 +119,6 @@ EXPORT_NO_SYMBOLS; typedef struct enet_statistics hp100_stats_t; #endif -#ifndef __initfunc -#define __initfunc(__initarg) __initarg -#else -#include <linux/init.h> -#endif - #include "hp100.h" /* @@ -302,38 +296,38 @@ MODULE_PARM( hp100_mode, "1i" ); */ #ifdef LINUX_2_1 -static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); +static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); #else -static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ); -#endif -static int hp100_open( struct device *dev ); -static int hp100_close( struct device *dev ); -static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ); -static int hp100_start_xmit_bm (struct sk_buff *skb, struct device *dev ); -static void hp100_rx( struct device *dev ); -static hp100_stats_t *hp100_get_stats( struct device *dev ); -static void hp100_misc_interrupt( struct device *dev ); -static void hp100_update_stats( struct device *dev ); +static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ); +#endif +static int hp100_open( struct net_device *dev ); +static int hp100_close( struct net_device *dev ); +static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ); +static int hp100_start_xmit_bm (struct sk_buff *skb, struct net_device *dev ); +static void hp100_rx( struct net_device *dev ); +static hp100_stats_t *hp100_get_stats( struct net_device *dev ); +static void hp100_misc_interrupt( struct net_device *dev ); +static void hp100_update_stats( struct net_device *dev ); static void hp100_clear_stats( int ioaddr ); -static void hp100_set_multicast_list( struct device *dev); +static void hp100_set_multicast_list( struct net_device *dev); static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ); -static void hp100_start_interface( struct device *dev ); -static void hp100_stop_interface( struct device *dev ); -static void hp100_load_eeprom( struct device *dev, u_short ioaddr ); -static int hp100_sense_lan( struct device *dev ); -static int hp100_login_to_vg_hub( struct device *dev, u_short force_relogin ); -static int hp100_down_vg_link( struct device *dev ); -static void hp100_cascade_reset( struct device *dev, u_short enable ); -static void hp100_BM_shutdown( struct device *dev ); -static void hp100_mmuinit( struct device *dev ); -static void hp100_init_pdls( struct device *dev ); -static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static int hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static void hp100_rxfill( struct device *dev ); -static void hp100_hwinit( struct device *dev ); -static void hp100_clean_txring( struct device *dev ); +static void hp100_start_interface( struct net_device *dev ); +static void hp100_stop_interface( struct net_device *dev ); +static void hp100_load_eeprom( struct net_device *dev, u_short ioaddr ); +static int hp100_sense_lan( struct net_device *dev ); +static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ); +static int hp100_down_vg_link( struct net_device *dev ); +static void hp100_cascade_reset( struct net_device *dev, u_short enable ); +static void hp100_BM_shutdown( struct net_device *dev ); +static void hp100_mmuinit( struct net_device *dev ); +static void hp100_init_pdls( struct net_device *dev ); +static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); +static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); +static void hp100_rxfill( struct net_device *dev ); +static void hp100_hwinit( struct net_device *dev ); +static void hp100_clean_txring( struct net_device *dev ); #ifdef HP100_DEBUG -static void hp100_RegisterDump( struct device *dev ); +static void hp100_RegisterDump( struct net_device *dev ); #endif /* TODO: This function should not really be needed in a good design... */ @@ -348,7 +342,7 @@ static void wait( void ) * since this could cause problems when the card is not installed. */ -int __init hp100_probe( struct device *dev ) +int __init hp100_probe( struct net_device *dev ) { int base_addr = dev ? dev -> base_addr : 0; int ioaddr = 0; @@ -421,7 +415,7 @@ int __init hp100_probe( struct device *dev ) continue; } /* found... */ - ioaddr = pci_dev -> base_address[ 0 ] & ~3; + ioaddr = pci_dev ->resource[ 0 ].start; if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; pci_read_config_word( pci_dev, PCI_COMMAND, &pci_command ); if ( !( pci_command & PCI_COMMAND_IO ) ) { @@ -525,9 +519,9 @@ int __init hp100_probe( struct device *dev ) #ifdef LINUX_2_1 -static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) +static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) #else -static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ) +static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ) #endif { int i; @@ -943,7 +937,7 @@ static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_ch /* This procedure puts the card into a stable init state */ -static void hp100_hwinit( struct device *dev ) +static void hp100_hwinit( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1039,7 +1033,7 @@ static void hp100_hwinit( struct device *dev ) * mmuinit - Reinitialise Cascade MMU and MAC settings. * Note: Must already be in reset and leaves card in reset. */ -static void hp100_mmuinit( struct device *dev ) +static void hp100_mmuinit( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1232,7 +1226,7 @@ static void hp100_mmuinit( struct device *dev ) * open/close functions */ -static int hp100_open( struct device *dev ) +static int hp100_open( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; #ifdef HP100_DEBUG_B @@ -1276,7 +1270,7 @@ static int hp100_open( struct device *dev ) /* The close function is called when the interface is to be brought down */ -static int hp100_close( struct device *dev ) +static int hp100_close( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1311,7 +1305,7 @@ static int hp100_close( struct device *dev ) /* * Configure the PDL Rx rings and LAN */ -static void hp100_init_pdls( struct device *dev ) +static void hp100_init_pdls( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; hp100_ring_t *ringptr; @@ -1364,7 +1358,7 @@ static void hp100_init_pdls( struct device *dev ) /* These functions "format" the entries in the pdl structure */ /* They return how much memory the fragments need. */ -static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) { /* pdlptr is starting address for this pdl */ @@ -1390,7 +1384,7 @@ static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, } -static int hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) { if( 0!=( ((unsigned)pdlptr) & 0xf) ) printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned) pdlptr); @@ -1410,7 +1404,7 @@ static int hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, * Returns: 0 if unable to allocate skb_buff * 1 if successful */ -int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct device *dev ) +int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct net_device *dev ) { #ifdef HP100_DEBUG_B int ioaddr = dev->base_addr; @@ -1494,7 +1488,7 @@ int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct device *dev ) * b. Put the physical address of the buffer into the PDL. * c. Output physical address of PDL to adapter. */ -static void hp100_rxfill( struct device *dev ) +static void hp100_rxfill( struct net_device *dev ) { int ioaddr=dev->base_addr; @@ -1542,7 +1536,7 @@ static void hp100_rxfill( struct device *dev ) * BM_shutdown - shutdown bus mastering and leave chip in reset state */ -static void hp100_BM_shutdown( struct device *dev ) +static void hp100_BM_shutdown( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1636,7 +1630,7 @@ static void hp100_BM_shutdown( struct device *dev ) */ /* tx function for busmaster mode */ -static int hp100_start_xmit_bm( struct sk_buff *skb, struct device *dev ) +static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev ) { unsigned long flags; int i, ok_flag; @@ -1774,7 +1768,7 @@ static int hp100_start_xmit_bm( struct sk_buff *skb, struct device *dev ) * * Needs the PERFORMANCE page selected. */ -static void hp100_clean_txring( struct device *dev ) +static void hp100_clean_txring( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1816,7 +1810,7 @@ static void hp100_clean_txring( struct device *dev ) /* tx function for slave modes */ -static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) +static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) { int i, ok_flag; int ioaddr = dev->base_addr; @@ -1986,7 +1980,7 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) * and netif_rx. */ -static void hp100_rx( struct device *dev ) +static void hp100_rx( struct net_device *dev ) { int packets, pkt_len; int ioaddr = dev->base_addr; @@ -2105,7 +2099,7 @@ static void hp100_rx( struct device *dev ) /* * Receive Function for Busmaster Mode */ -static void hp100_rx_bm( struct device *dev ) +static void hp100_rx_bm( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -2234,7 +2228,7 @@ static void hp100_rx_bm( struct device *dev ) /* * statistics */ -static hp100_stats_t *hp100_get_stats( struct device *dev ) +static hp100_stats_t *hp100_get_stats( struct net_device *dev ) { int ioaddr = dev->base_addr; @@ -2248,7 +2242,7 @@ static hp100_stats_t *hp100_get_stats( struct device *dev ) return &((struct hp100_private *)dev->priv)->stats; } -static void hp100_update_stats( struct device *dev ) +static void hp100_update_stats( struct net_device *dev ) { int ioaddr = dev->base_addr; u_short val; @@ -2273,7 +2267,7 @@ static void hp100_update_stats( struct device *dev ) hp100_page( PERFORMANCE ); } -static void hp100_misc_interrupt( struct device *dev ) +static void hp100_misc_interrupt( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -2315,7 +2309,7 @@ static void hp100_clear_stats( int ioaddr ) * Set or clear the multicast filter for this adapter. */ -static void hp100_set_multicast_list( struct device *dev ) +static void hp100_set_multicast_list( struct net_device *dev ) { unsigned long flags; int ioaddr = dev->base_addr; @@ -2470,7 +2464,7 @@ static void hp100_set_multicast_list( struct device *dev ) static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr; @@ -2611,7 +2605,7 @@ static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ) * some misc functions */ -static void hp100_start_interface( struct device *dev ) +static void hp100_start_interface( struct net_device *dev ) { unsigned long flags; int ioaddr = dev->base_addr; @@ -2678,7 +2672,7 @@ static void hp100_start_interface( struct device *dev ) } -static void hp100_stop_interface( struct device *dev ) +static void hp100_stop_interface( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -2716,7 +2710,7 @@ static void hp100_stop_interface( struct device *dev ) } -static void hp100_load_eeprom( struct device *dev, u_short probe_ioaddr ) +static void hp100_load_eeprom( struct net_device *dev, u_short probe_ioaddr ) { int i; int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr; @@ -2739,7 +2733,7 @@ static void hp100_load_eeprom( struct device *dev, u_short probe_ioaddr ) * LAN_100 - Connected to 100Mbit/s network * LAN_ERR - not connected or 100Mbit/s Hub down */ -static int hp100_sense_lan( struct device *dev ) +static int hp100_sense_lan( struct net_device *dev ) { int ioaddr = dev->base_addr; u_short val_VG, val_10; @@ -2781,7 +2775,7 @@ static int hp100_sense_lan( struct device *dev ) -static int hp100_down_vg_link( struct device *dev ) +static int hp100_down_vg_link( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -2875,7 +2869,7 @@ static int hp100_down_vg_link( struct device *dev ) } -static int hp100_login_to_vg_hub( struct device *dev, u_short force_relogin ) +static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -3048,7 +3042,7 @@ static int hp100_login_to_vg_hub( struct device *dev, u_short force_relogin ) } -static void hp100_cascade_reset( struct device *dev, u_short enable ) +static void hp100_cascade_reset( struct net_device *dev, u_short enable ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -3085,7 +3079,7 @@ static void hp100_cascade_reset( struct device *dev, u_short enable ) } #ifdef HP100_DEBUG -void hp100_RegisterDump( struct device *dev ) +void hp100_RegisterDump( struct net_device *dev ) { int ioaddr=dev->base_addr; int Page; @@ -3142,7 +3136,7 @@ static char *hp100_name[5] = { devname[0], devname[1], #endif /* List of devices */ -static struct device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; +static struct net_device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; /* * Note: if you have more than five 100vg cards in your pc, feel free to @@ -3168,8 +3162,8 @@ int init_module( void ) while((hp100_port[++i] != -1) && (i < 5)) { /* Create device and set basics args */ - hp100_devlist[i] = kmalloc(sizeof(struct device), GFP_KERNEL); - memset(hp100_devlist[i], 0x00, sizeof(struct device)); + hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); + memset(hp100_devlist[i], 0x00, sizeof(struct net_device)); hp100_devlist[i]->name = hp100_name[i]; hp100_devlist[i]->base_addr = hp100_port[i]; hp100_devlist[i]->init = &hp100_probe; @@ -3179,8 +3173,8 @@ int init_module( void ) { /* DeAllocate everything */ /* Note: if dev->priv is mallocated, there is no way to fail */ - kfree_s(hp100_devlist[i], sizeof(struct device)); - hp100_devlist[i] = (struct device *) NULL; + kfree_s(hp100_devlist[i], sizeof(struct net_device)); + hp100_devlist[i] = (struct net_device *) NULL; } else cards++; @@ -3195,7 +3189,7 @@ void cleanup_module( void ) /* TODO: Check if all skb's are released/freed. */ for(i = 0; i < 5; i++) - if(hp100_devlist[i] != (struct device *) NULL) + if(hp100_devlist[i] != (struct net_device *) NULL) { unregister_netdev( hp100_devlist[i] ); release_region( hp100_devlist[i]->base_addr, HP100_REGION_SIZE ); @@ -3205,8 +3199,8 @@ void cleanup_module( void ) iounmap( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt ); kfree_s( hp100_devlist[i]->priv, sizeof( struct hp100_private ) ); hp100_devlist[i]->priv = NULL; - kfree_s(hp100_devlist[i], sizeof(struct device)); - hp100_devlist[i] = (struct device *) NULL; + kfree_s(hp100_devlist[i], sizeof(struct net_device)); + hp100_devlist[i] = (struct net_device *) NULL; } } diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index b8249f1f9..f10944aba 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -54,10 +54,10 @@ struct hplance_private { * plus board-specific init, open and close actions. * Oh, and we need to tell the generic code how to read and write LANCE registers... */ -int hplance_probe(struct device *dev); -static int hplance_init(struct device *dev, int scode); -static int hplance_open(struct device *dev); -static int hplance_close(struct device *dev); +int hplance_probe(struct net_device *dev); +static int hplance_init(struct net_device *dev, int scode); +static int hplance_open(struct net_device *dev); +static int hplance_close(struct net_device *dev); static void hplance_writerap(struct hplance_private *lp, unsigned short value); static void hplance_writerdp(struct hplance_private *lp, unsigned short value); static unsigned short hplance_readrdp(struct hplance_private *lp); @@ -67,7 +67,7 @@ static struct hplance_private *root_hplance_dev = NULL; #endif /* Find all the HP Lance boards and initialise them... */ -int __init hplance_probe(struct device *dev) +int __init hplance_probe(struct net_device *dev) { int cards = 0, called = 0; @@ -98,7 +98,7 @@ int __init hplance_probe(struct device *dev) } /* Initialise a single lance board at the given select code */ -static int __init hplance_init(struct device *dev, int scode) +static int __init hplance_init(struct net_device *dev, int scode) { /* const char *name = dio_scodetoname(scode); */ static const char name[] = "HP LANCE"; @@ -198,7 +198,7 @@ static unsigned short hplance_readrdp(struct hplance_private *lp) return val; } -static int hplance_open(struct device *dev) +static int hplance_open(struct net_device *dev) { int status; struct hplance_private *lp = (struct hplance_private *)dev->priv; @@ -214,7 +214,7 @@ static int hplance_open(struct device *dev) return 0; } -static int hplance_close(struct device *dev) +static int hplance_close(struct net_device *dev) { struct hplance_private *lp = (struct hplance_private *)dev->priv; struct hplance_reg *hpregs = (struct hplance_reg *)lp->base; diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 5ced788bb..483d94e45 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -3,7 +3,7 @@ /* also some code & lots of fixes by Timo Rossi (trossi@cc.jyu.fi) */ /* The code is mostly based on the linux/68k Ariadne driver */ -/* copyrighted by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be) */ +/* copyrighted by Geert Uytterhoeven (geert@linux-m68k.org) */ /* and Peter De Schrijver (Peter.DeSchrijver@linux.cc.kuleuven.ac.be) */ /* This file is subject to the terms and conditions of the GNU General */ @@ -90,14 +90,14 @@ struct hydra_private unsigned int key; }; -static int hydra_open(struct device *dev); -static int hydra_start_xmit(struct sk_buff *skb, struct device *dev); +static int hydra_open(struct net_device *dev); +static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev); static void hydra_interrupt(int irq, void *data, struct pt_regs *fp); -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u8 *nicbase); -static int hydra_close(struct device *dev); -static struct net_device_stats *hydra_get_stats(struct device *dev); +static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase); +static int hydra_close(struct net_device *dev); +static struct net_device_stats *hydra_get_stats(struct net_device *dev); #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); +static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs); #endif @@ -157,7 +157,7 @@ static void memcpyw(u16 *dest, u16 *src, int len) #endif -int __init hydra_probe(struct device *dev) +int __init hydra_probe(struct net_device *dev) { struct hydra_private *priv; u32 board; @@ -210,7 +210,7 @@ int __init hydra_probe(struct device *dev) } -static int hydra_open(struct device *dev) +static int hydra_open(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -282,7 +282,8 @@ static int hydra_open(struct device *dev) dev->interrupt = 0; dev->start = 1; - if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, 0, "Hydra Ethernet", dev)) + if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, SA_SHIRQ, + "Hydra Ethernet", dev)) return(-EAGAIN); MOD_INC_USE_COUNT; @@ -291,7 +292,7 @@ static int hydra_open(struct device *dev) } -static int hydra_close(struct device *dev) +static int hydra_close(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -322,7 +323,7 @@ static void hydra_interrupt(int irq, void *data, struct pt_regs *fp) { volatile u8 *nicbase; - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct hydra_private *priv; u16 intbits; @@ -433,7 +434,7 @@ static void hydra_interrupt(int irq, void *data, struct pt_regs *fp) * packet transmit routine */ -static int hydra_start_xmit(struct sk_buff *skb, struct device *dev) +static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -524,7 +525,7 @@ static int hydra_start_xmit(struct sk_buff *skb, struct device *dev) } -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u8 *nicbase) +static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase) { volatile u16 *board_ram_ptr; struct sk_buff *skb; @@ -633,7 +634,7 @@ note-for-v2.1: not really problem anymore. hasn't been for a long time. } -static struct net_device_stats *hydra_get_stats(struct device *dev) +static struct net_device_stats *hydra_get_stats(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; #if 0 @@ -647,7 +648,7 @@ static struct net_device_stats *hydra_get_stats(struct device *dev) } #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) +static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs) { struct hydra_private *priv = (struct hydra_private *)dev->priv; u8 *board = priv->hydra_base; @@ -662,7 +663,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device hydra_dev = +static struct net_device hydra_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index 947f8c75c..cf2514fa6 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -149,10 +149,10 @@ static char mcchannelid[] = { #include <linux/trdevice.h> #include <linux/stddef.h> #include <linux/init.h> +#include <linux/spinlock.h> #include <net/checksum.h> #include <asm/io.h> -#include <asm/spinlock.h> #include <asm/system.h> #include <asm/bitops.h> @@ -193,27 +193,27 @@ unsigned char ibmtr_debug_trace=0; #define TRC_INIT 0x01 /* Trace initialization & PROBEs */ #define TRC_INITV 0x02 /* verbose init trace points */ -int ibmtr_probe(struct device *dev); -static int ibmtr_probe1(struct device *dev, int ioaddr); +int ibmtr_probe(struct net_device *dev); +static int ibmtr_probe1(struct net_device *dev, int ioaddr); static unsigned char get_sram_size(struct tok_info *adapt_info); #ifdef PCMCIA extern unsigned char pcmcia_reality_check(unsigned char gss); #endif -static int tok_init_card(struct device *dev); +static int tok_init_card(struct net_device *dev); void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int trdev_init(struct device *dev); -static void initial_tok_int(struct device *dev); -static void open_sap(unsigned char type,struct device *dev); +static int trdev_init(struct net_device *dev); +static void initial_tok_int(struct net_device *dev); +static void open_sap(unsigned char type,struct net_device *dev); void tok_open_adapter(unsigned long dev_addr); -static void tr_rx(struct device *dev); -static void tr_tx(struct device *dev); -static int tok_open(struct device *dev); -static int tok_close(struct device *dev); -static int tok_send_packet(struct sk_buff *skb, struct device *dev); -static struct net_device_stats * tok_get_stats(struct device *dev); -void ibmtr_readlog(struct device *dev); -void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -int ibmtr_change_mtu(struct device *dev, int mtu); +static void tr_rx(struct net_device *dev); +static void tr_tx(struct net_device *dev); +static int tok_open(struct net_device *dev); +static int tok_close(struct net_device *dev); +static int tok_send_packet(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats * tok_get_stats(struct net_device *dev); +void ibmtr_readlog(struct net_device *dev); +void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev); +int ibmtr_change_mtu(struct net_device *dev, int mtu); static unsigned int ibmtr_portlist[] __initdata = { 0xa20, 0xa24, 0 @@ -250,7 +250,7 @@ static void __init HWPrtChanID (__u32 pcid, short stride) * which references it. */ -int __init ibmtr_probe(struct device *dev) +int __init ibmtr_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -293,7 +293,7 @@ int __init ibmtr_probe(struct device *dev) return -ENODEV; } -static int __init ibmtr_probe1(struct device *dev, int PIOaddr) +static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) { unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; __u32 t_mmio=0; @@ -767,7 +767,7 @@ static unsigned char __init get_sram_size(struct tok_info *adapt_info) return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4); } -static int __init trdev_init(struct device *dev) +static int __init trdev_init(struct net_device *dev) { struct tok_info *ti=(struct tok_info *)dev->priv; @@ -791,7 +791,7 @@ static int __init trdev_init(struct device *dev) -static int tok_open(struct device *dev) +static int tok_open(struct net_device *dev) { struct tok_info *ti=(struct tok_info *)dev->priv; @@ -815,7 +815,7 @@ static int tok_open(struct device *dev) } -static int tok_close(struct device *dev) +static int tok_close(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; @@ -846,7 +846,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; struct tok_info *ti; - struct device *dev; + struct net_device *dev; dev = dev_id; #if TR_VERBOSE @@ -1220,7 +1220,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) spin_unlock(&(ti->lock)); } -static void initial_tok_int(struct device *dev) +static void initial_tok_int(struct net_device *dev) { __u32 encoded_addr; @@ -1288,7 +1288,7 @@ static void initial_tok_int(struct device *dev) tok_open_adapter((unsigned long)dev); } -static int tok_init_card(struct device *dev) +static int tok_init_card(struct net_device *dev) { struct tok_info *ti; short PIOaddr; @@ -1326,7 +1326,7 @@ static int tok_init_card(struct device *dev) return 0; } -static void open_sap(unsigned char type,struct device *dev) +static void open_sap(unsigned char type,struct net_device *dev) { int i; struct tok_info *ti=(struct tok_info *) dev->priv; @@ -1351,7 +1351,7 @@ static void open_sap(unsigned char type,struct device *dev) void tok_open_adapter(unsigned long dev_addr) { - struct device *dev=(struct device *)dev_addr; + struct net_device *dev=(struct net_device *)dev_addr; struct tok_info *ti; int i; @@ -1400,7 +1400,7 @@ void tok_open_adapter(unsigned long dev_addr) } -static void tr_tx(struct device *dev) +static void tr_tx(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data; @@ -1475,7 +1475,7 @@ static void tr_tx(struct device *dev) if (ti->readlog_pending) ibmtr_readlog(dev); } -static void tr_rx(struct device *dev) +static void tr_rx(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; __u32 rbuffer, rbufdata; @@ -1630,7 +1630,7 @@ static void tr_rx(struct device *dev) netif_rx(skb); } -static int tok_send_packet(struct sk_buff *skb, struct device *dev) +static int tok_send_packet(struct sk_buff *skb, struct net_device *dev) { struct tok_info *ti; ti=(struct tok_info *) dev->priv; @@ -1668,7 +1668,7 @@ static int tok_send_packet(struct sk_buff *skb, struct device *dev) return 0; } -void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev) { +void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev) { tmr->expires = jiffies + TR_RETRY_INTERVAL; tmr->data = (unsigned long) dev; tmr->function = tok_open_adapter; @@ -1676,7 +1676,7 @@ void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev) { add_timer(tmr); } -void ibmtr_readlog(struct device *dev) { +void ibmtr_readlog(struct net_device *dev) { struct tok_info *ti; ti=(struct tok_info *) dev->priv; @@ -1692,14 +1692,14 @@ void ibmtr_readlog(struct device *dev) { this device -- the tr.... structure is an ethnet look-alike so at least for this iteration may suffice. */ -static struct net_device_stats * tok_get_stats(struct device *dev) { +static struct net_device_stats * tok_get_stats(struct net_device *dev) { struct tok_info *toki; toki=(struct tok_info *) dev->priv; return (struct net_device_stats *) &toki->tr_stats; } -int ibmtr_change_mtu(struct device *dev, int mtu) { +int ibmtr_change_mtu(struct net_device *dev, int mtu) { struct tok_info *ti = (struct tok_info *) dev->priv; if (ti->ring_speed == 16 && mtu > ti->maxmtu16) @@ -1713,7 +1713,7 @@ int ibmtr_change_mtu(struct device *dev, int mtu) { #ifdef MODULE /* 3COM 3C619C supports 8 interrupts, 32 I/O ports */ -static struct device* dev_ibmtr[IBMTR_MAX_ADAPTERS]; +static struct net_device* dev_ibmtr[IBMTR_MAX_ADAPTERS]; static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24}; static int irq[IBMTR_MAX_ADAPTERS] = {0,0}; static int mem[IBMTR_MAX_ADAPTERS] = {0,0}; @@ -1739,7 +1739,7 @@ int init_module(void) dev_ibmtr[i]->init = &ibmtr_probe; if (register_trdev(dev_ibmtr[i]) != 0) { - kfree_s(dev_ibmtr[i], sizeof(struct device)); + kfree_s(dev_ibmtr[i], sizeof(struct net_device)); dev_ibmtr[i] = NULL; if (i == 0) { printk("ibmtr: register_trdev() returned non-zero.\n"); @@ -1762,7 +1762,7 @@ void cleanup_module(void) free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]); release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT); kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info)); - kfree_s(dev_ibmtr[i], sizeof(struct device)); + kfree_s(dev_ibmtr[i], sizeof(struct net_device)); dev_ibmtr[i] = NULL; } } diff --git a/drivers/net/ipddp.c b/drivers/net/ipddp.c index ac0d6b27e..5e739b298 100644 --- a/drivers/net/ipddp.c +++ b/drivers/net/ipddp.c @@ -75,15 +75,15 @@ static int ipddp_mode = IPDDP_DECAP; static unsigned int ipddp_debug = IPDDP_DEBUG; /* Index to functions, as function prototypes. */ -static int ipddp_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *ipddp_get_stats(struct device *dev); +static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *ipddp_get_stats(struct net_device *dev); static int ipddp_create(struct ipddp_route *new_rt); static int ipddp_delete(struct ipddp_route *rt); static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt); -static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd); +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -static int ipddp_open(struct device *dev) +static int ipddp_open(struct net_device *dev) { #ifdef MODULE MOD_INC_USE_COUNT; @@ -92,7 +92,7 @@ static int ipddp_open(struct device *dev) return 0; } -static int ipddp_close(struct device *dev) +static int ipddp_close(struct net_device *dev) { #ifdef MODULE MOD_DEC_USE_COUNT; @@ -101,7 +101,7 @@ static int ipddp_close(struct device *dev) return 0; } -int ipddp_init(struct device *dev) +int ipddp_init(struct net_device *dev) { static unsigned version_printed = 0; @@ -149,7 +149,7 @@ int ipddp_init(struct device *dev) /* * Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *ipddp_get_stats(struct device *dev) +static struct net_device_stats *ipddp_get_stats(struct net_device *dev) { return (struct net_device_stats *)dev->priv; } @@ -157,7 +157,7 @@ static struct net_device_stats *ipddp_get_stats(struct device *dev) /* * Transmit LLAP/ELAP frame using aarp_send_ddp. */ -static int ipddp_xmit(struct sk_buff *skb, struct device *dev) +static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) { u32 paddr = ((struct rtable*)skb->dst)->rt_gateway; struct ddpehdr *ddp; @@ -297,7 +297,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt) return (NULL); } -static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data; @@ -324,7 +324,7 @@ static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd) #ifdef MODULE /* Module specific functions for ipddp.c */ -static struct device dev_ipddp= +static struct net_device dev_ipddp= { "ipddp0\0 ", 0, 0, 0, 0, diff --git a/drivers/net/ipddp.h b/drivers/net/ipddp.h index 076373b81..0729a4d68 100644 --- a/drivers/net/ipddp.h +++ b/drivers/net/ipddp.h @@ -13,7 +13,7 @@ struct ipddp_route { - struct device *dev; /* Carrier device */ + struct net_device *dev; /* Carrier device */ __u32 ip; /* IP address */ struct at_addr at; /* Gateway appletalk address */ int flags; diff --git a/drivers/net/irda/Config.in b/drivers/net/irda/Config.in index df988de48..5be68c382 100644 --- a/drivers/net/irda/Config.in +++ b/drivers/net/irda/Config.in @@ -15,11 +15,12 @@ dep_tristate 'SMC IrCC' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA comment 'Dongle support' bool 'Serial dongle support' CONFIG_DONGLE if [ "$CONFIG_DONGLE" != "n" ]; then - dep_tristate ' ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA - dep_tristate ' ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA - dep_tristate ' Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA - dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA - dep_tristate ' Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA + dep_tristate ' ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA + dep_tristate ' ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA + dep_tristate ' Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA + dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA + dep_tristate ' Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA + dep_tristate ' Adaptec Airport 1000/2000 dongle' CONFIG_AIRPORT_DONGLE $CONFIG_IRDA fi endmenu diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index b92dde935..3c471f233 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile @@ -156,6 +156,14 @@ else endif endif +ifeq ($(CONFIG_AIRPORT_DONGLE),y) +L_OBJS += airport.o +else + ifeq ($(CONFIG_AIRPORT_DONGLE),m) + M_OBJS += airport.o + endif +endif + include $(TOPDIR)/Rules.make clean: diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c index 46634c42e..f83fce38c 100644 --- a/drivers/net/irda/actisys.c +++ b/drivers/net/irda/actisys.c @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Sun May 16 14:35:11 1999 + * Modified at: Sat Jun 26 16:57:57 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -37,11 +37,11 @@ static void actisys_reset(struct irda_device *dev); static void actisys_open(struct irda_device *idev, int type); static void actisys_close(struct irda_device *dev); -static void actisys_change_speed( struct irda_device *dev, int baudrate); +static void actisys_change_speed( struct irda_device *dev, __u32 speed); static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos); /* These are the baudrates supported */ -static int baud_rates[] = { 9600, 19200, 57600, 115200, 38400}; +static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400}; static struct dongle dongle = { ACTISYS_DONGLE, @@ -107,9 +107,9 @@ static void actisys_close(struct irda_device *idev) * To cycle through the available baud rates, pulse RTS low for a few * ms. */ -static void actisys_change_speed(struct irda_device *idev, int baudrate) +static void actisys_change_speed(struct irda_device *idev, __u32 speed) { - int current_baudrate; + __u32 current_baudrate; int index = 0; DEBUG(4, __FUNCTION__ "()\n"); @@ -126,7 +126,7 @@ static void actisys_change_speed(struct irda_device *idev, int baudrate) DEBUG( 4, __FUNCTION__ "(), index=%d\n", index); /* Cycle through avaiable baudrates until we reach the correct one */ - while (current_baudrate != baudrate) { + while (current_baudrate != speed) { DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); @@ -135,14 +135,14 @@ static void actisys_change_speed(struct irda_device *idev, int baudrate) /* Wait at a few ms */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2); + schedule_timeout(MSECS_TO_JIFFIES(20)); /* Set DTR, Set RTS */ irda_device_set_dtr_rts(idev, TRUE, TRUE); /* Wait at a few ms again */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2); + schedule_timeout(MSECS_TO_JIFFIES(20)); /* Go to next baudrate */ if (idev->io.dongle_id == ACTISYS_DONGLE) @@ -152,7 +152,7 @@ static void actisys_change_speed(struct irda_device *idev, int baudrate) current_baudrate = baud_rates[index]; } - DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",baud_rates[index]); + DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); } /* @@ -174,7 +174,7 @@ static void actisys_reset(struct irda_device *idev) /* Sleep 10-20 ms*/ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2); + schedule_timeout(MSECS_TO_JIFFIES(20)); /* Go back to normal mode */ irda_device_set_dtr_rts(idev, TRUE, TRUE); diff --git a/drivers/net/irda/airport.c b/drivers/net/irda/airport.c new file mode 100644 index 000000000..edfc2e6e6 --- /dev/null +++ b/drivers/net/irda/airport.c @@ -0,0 +1,374 @@ +/********************************************************************* + * + * Filename: airport.c + * Version: 0.2 + * Description: Implementation for the Adaptec Airport 1000 and 2000 + * dongles + * Status: Experimental. + * Author: Fons Botman <budely@tref.nl> + * Created at: Wed May 19 23:14:34 CEST 1999 + * Based on: actisys.c + * By: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1998-1999 Fons Botman, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * Neither Fons Botman nor anyone else admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/tty.h> +#include <linux/sched.h> +#include <linux/init.h> + +#include <net/irda/irda.h> +#include <net/irda/irmod.h> +#include <net/irda/irda_device.h> +#include <net/irda/dongle.h> + + +static void airport_reset(struct irda_device *dev); +static void airport_open(struct irda_device *idev, int type); +static void airport_close(struct irda_device *dev); +static void airport_change_speed( struct irda_device *dev, __u32 speed); +static void airport_init_qos(struct irda_device *idev, struct qos_info *qos); + + +static struct dongle dongle = { + AIRPORT_DONGLE, + airport_open, + airport_close, + airport_reset, + airport_change_speed, + airport_init_qos, +}; + + +int __init airport_init(void) +{ + int ret; + + DEBUG(2, __FUNCTION__ "()\n"); + ret = irda_device_register_dongle(&dongle); + if (ret < 0) + return ret; + return 0; +} + +void airport_cleanup(void) +{ + DEBUG(2, __FUNCTION__ "()\n"); + irda_device_unregister_dongle(&dongle); +} + +static void airport_open(struct irda_device *idev, int type) +{ + DEBUG(2, __FUNCTION__ "(,%d)\n", type); + if (strlen(idev->description) < sizeof(idev->description) - 13) + strcat(idev->description, " <-> airport"); + else + DEBUG(0, __FUNCTION__ " description too long: %s\n", + idev->description); + + idev->io.dongle_id = type; + idev->flags |= IFF_DONGLE; + + MOD_INC_USE_COUNT; +} + +static void airport_close(struct irda_device *idev) +{ + DEBUG(2, __FUNCTION__ "()\n"); + /* Power off dongle */ + irda_device_set_dtr_rts(idev, FALSE, FALSE); + + MOD_DEC_USE_COUNT; +} + +static void airport_set_command_mode(struct irda_device *idev) +{ + DEBUG(2, __FUNCTION__ "()\n"); + irda_device_set_dtr_rts(idev, FALSE, TRUE); +} + +static void airport_set_normal_mode(struct irda_device *idev) +{ + DEBUG(2, __FUNCTION__ "()\n"); + irda_device_set_dtr_rts(idev, TRUE, TRUE); +} + + +void airport_write_char(struct irda_device *idev, unsigned char c) +{ + int actual; + DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff); + actual = idev->raw_write(idev, &c, 1); + ASSERT(actual == 1, return;); +} + +#define JIFFIES_TO_MSECS(j) ((j)*1000/HZ) + +static int airport_waitfor_char(struct irda_device *idev, unsigned char c) +{ + int i, found = FALSE; + int before; + DEBUG(2, __FUNCTION__ "(,0x%x)\n", c); + + /* Sleep approx. 10 ms */ + before = jiffies; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(MSECS_TO_JIFFIES(20)); + DEBUG(4, __FUNCTION__ " waited %ldms\n", + JIFFIES_TO_MSECS(jiffies - before)); + + for ( i = 0 ; !found && i < idev->rx_buff.len ; i++ ) { + /* DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */ + found = c == idev->rx_buff.data[i]; + } + idev->rx_buff.len = 0; + + DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false")); + return found; +} + +static int airport_check_command_mode(struct irda_device *idev) +{ + int i; + int found = FALSE; + + DEBUG(2, __FUNCTION__ "()\n"); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(MSECS_TO_JIFFIES(20)); + airport_set_command_mode(idev); + + /* Loop until the time expires (200ms) or we get the magic char. */ + + for ( i = 0 ; i < 25 ; i++ ) { + airport_write_char(idev, 0xff); + if (airport_waitfor_char(idev, 0xc3)) { + found = TRUE; + break; + } + } + + if (found) { + DEBUG(2, __FUNCTION__ " OK. (%d)\n", i); + } else { + DEBUG(0, __FUNCTION__ " FAILED!\n"); + } + return found; +} + + +static int airport_write_register(struct irda_device *idev, unsigned char reg) +{ + int ok = FALSE; + int i; + + DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg); + airport_check_command_mode(idev); + + for ( i = 0 ; i < 6 ; i++ ) { + airport_write_char(idev, reg); + if (!airport_waitfor_char(idev, reg)) + continue; + + /* Now read it back */ + airport_write_char(idev, (reg << 4) | 0x0f); + if (airport_waitfor_char(idev, reg)) { + ok = TRUE; + break; + } + } + + airport_set_normal_mode(idev); + if (ok) { + DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg); + } else { + DEBUG(0, __FUNCTION__ "(,0x%x) returns False!\n", reg); + } + return ok; +} + + +/* + * Function airport_change_speed (tty, baud) + * + * Change speed of the Airport type IrDA dongles. + */ +static void airport_change_speed(struct irda_device *idev, __u32 speed) +{ + __u32 current_baudrate; + int baudcode; + + DEBUG(4, __FUNCTION__ "(,%d)\n", speed); + + ASSERT(idev != NULL, return;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + + /* Find the correct baudrate code for the required baudrate */ + switch (speed) { + case 2400: baudcode = 0x10; break; + case 4800: baudcode = 0x20; break; + case 9600: baudcode = 0x30; break; + case 19200: baudcode = 0x40; break; + case 38400: baudcode = 0x50; break; + case 57600: baudcode = 0x60; break; + case 115200: baudcode = 0x70; break; + default: + DEBUG(0, __FUNCTION__ " bad baud rate: %d\n", speed); + return; + } + + current_baudrate = idev->qos.baud_rate.value; + DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate); + + /* The dongle falls back to 9600 baud */ + if (current_baudrate != 9600) { + DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n"); + ASSERT(idev->change_speed , return;); + idev->change_speed(idev, 9600); + idev->qos.baud_rate.value = 9600; + } + + if (idev->set_raw_mode) + idev->set_raw_mode(idev, TRUE); + + /* Set the new speed in both registers */ + if (airport_write_register(idev, baudcode)) { + if (airport_write_register(idev, baudcode|0x01)) { + /* ok */ + } else { + DEBUG(0, __FUNCTION__ + " Cannot set new speed in second register\n"); + } + } else { + DEBUG(0, __FUNCTION__ + " Cannot set new speed in first register\n"); + } + + if (idev->set_raw_mode) + idev->set_raw_mode(idev, FALSE); + + /* How do I signal an error in these functions? */ + + DEBUG(4, __FUNCTION__ " returning\n"); +} + + +/* + * Function airport_reset (idev) + * + * Reset the Airport type dongle. Warning, this function must only be + * called with a process context! + * + */ +static void airport_reset(struct irda_device *idev) +{ + int ok; + + DEBUG(2, __FUNCTION__ "()\n"); + ASSERT(idev != NULL, return;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(idev->set_raw_mode /* The airport needs this */, return;); + + if (idev->set_raw_mode) + idev->set_raw_mode(idev, TRUE); + + airport_set_normal_mode(idev); + + /* Sleep 2000 ms */ + DEBUG(2, __FUNCTION__ " waiting for powerup\n"); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(MSECS_TO_JIFFIES(2000)); + DEBUG(2, __FUNCTION__ " finished waiting for powerup\n"); + + /* set dongle speed to 9600 */ + ok = TRUE; + + if (ok) + ok = airport_write_register(idev, 0x30); + if (!ok) + MESSAGE(__FUNCTION__ "() dongle not connected?\n"); + if (ok) + ok = airport_write_register(idev, 0x31); + + if (ok) + ok = airport_write_register(idev, 0x02); + if (ok) + ok = airport_write_register(idev, 0x03); + + if (ok) { + ok = airport_check_command_mode(idev); + + if (ok) { + airport_write_char(idev, 0x04); + ok = airport_waitfor_char(idev, 0x04); + } + airport_set_normal_mode(idev); + } + + if (idev->set_raw_mode) + idev->set_raw_mode(idev, FALSE); + + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(MSECS_TO_JIFFIES(20)); + DEBUG(4, __FUNCTION__ " waited 20ms\n"); + + idev->qos.baud_rate.value = 9600; + if (!ok) + MESSAGE(__FUNCTION__ "() failed.\n"); + DEBUG(2, __FUNCTION__ " returning.\n"); +} + +/* + * Function airport_init_qos (qos) + * + * Initialize QoS capabilities + * + */ +static void airport_init_qos(struct irda_device *idev, struct qos_info *qos) +{ + qos->baud_rate.bits &= + IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + /* May need 1ms */ + qos->min_turn_time.bits &= 0x07; +} + +#ifdef MODULE + +MODULE_AUTHOR("Fons Botman <budely@tref.nl>"); +MODULE_DESCRIPTION("Adaptec Airport 1000 and 2000 dongle driver"); + +/* + * Function init_module (void) + * + * Initialize Airport module + * + */ +int init_module(void) +{ + return airport_init(); +} + +/* + * Function cleanup_module (void) + * + * Cleanup Airport module + * + */ +void cleanup_module(void) +{ + airport_cleanup(); +} + +#endif diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c index 930abe63e..f531c1af4 100644 --- a/drivers/net/irda/esi.c +++ b/drivers/net/irda/esi.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Thomas Davis, <ratbert@radiks.net> * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Sun May 16 14:35:21 1999 + * Modified at: Sat Jun 26 16:50:17 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: esi.c * @@ -39,7 +39,7 @@ static void esi_open(struct irda_device *idev, int type); static void esi_close(struct irda_device *driver); -static void esi_change_speed(struct irda_device *idev, int baud); +static void esi_change_speed(struct irda_device *idev, __u32 speed); static void esi_reset(struct irda_device *idev); static void esi_qos_init(struct irda_device *idev, struct qos_info *qos); @@ -81,19 +81,19 @@ static void esi_close(struct irda_device *idev) } /* - * Function esi_change_speed (tty, baud) + * Function esi_change_speed (idev, speed) * * Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle * */ -static void esi_change_speed(struct irda_device *idev, int baud) +static void esi_change_speed(struct irda_device *idev, __u32 speed) { int dtr, rts; ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - switch (baud) { + switch (speed) { case 19200: dtr = TRUE; rts = FALSE; diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c index a3d28dedb..2d1d1f269 100644 --- a/drivers/net/irda/girbil.c +++ b/drivers/net/irda/girbil.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Feb 6 21:02:33 1999 - * Modified at: Tue Jun 1 08:47:41 1999 + * Modified at: Sun Jul 18 12:09:26 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -37,7 +37,7 @@ static void girbil_reset(struct irda_device *dev); static void girbil_open(struct irda_device *dev, int type); static void girbil_close(struct irda_device *dev); -static void girbil_change_speed(struct irda_device *dev, int baud); +static void girbil_change_speed(struct irda_device *dev, __u32 speed); static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); /* Control register 1 */ @@ -111,7 +111,7 @@ static void girbil_close(struct irda_device *idev) * function must be called with a process context! * */ -static void girbil_change_speed(struct irda_device *idev, int speed) +static void girbil_change_speed(struct irda_device *idev, __u32 speed) { __u8 control[2]; @@ -138,6 +138,9 @@ static void girbil_change_speed(struct irda_device *idev, int speed) } control[1] = GIRBIL_LOAD; + /* Need to reset the dongle and go to 9600 bps before programming */ + girbil_reset(idev); + /* Set DTR and Clear RTS to enter command mode */ irda_device_set_dtr_rts(idev, FALSE, TRUE); @@ -145,7 +148,7 @@ static void girbil_change_speed(struct irda_device *idev, int speed) irda_device_raw_write(idev, control, 2); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2); + schedule_timeout(MSECS_TO_JIFFIES(100)); /* Go back to normal mode */ irda_device_set_dtr_rts(idev, TRUE, TRUE); @@ -168,18 +171,22 @@ void girbil_reset(struct irda_device *idev) ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + /* Make sure the IrDA chip also goes to defalt speed */ + if (idev->change_speed) + idev->change_speed(idev, 9600); + /* Reset dongle */ irda_device_set_dtr_rts(idev, TRUE, FALSE); /* Sleep at least 5 ms */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + schedule_timeout(MSECS_TO_JIFFIES(10)); /* Set DTR and clear RTS to enter command mode */ irda_device_set_dtr_rts(idev, FALSE, TRUE); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + schedule_timeout(MSECS_TO_JIFFIES(10)); /* Write control byte */ irda_device_raw_write(idev, &control, 1); @@ -189,10 +196,6 @@ void girbil_reset(struct irda_device *idev) /* Go back to normal mode */ irda_device_set_dtr_rts(idev, TRUE, TRUE); - - /* Make sure the IrDA chip also goes to defalt speed */ - if (idev->change_speed) - idev->change_speed(idev, 9600); } /* diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 096027b8f..b60241a40 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Tue Jun 1 10:02:42 1999 + * Modified at: Tue Aug 31 13:54:27 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: serial.c by Linus Torvalds * @@ -47,11 +47,11 @@ #include <linux/serial_reg.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/spinlock.h> #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> -#include <asm/spinlock.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> @@ -79,9 +79,9 @@ static void irport_write_wakeup(struct irda_device *idev); static int irport_write(int iobase, int fifo_size, __u8 *buf, int len); static void irport_receive(struct irda_device *idev); -static int irport_net_init(struct device *dev); -static int irport_net_open(struct device *dev); -static int irport_net_close(struct device *dev); +static int irport_net_init(struct net_device *dev); +static int irport_net_open(struct net_device *dev); +static int irport_net_close(struct net_device *dev); static int irport_is_receiving(struct irda_device *idev); static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts); static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len); @@ -272,7 +272,7 @@ int irport_probe(int iobase) * Set speed of IrDA port to specified baudrate * */ -void irport_change_speed(struct irda_device *idev, int speed) +void irport_change_speed(struct irda_device *idev, __u32 speed) { unsigned long flags; int iobase; @@ -280,7 +280,7 @@ void irport_change_speed(struct irda_device *idev, int speed) int lcr; /* Line control reg */ int divisor; - DEBUG(0, __FUNCTION__ "(), Setting speed to: %d\n", speed); + DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -319,7 +319,7 @@ void irport_change_speed(struct irda_device *idev, int speed) outb(fcr, iobase+UART_FCR); /* Enable FIFO's */ /* Turn on interrups */ - outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, iobase+UART_IER); + outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER); spin_unlock_irqrestore(&idev->lock, flags); } @@ -375,7 +375,7 @@ static void irport_write_wakeup(struct irda_device *idev) outb(fcr, iobase+UART_FCR); /* Turn on receive interrupts */ - outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER); + outb(/* UART_IER_RLSI| */UART_IER_RDI, iobase+UART_IER); } } @@ -413,7 +413,7 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len) * waits until the next transmitt interrupt, and continues until the * frame is transmited. */ -int irport_hard_xmit(struct sk_buff *skb, struct device *dev) +int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; unsigned long flags; @@ -432,7 +432,7 @@ int irport_hard_xmit(struct sk_buff *skb, struct device *dev) /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) { int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 5) + if ((tickssofar < 5) || !dev->start) return -EBUSY; WARNING("%s: transmit timed out\n", dev->name); @@ -443,7 +443,7 @@ int irport_hard_xmit(struct sk_buff *skb, struct device *dev) } spin_lock_irqsave(&idev->lock, flags); - + /* Init tx buffer */ idev->tx_buff.data = idev->tx_buff.head; @@ -465,15 +465,15 @@ int irport_hard_xmit(struct sk_buff *skb, struct device *dev) } /* - * Function irport_receive (void) + * Function irport_receive (idev) * * Receive one frame from the infrared port * */ static void irport_receive(struct irda_device *idev) { - int iobase; int boguscount = 0; + int iobase; ASSERT(idev != NULL, return;); @@ -488,7 +488,7 @@ static void irport_receive(struct irda_device *idev) /* Make sure we don't stay here to long */ if (boguscount++ > 32) { - DEBUG(0,__FUNCTION__ "(), breaking!\n"); + DEBUG(2,__FUNCTION__ "(), breaking!\n"); break; } } while (inb(iobase+UART_LSR) & UART_LSR_DR); @@ -527,12 +527,11 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) switch (iir) { case UART_IIR_RLSI: - DEBUG(0, __FUNCTION__ "(), RLSI\n"); + DEBUG(2, __FUNCTION__ "(), RLSI\n"); break; case UART_IIR_RDI: - if (lsr & UART_LSR_DR) - /* Receive interrupt */ - irport_receive(idev); + /* Receive interrupt */ + irport_receive(idev); break; case UART_IIR_THRI: if (lsr & UART_LSR_THRE) @@ -545,7 +544,7 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) } /* Make sure we don't stay here to long */ - if (boguscount++ > 32) + if (boguscount++ > 100) break; iir = inb(iobase + UART_IIR) & UART_IIR_ID; @@ -555,7 +554,7 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) spin_unlock(&idev->lock); } -static int irport_net_init(struct device *dev) +static int irport_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -571,7 +570,7 @@ static int irport_net_init(struct device *dev) * * */ -static int irport_net_open(struct device *dev) +static int irport_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -586,18 +585,14 @@ static int irport_net_open(struct device *dev) return -EAGAIN; irport_start(idev, iobase); - - MOD_INC_USE_COUNT; - - /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + irda_device_net_open(dev); /* Change speed to make sure dongles follow us again */ if (idev->change_speed) idev->change_speed(idev, 9600); + MOD_INC_USE_COUNT; + return 0; } @@ -607,22 +602,22 @@ static int irport_net_open(struct device *dev) * * */ -static int irport_net_close(struct device *dev) +static int irport_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; + DEBUG(4, __FUNCTION__ "()\n"); + ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; - DEBUG(4, __FUNCTION__ "()\n"); + ASSERT(idev != NULL, return -1;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;) iobase = idev->io.iobase2; - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; - + irda_device_net_close(dev); irport_stop(idev, iobase); free_irq(idev->io.irq2, idev); @@ -664,7 +659,7 @@ static int irport_is_receiving(struct irda_device *idev) } /* - * Function irtty_set_dtr_rts (tty, dtr, rts) + * Function irport_set_dtr_rts (tty, dtr, rts) * * This function can be used by dongles etc. to set or reset the status * of the dtr and rts lines diff --git a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c index e9e0bb6d5..6a439a1a8 100644 --- a/drivers/net/irda/irtty.c +++ b/drivers/net/irda/irtty.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Dec 9 21:18:38 1997 - * Modified at: Mon May 10 15:45:50 1999 + * Modified at: Tue Sep 28 08:39:29 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: slip.c by Laurence Culhane, <loz@holmes.demon.co.uk> * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> @@ -25,11 +25,13 @@ ********************************************************************/ #include <linux/module.h> -#include <asm/uaccess.h> #include <linux/kernel.h> #include <linux/tty.h> -#include <asm/segment.h> #include <linux/init.h> +#include <linux/skbuff.h> + +#include <asm/segment.h> +#include <asm/uaccess.h> #include <net/irda/irda.h> #include <net/irda/irtty.h> @@ -44,20 +46,23 @@ static struct tty_ldisc irda_ldisc; static int qos_mtt_bits = 0x03; /* 5 ms or more */ -static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev); +static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev); static void irtty_wait_until_sent(struct irda_device *driver); static int irtty_is_receiving(struct irda_device *idev); static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts); static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len); -static int irtty_net_init(struct device *dev); -static int irtty_net_open(struct device *dev); -static int irtty_net_close(struct device *dev); +static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, + int timeout); +static void irtty_set_raw_mode(struct irda_device *dev, int mode); +static int irtty_net_init(struct net_device *dev); +static int irtty_net_open(struct net_device *dev); +static int irtty_net_close(struct net_device *dev); static int irtty_open(struct tty_struct *tty); static void irtty_close(struct tty_struct *tty); static int irtty_ioctl(struct tty_struct *, void *, int, void *); static int irtty_receive_room(struct tty_struct *tty); -static void irtty_change_speed(struct irda_device *dev, int baud); +static void irtty_change_speed(struct irda_device *dev, __u32 speed); static void irtty_write_wakeup(struct tty_struct *tty); static void irtty_receive_buf(struct tty_struct *, const unsigned char *, @@ -91,10 +96,9 @@ int __init irtty_init(void) irda_ldisc.receive_room = irtty_receive_room; irda_ldisc.write_wakeup = irtty_write_wakeup; - if (( status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) { - printk(KERN_ERR - "IrDA: can't register line discipline (err = %d)\n", - status); + if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) { + ERROR("IrDA: can't register line discipline (err = %d)\n", + status); } return status; @@ -111,9 +115,7 @@ static void irtty_cleanup(void) { int ret; - /* - * Unregister tty line-discipline - */ + /* Unregister tty line-discipline */ if ((ret = tty_register_ldisc(N_IRDA, NULL))) { ERROR(__FUNCTION__ "(), can't unregister line discipline (err = %d)\n", @@ -209,9 +211,11 @@ static int irtty_open(struct tty_struct *tty) /* Initialize callbacks */ self->idev.change_speed = irtty_change_speed; self->idev.is_receiving = irtty_is_receiving; + self->idev.wait_until_sent = irtty_wait_until_sent; self->idev.set_dtr_rts = irtty_set_dtr_rts; + self->idev.set_raw_mode = irtty_set_raw_mode; self->idev.raw_write = irtty_raw_write; - self->idev.wait_until_sent = irtty_wait_until_sent; + self->idev.raw_read = irtty_raw_read; /* Override the network functions we need to use */ self->idev.netdev.init = irtty_net_init; @@ -287,19 +291,19 @@ static void irtty_stop_receiver(struct irda_device *idev, int stop) } /* - * Function irtty_change_speed (self, baud) + * Function irtty_change_speed (self, speed) * * Change the speed of the serial port. The driver layer must check that * all transmission has finished using the irtty_wait_until_sent() * function. */ -static void irtty_change_speed(struct irda_device *idev, int baud) +static void irtty_change_speed(struct irda_device *idev, __u32 speed) { struct termios old_termios; struct irtty_cb *self; int cflag; - DEBUG(4,__FUNCTION__ "(), <%ld>\n", jiffies); + DEBUG(4, __FUNCTION__ "(), <%ld>\n", jiffies); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -314,9 +318,9 @@ static void irtty_change_speed(struct irda_device *idev, int baud) cflag &= ~CBAUD; - DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", baud); + DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", speed); - switch (baud) { + switch (speed) { case 1200: cflag |= B1200; break; @@ -401,9 +405,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRTTY_MAGIC, return;); - + DEBUG(5, __FUNCTION__ "(,,,count=%d)\n", count); /* Read the characters out of the buffer */ while (count--) { /* @@ -411,13 +413,25 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, */ if (fp && *fp++) { DEBUG( 0, "Framing or parity error!\n"); - irda_device_set_media_busy( &self->idev, TRUE); + irda_device_set_media_busy(&self->idev.netdev, TRUE); cp++; continue; } - /* Unwrap and destuff one byte */ - async_unwrap_char(&self->idev, *cp++); + + DEBUG(6, __FUNCTION__ " char=0x%02x\n", *cp); + if (self->idev.raw_mode) { + struct irda_device *idev = &self->idev; + + /* What should we do when the buffer is full? */ + if (idev->rx_buff.len == idev->rx_buff.truesize) + idev->rx_buff.len = 0; + + idev->rx_buff.data[idev->rx_buff.len++] = *cp++; + } else { + /* Unwrap and destuff one byte */ + async_unwrap_char(&self->idev, *cp++); + } } } @@ -427,7 +441,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, * Transmit frame * */ -static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev) +static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irtty_cb *self; struct irda_device *idev; @@ -615,6 +629,72 @@ static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts) set_fs(fs); } +/* + * Function irtty_set_raw_mode (idev, status) + * + * For the airport dongle, we need support for reading raw characters + * from the IrDA device. This function switches between those modes. + * FALSE is the default mode, and will then treat incoming data as IrDA + * packets. + */ +void irtty_set_raw_mode(struct irda_device *idev, int status) +{ + struct irtty_cb *self; + + DEBUG(2, __FUNCTION__ "(), status=%s\n", status ? "TRUE" : "FALSE"); + + ASSERT(idev != NULL, return;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + + self = (struct irtty_cb *) idev->priv; + + /* save status for driver */ + self->idev.raw_mode = status; + + /* reset the buffer state */ + idev->rx_buff.data = idev->rx_buff.head; + idev->rx_buff.len = 0; + idev->rx_buff.state = OUTSIDE_FRAME; +} + +/* + * Function irtty_raw_read (idev, buf, len) + * + * Receive incomming data. This function sleeps, so it must only be + * called with a process context. Timeout is currently defined to be + * a multiple of 10 ms. + */ +static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, + int timeout) +{ + int count; + + buf = idev->rx_buff.data; + + /* Wait for the requested amount of data to arrive */ + while (len < idev->rx_buff.len) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(MSECS_TO_JIFFIES(10)); + + if (!timeout--) + break; + } + + count = idev->rx_buff.len < len ? idev->rx_buff.len : len; + + /* + * Reset the state, this mean that a raw read is sort of a + * datagram read, and _not_ a stream style read. Be aware of the + * difference. Implementing it the other way will just be painful ;-) + */ + idev->rx_buff.data = idev->rx_buff.head; + idev->rx_buff.len = 0; + idev->rx_buff.state = OUTSIDE_FRAME; + + /* Return the amount we were able to get */ + return count; +} + static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) { struct irtty_cb *self; @@ -634,7 +714,9 @@ static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) return actual; } -static int irtty_net_init(struct device *dev) + + +static int irtty_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -644,27 +726,28 @@ static int irtty_net_init(struct device *dev) return 0; } -static int irtty_net_open(struct device *dev) +static int irtty_net_open(struct net_device *dev) { - ASSERT(dev != NULL, return -1;); + struct irda_device *idev = dev->priv; + + irda_device_net_open(dev); - /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + /* Make sure we can receive more data */ + irtty_stop_receiver(idev, FALSE); MOD_INC_USE_COUNT; return 0; } -static int irtty_net_close(struct device *dev) +static int irtty_net_close(struct net_device *dev) { - ASSERT(dev != NULL, return -1;); - - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; + struct irda_device *idev = dev->priv; + + /* Make sure we don't receive more data */ + irtty_stop_receiver(idev, TRUE); + + irda_device_net_close(dev); MOD_DEC_USE_COUNT; @@ -701,10 +784,3 @@ void cleanup_module(void) } #endif /* MODULE */ - - - - - - - diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c index 4758914dd..203838cea 100644 --- a/drivers/net/irda/litelink.c +++ b/drivers/net/irda/litelink.c @@ -6,7 +6,7 @@ * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri May 7 12:50:33 1999 - * Modified at: Wed May 19 07:25:15 1999 + * Modified at: Sat Jun 26 17:01:05 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -44,12 +44,12 @@ static void litelink_open(struct irda_device *idev, int type); static void litelink_close(struct irda_device *dev); -static void litelink_change_speed(struct irda_device *dev, int baudrate); +static void litelink_change_speed(struct irda_device *dev, __u32); static void litelink_reset(struct irda_device *dev); static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos); /* These are the baudrates supported */ -static int baud_rates[] = { 115200, 57600, 38400, 19200, 9600 }; +static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 }; static struct dongle dongle = { LITELINK_DONGLE, @@ -89,12 +89,12 @@ static void litelink_close(struct irda_device *idev) } /* - * Function litelink_change_speed (tty, baud) + * Function litelink_change_speed (idev, speed) * * Change speed of the Litelink dongle. To cycle through the available * baud rates, pulse RTS low for a few ms. */ -static void litelink_change_speed(struct irda_device *idev, int baudrate) +static void litelink_change_speed(struct irda_device *idev, __u32 speed) { int i; @@ -114,7 +114,7 @@ static void litelink_change_speed(struct irda_device *idev, int baudrate) udelay(MIN_DELAY); /* Cycle through avaiable baudrates until we reach the correct one */ - for (i=0; i<5 && baud_rates[i] != baudrate; i++) { + for (i=0; i<5 && baud_rates[i] != speed; i++) { /* Set DTR, clear RTS */ irda_device_set_dtr_rts(idev, FALSE, TRUE); diff --git a/drivers/net/irda/pc87108.c b/drivers/net/irda/pc87108.c index 32220bf43..3b575d01e 100644 --- a/drivers/net/irda/pc87108.c +++ b/drivers/net/irda/pc87108.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Mon May 24 15:19:21 1999 + * Modified at: Wed Aug 11 09:26:26 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -107,19 +107,19 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma); static void pc87108_pio_receive(struct irda_device *idev); static int pc87108_dma_receive(struct irda_device *idev); static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase); -static int pc87108_hard_xmit(struct sk_buff *skb, struct device *dev); +static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size); static void pc87108_dma_write(struct irda_device *idev, int iobase); -static void pc87108_change_speed(struct irda_device *idev, int baud); +static void pc87108_change_speed(struct irda_device *idev, __u32 baud); static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void pc87108_wait_until_sent(struct irda_device *idev); static int pc87108_is_receiving(struct irda_device *idev); static int pc87108_read_dongle_id (int iobase); static void pc87108_init_dongle_interface (int iobase, int dongle_id); -static int pc87108_net_init(struct device *dev); -static int pc87108_net_open(struct device *dev); -static int pc87108_net_close(struct device *dev); +static int pc87108_net_init(struct net_device *dev); +static int pc87108_net_open(struct net_device *dev); +static int pc87108_net_close(struct net_device *dev); /* * Function pc87108_init () @@ -615,7 +615,7 @@ static void pc87108_change_dongle_speed( int iobase, int speed, int dongle_id) * Change the speed of the device * */ -static void pc87108_change_speed( struct irda_device *idev, int speed) +static void pc87108_change_speed(struct irda_device *idev, __u32 speed) { __u8 mcr = MCR_SIR; __u8 bank; @@ -712,7 +712,7 @@ static void pc87108_change_speed( struct irda_device *idev, int speed) * Transmit the frame! * */ -static int pc87108_hard_xmit( struct sk_buff *skb, struct device *dev) +static int pc87108_hard_xmit( struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1303,7 +1303,7 @@ static void pc87108_wait_until_sent( struct irda_device *idev) { /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(6); + schedule_timeout(MSECS_TO_JIFFIES(60)); } /* @@ -1344,7 +1344,7 @@ static int pc87108_is_receiving( struct irda_device *idev) * Initialize network device * */ -static int pc87108_net_init( struct device *dev) +static int pc87108_net_init( struct net_device *dev) { DEBUG( 4, __FUNCTION__ "()\n"); @@ -1363,7 +1363,7 @@ static int pc87108_net_init( struct device *dev) * Start the device * */ -static int pc87108_net_open( struct device *dev) +static int pc87108_net_open( struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1391,12 +1391,7 @@ static int pc87108_net_open( struct device *dev) free_irq( idev->io.irq, idev); return -EAGAIN; } - - /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - + /* Save current bank */ bank = inb( iobase+BSR); @@ -1407,6 +1402,8 @@ static int pc87108_net_open( struct device *dev) /* Restore bank register */ outb( bank, iobase+BSR); + irda_device_net_open(dev); + MOD_INC_USE_COUNT; return 0; @@ -1418,40 +1415,38 @@ static int pc87108_net_open( struct device *dev) * Stop the device * */ -static int pc87108_net_close(struct device *dev) +static int pc87108_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + DEBUG(4, __FUNCTION__ "()\n"); - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; + irda_device_net_close(dev); - ASSERT( dev != NULL, return -1;); + ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(idev != NULL, return 0;); + ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); iobase = idev->io.iobase; - disable_dma( idev->io.dma); + disable_dma(idev->io.dma); /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Disable interrupts */ - switch_bank( iobase, BANK0); - outb( 0, iobase+IER); + switch_bank(iobase, BANK0); + outb(0, iobase+IER); - free_irq( idev->io.irq, idev); - free_dma( idev->io.dma); + free_irq(idev->io.irq, idev); + free_dma(idev->io.dma); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); MOD_DEC_USE_COUNT; diff --git a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c index d1e7de8d5..00ab408d6 100644 --- a/drivers/net/irda/smc-ircc.c +++ b/drivers/net/irda/smc-ircc.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Thomas Davis (tadavis@jps.net) * Created at: - * Modified at: Wed May 19 15:30:08 1999 + * Modified at: Wed Sep 22 07:47:19 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Thomas Davis, All Rights Reserved. @@ -52,27 +52,29 @@ static char *driver_name = "smc-ircc"; #define CHIP_IO_EXTENT 8 -static unsigned int io[] = { 0x2e8, 0x140, ~0, ~0 }; -static unsigned int io2[] = { 0x2f8, 0x3e8, 0, 0}; +static unsigned int io[] = { 0x2e8, 0x140, 0x118, ~0 }; +static unsigned int io2[] = { 0x2f8, 0x3e8, 0x2e8, 0}; static struct ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL}; /* Some prototypes */ static int ircc_open( int i, unsigned int iobase, unsigned int board_addr); +#ifdef MODULE static int ircc_close( struct irda_device *idev); +#endif /* MODULE */ static int ircc_probe( int iobase, int board_addr); static int ircc_dma_receive( struct irda_device *idev); static int ircc_dma_receive_complete(struct irda_device *idev, int iobase); -static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev); +static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev); static void ircc_dma_write( struct irda_device *idev, int iobase); -static void ircc_change_speed( struct irda_device *idev, int baud); +static void ircc_change_speed( struct irda_device *idev, __u32 speed); static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void ircc_wait_until_sent( struct irda_device *idev); static int ircc_is_receiving( struct irda_device *idev); -static int ircc_net_init( struct device *dev); -static int ircc_net_open( struct device *dev); -static int ircc_net_close( struct device *dev); +static int ircc_net_init( struct net_device *dev); +static int ircc_net_open( struct net_device *dev); +static int ircc_net_close( struct net_device *dev); static int ircc_debug=3; static int ircc_irq=255; @@ -264,6 +266,7 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) * Close driver instance * */ +#ifdef MODULE static int ircc_close( struct irda_device *idev) { int iobase; @@ -304,6 +307,7 @@ static int ircc_close( struct irda_device *idev) DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } +#endif /* MODULE */ /* * Function ircc_probe (iobase, board_addr, irq, dma) @@ -311,7 +315,7 @@ static int ircc_close( struct irda_device *idev) * Returns non-negative on success. * */ -static int ircc_probe( int iobase, int iobase2) +static int ircc_probe(int iobase, int iobase2) { int version = 1; int low, high, chip, config, dma, irq; @@ -327,17 +331,17 @@ static int ircc_probe( int iobase, int iobase2) irq = config >> 4 & 0x0f; dma = config & 0x0f; - if (high == 0x10 && low == 0xb8 && chip == 0xf1) { - DEBUG(0, "SMC IrDA Controller found; version = %d, " + if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) { + DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, " "port 0x%04x, dma %d, interrupt %d\n", - version, iobase, dma, irq); + chip & 0x0f, version, iobase, dma, irq); } else { return -1; } serial_out(iobase, UART_MASTER, 0); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + DEBUG(ircc_debug, "--> " __FUNCTION__ "\n"); return config; } @@ -348,7 +352,7 @@ static int ircc_probe( int iobase, int iobase2) * Change the speed of the device * */ -static void ircc_change_speed( struct irda_device *idev, int speed) +static void ircc_change_speed( struct irda_device *idev, __u32 speed) { struct ircc_cb *self; int iobase, ir_mode, select, fast; @@ -448,7 +452,7 @@ static void ircc_change_speed( struct irda_device *idev, int speed) * Transmit the frame! * */ -static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev) +static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -798,7 +802,7 @@ static void ircc_wait_until_sent( struct irda_device *idev) /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(6); + schedule_timeout(MSECS_TO_JIFFIES(60)); DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } @@ -835,7 +839,7 @@ static int ircc_is_receiving( struct irda_device *idev) * Initialize network device * */ -static int ircc_net_init( struct device *dev) +static int ircc_net_init( struct net_device *dev) { DEBUG(ircc_debug, __FUNCTION__ " -->\n"); @@ -855,7 +859,7 @@ static int ircc_net_init( struct device *dev) * Start the device * */ -static int ircc_net_open( struct device *dev) +static int ircc_net_open( struct net_device *dev) { struct irda_device *idev; int iobase; @@ -884,9 +888,7 @@ static int ircc_net_open( struct device *dev) } /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + irda_device_net_open(dev); /* turn on interrupts */ @@ -902,17 +904,13 @@ static int ircc_net_open( struct device *dev) * Stop the device * */ -static int ircc_net_close(struct device *dev) +static int ircc_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; DEBUG(ircc_debug, __FUNCTION__ " -->\n"); - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; - ASSERT( dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -921,6 +919,8 @@ static int ircc_net_close(struct device *dev) iobase = idev->io.iobase; + irda_device_net_close(dev); + disable_dma( idev->io.dma); /* Disable interrupts */ diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c index c47cf68d7..6f3c49f6f 100644 --- a/drivers/net/irda/tekram.c +++ b/drivers/net/irda/tekram.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Sun May 16 14:33:42 1999 + * Modified at: Thu Jul 15 01:17:53 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -36,7 +36,7 @@ static void tekram_reset(struct irda_device *dev); static void tekram_open(struct irda_device *dev, int type); static void tekram_close(struct irda_device *dev); -static void tekram_change_speed(struct irda_device *dev, int baud); +static void tekram_change_speed(struct irda_device *dev, __u32 speed); static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos); #define TEKRAM_115200 0x00 @@ -85,7 +85,7 @@ static void tekram_close(struct irda_device *idev) } /* - * Function tekram_change_speed (tty, baud) + * Function tekram_change_speed (tty, speed) * * Set the speed for the Tekram IRMate 210 type dongle. Warning, this * function must be called with a process context! @@ -100,7 +100,7 @@ static void tekram_close(struct irda_device *idev) * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here * after */ -static void tekram_change_speed(struct irda_device *idev, int baud) +static void tekram_change_speed(struct irda_device *idev, __u32 speed) { __u8 byte; @@ -109,7 +109,7 @@ static void tekram_change_speed(struct irda_device *idev, int baud) ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - switch (baud) { + switch (speed) { default: case 9600: byte = TEKRAM_PW|TEKRAM_9600; @@ -135,7 +135,7 @@ static void tekram_change_speed(struct irda_device *idev, int baud) irda_device_set_dtr_rts(idev, TRUE, FALSE); /* Wait at least 7us */ - udelay(7); + udelay(10); /* Write control byte */ irda_device_raw_write(idev, &byte, 1); diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c index 0986211f1..d0dbaa4f7 100644 --- a/drivers/net/irda/toshoboe.c +++ b/drivers/net/irda/toshoboe.c @@ -28,10 +28,22 @@ /* an olivetti notebook which doesn't have FIR, a toshiba libretto, and */ /* an hp printer, this works fine at 4MBPS with my HP printer */ -static char *rcsid = "$Id: toshoboe.c,v 1.5 1999/05/12 12:24:39 root Exp root $"; +static char *rcsid = "$Id: toshoboe.c,v 1.9 1999/06/29 14:21:06 root Exp $"; /* * $Log: toshoboe.c,v $ + * Revision 1.9 1999/06/29 14:21:06 root + * *** empty log message *** + * + * Revision 1.8 1999/06/29 14:15:08 root + * *** empty log message *** + * + * Revision 1.7 1999/06/29 13:46:42 root + * *** empty log message *** + * + * Revision 1.6 1999/06/29 12:31:03 root + * *** empty log message *** + * * Revision 1.5 1999/05/12 12:24:39 root * *** empty log message *** * @@ -93,6 +105,10 @@ static char *rcsid = "$Id: toshoboe.c,v 1.5 1999/05/12 12:24:39 root Exp root $" #include <net/irda/irlap_frame.h> #include <net/irda/irda_device.h> +#ifdef CONFIG_APM +#include <linux/apm_bios.h> +#endif + #include <net/irda/toshoboe.h> static char *driver_name = "toshoboe"; @@ -100,8 +116,10 @@ static char *driver_name = "toshoboe"; static struct toshoboe_cb *dev_self[NSELFS + 1] = {NULL, NULL, NULL, NULL, NULL}; +static int max_baud = 4000000; + /* Shutdown the chip and point the taskfile reg somewhere else */ -static void +static void toshoboe_stopchip (struct toshoboe_cb *self) { DEBUG (4, __FUNCTION__ "()\n"); @@ -117,16 +135,19 @@ toshoboe_stopchip (struct toshoboe_cb *self) outb_p (0x00, OBOE_ISR); /*FIXME: should i do this to disbale ints */ outb_p (0x80, OBOE_RST); outb_p (0xe, OBOE_LOCK); + } /*Set the baud rate */ -static void +static void toshoboe_setbaud (struct toshoboe_cb *self, int baud) { + unsigned long flags; DEBUG (4, __FUNCTION__ "()\n"); printk (KERN_WARNING "ToshOboe: seting baud to %d\n", baud); + save_flags (flags); cli (); switch (baud) { @@ -177,7 +198,7 @@ toshoboe_setbaud (struct toshoboe_cb *self, int baud) break; } - sti (); + restore_flags (flags); outb_p (0x00, OBOE_RST); outb_p (0x80, OBOE_RST); @@ -186,7 +207,7 @@ toshoboe_setbaud (struct toshoboe_cb *self, int baud) } /* Wake the chip up and get it looking at the taskfile */ -static void +static void toshoboe_startchip (struct toshoboe_cb *self) { __u32 physaddr; @@ -217,7 +238,7 @@ toshoboe_startchip (struct toshoboe_cb *self) } /*Let the chip look at memory */ -static void +static void toshoboe_enablebm (struct toshoboe_cb *self) { DEBUG (4, __FUNCTION__ "()\n"); @@ -225,7 +246,7 @@ toshoboe_enablebm (struct toshoboe_cb *self) } /*Don't let the chip look at memory */ -static void +static void toshoboe_disablebm (struct toshoboe_cb *self) { __u8 command; @@ -238,13 +259,15 @@ toshoboe_disablebm (struct toshoboe_cb *self) } /*setup the taskfile */ -static void +static void toshoboe_initbuffs (struct toshoboe_cb *self) { int i; + unsigned long flags; DEBUG (4, __FUNCTION__ "()\n"); + save_flags (flags); cli (); for (i = 0; i < TX_SLOTS; ++i) @@ -261,25 +284,32 @@ toshoboe_initbuffs (struct toshoboe_cb *self) self->taskfile->recv[i].buffer = virt_to_bus (self->recv_bufs[i]); } - sti (); + restore_flags (flags); } + + /*Transmit something */ -static int -toshoboe_hard_xmit (struct sk_buff *skb, struct device *dev) +static int +toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; struct toshoboe_cb *self; int mtt, len; idev = (struct irda_device *) dev->priv; - ASSERT (idev != NULL, return 0;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT (idev != NULL, return 0; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; + ); self = idev->priv; - ASSERT (self != NULL, return 0;); + ASSERT (self != NULL, return 0; + ); + if (self->stopped) + return 0; #ifdef ONETASK if (self->txpending) @@ -343,7 +373,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct device *dev) } /*interrupt handler */ -static void +static void toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct irda_device *idev = (struct irda_device *) dev_id; @@ -399,8 +429,9 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) #endif { int len = self->taskfile->recv[self->rxs].len; - - if (len>2) len-=2; + + if (len > 2) + len -= 2; skb = dev_alloc_skb (len + 1); if (skb) @@ -459,27 +490,34 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) /* Change the baud rate */ -static void -toshoboe_change_speed (struct irda_device *idev, int speed) +static void +toshoboe_change_speed (struct irda_device *idev, __u32 speed) { struct toshoboe_cb *self; DEBUG (4, __FUNCTION__ "()\n"); - ASSERT (idev != NULL, return;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT (idev != NULL, return; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return; + ); self = idev->priv; - ASSERT (self != NULL, return;); + ASSERT (self != NULL, return; + ); + idev->io.baudrate = speed; + if (self->stopped) + return; + toshoboe_setbaud (self, speed); } /* Check all xmit_tasks finished */ -static void +static void toshoboe_wait_until_sent (struct irda_device *idev) { struct toshoboe_cb *self; @@ -487,24 +525,30 @@ toshoboe_wait_until_sent (struct irda_device *idev) DEBUG (4, __FUNCTION__ "()\n"); - ASSERT (idev != NULL, return;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT (idev != NULL, return; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return; + ); self = idev->priv; - ASSERT (self != NULL, return;); + ASSERT (self != NULL, return; + ); + + if (self->stopped) + return; for (i = 0; i < TX_SLOTS; ++i) { while (self->taskfile->xmit[i].control) { current->state = TASK_INTERRUPTIBLE; - schedule_timeout (6); + schedule_timeout (MSECS_TO_JIFFIES(60)); } } } -static int +static int toshoboe_is_receiving (struct irda_device *idev) { DEBUG (4, __FUNCTION__ "()\n"); @@ -514,8 +558,8 @@ toshoboe_is_receiving (struct irda_device *idev) } -static int -toshoboe_net_init (struct device *dev) +static int +toshoboe_net_init (struct net_device *dev) { DEBUG (4, __FUNCTION__ "()\n"); @@ -527,37 +571,12 @@ toshoboe_net_init (struct device *dev) } - - -static int -toshoboe_net_open (struct device *dev) +static void +toshoboe_initptrs (struct toshoboe_cb *self) { - struct irda_device *idev; - struct toshoboe_cb *self; - - DEBUG (4, __FUNCTION__ "()\n"); - - ASSERT (dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; - - ASSERT (idev != NULL, return 0;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;); - - self = idev->priv; - ASSERT (self != NULL, return 0;); - - if (request_irq (idev->io.irq, toshoboe_interrupt, - SA_SHIRQ | SA_INTERRUPT, idev->name, (void *) idev)) - { - - return -EAGAIN; - } - - toshoboe_initbuffs (self); - toshoboe_enablebm (self); - toshoboe_startchip (self); - + unsigned long flags; + save_flags (flags); cli (); /*FIXME: need to test this carefully to check which one */ @@ -580,45 +599,91 @@ toshoboe_net_open (struct device *dev) self->txpending = 0; - sti (); + restore_flags (flags); +} - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; +static int +toshoboe_net_open (struct net_device *dev) +{ + struct irda_device *idev; + struct toshoboe_cb *self; + + DEBUG (4, __FUNCTION__ "()\n"); + + ASSERT (dev != NULL, return -1; + ); + idev = (struct irda_device *) dev->priv; + + ASSERT (idev != NULL, return 0; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; + ); + + self = idev->priv; + ASSERT (self != NULL, return 0; + ); + + if (self->stopped) + return 0; + + + if (request_irq (idev->io.irq, toshoboe_interrupt, + SA_SHIRQ | SA_INTERRUPT, idev->name, (void *) idev)) + { + + return -EAGAIN; + } + + toshoboe_initbuffs (self); + toshoboe_enablebm (self); + toshoboe_startchip (self); + toshoboe_initptrs (self); + + irda_device_net_open(dev); + + self->open = 1; + MOD_INC_USE_COUNT; return 0; } -static int -toshoboe_net_close (struct device *dev) +static int +toshoboe_net_close (struct net_device *dev) { struct irda_device *idev; struct toshoboe_cb *self; DEBUG (4, __FUNCTION__ "()\n"); - ASSERT (dev != NULL, return -1;); + ASSERT (dev != NULL, return -1; + ); idev = (struct irda_device *) dev->priv; - ASSERT (idev != NULL, return 0;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;); - - dev->tbusy = 1; - dev->start = 0; + ASSERT (idev != NULL, return 0; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; + ); + irda_device_net_close(dev); self = idev->priv; - ASSERT (self != NULL, return 0;); + ASSERT (self != NULL, return 0; + ); + + self->open = 0; free_irq (idev->io.irq, (void *) idev); - toshoboe_stopchip (self); - toshoboe_disablebm (self); + if (!self->stopped) + { + toshoboe_stopchip (self); + toshoboe_disablebm (self); + } MOD_DEC_USE_COUNT; @@ -630,7 +695,9 @@ toshoboe_net_close (struct device *dev) #ifdef MODULE -static int +MODULE_PARM (max_baud, "i"); + +static int toshoboe_close (struct irda_device *idev) { struct toshoboe_cb *self; @@ -638,14 +705,21 @@ toshoboe_close (struct irda_device *idev) DEBUG (4, __FUNCTION__ "()\n"); - ASSERT (idev != NULL, return -1;); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT (idev != NULL, return -1; + ); + ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return -1; + ); self = idev->priv; - ASSERT (self != NULL, return -1;); + ASSERT (self != NULL, return -1; + ); - toshoboe_stopchip (self); + if (!self->stopped) + { + toshoboe_stopchip (self); + toshoboe_disablebm (self); + } release_region (idev->io.iobase, idev->io.io_ext); @@ -678,13 +752,13 @@ toshoboe_close (struct irda_device *idev) -static int +static int toshoboe_open (struct pci_dev *pci_dev) { struct toshoboe_cb *self; struct irda_device *idev; int i = 0; - int ok=0; + int ok = 0; DEBUG (4, __FUNCTION__ "()\n"); @@ -709,11 +783,12 @@ toshoboe_open (struct pci_dev *pci_dev) memset (self, 0, sizeof (struct toshoboe_cb)); + dev_self[i] = self; /*This needs moving if we ever get more than one chip */ - dev_self[i] = self; - + self->open = 0; + self->stopped = 0; self->pdev = pci_dev; - self->base = pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + self->base = pci_dev->resource[0].start; idev = &self->idev; @@ -722,6 +797,7 @@ toshoboe_open (struct pci_dev *pci_dev) idev->io.iobase = self->base; idev->io.irq = pci_dev->irq; idev->io.io_ext = CHIP_IO_EXTENT; + idev->io.baudrate = 9600; /* Lock the port that we need */ i = check_region (idev->io.iobase, idev->io.io_ext); @@ -736,16 +812,29 @@ toshoboe_open (struct pci_dev *pci_dev) return -ENODEV; } - request_region (idev->io.iobase, idev->io.io_ext, driver_name); irda_init_max_qos_capabilies (&idev->qos); - - idev->qos.baud_rate.bits = IR_2400 | /*IR_4800 | */ IR_9600 | IR_19200 | - IR_115200; + idev->qos.baud_rate.bits = 0; + + if (max_baud >= 2400) + idev->qos.baud_rate.bits |= IR_2400; + /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */ + if (max_baud >= 9600) + idev->qos.baud_rate.bits |= IR_9600; + if (max_baud >= 19200) + idev->qos.baud_rate.bits |= IR_19200; + if (max_baud >= 115200) + idev->qos.baud_rate.bits |= IR_115200; #ifdef ENABLE_FAST - idev->qos.baud_rate.bits|= IR_576000 | IR_1152000 | (IR_4000000 << 8); + if (max_baud >= 576000) + idev->qos.baud_rate.bits |= IR_576000; + if (max_baud >= 1152000) + idev->qos.baud_rate.bits |= IR_1152000; + if (max_baud >= 4000000) + idev->qos.baud_rate.bits |= (IR_4000000 << 8); #endif + idev->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */ irda_qos_bits_to_value (&idev->qos); @@ -753,7 +842,8 @@ toshoboe_open (struct pci_dev *pci_dev) idev->flags = IFF_SIR | IFF_DMA | IFF_PIO; #ifdef ENABLE_FAST - idev->flags |= IFF_FIR; + if (max_baud >= 576000) + idev->flags |= IFF_FIR; #endif /* These aren't much use as we need to have a whole panoply of @@ -779,12 +869,13 @@ toshoboe_open (struct pci_dev *pci_dev) self->txs = 0; self->rxs = 0; - self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL | GFP_DMA); - if (!self->taskfilebuf) { - printk(KERN_ERR "toshoboe: kmalloc for DMA failed()\n"); - kfree(self); - return -ENOMEM; - } + self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL); + if (!self->taskfilebuf) + { + printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n"); + kfree (self); + return -ENOMEM; + } memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN); @@ -803,27 +894,35 @@ toshoboe_open (struct pci_dev *pci_dev) for (i = 0; i < TX_SLOTS; ++i) { self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA); - if (self->xmit_bufs[i]) ok++; + if (self->xmit_bufs[i]) + ok++; } for (i = 0; i < RX_SLOTS; ++i) { self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA); - if (self->recv_bufs[i]) ok++; + if (self->recv_bufs[i]) + ok++; } - if (ok!=RX_SLOTS+TX_SLOTS) { - printk(KERN_ERR "toshoboe: kmalloc for buffers failed()\n"); + if (ok != RX_SLOTS + TX_SLOTS) + { + printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n"); - for (i = 0; i < TX_SLOTS; ++i) if (self->xmit_bufs[i]) kfree(self->xmit_bufs[i]); - for (i = 0; i < RX_SLOTS; ++i) if (self->recv_bufs[i]) kfree(self->recv_bufs[i]); + for (i = 0; i < TX_SLOTS; ++i) + if (self->xmit_bufs[i]) + kfree (self->xmit_bufs[i]); + for (i = 0; i < RX_SLOTS; ++i) + if (self->recv_bufs[i]) + kfree (self->recv_bufs[i]); - kfree(self); - return -ENOMEM; + kfree (self); + return -ENOMEM; - } + } + request_region (idev->io.iobase, idev->io.io_ext, driver_name); irda_device_open (idev, driver_name, self); @@ -838,6 +937,121 @@ toshoboe_open (struct pci_dev *pci_dev) return (0); } +#ifdef CONFIG_APM +static void +toshoboe_gotosleep (struct toshoboe_cb *self) +{ + int i = 10; + + printk (KERN_WARNING "ToshOboe: suspending\n"); + + if (self->stopped) + return; + + self->stopped = 1; + + if (!self->open) + return; + +/*FIXME: can't sleep here wait one second */ + + while ((i--) && (self->txpending)) + udelay (100000); + + toshoboe_stopchip (self); + toshoboe_disablebm (self); + + self->txpending = 0; + +} + + +static void +toshoboe_wakeup (struct toshoboe_cb *self) +{ + struct irda_device *idev = &self->idev; + struct net_device *dev = &idev->netdev; + unsigned long flags; + + if (!self->stopped) + return; + + if (!self->open) + { + self->stopped = 0; + return; + } + + save_flags (flags); + cli (); + + toshoboe_initbuffs (self); + toshoboe_enablebm (self); + toshoboe_startchip (self); + + toshoboe_setbaud (self, idev->io.baudrate); + + toshoboe_initptrs (self); + + + + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + self->stopped = 0; + + restore_flags (flags); + printk (KERN_WARNING "ToshOboe: waking up\n"); + +} + +static int +toshoboe_apmproc (apm_event_t event) +{ + static int down = 0; /*Filter out double events */ + int i; + + switch (event) + { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + if (!down) + { + + for (i = 0; i < 4; i++) + { + if (dev_self[i]) + toshoboe_gotosleep (dev_self[i]); + } + + } + down = 1; + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + if (down) + { + + + + for (i = 0; i < 4; i++) + { + if (dev_self[i]) + toshoboe_wakeup (dev_self[i]); + } + + + + } + down = 0; + break; + } + return 0; +} + + +#endif + int __init toshoboe_init (void) { struct pci_dev *pci_dev = NULL; @@ -850,7 +1064,7 @@ int __init toshoboe_init (void) if (pci_dev) { printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n", - pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK, + pci_dev->resource[0].start, pci_dev->irq); if (!toshoboe_open (pci_dev)) @@ -860,15 +1074,21 @@ int __init toshoboe_init (void) } while (pci_dev); + if (found) - return 0; + { +#ifdef CONFIG_APM + apm_register_callback (toshoboe_apmproc); +#endif + return 0; + } return -ENODEV; } #ifdef MODULE -static void +static void toshoboe_cleanup (void) { int i; @@ -880,18 +1100,23 @@ toshoboe_cleanup (void) if (dev_self[i]) toshoboe_close (&(dev_self[i]->idev)); } + +#ifdef CONFIG_APM + apm_unregister_callback (toshoboe_apmproc); +#endif + } -int +int init_module (void) { return toshoboe_init (); } -void +void cleanup_module (void) { toshoboe_cleanup (); diff --git a/drivers/net/irda/uircc.c b/drivers/net/irda/uircc.c index d5eba5fe2..869ccd5d6 100644 --- a/drivers/net/irda/uircc.c +++ b/drivers/net/irda/uircc.c @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Dec 26 10:59:03 1998 - * Modified at: Wed May 19 15:29:56 1999 + * Modified at: Tue Aug 24 13:33:57 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -71,16 +71,16 @@ static int uircc_close(struct irda_device *idev); static int uircc_probe(int iobase, int board_addr, int irq, int dma); static int uircc_dma_receive(struct irda_device *idev); static int uircc_dma_receive_complete(struct irda_device *idev, int iobase); -static int uircc_hard_xmit(struct sk_buff *skb, struct device *dev); +static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev); static void uircc_dma_write(struct irda_device *idev, int iobase); -static void uircc_change_speed(struct irda_device *idev, int baud); +static void uircc_change_speed(struct irda_device *idev, __u32 baud); static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void uircc_wait_until_sent(struct irda_device *idev); static int uircc_is_receiving(struct irda_device *idev); -static int uircc_toshiba_cmd(int *retval, int arg0, int arg1, int arg2); -static int uircc_net_init(struct device *dev); -static int uircc_net_open(struct device *dev); -static int uircc_net_close(struct device *dev); +static int uircc_toshiba_cmd(int *retval, int arg0, int arg1, int arg2); +static int uircc_net_init(struct net_device *dev); +static int uircc_net_open(struct net_device *dev); +static int uircc_net_close(struct net_device *dev); /* * Function uircc_init () @@ -318,7 +318,7 @@ static int uircc_probe(int iobase, int iobase2, int irq, int dma) * Change the speed of the device * */ -static void uircc_change_speed(struct irda_device *idev, int speed) +static void uircc_change_speed(struct irda_device *idev, __u32 speed) { struct uircc_cb *self; int iobase; @@ -406,7 +406,7 @@ static void uircc_change_speed(struct irda_device *idev, int speed) * Transmit the frame! * */ -static int uircc_hard_xmit(struct sk_buff *skb, struct device *dev) +static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -767,7 +767,7 @@ static void uircc_wait_until_sent( struct irda_device *idev) { /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(6); + schedule_timeout(MSECS_TO_JIFFIES(60)); } /* @@ -798,7 +798,7 @@ static int uircc_is_receiving( struct irda_device *idev) * Initialize network device * */ -static int uircc_net_init( struct device *dev) +static int uircc_net_init( struct net_device *dev) { DEBUG( 4, __FUNCTION__ "()\n"); @@ -817,7 +817,7 @@ static int uircc_net_init( struct device *dev) * Start the device * */ -static int uircc_net_open(struct device *dev) +static int uircc_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -846,9 +846,7 @@ static int uircc_net_open(struct device *dev) } /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + irda_device_net_open(dev); /* turn on interrupts */ @@ -863,17 +861,13 @@ static int uircc_net_open(struct device *dev) * Stop the device * */ -static int uircc_net_close(struct device *dev) +static int uircc_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; DEBUG(4, __FUNCTION__ "()\n"); - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; - ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -882,6 +876,8 @@ static int uircc_net_close(struct device *dev) iobase = idev->io.iobase; + irda_device_net_close(dev); + disable_dma(idev->io.dma); /* Disable interrupts */ diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 292b97a3a..0885e74a3 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Wed Nov 4 11:46:16 1998 - * Modified at: Fri May 21 22:18:19 1999 + * Modified at: Wed Aug 11 09:27:54 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -87,17 +87,17 @@ static int w83977af_close(struct irda_device *idev); static int w83977af_probe(int iobase, int irq, int dma); static int w83977af_dma_receive(struct irda_device *idev); static int w83977af_dma_receive_complete(struct irda_device *idev); -static int w83977af_hard_xmit(struct sk_buff *skb, struct device *dev); +static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size); static void w83977af_dma_write(struct irda_device *idev, int iobase); -static void w83977af_change_speed(struct irda_device *idev, int baud); +static void w83977af_change_speed(struct irda_device *idev, __u32 speed); static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void w83977af_wait_until_sent(struct irda_device *idev); static int w83977af_is_receiving(struct irda_device *idev); -static int w83977af_net_init(struct device *dev); -static int w83977af_net_open(struct device *dev); -static int w83977af_net_close(struct device *dev); +static int w83977af_net_init(struct net_device *dev); +static int w83977af_net_open(struct net_device *dev); +static int w83977af_net_close(struct net_device *dev); /* * Function w83977af_init () @@ -376,7 +376,7 @@ int w83977af_probe( int iobase, int irq, int dma) * Change the speed of the device * */ -void w83977af_change_speed(struct irda_device *idev, int speed) +void w83977af_change_speed(struct irda_device *idev, __u32 speed) { int ir_mode = HCR_SIR; int iobase; @@ -460,7 +460,7 @@ void w83977af_change_speed(struct irda_device *idev, int speed) * Sets up a DMA transfer to send the current frame. * */ -int w83977af_hard_xmit(struct sk_buff *skb, struct device *dev) +int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1155,7 +1155,7 @@ static int w83977af_is_receiving(struct irda_device *idev) * * */ -static int w83977af_net_init(struct device *dev) +static int w83977af_net_init(struct net_device *dev) { DEBUG(0, __FUNCTION__ "()\n"); @@ -1174,7 +1174,7 @@ static int w83977af_net_init(struct device *dev) * Start the device * */ -static int w83977af_net_open(struct device *dev) +static int w83977af_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1203,11 +1203,6 @@ static int w83977af_net_open(struct device *dev) return -EAGAIN; } - /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - /* Save current set */ set = inb(iobase+SSR); @@ -1222,6 +1217,9 @@ static int w83977af_net_open(struct device *dev) /* Restore bank register */ outb(set, iobase+SSR); + /* Ready to play! */ + irda_device_net_open(dev); + MOD_INC_USE_COUNT; return 0; @@ -1233,19 +1231,16 @@ static int w83977af_net_open(struct device *dev) * Stop the device * */ -static int w83977af_net_close(struct device *dev) +static int w83977af_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; __u8 set; DEBUG(0, __FUNCTION__ "()\n"); - - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; ASSERT(dev != NULL, return -1;); + idev = (struct irda_device *) dev->priv; ASSERT(idev != NULL, return 0;); @@ -1253,6 +1248,9 @@ static int w83977af_net_close(struct device *dev) iobase = idev->io.iobase; + /* Stop device */ + irda_device_net_close(dev); + disable_dma(idev->io.dma); /* Save current set */ diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 5ab3edb7f..ebee89f9f 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -82,15 +82,15 @@ static unsigned short known_revisions[] = /* Index to functions, as function prototypes. */ -extern int sonic_probe(struct device *dev); -static int sonic_probe1(struct device *dev, unsigned int base_addr, unsigned int irq); +extern int sonic_probe(struct net_device *dev); +static int sonic_probe1(struct net_device *dev, unsigned int base_addr, unsigned int irq); /* * Probe for a SONIC ethernet controller on a Mips Jazz board. * Actually probing is superfluous but we're paranoid. */ -__initfunc(int sonic_probe(struct device *dev)) +int __init sonic_probe(struct net_device *dev) { unsigned int base_addr = dev ? dev->base_addr : 0; int i; @@ -115,8 +115,8 @@ __initfunc(int sonic_probe(struct device *dev)) return -ENODEV; } -__initfunc(static int sonic_probe1(struct device *dev, - unsigned int base_addr, unsigned int irq)) +static int __init sonic_probe1(struct net_device *dev, + unsigned int base_addr, unsigned int irq) { static unsigned version_printed = 0; unsigned int silicon_revision; diff --git a/drivers/net/lance.c b/drivers/net/lance.c index 9054744fc..c392d80a9 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -68,8 +68,8 @@ static const char *version = "lance.c:v1.14ac 1998/11/20 dplatt@3do.com, becker@ #include <linux/skbuff.h> static unsigned int lance_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0}; -int lance_probe(struct device *dev); -int lance_probe1(struct device *dev, int ioaddr, int irq, int options); +int lance_probe(struct net_device *dev); +int lance_probe1(struct net_device *dev, int ioaddr, int irq, int options); #ifdef LANCE_DEBUG int lance_debug = LANCE_DEBUG; @@ -283,15 +283,15 @@ static unsigned int pci_irq_line = 0; Assume yes until we know the memory size. */ static unsigned char lance_need_isa_bounce_buffers = 1; -static int lance_open(struct device *dev); -static int lance_open_fail(struct device *dev); -static void lance_init_ring(struct device *dev, int mode); -static int lance_start_xmit(struct sk_buff *skb, struct device *dev); -static int lance_rx(struct device *dev); +static int lance_open(struct net_device *dev); +static int lance_open_fail(struct net_device *dev); +static void lance_init_ring(struct net_device *dev, int mode); +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int lance_rx(struct net_device *dev); static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int lance_close(struct device *dev); -static struct net_device_stats *lance_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int lance_close(struct net_device *dev); +static struct net_device_stats *lance_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); @@ -308,7 +308,7 @@ MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); static char ifnames[MAX_CARDS][IF_NAMELEN] = { {0, }, }; -static struct device dev_lance[MAX_CARDS] = +static struct net_device dev_lance[MAX_CARDS] = {{ 0, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, @@ -320,7 +320,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) { - struct device *dev = &dev_lance[this_dev]; + struct net_device *dev = &dev_lance[this_dev]; dev->name = ifnames[this_dev]; dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -347,7 +347,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) { - struct device *dev = &dev_lance[this_dev]; + struct net_device *dev = &dev_lance[this_dev]; if (dev->priv != NULL) { kfree(dev->priv); dev->priv = NULL; @@ -363,7 +363,7 @@ void cleanup_module(void) board probes now that kmalloc() can allocate ISA DMA-able regions. This also allows the LANCE driver to be used as a module. */ -int lance_probe(struct device *dev) +int lance_probe(struct net_device *dev) { int *port, result; @@ -382,7 +382,7 @@ int lance_probe(struct device *dev) unsigned short pci_command; pci_irq_line = pdev->irq; - pci_ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr = pdev->resource[0].start; /* PCI Spec 2.1 states that it is either the driver or PCI card's * responsibility to set the PCI Master Enable Bit if needed. * (From Mark Stockton <marks@schooner.sys.hou.compaq.com>) @@ -420,7 +420,7 @@ int lance_probe(struct device *dev) return -ENODEV; } -int __init lance_probe1(struct device *dev, int ioaddr, int irq, int options) +int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options) { struct lance_private *lp; short dma_channels; /* Mark spuriously-busy DMA channels */ @@ -677,7 +677,7 @@ int __init lance_probe1(struct device *dev, int ioaddr, int irq, int options) } static int -lance_open_fail(struct device *dev) +lance_open_fail(struct net_device *dev) { return -ENODEV; } @@ -685,7 +685,7 @@ lance_open_fail(struct device *dev) static int -lance_open(struct device *dev) +lance_open(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int ioaddr = dev->base_addr; @@ -776,7 +776,7 @@ lance_open(struct device *dev) */ static void -lance_purge_tx_ring(struct device *dev) +lance_purge_tx_ring(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -792,7 +792,7 @@ lance_purge_tx_ring(struct device *dev) /* Initialize the LANCE Rx and Tx rings. */ static void -lance_init_ring(struct device *dev, int gfp) +lance_init_ring(struct net_device *dev, int gfp) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -835,7 +835,7 @@ lance_init_ring(struct device *dev, int gfp) } static void -lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit) +lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -848,7 +848,7 @@ lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit) outw(csr0_bits, dev->base_addr + LANCE_DATA); } -static int lance_start_xmit(struct sk_buff *skb, struct device *dev) +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int ioaddr = dev->base_addr; @@ -967,7 +967,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct device *dev) static void lance_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; int csr0, ioaddr, boguscnt=10; int must_restart; @@ -1093,7 +1093,7 @@ lance_interrupt(int irq, void *dev_id, struct pt_regs * regs) } static int -lance_rx(struct device *dev) +lance_rx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1171,7 +1171,7 @@ lance_rx(struct device *dev) } static int -lance_close(struct device *dev) +lance_close(struct net_device *dev) { int ioaddr = dev->base_addr; struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1220,7 +1220,7 @@ lance_close(struct device *dev) return 0; } -static struct net_device_stats *lance_get_stats(struct device *dev) +static struct net_device_stats *lance_get_stats(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; short ioaddr = dev->base_addr; @@ -1243,7 +1243,7 @@ static struct net_device_stats *lance_get_stats(struct device *dev) /* Set or clear the multicast filter for this adaptor. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; diff --git a/drivers/net/lapbether.c b/drivers/net/lapbether.c index 2556901a3..a4564afcb 100644 --- a/drivers/net/lapbether.c +++ b/drivers/net/lapbether.c @@ -38,14 +38,14 @@ #include <linux/notifier.h> #include <linux/proc_fs.h> #include <linux/stat.h> -#include <linux/firewall.h> +#include <linux/netfilter.h> #include <linux/module.h> #include <linux/lapb.h> #include <linux/init.h> static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; -static int lapbeth_rcv(struct sk_buff *, struct device *, struct packet_type *); +static int lapbeth_rcv(struct sk_buff *, struct net_device *, struct packet_type *); static int lapbeth_device_event(struct notifier_block *, unsigned long, void *); static struct packet_type lapbeth_packet_type = { @@ -67,8 +67,8 @@ static struct notifier_block lapbeth_dev_notifier = { static struct lapbethdev { struct lapbethdev *next; char ethname[14]; /* ether device name */ - struct device *ethdev; /* link to ethernet device */ - struct device axdev; /* lapbeth device (lapb#) */ + struct net_device *ethdev; /* link to ethernet device */ + struct net_device axdev; /* lapbeth device (lapb#) */ struct net_device_stats stats; /* some statistics */ } *lapbeth_devices = NULL; @@ -79,7 +79,7 @@ static struct lapbethdev { /* * Get the ethernet device for a LAPB device */ -static __inline__ struct device *lapbeth_get_ether_dev(struct device *dev) +static __inline__ struct net_device *lapbeth_get_ether_dev(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -91,7 +91,7 @@ static __inline__ struct device *lapbeth_get_ether_dev(struct device *dev) /* * Get the LAPB device for the ethernet device */ -static __inline__ struct device *lapbeth_get_x25_dev(struct device *dev) +static __inline__ struct net_device *lapbeth_get_x25_dev(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -102,7 +102,7 @@ static __inline__ struct device *lapbeth_get_x25_dev(struct device *dev) return NULL; } -static __inline__ int dev_is_ethdev(struct device *dev) +static __inline__ int dev_is_ethdev(struct net_device *dev) { return ( dev->type == ARPHRD_ETHER @@ -114,7 +114,7 @@ static __inline__ int dev_is_ethdev(struct device *dev) * Sanity check: remove all devices that ceased to exists and * return '1' if the given LAPB device was affected. */ -static int lapbeth_check_devices(struct device *dev) +static int lapbeth_check_devices(struct net_device *dev) { struct lapbethdev *lapbeth, *lapbeth_prev; int result = 0; @@ -154,7 +154,7 @@ static int lapbeth_check_devices(struct device *dev) /* * Receive a LAPB frame via an ethernet interface. */ -static int lapbeth_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype) +static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) { int len, err; struct lapbethdev *lapbeth; @@ -204,7 +204,7 @@ static void lapbeth_data_indication(void *token, struct sk_buff *skb) /* * Send a LAPB frame via an ethernet interface */ -static int lapbeth_xmit(struct sk_buff *skb, struct device *dev) +static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) { struct lapbethdev *lapbeth; int err; @@ -254,7 +254,7 @@ static void lapbeth_data_transmit(void *token, struct sk_buff *skb) { struct lapbethdev *lapbeth = (struct lapbethdev *)token; unsigned char *ptr; - struct device *dev; + struct net_device *dev; int size; skb->protocol = htons(ETH_P_X25); @@ -322,7 +322,7 @@ static void lapbeth_disconnected(void *token, int reason) /* * Statistics */ -static struct net_device_stats *lapbeth_get_stats(struct device *dev) +static struct net_device_stats *lapbeth_get_stats(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -334,7 +334,7 @@ static struct net_device_stats *lapbeth_get_stats(struct device *dev) /* * Set AX.25 callsign */ -static int lapbeth_set_mac_address(struct device *dev, void *addr) +static int lapbeth_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -343,7 +343,7 @@ static int lapbeth_set_mac_address(struct device *dev, void *addr) return 0; } -static int lapbeth_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int lapbeth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { return -EINVAL; } @@ -351,7 +351,7 @@ static int lapbeth_ioctl(struct device *dev, struct ifreq *ifr, int cmd) /* * open/close a device */ -static int lapbeth_open(struct device *dev) +static int lapbeth_open(struct net_device *dev) { struct lapb_register_struct lapbeth_callbacks; struct lapbethdev *lapbeth; @@ -384,7 +384,7 @@ static int lapbeth_open(struct device *dev) return 0; } -static int lapbeth_close(struct device *dev) +static int lapbeth_close(struct net_device *dev) { struct lapbethdev *lapbeth; int err; @@ -402,7 +402,7 @@ static int lapbeth_close(struct device *dev) return 0; } -static int lapbeth_dev_init(struct device *dev) +static int lapbeth_dev_init(struct net_device *dev) { return 0; } @@ -412,7 +412,7 @@ static int lapbeth_dev_init(struct device *dev) /* * Setup a new device. */ -static int lapbeth_new_device(struct device *dev) +static int lapbeth_new_device(struct net_device *dev) { int k; unsigned char *buf; @@ -432,11 +432,11 @@ static int lapbeth_new_device(struct device *dev) buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXLAPBDEV; k++) { - struct device *odev; + struct net_device *odev; sprintf(buf, "lapb%d", k); - if ((odev = dev_get(buf)) == NULL || lapbeth_check_devices(odev)) + if ((odev = __dev_get_by_name(buf)) == NULL || lapbeth_check_devices(odev)) break; } @@ -490,7 +490,7 @@ static int lapbeth_new_device(struct device *dev) */ static int lapbeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) { - struct device *dev = (struct device *)ptr; + struct net_device *dev = (struct net_device *)ptr; if (!dev_is_ethdev(dev)) return NOTIFY_DONE; @@ -524,7 +524,7 @@ static int lapbeth_device_event(struct notifier_block *this,unsigned long event, */ int lapbeth_init(void) { - struct device *dev; + struct net_device *dev; lapbeth_packet_type.type = htons(ETH_P_DEC); dev_add_pack(&lapbeth_packet_type); diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index b61d45e67..5f99b56d9 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -46,17 +46,17 @@ static const char *version = #include <linux/etherdevice.h> #include "8390.h" -int lne390_probe(struct device *dev); -int lne390_probe1(struct device *dev, int ioaddr); +int lne390_probe(struct net_device *dev); +int lne390_probe1(struct net_device *dev, int ioaddr); -static int lne390_open(struct device *dev); -static int lne390_close(struct device *dev); +static int lne390_open(struct net_device *dev); +static int lne390_close(struct net_device *dev); -static void lne390_reset_8390(struct device *dev); +static void lne390_reset_8390(struct net_device *dev); -static void lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void lne390_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void lne390_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page); +static void lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); #define LNE390_START_PG 0x00 /* First page of TX buffer */ #define LNE390_STOP_PG 0x80 /* Last page +1 of RX ring */ @@ -100,7 +100,7 @@ static unsigned int shmem_mapB[] __initdata = {0xff, 0xfe, 0x0e, 0xfff, 0xffe, 0 * PROM for a match against the value assigned to Mylex. */ -int __init lne390_probe(struct device *dev) +int __init lne390_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -127,7 +127,7 @@ int __init lne390_probe(struct device *dev) return ENODEV; } -int __init lne390_probe1(struct device *dev, int ioaddr) +int __init lne390_probe1(struct net_device *dev, int ioaddr) { int i, revision; unsigned long eisa_id; @@ -281,7 +281,7 @@ int __init lne390_probe1(struct device *dev, int ioaddr) * file, this just toggles the "Board Enable" bits (bit 2 and 0). */ -static void lne390_reset_8390(struct device *dev) +static void lne390_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -313,7 +313,7 @@ static void lne390_reset_8390(struct device *dev) */ static void -lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - LNE390_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -326,7 +326,7 @@ lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page * be rounded up to a doubleword value via lne390_get_8390_hdr() above. */ -static void lne390_block_input(struct device *dev, int count, struct sk_buff *skb, +static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (LNE390_START_PG<<8); @@ -343,7 +343,7 @@ static void lne390_block_input(struct device *dev, int count, struct sk_buff *sk } } -static void lne390_block_output(struct device *dev, int count, +static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - LNE390_START_PG)<<8); @@ -352,14 +352,14 @@ static void lne390_block_output(struct device *dev, int count, memcpy_toio(shmem, buf, count); } -static int lne390_open(struct device *dev) +static int lne390_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int lne390_close(struct device *dev) +static int lne390_close(struct net_device *dev) { if (ei_debug > 1) @@ -374,7 +374,7 @@ static int lne390_close(struct device *dev) #define MAX_LNE_CARDS 4 /* Max number of LNE390 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_LNE_CARDS] = { 0, }; -static struct device dev_lne[MAX_LNE_CARDS] = { +static struct net_device dev_lne[MAX_LNE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -396,7 +396,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { - struct device *dev = &dev_lne[this_dev]; + struct net_device *dev = &dev_lne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -423,7 +423,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { - struct device *dev = &dev_lne[this_dev]; + struct net_device *dev = &dev_lne[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 2f4089577..ad0191b56 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -58,7 +58,7 @@ * The higher levels take care of making this non-reentrant (it's * called with bh's disabled). */ -static int loopback_xmit(struct sk_buff *skb, struct device *dev) +static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = (struct net_device_stats *)dev->priv; @@ -102,19 +102,19 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) return(0); } -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { return (struct net_device_stats *)dev->priv; } -static int loopback_open(struct device *dev) +static int loopback_open(struct net_device *dev) { dev->flags|=IFF_LOOPBACK; return 0; } /* Initialize the rest of the LOOPBACK device. */ -int __init loopback_init(struct device *dev) +int __init loopback_init(struct net_device *dev) { dev->mtu = LOOPBACK_MTU; dev->tbusy = 0; diff --git a/drivers/net/ltpc.c b/drivers/net/ltpc.c index 6c3740585..53fe53464 100644 --- a/drivers/net/ltpc.c +++ b/drivers/net/ltpc.c @@ -240,9 +240,9 @@ static int dma=0; #include "ltpc.h" /* function prototypes */ -static int do_read(struct device *dev, void *cbuf, int cbuflen, +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen); -static int sendup_buffer (struct device *dev); +static int sendup_buffer (struct net_device *dev); /* Dma Memory related stuff, cribbed directly from 3c505.c */ @@ -348,7 +348,7 @@ static struct xmitQel qels[16]; static unsigned char mailbox[16]; static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static int wait_timeout(struct device *dev, int c) +static int wait_timeout(struct net_device *dev, int c) { /* returns true if it stayed c */ /* this uses base+6, but it's ok */ @@ -383,7 +383,7 @@ static int getmbox(void) } /* read a command from the card */ -static void handlefc(struct device *dev) +static void handlefc(struct net_device *dev) { /* called *only* from idle, non-reentrant */ int dma = dev->dma; @@ -407,7 +407,7 @@ static void handlefc(struct device *dev) } /* read data from the card */ -static void handlefd(struct device *dev) +static void handlefd(struct net_device *dev) { int dma = dev->dma; int base = dev->base_addr; @@ -429,7 +429,7 @@ static void handlefd(struct device *dev) sendup_buffer(dev); } -static void handlewrite(struct device *dev) +static void handlewrite(struct net_device *dev) { /* called *only* from idle, non-reentrant */ /* on entry, 0xfb and ltdmabuf holds data */ @@ -457,7 +457,7 @@ static void handlewrite(struct device *dev) } } -static void handleread(struct device *dev) +static void handleread(struct net_device *dev) { /* on entry, 0xfb */ /* on exit, ltdmabuf holds data */ @@ -480,7 +480,7 @@ static void handleread(struct device *dev) if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); } -static void handlecommand(struct device *dev) +static void handlecommand(struct net_device *dev) { /* on entry, 0xfa and ltdmacbuf holds command */ int dma = dev->dma; @@ -510,7 +510,7 @@ static int QInIdle=0; * an interrupt, or because the line is tri-stated */ -static void idle(struct device *dev) +static void idle(struct net_device *dev) { unsigned long flags; int state; @@ -665,7 +665,7 @@ done: } -static int do_write(struct device *dev, void *cbuf, int cbuflen, +static int do_write(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen) { @@ -689,7 +689,7 @@ static int do_write(struct device *dev, void *cbuf, int cbuflen, return -1; } -static int do_read(struct device *dev, void *cbuf, int cbuflen, +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen) { @@ -717,10 +717,10 @@ static int do_read(struct device *dev, void *cbuf, int cbuflen, static struct timer_list ltpc_timer; -static int ltpc_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *ltpc_get_stats(struct device *dev); +static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *ltpc_get_stats(struct net_device *dev); -static int ltpc_open(struct device *dev) +static int ltpc_open(struct net_device *dev) { #ifdef MODULE MOD_INC_USE_COUNT; @@ -728,7 +728,7 @@ static int ltpc_open(struct device *dev) return 0; } -static int ltpc_close(struct device *dev) +static int ltpc_close(struct net_device *dev) { #ifdef MODULE MOD_DEC_USE_COUNT; @@ -736,14 +736,14 @@ static int ltpc_close(struct device *dev) return 0; } -static int read_30 ( struct device *dev) +static int read_30 ( struct net_device *dev) { lt_command c; c.getflags.command = LT_GETFLAGS; return do_read(dev, &c, sizeof(c.getflags),&c,0); } -static int set_30 (struct device *dev,int x) +static int set_30 (struct net_device *dev,int x) { lt_command c; c.setflags.command = LT_SETFLAGS; @@ -753,7 +753,7 @@ static int set_30 (struct device *dev,int x) /* LLAP to DDP translation */ -static int sendup_buffer (struct device *dev) +static int sendup_buffer (struct net_device *dev) { /* on entry, command is in ltdmacbuf, data in ltdmabuf */ /* called from idle, non-reentrant */ @@ -825,7 +825,7 @@ static int sendup_buffer (struct device *dev) static void ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; if (dev==NULL) { printk("ltpc_interrupt: unknown device.\n"); @@ -852,7 +852,7 @@ static void ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) * ***/ -static int ltpc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; /* we'll keep the localtalk node address in dev->pa_addr */ @@ -897,13 +897,13 @@ static int ltpc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) } } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { /* This needs to be present to keep netatalk happy. */ /* Actually netatalk needs fixing! */ } -static int ltpc_hard_header (struct sk_buff *skb, struct device *dev, +static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { if(debug&DEBUG_VERBOSE) @@ -912,7 +912,7 @@ static int ltpc_hard_header (struct sk_buff *skb, struct device *dev, return 0; } -static int ltpc_init(struct device *dev) +static int ltpc_init(struct net_device *dev) { /* Initialize the device structure. */ @@ -947,7 +947,7 @@ static int ltpc_poll_counter = 0; static void ltpc_poll(unsigned long l) { - struct device *dev = (struct device *) l; + struct net_device *dev = (struct net_device *) l; del_timer(<pc_timer); @@ -970,7 +970,7 @@ static void ltpc_poll(unsigned long l) /* DDP to LLAP translation */ -static int ltpc_xmit(struct sk_buff *skb, struct device *dev) +static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev) { /* in kernel 1.3.xx, on entry skb->data points to ddp header, * and skb->len is the length of the ddp data + ddp header @@ -1010,7 +1010,7 @@ static int ltpc_xmit(struct sk_buff *skb, struct device *dev) return 0; } -static struct net_device_stats *ltpc_get_stats(struct device *dev) +static struct net_device_stats *ltpc_get_stats(struct net_device *dev) { struct net_device_stats *stats = &((struct ltpc_private *) dev->priv)->stats; return stats; @@ -1088,7 +1088,7 @@ int __init ltpc_probe_dma(int base) return dma; } -int __init ltpc_probe(struct device *dev) +int __init ltpc_probe(struct net_device *dev) { int err; int x=0,y=0; @@ -1281,7 +1281,7 @@ void __init ltpc_setup(char *str, int *ints) static char dev_name[8]; -static struct device dev_ltpc = { +static struct net_device dev_ltpc = { dev_name, 0, 0, 0, 0, 0x0, 0, diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 8d433d6b1..94dc1118f 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -23,7 +23,7 @@ #include "mace.h" #ifdef MODULE -static struct device *mace_devs = NULL; +static struct net_device *mace_devs = NULL; #endif #define N_RX_RING 8 @@ -69,21 +69,21 @@ struct mace_data { + (N_RX_RING + NCMDS_TX * N_TX_RING + 3) * sizeof(struct dbdma_cmd)) static int bitrev(int); -static int mace_open(struct device *dev); -static int mace_close(struct device *dev); -static int mace_xmit_start(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *mace_stats(struct device *dev); -static void mace_set_multicast(struct device *dev); -static void mace_reset(struct device *dev); -static int mace_set_address(struct device *dev, void *addr); +static int mace_open(struct net_device *dev); +static int mace_close(struct net_device *dev); +static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *mace_stats(struct net_device *dev); +static void mace_set_multicast(struct net_device *dev); +static void mace_reset(struct net_device *dev); +static int mace_set_address(struct net_device *dev, void *addr); static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); -static void mace_set_timeout(struct device *dev); +static void mace_set_timeout(struct net_device *dev); static void mace_tx_timeout(unsigned long data); static inline void dbdma_reset(volatile struct dbdma_regs *dma); static inline void mace_clean_rings(struct mace_data *mp); -static void __mace_set_address(struct device *dev, void *addr); +static void __mace_set_address(struct net_device *dev, void *addr); /* * If we can't get a skbuff when we need it, we use this area for DMA. @@ -102,7 +102,7 @@ bitrev(int b) } int -mace_probe(struct device *dev) +mace_probe(struct net_device *dev) { int j, rev; struct mace_data *mp; @@ -222,7 +222,7 @@ static void dbdma_reset(volatile struct dbdma_regs *dma) udelay(1); } -static void mace_reset(struct device *dev) +static void mace_reset(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -269,7 +269,7 @@ static void mace_reset(struct device *dev) out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO); } -static void __mace_set_address(struct device *dev, void *addr) +static void __mace_set_address(struct net_device *dev, void *addr) { volatile struct mace *mb = ((struct mace_data *) dev->priv)->mace; unsigned char *p = addr; @@ -283,7 +283,7 @@ static void __mace_set_address(struct device *dev, void *addr) out_8(&mb->padr, dev->dev_addr[i] = p[i]); } -static int mace_set_address(struct device *dev, void *addr) +static int mace_set_address(struct net_device *dev, void *addr) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -301,7 +301,7 @@ static int mace_set_address(struct device *dev, void *addr) return 0; } -static int mace_open(struct device *dev) +static int mace_open(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -392,7 +392,7 @@ static inline void mace_clean_rings(struct mace_data *mp) } } -static int mace_close(struct device *dev) +static int mace_close(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -416,7 +416,7 @@ static int mace_close(struct device *dev) return 0; } -static inline void mace_set_timeout(struct device *dev) +static inline void mace_set_timeout(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; unsigned long flags; @@ -433,7 +433,7 @@ static inline void mace_set_timeout(struct device *dev) restore_flags(flags); } -static int mace_xmit_start(struct sk_buff *skb, struct device *dev) +static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct dbdma_regs *td = mp->tx_dma; @@ -489,7 +489,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct device *dev) return 0; } -static struct net_device_stats *mace_stats(struct device *dev) +static struct net_device_stats *mace_stats(struct net_device *dev) { struct mace_data *p = (struct mace_data *) dev->priv; @@ -501,7 +501,7 @@ static struct net_device_stats *mace_stats(struct device *dev) */ #define CRC_POLY 0xedb88320 -static void mace_set_multicast(struct device *dev) +static void mace_set_multicast(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -579,7 +579,7 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr) static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; volatile struct dbdma_regs *td = mp->tx_dma; @@ -682,8 +682,10 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++mp->stats.tx_carrier_errors; if (fs & (UFLO|LCOL|RTRY)) ++mp->stats.tx_aborted_errors; - } else + } else { + mp->stats.tx_bytes += mp->tx_bufs[i]->len; ++mp->stats.tx_packets; + } dev_kfree_skb(mp->tx_bufs[i]); --mp->tx_active; if (++i >= N_TX_RING) @@ -720,7 +722,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) static void mace_tx_timeout(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; volatile struct dbdma_regs *td = mp->tx_dma; @@ -792,7 +794,7 @@ static void mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct dbdma_regs *rd = mp->rx_dma; volatile struct dbdma_cmd *cp, *np; @@ -848,6 +850,7 @@ static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); mp->rx_bufs[i] = 0; + mp->stats.rx_bytes += skb->len; ++mp->stats.rx_packets; } } else { diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c new file mode 100644 index 000000000..d14ccf3fb --- /dev/null +++ b/drivers/net/macsonic.c @@ -0,0 +1,485 @@ +/* + * macsonic.c + * + * (C) 1998 Alan Cox + * + * Debugging Andreas Ehliar, Michael Schmitz + * + * Based on code + * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de) + * + * This driver is based on work from Andreas Busse, but most of + * the code is rewritten. + * + * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) + * + * A driver for the Mac onboard Sonic ethernet chip. + * + * 98/12/21 MSch: judged from tests on Q800, it's basically working, + * but eating up both receive and transmit resources + * and duplicating packets. Needs more testing. + * + * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed. + */ + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/ctype.h> +#include <linux/fcntl.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/in.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/nubus.h> +#include <asm/bootinfo.h> +#include <asm/system.h> +#include <asm/bitops.h> +#include <asm/pgtable.h> +#include <asm/segment.h> +#include <asm/io.h> +#include <asm/dma.h> +#include <asm/macintosh.h> + +#include <linux/errno.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> + +#include <config/macsonic.h> + +#define SREGS_PAD(n) u16 n; + +#include "sonic.h" + +extern int mac_onboard_sonic_probe(void); + +static int setup_debug = -1; +static int setup_offset = -1; +static int setup_shift = -1; + +/* + * This seems to be the right default for the Q800 + */ + +static int reg_offset = 0; +static int reg_shift = 0; + +/* + * Macros to access SONIC registers + */ + +#define MAC_SONIC_REGISTERS 0x50F0A000 +#define MAC_SONIC_PROM_BASE 0x50f08000 +#define MAC_SONIC_IRQ 9 /* Nubus 9 */ + +/* + * FIXME: We may need to invert the byte ordering. These should + * be ok for other aspects as they are uncached spaces. + * The original macros from jazzsonic.c works for me + * on my LC 630, YMMV /Andreas Ehliar + */ + +#if 0 +#define SONIC_READ(reg) \ + *((volatile unsigned int *)base_addr+((reg)<<2)+2) + +#define SONIC_WRITE(reg,val) \ + *((volatile unsigned int *)base_addr+((reg)<<2)+2) = val +#else +#define SONIC_READ(reg) \ + *((volatile unsigned int *)base_addr+reg) + +#define SONIC_WRITE(reg,val) \ + *((volatile unsigned int *)base_addr+reg) = val +#endif + +#define SONIC_READ_PROM(addr) \ + *((volatile unsigned char *)prom_addr+addr) +/* + * Function : mac_sonic_setup(char *str, int *ints) + * + * Purpose : booter command line initialization of the overrides array, + * + * Inputs : str - unused, ints - array of integer parameters with ints[0] + * equal to the number of ints. + * + * Currently unused in the new driver; need to add settable parameters to the + * detect function. + * + */ + +void mac_sonic_setup(char *str, int *ints) { + /* Format of macsonic parameter is: + * macsonic=<debug>,<offset>,<shift> + * Negative values mean don't change. + */ + + /* Grmbl... the standard parameter parsing can't handle negative numbers + * :-( So let's do it ourselves! + */ + + int i = ints[0]+1, fact; + + while( str && (isdigit(*str) || *str == '-') && i <= 10) { + if (*str == '-') + fact = -1, ++str; + else + fact = 1; + ints[i++] = simple_strtoul( str, NULL, 0 ) * fact; + if ((str = strchr( str, ',' )) != NULL) + ++str; + } + ints[0] = i-1; + + if (ints[0] < 1) { + printk( "mac_sonic_setup: no arguments!\n" ); + return; + } + + if (ints[0] >= 1) { + /* 0 <= n <= 2 */ + if (ints[1] >= 0 && ints[1] <= 8) + setup_debug = ints[1]; + else if (ints[1] > 16) + printk( "mac_sonic_setup: invalid debug level %d !\n", ints[1] ); + } + if (ints[0] >= 2) { + /* 0 <= n <= 2 */ + if (ints[2] >= 0 && ints[2] <= 16) + setup_offset = ints[2]; + else if (ints[2] > 16) + printk( "mac_sonic_setup: invalid offset %d !\n", ints[2] ); + } + if (ints[0] >= 3) { + /* 0 <= n <= 2 */ + if (ints[3] >= 0 && ints[3] <= 16) + setup_shift = ints[3]; + else if (ints[3] > 16) + printk( "mac_sonic_setup: invalid shift %d !\n", ints[3] ); + } +} + +static int sonic_debug = 0; + +/* + * For reversing the PROM address + */ + +static unsigned char nibbletab[] = {0, 8, 4, 12, 2, 10, 6, 14, + 1, 9, 5, 13, 3, 11, 7, 15}; + +int __init mac_onboard_sonic_probe(void) +{ + struct net_device *dev; + unsigned int silicon_revision; + unsigned int val; + struct sonic_local *lp; + int i; + int base_addr = MAC_SONIC_REGISTERS; + int prom_addr = MAC_SONIC_PROM_BASE; + static int one=0; + + if (!MACH_IS_MAC) + return -ENODEV; + + if(++one!=1) /* Only one is allowed */ + return -ENODEV; + + printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); + + if (macintosh_config->ether_type != MAC_ETHER_SONIC) + { + printk("none.\n"); + return -ENODEV; + } + + printk("yes\n"); + + if (setup_debug >= 0) + sonic_debug = setup_debug; + + /* + * This may depend on the actual Mac model ... works for me. + */ + reg_offset = + (setup_offset >= 0) ? setup_offset : 0; + reg_shift = + (setup_shift >= 0) ? setup_shift : 0; + + /* + * get the Silicon Revision ID. If this is one of the known + * one assume that we found a SONIC ethernet controller at + * the expected location. + * (This is not implemented in the Macintosh driver yet; need + * to collect values from various sources. Mine is 0x4 ...) + */ + + silicon_revision = SONIC_READ(SONIC_SR); + if (sonic_debug > 1) + printk("SONIC Silicon Revision = 0x%04x\n", silicon_revision); + + /* + * We need to allocate sonic_local later on, making sure it's + * aligned on a 64k boundary. So, no space for dev->priv allocated + * here ... + */ + dev = init_etherdev(0,0); + + if(dev==NULL) + return -ENOMEM; + + printk("%s: %s found at 0x%08x, ", + dev->name, "SONIC ethernet", base_addr); + + if (sonic_debug > 1) + printk("using offset %d shift %d,", reg_offset, reg_shift); + + /* Fill in the 'dev' fields. */ + dev->base_addr = base_addr; + dev->irq = MAC_SONIC_IRQ; + + /* + * Put the sonic into software reset, then + * retrieve and print the ethernet address. + */ + + SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); + + /* + * We can't trust MacOS to initialise things it seems. + */ + + if (sonic_debug > 1) + printk("SONIC_DCR was %X\n",SONIC_READ(SONIC_DCR)); + + SONIC_WRITE(SONIC_DCR, + SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS | SONIC_DCR_DW); + + /* + * We don't want floating spare IRQ's around, not on + * level triggered systems! + * Strange though - writing to the ISR only clears currently + * pending IRQs, but doesn't disable them... Does this make + * a difference?? Seems it does ... + */ +#if 1 + SONIC_WRITE(SONIC_ISR,0x7fff); + SONIC_WRITE(SONIC_IMR,0); +#else + SONIC_WRITE(SONIC_ISR, SONIC_IMR_DEFAULT); +#endif + + /* This is how it is done in jazzsonic.c + * It doesn't seem to work here though. + */ + if (sonic_debug > 2) { + printk("Retreiving CAM entry 0. This should be the HW address.\n"); + + SONIC_WRITE(SONIC_CEP, 0); + for (i = 0; i < 3; i++) + { + val = SONIC_READ(SONIC_CAP0 - i); + dev->dev_addr[i * 2] = val; + dev->dev_addr[i * 2 + 1] = val >> 8; + } + + printk("HW Address from CAM 0: "); + for (i = 0; i < 6; i++) + { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + printk("\n"); + + printk("Retreiving CAM entry 15. Another candidate...\n"); + + /* + * MacOS seems to use CAM entry 15 ... + */ + SONIC_WRITE(SONIC_CEP, 15); + for (i = 0; i < 3; i++) + { + val = SONIC_READ(SONIC_CAP0 - i); + dev->dev_addr[i * 2] = val; + dev->dev_addr[i * 2 + 1] = val >> 8; + } + + printk("HW Address from CAM 15: "); + for (i = 0; i < 6; i++) + { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + printk("\n"); + } + + /* + * if we can read the PROM, we're safe :-) + */ + if (sonic_debug > 1) + printk("Retreiving HW address from the PROM: "); + + for(i=0;i<6;i++){ + dev->dev_addr[i]=SONIC_READ_PROM(i); + } + if (sonic_debug > 1) { + for (i = 0; i < 6; i++) + { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + printk("\n"); + } + /* + * If its not one of these we have + * screwed up on this Mac model + */ + + if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && + memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && + memcmp(dev->dev_addr, "\x00\x05\x02", 3)) + { + /* + * Try bit reversed + */ + for(i=0;i<6;i++){ + val = SONIC_READ_PROM(i); + dev->dev_addr[i]=(nibbletab[val & 0xf] << 4) | + nibbletab[(val >> 4) &0xf]; + } + if (sonic_debug > 1) { + printk("Trying bit reversed: "); + for (i = 0; i < 6; i++) + { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + printk("\n"); + } + if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && + memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && + memcmp(dev->dev_addr, "\x00\x05\x02", 3)) + { + /* + * Still nonsense ... messed up someplace! + */ + printk("ERROR (INVALID MAC)\n"); + return -EIO; + } + } + + printk(" MAC "); + for (i = 0; i < 6; i++) + { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + + printk(" IRQ %d\n", MAC_SONIC_IRQ); + + /* Initialize the device structure. */ + if (dev->priv == NULL) + { + if (sonic_debug > 2) { + printk("Allocating memory for dev->priv aka lp\n"); + printk("Memory to allocate: %d\n",sizeof(*lp)); + } + /* + * the memory be located in the same 64kb segment + */ + lp = NULL; + i = 0; + do + { + lp = (struct sonic_local *) kmalloc(sizeof(*lp), GFP_KERNEL); + if ((unsigned long) lp >> 16 != ((unsigned long) lp + sizeof(*lp)) >> 16) + { + /* FIXME, free the memory later */ + kfree(lp); + lp = NULL; + } + } + while (lp == NULL && i++ < 20); + + if (lp == NULL) + { + printk("%s: couldn't allocate memory for descriptors\n", + dev->name); + return -ENOMEM; + } + + if (sonic_debug > 2) { + printk("Memory allocated after %d tries\n",i); + } + + /* XXX sonic_local has the TDA, RRA, RDA, don't cache */ + kernel_set_cachemode((u32)lp, 8192, IOMAP_NOCACHE_SER); + memset(lp, 0, sizeof(struct sonic_local)); + + lp->cda_laddr = (u32)lp; + if (sonic_debug > 2) { + printk("memory allocated for sonic at 0x%x\n",lp); + } + lp->tda_laddr = lp->cda_laddr + sizeof(lp->cda); + lp->rra_laddr = lp->tda_laddr + sizeof(lp->tda); + lp->rda_laddr = lp->rra_laddr + sizeof(lp->rra); + + /* allocate receive buffer area */ + /* FIXME, maybe we should use skbs */ + if ((lp->rba = (char *) kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL)) == NULL) + { + printk("%s: couldn't allocate receive buffers\n", dev->name); + return -ENOMEM; + } + /* XXX RBA written by Sonic, not cached either */ + kernel_set_cachemode((u32)lp->rba, 6*8192, IOMAP_NOCACHE_SER); + lp->rba_laddr = (u32)lp->rba; + flush_cache_all(); + dev->priv = (struct sonic_local *) lp; + } + lp = (struct sonic_local *) dev->priv; + dev->open = sonic_open; + dev->stop = sonic_close; + dev->hard_start_xmit = sonic_send_packet; + dev->get_stats = sonic_get_stats; + dev->set_multicast_list = &sonic_multicast_list; + + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(dev); + return 0; +} + +/* + * SONIC uses a nubus IRQ + */ + +#define sonic_request_irq(irq, vec, flags, name, dev) \ + nubus_request_irq(irq, dev, vec) +#define sonic_free_irq(irq,id) nubus_free_irq(irq) + +/* + * No funnies on memory mapping. + */ + +#define sonic_chiptomem(x) (x) + +/* + * No VDMA on a Macintosh. So we need request no such facility. + */ + +#define vdma_alloc(x,y) ((u32)(x)) +#define vdma_free(x) +#define PHYSADDR(x) (x) + +#include "sonic.c" diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c new file mode 100644 index 000000000..fd6744284 --- /dev/null +++ b/drivers/net/mvme147.c @@ -0,0 +1,209 @@ +/* mvme147.c : the Linux/mvme147/lance ethernet driver + * + * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk> + * Based on the Sun Lance driver and the NetBSD HP Lance driver + * Uses the generic 7990.c LANCE code. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> +#include <linux/ioport.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <asm/system.h> +#include <asm/io.h> +#include <asm/pgtable.h> + +/* Used for the temporal inet entries and routing */ +#include <linux/socket.h> +#include <linux/route.h> + +#include <linux/dio.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> + +#include <asm/mvme147hw.h> + +/* We have 16834 bytes of RAM for the init block and buffers. This places + * an upper limit on the number of buffers we can use. NetBSD uses 8 Rx + * buffers and 2 Tx buffers. + */ +#define LANCE_LOG_TX_BUFFERS 1 +#define LANCE_LOG_RX_BUFFERS 3 + +#include "7990.h" /* use generic LANCE code */ + +/* Our private data structure */ +struct m147lance_private { + struct lance_private lance; + void *base; + void *ram; +}; + +/* function prototypes... This is easy because all the grot is in the + * generic LANCE support. All we have to support is probing for boards, + * plus board-specific init, open and close actions. + * Oh, and we need to tell the generic code how to read and write LANCE registers... + */ +int mvme147lance_probe(struct net_device *dev); +static int m147lance_open(struct net_device *dev); +static int m147lance_close(struct net_device *dev); +static void m147lance_writerap(struct m147lance_private *lp, unsigned short value); +static void m147lance_writerdp(struct m147lance_private *lp, unsigned short value); +static unsigned short m147lance_readrdp(struct m147lance_private *lp); + +typedef void (*writerap_t)(void *, unsigned short); +typedef void (*writerdp_t)(void *, unsigned short); +typedef void (*readrdp_t)(void *); + +#ifdef MODULE +static struct m147lance_private *root_m147lance_dev = NULL; +#endif + +/* Initialise the one and only on-board 7990 */ +int __init mvme147lance_probe(struct net_device *dev) +{ + static int called = 0; + static const char name[] = "MVME147 LANCE"; + struct m147lance_private *lp; + u_long *addr; + u_long address; + + if (!MACH_IS_MVME147 || called) + return(ENODEV); + called++; + + dev->priv = kmalloc(sizeof(struct m147lance_private), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct m147lance_private)); + + /* Fill the dev fields */ + dev->base_addr = (unsigned long)MVME147_LANCE_BASE; + dev->open = &m147lance_open; + dev->stop = &m147lance_close; + dev->hard_start_xmit = &lance_start_xmit; + dev->get_stats = &lance_get_stats; + dev->set_multicast_list = &lance_set_multicast; + dev->dma = 0; + + addr=(u_long *)ETHERNET_ADDRESS; + address = *addr; + dev->dev_addr[0]=0x08; + dev->dev_addr[1]=0x00; + dev->dev_addr[2]=0x3e; + address=address>>8; + dev->dev_addr[5]=address&0xff; + address=address>>8; + dev->dev_addr[4]=address&0xff; + address=address>>8; + dev->dev_addr[3]=address&0xff; + + printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, dev->base_addr, MVME147_LANCE_IRQ, + dev->dev_addr[0], + dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], + dev->dev_addr[5]); + + lp = (struct m147lance_private *)dev->priv; + lp->ram = (void *)__get_dma_pages(GFP_ATOMIC, 3); /* 16K */ + if (!lp->ram) + { + printk("%s: No memory for LANCE buffers\n", dev->name); + return -ENODEV; + } + + lp->lance.name = (char*)name; /* discards const, shut up gcc */ + lp->lance.ll = (struct lance_regs *)(dev->base_addr); + lp->lance.init_block = (struct lance_init_block *)(lp->ram); /* CPU addr */ + lp->lance.lance_init_block = (struct lance_init_block *)(lp->ram); /* LANCE addr of same RAM */ + lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */ + lp->lance.irq = MVME147_LANCE_IRQ; + lp->lance.writerap = (writerap_t)m147lance_writerap; + lp->lance.writerdp = (writerdp_t)m147lance_writerdp; + lp->lance.readrdp = (readrdp_t)m147lance_readrdp; + lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS; + lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; + lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK; + lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK; + ether_setup(dev); + +#ifdef MODULE + dev->ifindex = dev_new_index(); + lp->next_module = root_m147lance_dev; + root_m147lance_dev = lp; +#endif /* MODULE */ + + return 0; +} + +static void m147lance_writerap(struct m147lance_private *lp, unsigned short value) +{ + lp->lance.ll->rap = value; +} + +static void m147lance_writerdp(struct m147lance_private *lp, unsigned short value) +{ + lp->lance.ll->rdp = value; +} + +static unsigned short m147lance_readrdp(struct m147lance_private *lp) +{ + return lp->lance.ll->rdp; +} + +static int m147lance_open(struct net_device *dev) +{ + int status; + + status = lance_open(dev); /* call generic lance open code */ + if (status) + return status; + /* enable interrupts at board level. */ + m147_pcc->lan_cntrl=0; /* clear the interrupts (if any) */ + m147_pcc->lan_cntrl=0x08 | 0x04; /* Enable irq 4 */ + + MOD_INC_USE_COUNT; + return 0; +} + +static int m147lance_close(struct net_device *dev) +{ + /* disable interrupts at boardlevel */ + m147_pcc->lan_cntrl=0x0; /* disable interrupts */ + lance_close(dev); + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MODULE +int init_module(void) +{ + root_lance_dev = NULL; + return mvme147lance_probe(NULL); +} + +void cleanup_module(void) +{ + /* Walk the chain of devices, unregistering them */ + struct m147lance_private *lp; + while (root_m147lance_dev) { + lp = root_m147lance_dev->next_module; + unregister_netdev(root_lance_dev->dev); + free_pages(lp->ram, 3); + kfree(root_lance_dev->dev); + root_lance_dev = lp; + } +} + +#endif /* MODULE */ diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 58c11d17b..5bf2ba8c6 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -176,7 +176,7 @@ static inline int myri_do_handshake(struct myri_eth *mp) static inline int myri_load_lanai(struct myri_eth *mp) { - struct device *dev = mp->dev; + struct net_device *dev = mp->dev; struct myri_shmem *shmem = mp->shmem; unsigned char *rptr; int i; @@ -261,7 +261,7 @@ static void myri_init_rings(struct myri_eth *mp, int from_irq) { struct recvq *rq = mp->rq; struct myri_rxd *rxd = &rq->myri_rxd[0]; - struct device *dev = mp->dev; + struct net_device *dev = mp->dev; int gfp_flags = GFP_KERNEL; int i; @@ -323,7 +323,7 @@ static void dump_ehdr_and_myripad(unsigned char *stuff) } #endif -static inline void myri_tx(struct myri_eth *mp, struct device *dev) +static inline void myri_tx(struct myri_eth *mp, struct net_device *dev) { struct sendq *sq = mp->sq; int entry = mp->tx_old; @@ -348,7 +348,7 @@ static inline void myri_tx(struct myri_eth *mp, struct device *dev) * assume 802.3 if the type field is short enough to be a length. * This is normal practice and works for any 'now in use' protocol. */ -static unsigned short myri_type_trans(struct sk_buff *skb, struct device *dev) +static unsigned short myri_type_trans(struct sk_buff *skb, struct net_device *dev) { struct ethhdr *eth; unsigned char *rawp; @@ -388,7 +388,7 @@ static unsigned short myri_type_trans(struct sk_buff *skb, struct device *dev) return htons(ETH_P_802_2); } -static inline void myri_rx(struct myri_eth *mp, struct device *dev) +static inline void myri_rx(struct myri_eth *mp, struct net_device *dev) { struct recvq *rq = mp->rq; struct recvq *rqa = mp->rqack; @@ -506,7 +506,7 @@ static inline void myri_rx(struct myri_eth *mp, struct device *dev) static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct myri_eth *mp = (struct myri_eth *) dev->priv; struct lanai_regs *lregs = mp->lregs; struct myri_channel *chan = &mp->shmem->channel; @@ -537,14 +537,14 @@ static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs) DIRQ(("\n")); } -static int myri_open(struct device *dev) +static int myri_open(struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; return myri_init(mp, in_interrupt()); } -static int myri_close(struct device *dev) +static int myri_close(struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; @@ -552,7 +552,7 @@ static int myri_close(struct device *dev) return 0; } -static int myri_start_xmit(struct sk_buff *skb, struct device *dev) +static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; struct sendq *sq = mp->sq; @@ -656,7 +656,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct device *dev) * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) */ -static int myri_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int myri_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN); @@ -708,7 +708,7 @@ static int myri_rebuild_header(struct sk_buff *skb) { unsigned char *pad = (unsigned char *)skb->data; struct ethhdr *eth = (struct ethhdr *)(pad + MYRI_PAD_LEN); - struct device *dev = skb->dev; + struct net_device *dev = skb->dev; #ifdef DEBUG_HEADER DHDR(("myri_rebuild_header: pad[%02x,%02x] ", pad[0], pad[1])); @@ -744,7 +744,7 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) unsigned short type = hh->hh_type; unsigned char *pad = (unsigned char *)hh->hh_data; struct ethhdr *eth = (struct ethhdr *)(pad + MYRI_PAD_LEN); - struct device *dev = neigh->dev; + struct net_device *dev = neigh->dev; if (type == __constant_htons(ETH_P_802_3)) return -1; @@ -762,12 +762,12 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) /* Called by Address Resolution module to notify changes in address. */ -void myri_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) +void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) { memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); } -static int myri_change_mtu(struct device *dev, int new_mtu) +static int myri_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < (ETH_HLEN + MYRI_PAD_LEN)) || (new_mtu > MYRINET_MTU)) return -EINVAL; @@ -775,13 +775,13 @@ static int myri_change_mtu(struct device *dev, int new_mtu) return 0; } -static struct net_device_stats *myri_get_stats(struct device *dev) +static struct net_device_stats *myri_get_stats(struct net_device *dev) { return &(((struct myri_eth *)dev->priv)->enet_stats); } #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void myri_set_multicast(struct device *dev) +static void myri_set_multicast(struct net_device *dev) { /* Do nothing, all MyriCOM nodes transmit multicast frames * as broadcast packets... @@ -862,7 +862,7 @@ static void dump_eeprom(struct myri_eth *mp) } #endif -static inline int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int myri_ether_init(struct net_device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct myri_eth *mp; @@ -1074,7 +1074,7 @@ static inline int myri_ether_init(struct device *dev, struct linux_sbus_device * return 0; } -int __init myri_sbus_probe(struct device *dev) +int __init myri_sbus_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h index b069a346c..772c7592e 100644 --- a/drivers/net/myri_sbus.h +++ b/drivers/net/myri_sbus.h @@ -273,7 +273,7 @@ struct myri_eth { struct recvq *rqack; /* Where we ack rx's. */ struct recvq *rq; /* Where we put buffers. */ struct sendq *sq; /* Where we stuff tx's. */ - struct device *dev; /* Linux/NET dev struct. */ + struct net_device *dev; /* Linux/NET dev struct. */ int tx_old; /* To speed up tx cleaning. */ struct lanai_regs *lregs; /* Quick ptr to LANAI regs. */ struct sk_buff *rx_skbs[RX_RING_SIZE+1];/* RX skb's */ diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 36a841c08..ae8a4fbdc 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -126,21 +126,21 @@ bad_clone_list[] __initdata = { /* Non-zero only if the current card is a PCI with BIOS-set IRQ. */ static unsigned int pci_irq_line = 0; -int ne_probe(struct device *dev); -static int ne_probe1(struct device *dev, int ioaddr); +int ne_probe(struct net_device *dev); +static int ne_probe1(struct net_device *dev, int ioaddr); #ifdef CONFIG_PCI -static int ne_probe_pci(struct device *dev); +static int ne_probe_pci(struct net_device *dev); #endif -static int ne_open(struct device *dev); -static int ne_close(struct device *dev); +static int ne_open(struct net_device *dev); +static int ne_close(struct net_device *dev); -static void ne_reset_8390(struct device *dev); -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_reset_8390(struct net_device *dev); +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne_block_input(struct device *dev, int count, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct device *dev, const int count, +static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -177,7 +177,7 @@ struct netdev_entry netcard_drv = * the card. */ -int __init ne_probe(struct device *dev) +int __init ne_probe(struct net_device *dev) { int base_addr = dev ? dev->base_addr : 0; @@ -209,7 +209,7 @@ int __init ne_probe(struct device *dev) #endif #ifdef CONFIG_PCI -static int __init ne_probe_pci(struct device *dev) +static int __init ne_probe_pci(struct net_device *dev) { int i; @@ -218,7 +218,7 @@ static int __init ne_probe_pci(struct device *dev) unsigned int pci_ioaddr; while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { - pci_ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr = pdev->resource[0].start; /* Avoid already found cards from previous calls */ if (check_region(pci_ioaddr, NE_IO_EXTENT)) continue; @@ -243,7 +243,7 @@ static int __init ne_probe_pci(struct device *dev) } #endif /* CONFIG_PCI */ -static int __init ne_probe1(struct device *dev, int ioaddr) +static int __init ne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; @@ -497,14 +497,14 @@ static int __init ne_probe1(struct device *dev, int ioaddr) return 0; } -static int ne_open(struct device *dev) +static int ne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne_close(struct device *dev) +static int ne_close(struct net_device *dev) { if (ei_debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); @@ -516,7 +516,7 @@ static int ne_close(struct device *dev) /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ne_reset_8390(struct device *dev) +static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -542,7 +542,7 @@ static void ne_reset_8390(struct device *dev) we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -579,7 +579,7 @@ static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int r The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { #ifdef NE_SANITY_CHECK int xfer_count = count; @@ -646,7 +646,7 @@ static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, i ei_status.dmaing &= ~0x01; } -static void ne_block_output(struct device *dev, int count, +static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -756,7 +756,7 @@ retry: #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, }; -static struct device dev_ne[MAX_NE_CARDS] = { +static struct net_device dev_ne[MAX_NE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -787,7 +787,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; @@ -816,7 +816,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index 6decb8100..0a69d9004 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -126,19 +126,19 @@ const struct ne2_adapters_t ne2_adapters[] = { { 0x0000, NULL } }; -extern int netcard_probe(struct device *dev); +extern int netcard_probe(struct net_device *dev); -static int ne2_probe1(struct device *dev, int slot); +static int ne2_probe1(struct net_device *dev, int slot); -static int ne_open(struct device *dev); -static int ne_close(struct device *dev); +static int ne_open(struct net_device *dev); +static int ne_close(struct net_device *dev); -static void ne_reset_8390(struct device *dev); -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_reset_8390(struct net_device *dev); +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne_block_input(struct device *dev, int count, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct device *dev, const int count, +static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -146,7 +146,7 @@ static void ne_block_output(struct device *dev, const int count, * Note that at boot, this probe only picks up one card at a time. */ -int __init ne2_probe(struct device *dev) +int __init ne2_probe(struct net_device *dev) { static int current_mca_slot = -1; int i; @@ -175,7 +175,7 @@ int __init ne2_probe(struct device *dev) } -static int ne2_procinfo(char *buf, int slot, struct device *dev) +static int ne2_procinfo(char *buf, int slot, struct net_device *dev) { int len=0; @@ -198,7 +198,7 @@ static int ne2_procinfo(char *buf, int slot, struct device *dev) return len; } -static int __init ne2_probe1(struct device *dev, int slot) +static int __init ne2_probe1(struct net_device *dev, int slot) { int i, base_addr, irq; unsigned char POS; @@ -370,14 +370,14 @@ static int __init ne2_probe1(struct device *dev, int slot) return 0; } -static int ne_open(struct device *dev) +static int ne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne_close(struct device *dev) +static int ne_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -388,7 +388,7 @@ static int ne_close(struct device *dev) /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ne_reset_8390(struct device *dev) +static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -415,7 +415,7 @@ static void ne_reset_8390(struct device *dev) we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { @@ -455,7 +455,7 @@ static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, hints. The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { #ifdef NE_SANITY_CHECK @@ -518,7 +518,7 @@ static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, ei_status.dmaing &= ~0x01; } -static void ne_block_output(struct device *dev, int count, +static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -624,7 +624,7 @@ retry: #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, }; -static struct device dev_ne[MAX_NE_CARDS] = { +static struct net_device dev_ne[MAX_NE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -650,7 +650,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; @@ -672,7 +672,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; if (dev->priv != NULL) { mca_mark_as_unused(ei_status.priv); mca_set_adapter_procfn( ei_status.priv, NULL, NULL); diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index cd809d562..72f9d8f7e 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -86,7 +86,7 @@ pci_clone_list[] __initdata = { {0x4a14, 0x5000, "NetVin NV5000SC", 0}, {0x1106, 0x0926, "Via 86C926", ONLY_16BIT_IO}, {0x10bd, 0x0e34, "SureCom NE34", 0}, - {0x1050, 0x5a5a, "Winbond", 0}, + {0x1050, 0x5a5a, "Winbond W89C940F", 0}, {0x12c3, 0x0058, "Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, {0x12c3, 0x5598, "Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, @@ -104,19 +104,19 @@ pci_clone_list[] __initdata = { #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -int ne2k_pci_probe(struct device *dev); -static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq, +int ne2k_pci_probe(struct net_device *dev); +static struct net_device *ne2k_pci_probe1(struct net_device *dev, long ioaddr, int irq, int chip_idx); -static int ne2k_pci_open(struct device *dev); -static int ne2k_pci_close(struct device *dev); +static int ne2k_pci_open(struct net_device *dev); +static int ne2k_pci_close(struct net_device *dev); -static void ne2k_pci_reset_8390(struct device *dev); -static void ne2k_pci_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne2k_pci_reset_8390(struct net_device *dev); +static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne2k_pci_block_input(struct device *dev, int count, +static void ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne2k_pci_block_output(struct device *dev, const int count, +static void ne2k_pci_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -124,7 +124,7 @@ static void ne2k_pci_block_output(struct device *dev, const int count, /* No room in the standard 8390 structure for extra info we need. */ struct ne2k_pci_card { struct ne2k_pci_card *next; - struct device *dev; + struct net_device *dev; struct pci_dev *pci_dev; }; /* A list of all installed devices, for removing the driver module. */ @@ -150,7 +150,7 @@ init_module(void) void cleanup_module(void) { - struct device *dev; + struct net_device *dev; struct ne2k_pci_card *this_card; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ @@ -186,7 +186,7 @@ struct netdev_entry netcard_drv = {"ne2k_pci", ne2k_pci_probe1, NE_IO_EXTENT, 0}; #endif -int __init ne2k_pci_probe(struct device *dev) +int __init ne2k_pci_probe(struct net_device *dev) { struct pci_dev *pdev = NULL; int cards_found = 0; @@ -196,9 +196,9 @@ int __init ne2k_pci_probe(struct device *dev) return -ENODEV; while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev)) != NULL) { - u8 pci_irq_line; + int pci_irq_line; u16 pci_command, new_command; - u32 pci_ioaddr; + unsigned long pci_ioaddr; /* Note: some vendor IDs (RealTek) have non-NE2k cards as well. */ for (i = 0; pci_clone_list[i].vendor != 0; i++) @@ -208,7 +208,7 @@ int __init ne2k_pci_probe(struct device *dev) if (pci_clone_list[i].vendor == 0) continue; - pci_ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr = pdev->resource[0].start; pci_irq_line = pdev->irq; pci_read_config_word(pdev, PCI_COMMAND, &pci_command); @@ -232,19 +232,19 @@ int __init ne2k_pci_probe(struct device *dev) pci_command, new_command); pci_write_config_word(pdev, PCI_COMMAND, new_command); } - +#ifndef __sparc__ if (pci_irq_line <= 0 || pci_irq_line >= NR_IRQS) printk(KERN_WARNING " WARNING: The PCI BIOS assigned this PCI NE2k" " card to IRQ %d, which is unlikely to work!.\n" KERN_WARNING " You should use the PCI BIOS setup to assign" " a valid IRQ line.\n", pci_irq_line); - - printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#x, IRQ %d.\n", +#endif + printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#lx, IRQ %d.\n", pci_clone_list[i].name, pci_ioaddr, pci_irq_line); dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line, i); if (dev == 0) { /* Should not happen. */ - printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#x failed.\n", + printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#lx failed.\n", pci_ioaddr); continue; } else { @@ -263,7 +263,7 @@ int __init ne2k_pci_probe(struct device *dev) return cards_found ? 0 : -ENODEV; } -static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq, int chip_idx) +static struct net_device __init *ne2k_pci_probe1(struct net_device *dev, long ioaddr, int irq, int chip_idx) { int i; unsigned char SA_prom[32]; @@ -340,7 +340,6 @@ static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int /* Note: all PCI cards have at least 16 bit access, so we don't have to check for 8 bit cards. Most cards permit 32 bit access. */ - if (pci_clone_list[chip_idx].flags & ONLY_32BIT_IO) { for (i = 0; i < 4 ; i++) ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); @@ -367,7 +366,7 @@ static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int request_region(ioaddr, NE_IO_EXTENT, dev->name); - printk("%s: %s found at %#x, IRQ %d, ", + printk("%s: %s found at %#lx, IRQ %d, ", dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq); for(i = 0; i < 6; i++) { printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":"); @@ -397,7 +396,7 @@ static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int } static int -ne2k_pci_open(struct device *dev) +ne2k_pci_open(struct net_device *dev) { if (request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev)) return -EAGAIN; @@ -407,7 +406,7 @@ ne2k_pci_open(struct device *dev) } static int -ne2k_pci_close(struct device *dev) +ne2k_pci_close(struct net_device *dev) { ei_close(dev); free_irq(dev->irq, dev); @@ -418,7 +417,7 @@ ne2k_pci_close(struct device *dev) /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ static void -ne2k_pci_reset_8390(struct device *dev) +ne2k_pci_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -444,10 +443,10 @@ ne2k_pci_reset_8390(struct device *dev) the start of a page, so we optimize accordingly. */ static void -ne2k_pci_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - int nic_base = dev->base_addr; + long nic_base = dev->base_addr; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) { @@ -483,9 +482,9 @@ ne2k_pci_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_pa the packet out through the "remote DMA" dataport using outb. */ static void -ne2k_pci_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { - int nic_base = dev->base_addr; + long nic_base = dev->base_addr; char *buf = skb->data; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ @@ -527,10 +526,10 @@ ne2k_pci_block_input(struct device *dev, int count, struct sk_buff *skb, int rin } static void -ne2k_pci_block_output(struct device *dev, int count, +ne2k_pci_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { - int nic_base = NE_BASE; + long nic_base = NE_BASE; unsigned long dma_start; /* On little-endian it's always safe to round the count up for diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index 51d11cb0c..0f59bcb08 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -43,17 +43,17 @@ static const char *version = #include <linux/etherdevice.h> #include "8390.h" -int ne3210_probe(struct device *dev); -int ne3210_probe1(struct device *dev, int ioaddr); +int ne3210_probe(struct net_device *dev); +int ne3210_probe1(struct net_device *dev, int ioaddr); -static int ne3210_open(struct device *dev); -static int ne3210_close(struct device *dev); +static int ne3210_open(struct net_device *dev); +static int ne3210_close(struct net_device *dev); -static void ne3210_reset_8390(struct device *dev); +static void ne3210_reset_8390(struct net_device *dev); -static void ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne3210_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page); +static void ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); #define NE3210_START_PG 0x00 /* First page of TX buffer */ #define NE3210_STOP_PG 0x80 /* Last page +1 of RX ring */ @@ -95,7 +95,7 @@ static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0 * PROM for a match against the value assigned to Novell. */ -int __init ne3210_probe(struct device *dev) +int __init ne3210_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -122,7 +122,7 @@ int __init ne3210_probe(struct device *dev) return ENODEV; } -int __init ne3210_probe1(struct device *dev, int ioaddr) +int __init ne3210_probe1(struct net_device *dev, int ioaddr) { int i; unsigned long eisa_id; @@ -272,7 +272,7 @@ int __init ne3210_probe1(struct device *dev, int ioaddr) * Reset by toggling the "Board Enable" bits (bit 2 and 0). */ -static void ne3210_reset_8390(struct device *dev) +static void ne3210_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -304,7 +304,7 @@ static void ne3210_reset_8390(struct device *dev) */ static void -ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -317,7 +317,7 @@ ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page * be rounded up to a doubleword value via ne3210_get_8390_hdr() above. */ -static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (NE3210_START_PG<<8); @@ -334,7 +334,7 @@ static void ne3210_block_input(struct device *dev, int count, struct sk_buff *sk } } -static void ne3210_block_output(struct device *dev, int count, +static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8); @@ -343,14 +343,14 @@ static void ne3210_block_output(struct device *dev, int count, memcpy_toio(shmem, buf, count); } -static int ne3210_open(struct device *dev) +static int ne3210_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne3210_close(struct device *dev) +static int ne3210_close(struct net_device *dev) { if (ei_debug > 1) @@ -365,7 +365,7 @@ static int ne3210_close(struct device *dev) #define MAX_NE3210_CARDS 4 /* Max number of NE3210 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE3210_CARDS] = { 0, }; -static struct device dev_ne3210[MAX_NE3210_CARDS] = { +static struct net_device dev_ne3210[MAX_NE3210_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -387,7 +387,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) { - struct device *dev = &dev_ne3210[this_dev]; + struct net_device *dev = &dev_ne3210[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -414,7 +414,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) { - struct device *dev = &dev_ne3210[this_dev]; + struct net_device *dev = &dev_ne3210[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c index 3aa066f1d..857080e0f 100644 --- a/drivers/net/net_init.c +++ b/drivers/net/net_init.c @@ -38,6 +38,7 @@ #include <linux/fddidevice.h> #include <linux/hippidevice.h> #include <linux/trdevice.h> +#include <linux/fcdevice.h> #include <linux/if_arp.h> #include <linux/if_ltalk.h> #include <linux/rtnetlink.h> @@ -62,7 +63,7 @@ /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */ #define MAX_ETH_CARDS 16 -static struct device *ethdev_index[MAX_ETH_CARDS]; +static struct net_device *ethdev_index[MAX_ETH_CARDS]; /* Fill in the fields of the device structure with ethernet-generic values. @@ -75,17 +76,17 @@ static struct device *ethdev_index[MAX_ETH_CARDS]; long. */ -struct device * -init_etherdev(struct device *dev, int sizeof_priv) +struct net_device * +init_etherdev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("eth%d ") + int alloc_size = sizeof(struct net_device) + IFNAMSIZ + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; /* Putative name for the device. */ for (i = 0; i < MAX_ETH_CARDS; ++i) @@ -110,7 +111,9 @@ init_etherdev(struct device *dev, int sizeof_priv) alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if(dev==NULL) + return NULL; memset(dev, 0, alloc_size); if (sizeof_priv) dev->priv = (void *) (dev + 1); @@ -132,14 +135,16 @@ found: /* From the double loop above. */ ether_setup(dev); /* Hmmm, should this be called here? */ - if (new_device) + if (new_device) { + rtnl_lock(); register_netdevice(dev); - + rtnl_unlock(); + } return dev; } -static int eth_mac_addr(struct device *dev, void *p) +static int eth_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr=p; if(dev->start) @@ -148,7 +153,7 @@ static int eth_mac_addr(struct device *dev, void *p) return 0; } -static int eth_change_mtu(struct device *dev, int new_mtu) +static int eth_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < 68) || (new_mtu > 1500)) return -EINVAL; @@ -158,7 +163,7 @@ static int eth_change_mtu(struct device *dev, int new_mtu) #ifdef CONFIG_FDDI -static int fddi_change_mtu(struct device *dev, int new_mtu) +static int fddi_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN)) return(-EINVAL); @@ -170,9 +175,9 @@ static int fddi_change_mtu(struct device *dev, int new_mtu) #ifdef CONFIG_HIPPI #define MAX_HIP_CARDS 4 -static struct device *hipdev_index[MAX_HIP_CARDS]; +static struct net_device *hipdev_index[MAX_HIP_CARDS]; -static int hippi_change_mtu(struct device *dev, int new_mtu) +static int hippi_change_mtu(struct net_device *dev, int new_mtu) { /* * HIPPI's got these nice large MTUs. @@ -188,7 +193,7 @@ static int hippi_change_mtu(struct device *dev, int new_mtu) * For HIPPI we will actually use the lower 4 bytes of the hardware * address as the I-FIELD rather than the actual hardware address. */ -static int hippi_mac_addr(struct device *dev, void *p) +static int hippi_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; if(dev->start) @@ -198,16 +203,16 @@ static int hippi_mac_addr(struct device *dev, void *p) } -struct device *init_hippi_dev(struct device *dev, int sizeof_priv) +struct net_device *init_hippi_dev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("hip%d ") + int alloc_size = sizeof(struct net_device) + IFNAMSIZ + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; for (i = 0; i < MAX_HIP_CARDS; ++i) @@ -232,7 +237,9 @@ struct device *init_hippi_dev(struct device *dev, int sizeof_priv) alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if(dev==NULL) + return NULL; memset(dev, 0, alloc_size); if (sizeof_priv) dev->priv = (void *) (dev + 1); @@ -254,14 +261,16 @@ hipfound: /* From the double loop above. */ hippi_setup(dev); - if (new_device) + if (new_device) { + rtnl_lock(); register_netdevice(dev); - + rtnl_unlock(); + } return dev; } -void unregister_hipdev(struct device *dev) +void unregister_hipdev(struct net_device *dev) { int i; rtnl_lock(); @@ -276,7 +285,7 @@ void unregister_hipdev(struct device *dev) } -static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { /* Never send broadcast/multicast ARP messages */ p->mcast_probes = 0; @@ -292,7 +301,7 @@ static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p) #endif -void ether_setup(struct device *dev) +void ether_setup(struct net_device *dev) { int i; /* Fill in the fields of the device structure with ethernet-generic values. @@ -335,7 +344,7 @@ void ether_setup(struct device *dev) #ifdef CONFIG_FDDI -void fddi_setup(struct device *dev) +void fddi_setup(struct net_device *dev) { /* * Fill in the fields of the device structure with FDDI-generic values. @@ -365,7 +374,7 @@ void fddi_setup(struct device *dev) #endif #ifdef CONFIG_HIPPI -void hippi_setup(struct device *dev) +void hippi_setup(struct net_device *dev) { int i; @@ -415,18 +424,18 @@ void hippi_setup(struct device *dev) #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) -static int ltalk_change_mtu(struct device *dev, int mtu) +static int ltalk_change_mtu(struct net_device *dev, int mtu) { return -EINVAL; } -static int ltalk_mac_addr(struct device *dev, void *addr) +static int ltalk_mac_addr(struct net_device *dev, void *addr) { return -EINVAL; } -void ltalk_setup(struct device *dev) +void ltalk_setup(struct net_device *dev) { /* Fill in the fields of the device structure with localtalk-generic values. */ @@ -452,7 +461,7 @@ void ltalk_setup(struct device *dev) #endif -int ether_config(struct device *dev, struct ifmap *map) +int ether_config(struct net_device *dev, struct ifmap *map) { if (map->mem_start != (u_long)(-1)) dev->mem_start = map->mem_start; @@ -469,7 +478,7 @@ int ether_config(struct device *dev, struct ifmap *map) return 0; } -static int etherdev_get_index(struct device *dev) +static int etherdev_get_index(struct net_device *dev) { int i=MAX_ETH_CARDS; @@ -484,7 +493,7 @@ static int etherdev_get_index(struct device *dev) return -1; } -static void etherdev_put_index(struct device *dev) +static void etherdev_put_index(struct net_device *dev) { int i; for (i = 0; i < MAX_ETH_CARDS; ++i) { @@ -495,7 +504,7 @@ static void etherdev_put_index(struct device *dev) } } -int register_netdev(struct device *dev) +int register_netdev(struct net_device *dev) { int i=-1; @@ -515,7 +524,7 @@ int register_netdev(struct device *dev) return 0; } -void unregister_netdev(struct device *dev) +void unregister_netdev(struct net_device *dev) { rtnl_lock(); unregister_netdevice(dev); @@ -527,18 +536,18 @@ void unregister_netdev(struct device *dev) #ifdef CONFIG_TR /* The list of used and available "tr" slots */ #define MAX_TR_CARDS 16 -static struct device *trdev_index[MAX_TR_CARDS]; +static struct net_device *trdev_index[MAX_TR_CARDS]; -struct device *init_trdev(struct device *dev, int sizeof_priv) +struct net_device *init_trdev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("tr%d ") + int alloc_size = sizeof(struct net_device) + IFNAMSIZ + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; /* Putative name for the device. */ for (i = 0; i < MAX_TR_CARDS; ++i) @@ -562,7 +571,9 @@ struct device *init_trdev(struct device *dev, int sizeof_priv) } alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if(dev==NULL) + return NULL; memset(dev, 0, alloc_size); if (sizeof_priv) dev->priv = (void *) (dev + 1); @@ -594,13 +605,15 @@ trfound: /* From the double loop above. */ /* New-style flags. */ dev->flags = IFF_BROADCAST; - if (new_device) + if (new_device) { + rtnl_lock(); register_netdevice(dev); - + rtnl_unlock(); + } return dev; } -void tr_setup(struct device *dev) +void tr_setup(struct net_device *dev) { int i; @@ -618,7 +631,7 @@ void tr_setup(struct device *dev) } } -void tr_freedev(struct device *dev) +void tr_freedev(struct net_device *dev) { int i; for (i = 0; i < MAX_TR_CARDS; ++i) @@ -631,7 +644,7 @@ void tr_freedev(struct device *dev) } } -int register_trdev(struct device *dev) +int register_trdev(struct net_device *dev) { dev_init_buffers(dev); @@ -642,7 +655,7 @@ int register_trdev(struct device *dev) return 0; } -void unregister_trdev(struct device *dev) +void unregister_trdev(struct net_device *dev) { rtnl_lock(); unregister_netdevice(dev); @@ -651,7 +664,132 @@ void unregister_trdev(struct device *dev) } #endif - + +#ifdef CONFIG_NET_FC + +#define MAX_FC_CARDS 2 +static struct net_device *fcdev_index[MAX_FC_CARDS]; + +void fc_setup(struct net_device *dev) +{ +int i; + + /* register boot-defined "fc" devices */ + if (dev->name && (strncmp(dev->name, "fc", 2) == 0)) { + i = simple_strtoul(dev->name + 2, NULL, 0); + if (fcdev_index[i] == NULL) { + fcdev_index[i] = dev; + } + else if (dev != fcdev_index[i]) { + /* Really shouldn't happen! */ + printk("fc_setup: Ouch! Someone else took %s\n", + dev->name); + } + } + + dev->hard_header = fc_header; + dev->rebuild_header = fc_rebuild_header; + + dev->type = ARPHRD_IEEE802; + dev->hard_header_len = FC_HLEN; + dev->mtu = 2024; + dev->addr_len = FC_ALEN; + dev->tx_queue_len = 100; /* Long queues on fc */ + + memset(dev->broadcast,0xFF, FC_ALEN); + + /* New-style flags. */ + dev->flags = IFF_BROADCAST; + dev_init_buffers(dev); + return; +} + + +struct net_device *init_fcdev(struct net_device *dev, int sizeof_priv) +{ +int new_device = 0; +int i; + /* Use an existing correctly named device in Space.c:dev_base. */ + if (dev == NULL) { + int alloc_size = sizeof(struct net_device) + sizeof("fc%d ") + sizeof_priv + 3; + struct net_device *cur_dev; + char pname[8]; /* Putative name for the device. */ + + for (i = 0; i < MAX_FC_CARDS; ++i) + if (fcdev_index[i] == NULL) { + sprintf(pname, "fc%d", i); + for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next) + if (strcmp(pname, cur_dev->name) == 0) { + dev = cur_dev; + dev->init = NULL; + sizeof_priv = (sizeof_priv + 3) &~3; + dev->priv = sizeof_priv + ? kmalloc(sizeof_priv, GFP_KERNEL) + : NULL; + if (dev->priv) memset(dev->priv, 0, sizeof_priv); + goto fcfound; + } + } + + alloc_size &= ~3; /* Round to dword boundary. */ + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + memset(dev, 0, alloc_size); + if (sizeof_priv) + dev->priv = (void *) (dev + 1); + dev->name = sizeof_priv + (char *)(dev + 1); + new_device = 1; + } + +fcfound: /* From the double loop */ + + for (i = 0; i < MAX_FC_CARDS; ++i) + if (fcdev_index[i] == NULL) { + sprintf(dev->name, "fc%d", i); + fcdev_index[i] = dev; + break; + } + + fc_setup(dev); + if (new_device) { + rtnl_lock(); + register_netdevice(dev); + rtnl_unlock(); + } + return dev; +} + +void fc_freedev(struct net_device *dev) +{ +int i; + for (i = 0; i < MAX_FC_CARDS; ++i) { + if (fcdev_index[i] == dev) { + fcdev_index[i] = NULL; + break; + } + } +} + + +int register_fcdev(struct net_device *dev) +{ + dev_init_buffers(dev); + if (dev->init && dev->init(dev) != 0) { + unregister_fcdev(dev); + return -EIO; + } + return 0; +} + +void unregister_fcdev(struct net_device *dev) +{ + rtnl_lock(); + unregister_netdevice(dev); + rtnl_unlock(); + fc_freedev(dev); +} + +#endif /* CONFIG_NET_FC */ + /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c" diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index b5e959ddd..5df1c9ffa 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -100,26 +100,26 @@ struct ni5010_local { /* Index to functions, as function prototypes. */ -extern int ni5010_probe(struct device *dev); -static int ni5010_probe1(struct device *dev, int ioaddr); -static int ni5010_open(struct device *dev); -static int ni5010_send_packet(struct sk_buff *skb, struct device *dev); +extern int ni5010_probe(struct net_device *dev); +static int ni5010_probe1(struct net_device *dev, int ioaddr); +static int ni5010_open(struct net_device *dev); +static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev); static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void ni5010_rx(struct device *dev); -static int ni5010_close(struct device *dev); -static struct net_device_stats *ni5010_get_stats(struct device *dev); -static void ni5010_set_multicast_list(struct device *dev); -static void reset_receiver(struct device *dev); +static void ni5010_rx(struct net_device *dev); +static int ni5010_close(struct net_device *dev); +static struct net_device_stats *ni5010_get_stats(struct net_device *dev); +static void ni5010_set_multicast_list(struct net_device *dev); +static void reset_receiver(struct net_device *dev); -static int process_xmt_interrupt(struct device *dev); +static int process_xmt_interrupt(struct net_device *dev); #define tx_done(dev) 1 -extern void hardware_send_packet(struct device *dev, char *buf, int length); -extern void chipset_init(struct device *dev, int startp); +extern void hardware_send_packet(struct net_device *dev, char *buf, int length); +extern void chipset_init(struct net_device *dev, int startp); static void dump_packet(void *buf, int len); -static void show_registers(struct device *dev); +static void show_registers(struct net_device *dev); -__initfunc(int ni5010_probe(struct device *dev)) +int __init ni5010_probe(struct net_device *dev) { int *port; @@ -157,7 +157,7 @@ static inline int rd_port(int ioaddr) return inb(IE_SAPROM); } -__initfunc(void trigger_irq(int ioaddr)) +void __init trigger_irq(int ioaddr) { outb(0x00, EDLC_RESET); /* Clear EDLC hold RESET state */ outb(0x00, IE_RESET); /* Board reset */ @@ -182,7 +182,7 @@ __initfunc(void trigger_irq(int ioaddr)) * verifies that the correct device exists and functions. */ -__initfunc(static int ni5010_probe1(struct device *dev, int ioaddr)) +static int __init ni5010_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i; @@ -355,7 +355,7 @@ __initfunc(static int ni5010_probe1(struct device *dev, int ioaddr)) * there is non-reboot way to recover if something goes wrong. */ -static int ni5010_open(struct device *dev) +static int ni5010_open(struct net_device *dev) { int ioaddr = dev->base_addr; int i; @@ -414,7 +414,7 @@ static int ni5010_open(struct device *dev) return 0; } -static void reset_receiver(struct device *dev) +static void reset_receiver(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -426,7 +426,7 @@ static void reset_receiver(struct device *dev) outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */ } -static int ni5010_send_packet(struct sk_buff *skb, struct device *dev) +static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev) { PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name)); if (dev->tbusy) { @@ -472,7 +472,7 @@ static int ni5010_send_packet(struct sk_buff *skb, struct device *dev) static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct ni5010_local *lp; int ioaddr, status; int xmit_was_error = 0; @@ -531,7 +531,7 @@ static void dump_packet(void *buf, int len) /* We have a good packet, get it out of the buffer. */ static void -ni5010_rx(struct device *dev) +ni5010_rx(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -594,7 +594,7 @@ ni5010_rx(struct device *dev) } -static int process_xmt_interrupt(struct device *dev) +static int process_xmt_interrupt(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -635,7 +635,7 @@ static int process_xmt_interrupt(struct device *dev) /* The inverse routine to ni5010_open(). */ static int -ni5010_close(struct device *dev) +ni5010_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -659,7 +659,7 @@ ni5010_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ static struct net_device_stats * -ni5010_get_stats(struct device *dev) +ni5010_get_stats(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; @@ -682,7 +682,7 @@ ni5010_get_stats(struct device *dev) best-effort filtering. */ static void -ni5010_set_multicast_list(struct device *dev) +ni5010_set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -702,7 +702,7 @@ ni5010_set_multicast_list(struct device *dev) } } -extern void hardware_send_packet(struct device *dev, char *buf, int length) +extern void hardware_send_packet(struct net_device *dev, char *buf, int length) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -751,13 +751,13 @@ extern void hardware_send_packet(struct device *dev, char *buf, int length) if (NI5010_DEBUG) show_registers(dev); } -extern void chipset_init(struct device *dev, int startp) +extern void chipset_init(struct net_device *dev, int startp) { /* FIXME: Move some stuff here */ PRINTK3((KERN_DEBUG "%s: doing NOTHING in chipset_init\n", dev->name)); } -static void show_registers(struct device *dev) +static void show_registers(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -772,7 +772,7 @@ static void show_registers(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni5010 = { +static struct net_device dev_ni5010 = { devicename, 0, 0, 0, 0, 0, 0, diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index cc7a9976e..7efc0dca6 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -192,26 +192,26 @@ sizeof(nop_cmd) = 8; #define NI52_ADDR1 0x07 #define NI52_ADDR2 0x01 -static int ni52_probe1(struct device *dev,int ioaddr); +static int ni52_probe1(struct net_device *dev,int ioaddr); static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr); -static int ni52_open(struct device *dev); -static int ni52_close(struct device *dev); -static int ni52_send_packet(struct sk_buff *,struct device *); -static struct net_device_stats *ni52_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int ni52_open(struct net_device *dev); +static int ni52_close(struct net_device *dev); +static int ni52_send_packet(struct sk_buff *,struct net_device *); +static struct net_device_stats *ni52_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #if 0 -static void ni52_dump(struct device *,void *); +static void ni52_dump(struct net_device *,void *); #endif /* helper-functions */ -static int init586(struct device *dev); -static int check586(struct device *dev,char *where,unsigned size); -static void alloc586(struct device *dev); -static void startrecv586(struct device *dev); -static void *alloc_rfa(struct device *dev,void *ptr); -static void ni52_rcv_int(struct device *dev); -static void ni52_xmt_int(struct device *dev); -static void ni52_rnr_int(struct device *dev); +static int init586(struct net_device *dev); +static int check586(struct net_device *dev,char *where,unsigned size); +static void alloc586(struct net_device *dev); +static void startrecv586(struct net_device *dev); +static void *alloc_rfa(struct net_device *dev,void *ptr); +static void ni52_rcv_int(struct net_device *dev); +static void ni52_xmt_int(struct net_device *dev); +static void ni52_rnr_int(struct net_device *dev); struct priv { @@ -238,7 +238,7 @@ struct priv /********************************************** * close device */ -static int ni52_close(struct device *dev) +static int ni52_close(struct net_device *dev) { free_irq(dev->irq, dev); @@ -255,7 +255,7 @@ static int ni52_close(struct device *dev) /********************************************** * open device */ -static int ni52_open(struct device *dev) +static int ni52_open(struct net_device *dev) { ni_disint(); alloc586(dev); @@ -281,7 +281,7 @@ static int ni52_open(struct device *dev) /********************************************** * Check to see if there's an 82586 out there. */ -static int check586(struct device *dev,char *where,unsigned size) +static int check586(struct net_device *dev,char *where,unsigned size) { struct priv pb; struct priv *p = /* (struct priv *) dev->priv*/ &pb; @@ -323,7 +323,7 @@ static int check586(struct device *dev,char *where,unsigned size) /****************************************************************** * set iscp at the right place, called by ni52_probe1 and open586. */ -void alloc586(struct device *dev) +void alloc586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -358,7 +358,7 @@ void alloc586(struct device *dev) /********************************************** * probe the ni5210-card */ -__initfunc(int ni52_probe(struct device *dev)) +int __init ni52_probe(struct net_device *dev) { #ifndef MODULE int *port; @@ -409,7 +409,7 @@ __initfunc(int ni52_probe(struct device *dev)) return ENODEV; } -__initfunc(static int ni52_probe1(struct device *dev,int ioaddr)) +static int __init ni52_probe1(struct net_device *dev,int ioaddr) { int i,size; @@ -534,7 +534,7 @@ __initfunc(static int ni52_probe1(struct device *dev,int ioaddr)) * needs a correct 'allocated' memory */ -static int init586(struct device *dev) +static int init586(struct net_device *dev) { void *ptr; int i,result=0; @@ -769,7 +769,7 @@ static int init586(struct device *dev) * It sets up the Receive Frame Area (RFA). */ -static void *alloc_rfa(struct device *dev,void *ptr) +static void *alloc_rfa(struct net_device *dev,void *ptr) { volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr; volatile struct rbd_struct *rbd; @@ -817,7 +817,7 @@ static void *alloc_rfa(struct device *dev,void *ptr) static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; unsigned short stat; int cnt=0; struct priv *p; @@ -893,7 +893,7 @@ static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) * receive-interrupt */ -static void ni52_rcv_int(struct device *dev) +static void ni52_rcv_int(struct net_device *dev) { int status,cnt=0; unsigned short totlen; @@ -1016,7 +1016,7 @@ static void ni52_rcv_int(struct device *dev) * handle 'Receiver went not ready'. */ -static void ni52_rnr_int(struct device *dev) +static void ni52_rnr_int(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1039,7 +1039,7 @@ static void ni52_rnr_int(struct device *dev) * handle xmit - interrupt */ -static void ni52_xmt_int(struct device *dev) +static void ni52_xmt_int(struct net_device *dev) { int status; struct priv *p = (struct priv *) dev->priv; @@ -1092,7 +1092,7 @@ static void ni52_xmt_int(struct device *dev) * (re)start the receiver */ -static void startrecv586(struct device *dev) +static void startrecv586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1108,7 +1108,7 @@ static void startrecv586(struct device *dev) * send frame */ -static int ni52_send_packet(struct sk_buff *skb, struct device *dev) +static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev) { int len,i; #ifndef NO_NOPCOMMANDS @@ -1258,7 +1258,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct device *dev) * Someone wanna have the statistics */ -static struct net_device_stats *ni52_get_stats(struct device *dev) +static struct net_device_stats *ni52_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; unsigned short crc,aln,rsc,ovrn; @@ -1283,7 +1283,7 @@ static struct net_device_stats *ni52_get_stats(struct device *dev) /******************************************************** * Set MC list .. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(!dev->start) { @@ -1304,7 +1304,7 @@ static void set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni52 = { +static struct net_device dev_ni52 = { devicename, /* "ni5210": device name inserted by net_init.c */ 0, 0, 0, 0, 0x300, 9, /* I/O address, IRQ */ @@ -1349,7 +1349,7 @@ void cleanup_module(void) /* * DUMP .. we expect a not running CMD unit and enough space */ -void ni52_dump(struct device *dev,void *ptr) +void ni52_dump(struct net_device *dev,void *ptr) { struct priv *p = (struct priv *) dev->priv; struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr; diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index 9e22ce1a4..fc24bd1ee 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -220,19 +220,19 @@ struct priv int features; }; -static int ni65_probe1(struct device *dev,int); +static int ni65_probe1(struct net_device *dev,int); static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); -static void ni65_recv_intr(struct device *dev,int); -static void ni65_xmit_intr(struct device *dev,int); -static int ni65_open(struct device *dev); -static int ni65_lance_reinit(struct device *dev); +static void ni65_recv_intr(struct net_device *dev,int); +static void ni65_xmit_intr(struct net_device *dev,int); +static int ni65_open(struct net_device *dev); +static int ni65_lance_reinit(struct net_device *dev); static void ni65_init_lance(struct priv *p,unsigned char*,int,int); -static int ni65_send_packet(struct sk_buff *skb, struct device *dev); -static int ni65_close(struct device *dev); -static int ni65_alloc_buffer(struct device *dev); +static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev); +static int ni65_close(struct net_device *dev); +static int ni65_alloc_buffer(struct net_device *dev); static void ni65_free_buffer(struct priv *p); -static struct net_device_stats *ni65_get_stats(struct device *); -static void set_multicast_list(struct device *dev); +static struct net_device_stats *ni65_get_stats(struct net_device *); +static void set_multicast_list(struct net_device *dev); static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */ static int dmatab[] __initdata = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ @@ -265,7 +265,7 @@ static void ni65_set_performance(struct priv *p) /* * open interface (up) */ -static int ni65_open(struct device *dev) +static int ni65_open(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; int irqval = request_irq(dev->irq, &ni65_interrupt,0, @@ -295,7 +295,7 @@ static int ni65_open(struct device *dev) /* * close interface (down) */ -static int ni65_close(struct device *dev) +static int ni65_close(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -326,7 +326,7 @@ static int ni65_close(struct device *dev) #ifdef MODULE static #endif -__initfunc(int ni65_probe(struct device *dev)) +int __init ni65_probe(struct net_device *dev) { int *port; static int ports[] = {0x360,0x300,0x320,0x340, 0}; @@ -348,7 +348,7 @@ __initfunc(int ni65_probe(struct device *dev)) /* * this is the real card probe .. */ -__initfunc(static int ni65_probe1(struct device *dev,int ioaddr)) +static int __init ni65_probe1(struct net_device *dev,int ioaddr) { int i,j; struct priv *p; @@ -531,7 +531,7 @@ static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int m /* * allocate memory area and check the 16MB border */ -static void *ni65_alloc_mem(struct device *dev,char *what,int size,int type) +static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type) { struct sk_buff *skb=NULL; unsigned char *ptr; @@ -569,7 +569,7 @@ static void *ni65_alloc_mem(struct device *dev,char *what,int size,int type) /* * allocate all memory structures .. send/recv buffers etc ... */ -static int ni65_alloc_buffer(struct device *dev) +static int ni65_alloc_buffer(struct net_device *dev) { unsigned char *ptr; struct priv *p; @@ -655,7 +655,7 @@ static void ni65_free_buffer(struct priv *p) /* * stop and (re)start lance .. e.g after an error */ -static void ni65_stop_start(struct device *dev,struct priv *p) +static void ni65_stop_start(struct net_device *dev,struct priv *p) { int csr0 = CSR0_INEA; @@ -724,7 +724,7 @@ static void ni65_stop_start(struct device *dev,struct priv *p) /* * init lance (write init-values .. init-buffers) (open-helper) */ -static int ni65_lance_reinit(struct device *dev) +static int ni65_lance_reinit(struct net_device *dev) { int i; struct priv *p = (struct priv *) dev->priv; @@ -809,7 +809,7 @@ static int ni65_lance_reinit(struct device *dev) static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs) { int csr0; - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct priv *p; int bcnt = 32; @@ -925,7 +925,7 @@ static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs) * We have received an Xmit-Interrupt .. * send a new packet if necessary */ -static void ni65_xmit_intr(struct device *dev,int csr0) +static void ni65_xmit_intr(struct net_device *dev,int csr0) { struct priv *p = (struct priv *) dev->priv; @@ -990,7 +990,7 @@ static void ni65_xmit_intr(struct device *dev,int csr0) /* * We have received a packet */ -static void ni65_recv_intr(struct device *dev,int csr0) +static void ni65_recv_intr(struct net_device *dev,int csr0) { struct rmd *rmdp; int rmdstat,len; @@ -1082,7 +1082,7 @@ static void ni65_recv_intr(struct device *dev,int csr0) /* * kick xmitter .. */ -static int ni65_send_packet(struct sk_buff *skb, struct device *dev) +static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1162,7 +1162,7 @@ static int ni65_send_packet(struct sk_buff *skb, struct device *dev) return 0; } -static struct net_device_stats *ni65_get_stats(struct device *dev) +static struct net_device_stats *ni65_get_stats(struct net_device *dev) { #if 0 @@ -1179,7 +1179,7 @@ static struct net_device_stats *ni65_get_stats(struct device *dev) return &((struct priv *) dev->priv)->stats; } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(!ni65_lance_reinit(dev)) printk(KERN_ERR "%s: Can't switch card into MC mode!\n",dev->name); @@ -1189,7 +1189,7 @@ static void set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni65 = { +static struct net_device dev_ni65 = { devicename, /* "ni6510": device name inserted by net_init.c */ 0, 0, 0, 0, 0x360, 9, /* I/O address, IRQ */ diff --git a/drivers/net/olympic.c b/drivers/net/olympic.c index 07ae7b91c..460480c48 100644 --- a/drivers/net/olympic.c +++ b/drivers/net/olympic.c @@ -22,6 +22,9 @@ * * 6/8/99 - Official Release 0.2.0 * Merged into the kernel code + * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci + * resource. Driver also reports the card name returned by + * the pci resource. * * To Do: * @@ -83,7 +86,7 @@ */ static char *version = -"Olympic.c v0.2.0 6/8/99 - Peter De Schrijver & Mike Phillips" ; +"Olympic.c v0.3.0 8/18/99 - Peter De Schrijver & Mike Phillips" ; static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion", "Address Verification", "Neighbor Notification (Ring Poll)", @@ -128,26 +131,26 @@ static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; MODULE_PARM(message_level, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; -static int olympic_scan(struct device *dev); -static int olympic_init(struct device *dev); -static int olympic_open(struct device *dev); -static int olympic_xmit(struct sk_buff *skb, struct device *dev); -static int olympic_close(struct device *dev); -static void olympic_set_rx_mode(struct device *dev); +static int olympic_scan(struct net_device *dev); +static int olympic_init(struct net_device *dev); +static int olympic_open(struct net_device *dev); +static int olympic_xmit(struct sk_buff *skb, struct net_device *dev); +static int olympic_close(struct net_device *dev); +static void olympic_set_rx_mode(struct net_device *dev); static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct net_device_stats * olympic_get_stats(struct device *dev); -static int olympic_set_mac_address(struct device *dev, void *addr) ; -static void olympic_arb_cmd(struct device *dev); -static int olympic_change_mtu(struct device *dev, int mtu); -static void olympic_srb_bh(struct device *dev) ; -static void olympic_asb_bh(struct device *dev) ; +static struct net_device_stats * olympic_get_stats(struct net_device *dev); +static int olympic_set_mac_address(struct net_device *dev, void *addr) ; +static void olympic_arb_cmd(struct net_device *dev); +static int olympic_change_mtu(struct net_device *dev, int mtu); +static void olympic_srb_bh(struct net_device *dev) ; +static void olympic_asb_bh(struct net_device *dev) ; #if OLYMPIC_NETWORK_MONITOR #ifdef CONFIG_PROC_FS -static int sprintf_info(char *buffer, struct device *dev) ; +static int sprintf_info(char *buffer, struct net_device *dev) ; #endif #endif -__initfunc(int olympic_probe(struct device *dev)) +int __init olympic_probe(struct net_device *dev) { int cards_found; @@ -155,7 +158,7 @@ __initfunc(int olympic_probe(struct device *dev)) return cards_found ? 0 : -ENODEV; } -__initfunc(static int olympic_scan(struct device *dev)) +static int __init olympic_scan(struct net_device *dev) { struct pci_dev *pci_device = NULL ; struct olympic_private *olympic_priv; @@ -169,7 +172,7 @@ __initfunc(static int olympic_scan(struct device *dev)) /* Check to see if io has been allocated, if so, we've already done this card, so continue on the card discovery loop */ - if (check_region(pci_device->base_address[0] & (~3), OLYMPIC_IO_SPACE)) { + if (check_region(pci_device->resource[0].start, OLYMPIC_IO_SPACE)) { card_no++ ; continue ; } @@ -184,12 +187,13 @@ __initfunc(static int olympic_scan(struct device *dev)) dev->priv=(void *)olympic_priv; #if OLYMPIC_DEBUG printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv); -#endif +#endif dev->irq=pci_device->irq; - dev->base_addr=pci_device->base_address[0] & (~3); + dev->base_addr=pci_device->resource[0].start; dev->init=&olympic_init; - olympic_priv->olympic_mmio=ioremap(pci_device->base_address[1],256); - olympic_priv->olympic_lap=ioremap(pci_device->base_address[2],2048); + olympic_priv->olympic_card_name = (char *)pci_device->resource[0].name ; + olympic_priv->olympic_mmio=ioremap(pci_device->resource[1].start,256); + olympic_priv->olympic_lap=ioremap(pci_device->resource[2].start,2048); if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; @@ -222,7 +226,7 @@ __initfunc(static int olympic_scan(struct device *dev)) } -__initfunc(static int olympic_init(struct device *dev)) +static int __init olympic_init(struct net_device *dev) { struct olympic_private *olympic_priv; __u8 *olympic_mmio, *init_srb,*adapter_addr; @@ -233,7 +237,7 @@ __initfunc(static int olympic_init(struct device *dev)) olympic_mmio=olympic_priv->olympic_mmio; printk("%s \n", version); - printk("%s: IBM PCI tokenring card. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); + printk("%s: %s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); request_region(dev->base_addr, OLYMPIC_IO_SPACE, "olympic"); writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL); @@ -337,7 +341,7 @@ __initfunc(static int olympic_init(struct device *dev)) } -static int olympic_open(struct device *dev) +static int olympic_open(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb; @@ -628,7 +632,7 @@ static int olympic_open(struct device *dev) * of blindly processing the next frame. * */ -static void olympic_rx(struct device *dev) +static void olympic_rx(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -742,7 +746,7 @@ static void olympic_rx(struct device *dev) static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev= (struct device *)dev_id; + struct net_device *dev= (struct net_device *)dev_id; struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; __u32 sisr; @@ -834,7 +838,7 @@ static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) } -static int olympic_xmit(struct sk_buff *skb, struct device *dev) +static int olympic_xmit(struct sk_buff *skb, struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -864,7 +868,7 @@ static int olympic_xmit(struct sk_buff *skb, struct device *dev) } -static int olympic_close(struct device *dev) +static int olympic_close(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb; @@ -928,7 +932,7 @@ static int olympic_close(struct device *dev) } -static void olympic_set_rx_mode(struct device *dev) +static void olympic_set_rx_mode(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *olympic_mmio = olympic_priv->olympic_mmio ; @@ -1028,7 +1032,7 @@ static void olympic_set_rx_mode(struct device *dev) } -static void olympic_srb_bh(struct device *dev) +static void olympic_srb_bh(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *olympic_mmio = olympic_priv->olympic_mmio ; @@ -1175,14 +1179,14 @@ static void olympic_srb_bh(struct device *dev) } -static struct net_device_stats * olympic_get_stats(struct device *dev) +static struct net_device_stats * olympic_get_stats(struct net_device *dev) { struct olympic_private *olympic_priv ; olympic_priv=(struct olympic_private *) dev->priv; return (struct net_device_stats *) &olympic_priv->olympic_stats; } -static int olympic_set_mac_address (struct device *dev, void *addr) +static int olympic_set_mac_address (struct net_device *dev, void *addr) { struct sockaddr *saddr = addr ; struct olympic_private *olympic_priv = (struct olympic_private *)dev->priv ; @@ -1204,7 +1208,7 @@ static int olympic_set_mac_address (struct device *dev, void *addr) return 0 ; } -static void olympic_arb_cmd(struct device *dev) +static void olympic_arb_cmd(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -1394,7 +1398,7 @@ static void olympic_arb_cmd(struct device *dev) printk(KERN_WARNING "%s: Unknown arb command \n", dev->name); } -static void olympic_asb_bh(struct device *dev) +static void olympic_asb_bh(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *arb_block, *asb_block ; @@ -1434,7 +1438,7 @@ static void olympic_asb_bh(struct device *dev) olympic_priv->asb_queued = 0 ; } -static int olympic_change_mtu(struct device *dev, int mtu) +static int olympic_change_mtu(struct net_device *dev, int mtu) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv; __u16 max_mtu ; @@ -1465,7 +1469,7 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt off_t pos=0; int size; - struct device *dev; + struct net_device *dev; size = sprintf(buffer, @@ -1479,7 +1483,7 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev->base_addr == (pci_device->base_address[0] & (~3)) ) { /* Yep, an Olympic device */ + if (dev->base_addr == pci_device->resource[0].start ) { /* Yep, an Olympic device */ size = sprintf_info(buffer+len, dev); len+=size; pos=begin+len; @@ -1502,7 +1506,7 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt return len; } -static int sprintf_info(char *buffer, struct device *dev) +static int sprintf_info(char *buffer, struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; @@ -1602,7 +1606,7 @@ static int sprintf_info(char *buffer, struct device *dev) #ifdef MODULE -static struct device* dev_olympic[OLYMPIC_MAX_ADAPTERS]; +static struct net_device* dev_olympic[OLYMPIC_MAX_ADAPTERS]; int init_module(void) { @@ -1625,7 +1629,7 @@ int init_module(void) dev_olympic[i]->init = &olympic_probe; if (register_trdev(dev_olympic[i]) != 0) { - kfree_s(dev_olympic[i], sizeof(struct device)); + kfree_s(dev_olympic[i], sizeof(struct net_device)); dev_olympic[i] = NULL; if (i == 0) { printk("Olympic: No IBM PCI Token Ring cards found in system.\n"); @@ -1649,7 +1653,7 @@ void cleanup_module(void) unregister_trdev(dev_olympic[i]); release_region(dev_olympic[i]->base_addr, OLYMPIC_IO_SPACE); kfree_s(dev_olympic[i]->priv, sizeof(struct olympic_private)); - kfree_s(dev_olympic[i], sizeof(struct device)); + kfree_s(dev_olympic[i], sizeof(struct net_device)); dev_olympic[i] = NULL; } diff --git a/drivers/net/olympic.h b/drivers/net/olympic.h index 6f98b3b82..d5a06423a 100644 --- a/drivers/net/olympic.h +++ b/drivers/net/olympic.h @@ -243,6 +243,7 @@ struct olympic_private { __u8 *olympic_mmio; __u8 *olympic_lap; + char *olympic_card_name ; volatile int srb_queued; /* True if an SRB is still posted */ wait_queue_head_t srb_wait; diff --git a/drivers/net/pcmcia/.cvsignore b/drivers/net/pcmcia/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/drivers/net/pcmcia/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c new file mode 100644 index 000000000..6e511f4b7 --- /dev/null +++ b/drivers/net/pcmcia/3c589_cs.c @@ -0,0 +1,1178 @@ +/*====================================================================== + + A PCMCIA ethernet driver for the 3com 3c589 card. + + Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu + + 3c589_cs.c 1.134 1999/09/15 15:33:09 + + The network driver code is based on Donald Becker's 3c589 code: + + Written 1994 by Donald Becker. + Copyright 1993 United States Government as represented by the + Director, National Security Agency. This software may be used and + distributed according to the terms of the GNU Public License, + incorporated herein by reference. + Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov + +======================================================================*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/interrupt.h> +#include <linux/in.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/bitops.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/ioport.h> + +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/cisreg.h> +#include <pcmcia/ciscode.h> +#include <pcmcia/ds.h> + +/* To minimize the size of the driver source I only define operating + constants if they are used several times. You'll need the manual + if you want to understand driver details. */ +/* Offsets from base I/O address. */ +#define EL3_DATA 0x00 +#define EL3_TIMER 0x0a +#define EL3_CMD 0x0e +#define EL3_STATUS 0x0e + +#define EEPROM_READ 0x0080 +#define EEPROM_BUSY 0x8000 + +#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) + +/* The top five bits written to EL3_CMD are a command, the lower + 11 bits are the parameter, if applicable. */ +enum c509cmd { + TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, + RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11, + TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, + FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, + SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, + SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, + StatsDisable = 22<<11, StopCoax = 23<<11, +}; + +enum c509status { + IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, + TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, + IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000 +}; + +/* The SetRxFilter command accepts the following classes: */ +enum RxFilter { + RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 +}; + +/* Register window 1 offsets, the window used in normal operation. */ +#define TX_FIFO 0x00 +#define RX_FIFO 0x00 +#define RX_STATUS 0x08 +#define TX_STATUS 0x0B +#define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */ + +#define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */ +#define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */ +#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ +#define MEDIA_LED 0x0001 /* Enable link light on 3C589E cards. */ + +/* Time in jiffies before concluding Tx hung */ +#define TX_TIMEOUT ((400*HZ)/1000) + +struct el3_private { + dev_node_t node; + struct net_device_stats stats; + /* For transceiver monitoring */ + struct timer_list media; + u_short media_status; + u_short fast_poll; + u_long last_irq; +}; + +static char *if_names[] = { "auto", "10baseT", "10base2", "AUI" }; + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +static char *version = +"3c589_cs.c 1.134 1999/09/15 15:33:09 (David Hinds)"; +#else +#define DEBUG(n, args...) +#endif + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* Special hook for setting if_port when module is loaded */ +static int if_port = 0; + +/* Bit map of interrupts to choose from */ +static u_int irq_mask = 0xdeb8; +static int irq_list[4] = { -1 }; + +MODULE_PARM(if_port, "i"); +MODULE_PARM(irq_mask, "i"); +MODULE_PARM(irq_list, "1-4i"); + +/*====================================================================*/ + +static void tc589_config(dev_link_t *link); +static void tc589_release(u_long arg); +static int tc589_event(event_t event, int priority, + event_callback_args_t *args); + +static ushort read_eeprom(short ioaddr, int index); +static void tc589_reset(struct net_device *dev); +static void media_check(u_long arg); +static int el3_config(struct net_device *dev, struct ifmap *map); +static int el3_open(struct net_device *dev); +static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void update_stats(int addr, struct net_device *dev); +static struct net_device_stats *el3_get_stats(struct net_device *dev); +static int el3_rx(struct net_device *dev); +static int el3_close(struct net_device *dev); + +static void set_multicast_list(struct net_device *dev); + +static dev_info_t dev_info = "3c589_cs"; + +static dev_link_t *tc589_attach(void); +static void tc589_detach(dev_link_t *); + +static dev_link_t *dev_list = NULL; + +/*====================================================================== + + This bit of code is used to avoid unregistering network devices + at inappropriate times. 2.2 and later kernels are fairly picky + about when this can happen. + +======================================================================*/ + +static void flush_stale_links(void) +{ + dev_link_t *link, *next; + for (link = dev_list; link; link = next) { + next = link->next; + if (link->state & DEV_STALE_LINK) + tc589_detach(link); + } +} + +/*====================================================================*/ + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/*====================================================================== + + We never need to do anything when a tc589 device is "initialized" + by the net software, because we only register already-found cards. + +======================================================================*/ + +static int tc589_init(struct net_device *dev) +{ + return 0; +} + +/*====================================================================== + + tc589_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + +======================================================================*/ + +static dev_link_t *tc589_attach(void) +{ + client_reg_t client_reg; + dev_link_t *link; + struct net_device *dev; + int i, ret; + + DEBUG(0, "3c589_attach()\n"); + flush_stale_links(); + + /* Create new ethernet device */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + memset(link, 0, sizeof(struct dev_link_t)); + link->release.function = &tc589_release; + link->release.data = (u_long)link; + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->io.IOAddrLines = 4; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.Handler = &el3_interrupt; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + memset(dev, 0, sizeof(struct net_device)); + + /* Make up a EL3-specific-data structure. */ + dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL); + memset(dev->priv, 0, sizeof(struct el3_private)); + + /* The EL3-specific entries in the device structure. */ + dev->hard_start_xmit = &el3_start_xmit; + dev->set_config = &el3_config; + dev->get_stats = &el3_get_stats; + dev->set_multicast_list = &set_multicast_list; + ether_setup(dev); + dev->name = ((struct el3_private *)dev->priv)->node.dev_name; + dev->init = &tc589_init; + dev->open = &el3_open; + dev->stop = &el3_close; + dev->tbusy = 1; + link->priv = link->irq.Instance = dev; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &tc589_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != 0) { + cs_error(link->handle, RegisterClient, ret); + tc589_detach(link); + return NULL; + } + + return link; +} /* tc589_attach */ + +/*====================================================================== + + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. + +======================================================================*/ + +static void tc589_detach(dev_link_t *link) +{ + dev_link_t **linkp; + long flags; + + DEBUG(0, "3c589_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + save_flags(flags); + cli(); + if (link->state & DEV_RELEASE_PENDING) { + del_timer(&link->release); + link->state &= ~DEV_RELEASE_PENDING; + } + restore_flags(flags); + + if (link->state & DEV_CONFIG) { + tc589_release((u_long)link); + if (link->state & DEV_STALE_CONFIG) { + link->state |= DEV_STALE_LINK; + return; + } + } + + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, free bits */ + *linkp = link->next; + if (link->priv) { + struct net_device *dev = link->priv; + if (link->dev != NULL) + unregister_netdev(dev); + if (dev->priv) + kfree(dev->priv); + kfree(link->priv); + } + kfree(link); + +} /* tc589_detach */ + +/*====================================================================== + + tc589_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + ethernet device available to the system. + +======================================================================*/ + +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed + +static void tc589_config(dev_link_t *link) +{ + client_handle_t handle; + struct net_device *dev; + tuple_t tuple; + cisparse_t parse; + u_short buf[32]; + int last_fn, last_ret, i, j, multi = 0; + short ioaddr, *phys_addr; + char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + + handle = link->handle; + dev = link->priv; + phys_addr = (short *)dev->dev_addr; + + DEBUG(0, "3c589_config(0x%p)\n", link); + + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Is this a 3c562? */ + tuple.DesiredTuple = CISTPL_MANFID; + tuple.Attributes = TUPLE_RETURN_COMMON; + if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && + (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) { + if (le16_to_cpu(buf[0]) != MANFID_3COM) + printk(KERN_INFO "3c589_cs: hmmm, is this really a " + "3Com card??\n"); + multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562); + } + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* For the 3c562, the base address must be xx00-xx7f */ + for (i = j = 0; j < 0x400; j += 0x10) { + if (multi && (j & 0x80)) continue; + link->io.BasePort1 = j ^ 0x300; + i = CardServices(RequestIO, link->handle, &link->io); + if (i == CS_SUCCESS) break; + } + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestIO, i); + goto failed; + } + CS_CHECK(RequestIRQ, link->handle, &link->irq); + CS_CHECK(RequestConfiguration, link->handle, &link->conf); + + dev->irq = link->irq.AssignedIRQ; + dev->base_addr = link->io.BasePort1; + dev->tbusy = 0; + if (register_netdev(dev) != 0) { + printk(KERN_NOTICE "3c589_cs: register_netdev() failed\n"); + goto failed; + } + + link->state &= ~DEV_CONFIG_PENDING; + ioaddr = dev->base_addr; + EL3WINDOW(0); + + /* The 3c589 has an extra EEPROM for configuration info, including + the hardware address. The 3c562 puts the address in the CIS. */ + tuple.DesiredTuple = 0x88; + if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) { + CardServices(GetTupleData, handle, &tuple); + for (i = 0; i < 3; i++) + phys_addr[i] = htons(buf[i]); + } else { + for (i = 0; i < 3; i++) + phys_addr[i] = htons(read_eeprom(ioaddr, i)); + if (phys_addr[0] == 0x6060) { + printk(KERN_NOTICE "3c589_cs: IO port conflict at 0x%03lx" + "-0x%03lx\n", dev->base_addr, dev->base_addr+15); + goto failed; + } + } + + link->dev = &((struct el3_private *)dev->priv)->node; + + /* The address and resource configuration register aren't loaded from + the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. */ + outw(0x3f00, ioaddr + 8); + + /* The if_port symbol can be set when the module is loaded */ + if ((if_port >= 0) && (if_port <= 3)) + dev->if_port = if_port; + else + printk(KERN_NOTICE "3c589_cs: invalid if_port requested\n"); + + printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, hw_addr ", + dev->name, (multi ? "562" : "589"), dev->base_addr, + dev->irq); + for (i = 0; i < 6; i++) + printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + i = inl(ioaddr); + printk(KERN_INFO " %dK FIFO split %s Rx:Tx, %s xcvr\n", + (i & 7) ? 32 : 8, ram_split[(i >> 16) & 3], + if_names[dev->if_port]); + return; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + tc589_release((u_long)link); + return; + +} /* tc589_config */ + +/*====================================================================== + + After a card is removed, tc589_release() will unregister the net + device, and release the PCMCIA configuration. If the device is + still open, this will be postponed until it is closed. + +======================================================================*/ + +static void tc589_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *)arg; + + DEBUG(0, "3c589_release(0x%p)\n", link); + + if (link->open) { + DEBUG(1, "3c589_cs: release postponed, '%s' still open\n", + link->dev->dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + + link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); + +} /* tc589_release */ + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the net drivers from trying + to talk to the card any more. + +======================================================================*/ + +static int tc589_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + struct net_device *dev = link->priv; + + DEBUG(1, "3c589_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + dev->tbusy = 1; dev->start = 0; + link->release.expires = jiffies + HZ/20; + add_timer(&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + tc589_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) { + if (link->open) { + dev->tbusy = 1; dev->start = 0; + } + CardServices(ReleaseConfiguration, link->handle); + } + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) { + CardServices(RequestConfiguration, link->handle, &link->conf); + if (link->open) { + tc589_reset(dev); + dev->tbusy = 0; dev->start = 1; + } + } + break; + } + return 0; +} /* tc589_event */ + +/*====================================================================*/ + +/* + Use this for commands that may take time to finish +*/ +static void wait_for_completion(struct net_device *dev, int cmd) +{ + int i = 100; + outw(cmd, dev->base_addr + EL3_CMD); + while (--i > 0) + if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break; + if (i == 0) + printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", + dev->name, cmd); +} + +/* + Read a word from the EEPROM using the regular EEPROM access register. + Assume that we are in register window zero. +*/ +static ushort read_eeprom(short ioaddr, int index) +{ + int i; + outw(EEPROM_READ + index, ioaddr + 10); + /* Reading the eeprom takes 162 us */ + for (i = 1620; i >= 0; i--) + if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0) + break; + return inw(ioaddr + 12); +} + +/* + Set transceiver type, perhaps to something other than what the user + specified in dev->if_port. +*/ +static void tc589_set_xcvr(struct net_device *dev, int if_port) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + ushort ioaddr = dev->base_addr; + + EL3WINDOW(0); + switch (if_port) { + case 0: case 1: outw(0, ioaddr + 6); break; + case 2: outw(3<<14, ioaddr + 6); break; + case 3: outw(1<<14, ioaddr + 6); break; + } + /* On PCMCIA, this just turns on the LED */ + outw((if_port == 2) ? StartCoax : StopCoax, ioaddr + EL3_CMD); + /* 10baseT interface, enable link beat and jabber check. */ + EL3WINDOW(4); + outw(MEDIA_LED | ((if_port < 2) ? MEDIA_TP : 0), ioaddr + WN4_MEDIA); + EL3WINDOW(1); + if (if_port == 2) + lp->media_status = ((dev->if_port == 0) ? 0x8000 : 0x4000); + else + lp->media_status = ((dev->if_port == 0) ? 0x4010 : 0x8800); +} + +static void dump_status(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + EL3WINDOW(1); + printk(KERN_INFO " irq status %04x, rx status %04x, tx status " + "%02x tx free %04x\n", inw(ioaddr+EL3_STATUS), + inw(ioaddr+RX_STATUS), inb(ioaddr+TX_STATUS), + inw(ioaddr+TX_FREE)); + EL3WINDOW(4); + printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x" + " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06), + inw(ioaddr+0x08), inw(ioaddr+0x0a)); + EL3WINDOW(1); +} + +/* Reset and restore all of the 3c589 registers. */ +static void tc589_reset(struct net_device *dev) +{ + ushort ioaddr = dev->base_addr; + int i; + + EL3WINDOW(0); + outw(0x0001, ioaddr + 4); /* Activate board. */ + outw(0x3f00, ioaddr + 8); /* Set the IRQ line. */ + + /* Set the station address in window 2. */ + EL3WINDOW(2); + for (i = 0; i < 6; i++) + outb(dev->dev_addr[i], ioaddr + i); + + tc589_set_xcvr(dev, dev->if_port); + + /* Switch to the stats window, and clear all stats by reading. */ + outw(StatsDisable, ioaddr + EL3_CMD); + EL3WINDOW(6); + for (i = 0; i < 9; i++) + inb(ioaddr+i); + inw(ioaddr + 10); + inw(ioaddr + 12); + + /* Switch to register set 1 for normal use. */ + EL3WINDOW(1); + + /* Accept b-cast and phys addr only. */ + outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); + outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ + outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ + outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ + /* Allow status bits to be seen. */ + outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD); + /* Ack all pending events, and set active indicator mask. */ + outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, + ioaddr + EL3_CMD); + outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull + | AdapterFailure, ioaddr + EL3_CMD); +} + +static int el3_config(struct net_device *dev, struct ifmap *map) +{ + if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { + if (map->port <= 3) { + dev->if_port = map->port; + printk(KERN_INFO "%s: switched to %s port\n", + dev->name, if_names[dev->if_port]); + tc589_set_xcvr(dev, dev->if_port); + } else + return -EINVAL; + } + return 0; +} + +static int el3_open(struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + dev_link_t *link; + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (!DEV_OK(link)) + return -ENODEV; + + link->open++; + MOD_INC_USE_COUNT; + dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; + + tc589_reset(dev); + lp->media.function = &media_check; + lp->media.data = (u_long)dev; + lp->media.expires = jiffies + HZ; + add_timer(&lp->media); + + DEBUG(1, "%s: opened, status %4.4x.\n", + dev->name, inw(dev->base_addr + EL3_STATUS)); + + return 0; /* Always succeed */ +} + +static void el3_tx_timeout(struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + int ioaddr = dev->base_addr; + + printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name); + dump_status(dev); + lp->stats.tx_errors++; + dev->trans_start = jiffies; + /* Issue TX_RESET and TX_START commands. */ + wait_for_completion(dev, TxReset); + outw(TxEnable, ioaddr + EL3_CMD); + dev->tbusy = 0; +} + +static void pop_tx_status(struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + int ioaddr = dev->base_addr; + int i; + + /* Clear the Tx status stack. */ + for (i = 32; i > 0; i--) { + u_char tx_status = inb(ioaddr + TX_STATUS); + if (!(tx_status & 0x84)) break; + /* reset transmitter on jabber error or underrun */ + if (tx_status & 0x30) + wait_for_completion(dev, TxReset); + if (tx_status & 0x38) { + DEBUG(1, "%s: transmit error: status 0x%02x\n", + dev->name, tx_status); + outw(TxEnable, ioaddr + EL3_CMD); + lp->stats.tx_aborted_errors++; + } + outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */ + } +} + +static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + int ioaddr = dev->base_addr; + + /* Transmitter timeout, serious problems. */ + if (dev->tbusy) { + if (jiffies - dev->trans_start < TX_TIMEOUT) + return 1; + el3_tx_timeout(dev); + } + + DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " + "status %4.4x.\n", dev->name, (long)skb->len, + inw(ioaddr + EL3_STATUS)); + + /* Avoid timer-based retransmission conflicts. */ + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) + printk(KERN_NOTICE "%s: transmitter access conflict.\n", + dev->name); + else { + lp->stats.tx_bytes += skb->len; + /* Put out the doubleword header... */ + outw(skb->len, ioaddr + TX_FIFO); + outw(0x00, ioaddr + TX_FIFO); + /* ... and the packet rounded to a doubleword. */ + outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); + + dev->trans_start = jiffies; + if (inw(ioaddr + TX_FREE) > 1536) { + dev->tbusy = 0; + } else + /* Interrupt us when the FIFO has room for max-sized packet. */ + outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); + } + + dev_kfree_skb(skb); + pop_tx_status(dev); + + return 0; +} + +/* The EL3 interrupt handler. */ +static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *)dev_id; + struct el3_private *lp; + int ioaddr, status; + int i = 0; + + if ((dev == NULL) || !dev->start) + return; + lp = (struct el3_private *)dev->priv; + ioaddr = dev->base_addr; + +#ifdef PCMCIA_DEBUG + if (dev->interrupt) { + printk(KERN_NOTICE "%s: re-entering the interrupt handler.\n", + dev->name); + return; + } + dev->interrupt = 1; + DEBUG(3, "%s: interrupt, status %4.4x.\n", + dev->name, inw(ioaddr + EL3_STATUS)); +#endif + + while ((status = inw(ioaddr + EL3_STATUS)) & + (IntLatch | RxComplete | StatsFull)) { + if ((dev->start == 0) || ((status & 0xe000) != 0x2000)) { + DEBUG(1, "%s: interrupt from dead card\n", dev->name); + break; + } + + if (status & RxComplete) + el3_rx(dev); + + if (status & TxAvailable) { + DEBUG(3, " TX room bit was handled.\n"); + /* There's room in the FIFO for a full-sized packet. */ + outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); + dev->tbusy = 0; + mark_bh(NET_BH); + } + + if (status & TxComplete) + pop_tx_status(dev); + + if (status & (AdapterFailure | RxEarly | StatsFull)) { + /* Handle all uncommon interrupts. */ + if (status & StatsFull) /* Empty statistics. */ + update_stats(ioaddr, dev); + if (status & RxEarly) { /* Rx early is unused. */ + el3_rx(dev); + outw(AckIntr | RxEarly, ioaddr + EL3_CMD); + } + if (status & AdapterFailure) { + u16 fifo_diag; + EL3WINDOW(4); + fifo_diag = inw(ioaddr + 4); + EL3WINDOW(1); + printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic" + " register %04x.\n", dev->name, fifo_diag); + if (fifo_diag & 0x0400) { + /* Tx overrun */ + wait_for_completion(dev, TxReset); + outw(TxEnable, ioaddr + EL3_CMD); + } + if (fifo_diag & 0x2000) { + /* Rx underrun */ + wait_for_completion(dev, RxReset); + set_multicast_list(dev); + outw(RxEnable, ioaddr + EL3_CMD); + } + outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); + } + } + + if (++i > 10) { + printk(KERN_NOTICE "%s: infinite loop in interrupt, " + "status %4.4x.\n", dev->name, status); + /* Clear all interrupts */ + outw(AckIntr | 0xFF, ioaddr + EL3_CMD); + break; + } + /* Acknowledge the IRQ. */ + outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); + } + + lp->last_irq = jiffies; +#ifdef PCMCIA_DEBUG + DEBUG(3, "%s: exiting interrupt, status %4.4x.\n", + dev->name, inw(ioaddr + EL3_STATUS)); + dev->interrupt = 0; +#endif + return; +} + +static void media_check(u_long arg) +{ + struct net_device *dev = (struct net_device *)(arg); + struct el3_private *lp = (struct el3_private *)dev->priv; + int ioaddr = dev->base_addr; + u_short media, errs; + u_long flags; + + if (dev->start == 0) goto reschedule; + + EL3WINDOW(1); + /* Check for pending interrupt with expired latency timer: with + this, we can limp along even if the interrupt is blocked */ + if ((inw(ioaddr + EL3_STATUS) & IntLatch) && + (inb(ioaddr + EL3_TIMER) == 0xff)) { + if (!lp->fast_poll) + printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + el3_interrupt(dev->irq, dev, NULL); + lp->fast_poll = HZ; + } + if (lp->fast_poll) { + lp->fast_poll--; + lp->media.expires = jiffies + 1; + add_timer(&lp->media); + return; + } + + save_flags(flags); + cli(); + EL3WINDOW(4); + media = inw(ioaddr+WN4_MEDIA) & 0xc810; + + /* Ignore collisions unless we've had no irq's recently */ + if (jiffies - lp->last_irq < HZ) { + media &= ~0x0010; + } else { + /* Try harder to detect carrier errors */ + EL3WINDOW(6); + outw(StatsDisable, ioaddr + EL3_CMD); + errs = inb(ioaddr + 0); + outw(StatsEnable, ioaddr + EL3_CMD); + lp->stats.tx_carrier_errors += errs; + if (errs || (lp->media_status & 0x0010)) media |= 0x0010; + } + + if (media != lp->media_status) { + if ((media & lp->media_status & 0x8000) && + ((lp->media_status ^ media) & 0x0800)) + printk(KERN_INFO "%s: %s link beat\n", dev->name, + (lp->media_status & 0x0800 ? "lost" : "found")); + else if ((media & lp->media_status & 0x4000) && + ((lp->media_status ^ media) & 0x0010)) + printk(KERN_INFO "%s: coax cable %s\n", dev->name, + (lp->media_status & 0x0010 ? "ok" : "problem")); + if (dev->if_port == 0) { + if (media & 0x8000) { + if (media & 0x0800) + printk(KERN_INFO "%s: flipped to 10baseT\n", + dev->name); + else + tc589_set_xcvr(dev, 2); + } else if (media & 0x4000) { + if (media & 0x0010) + tc589_set_xcvr(dev, 1); + else + printk(KERN_INFO "%s: flipped to 10base2\n", + dev->name); + } + } + lp->media_status = media; + } + + EL3WINDOW(1); + restore_flags(flags); + +reschedule: + lp->media.expires = jiffies + HZ; + add_timer(&lp->media); +} + +static struct net_device_stats *el3_get_stats(struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + unsigned long flags; + dev_link_t *link; + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (DEV_OK(link)) { + save_flags(flags); + cli(); + update_stats(dev->base_addr, dev); + restore_flags(flags); + } + return &lp->stats; +} + +/* + Update statistics. We change to register window 6, so this should be run + single-threaded if the device is active. This is expected to be a rare + operation, and it's simpler for the rest of the driver to assume that + window 1 is always valid rather than use a special window-state variable. +*/ +static void update_stats(int ioaddr, struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + + DEBUG(2, "%s: updating the statistics.\n", dev->name); + /* Turn off statistics updates while reading. */ + outw(StatsDisable, ioaddr + EL3_CMD); + /* Switch to the stats window, and read everything. */ + EL3WINDOW(6); + lp->stats.tx_carrier_errors += inb(ioaddr + 0); + lp->stats.tx_heartbeat_errors += inb(ioaddr + 1); + /* Multiple collisions. */ inb(ioaddr + 2); + lp->stats.collisions += inb(ioaddr + 3); + lp->stats.tx_window_errors += inb(ioaddr + 4); + lp->stats.rx_fifo_errors += inb(ioaddr + 5); + lp->stats.tx_packets += inb(ioaddr + 6); + /* Rx packets */ inb(ioaddr + 7); + /* Tx deferrals */ inb(ioaddr + 8); + inw(ioaddr + 10); /* Total Rx and Tx octets. */ + inw(ioaddr + 12); + + /* Back to window 1, and turn statistics back on. */ + EL3WINDOW(1); + outw(StatsEnable, ioaddr + EL3_CMD); +} + +static int el3_rx(struct net_device *dev) +{ + struct el3_private *lp = (struct el3_private *)dev->priv; + int ioaddr = dev->base_addr; + int worklimit = 32; + short rx_status; + + DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", + dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); + while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && + (--worklimit >= 0)) { + if (rx_status & 0x4000) { /* Error, update stats. */ + short error = rx_status & 0x3800; + lp->stats.rx_errors++; + switch (error) { + case 0x0000: lp->stats.rx_over_errors++; break; + case 0x0800: lp->stats.rx_length_errors++; break; + case 0x1000: lp->stats.rx_frame_errors++; break; + case 0x1800: lp->stats.rx_length_errors++; break; + case 0x2000: lp->stats.rx_frame_errors++; break; + case 0x2800: lp->stats.rx_crc_errors++; break; + } + } else { + short pkt_len = rx_status & 0x7ff; + struct sk_buff *skb; + + skb = dev_alloc_skb(pkt_len+5); + + DEBUG(3, " Receiving packet size %d status %4.4x.\n", + pkt_len, rx_status); + if (skb != NULL) { + skb->dev = dev; + + skb_reserve(skb, 2); + insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len), + (pkt_len+3)>>2); + skb->protocol = eth_type_trans(skb, dev); + + netif_rx(skb); + lp->stats.rx_packets++; + lp->stats.rx_bytes += skb->len; + } else { + DEBUG(1, "%s: couldn't allocate a sk_buff of" + " size %d.\n", dev->name, pkt_len); + lp->stats.rx_dropped++; + } + } + /* Pop the top of the Rx FIFO */ + wait_for_completion(dev, RxDiscard); + } + if (worklimit == 0) + printk(KERN_NOTICE "%s: too much work in el3_rx!\n", dev->name); + return 0; +} + +/* Set or clear the multicast filter for this adapter. + num_addrs == -1 Promiscuous mode, receive all packets + num_addrs == 0 Normal mode, clear multicast list + num_addrs > 0 Multicast mode, receive normal and MC packets, and do + best-effort filtering. + */ +static void set_multicast_list(struct net_device *dev) +{ + short ioaddr = dev->base_addr; + dev_link_t *link; + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (!(DEV_OK(link))) return; +#ifdef PCMCIA_DEBUG + if (pc_debug > 2) { + static int old = 0; + if (old != dev->mc_count) { + old = dev->mc_count; + DEBUG(0, "%s: setting Rx mode to %d addresses.\n", + dev->name, old); + } + } +#endif + if (dev->flags & IFF_PROMISC) + outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, + ioaddr + EL3_CMD); + else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) + outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); + else + outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); +} + +static int el3_close(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + dev_link_t *link; + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (link == NULL) + return -ENODEV; + + DEBUG(1, "%s: shutting down ethercard.\n", dev->name); + + if (DEV_OK(link)) { + /* Turn off statistics ASAP. We update lp->stats below. */ + outw(StatsDisable, ioaddr + EL3_CMD); + + /* Disable the receiver and transmitter. */ + outw(RxDisable, ioaddr + EL3_CMD); + outw(TxDisable, ioaddr + EL3_CMD); + + if (dev->if_port == 2) + /* Turn off thinnet power. Green! */ + outw(StopCoax, ioaddr + EL3_CMD); + else if (dev->if_port == 1) { + /* Disable link beat and jabber */ + EL3WINDOW(4); + outw(0, ioaddr + WN4_MEDIA); + } + + /* Switching back to window 0 disables the IRQ. */ + EL3WINDOW(0); + /* But we explicitly zero the IRQ line select anyway. */ + outw(0x0f00, ioaddr + WN0_IRQ); + + /* Check if the card still exists */ + if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) + update_stats(ioaddr, dev); + } + + link->open--; + dev->start = 0; + del_timer(&((struct el3_private *)dev->priv)->media); + if (link->state & DEV_STALE_CONFIG) { + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + + MOD_DEC_USE_COUNT; + + return 0; +} + +/*====================================================================*/ + +static int __init init_3c589_cs(void) +{ + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "3c589_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &tc589_attach, &tc589_detach); + return 0; +} + +static void __exit exit_3c589_cs(void) +{ + DEBUG(0, "3c589_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + tc589_detach(dev_list); +} + +module_init(init_3c589_cs); +module_exit(exit_3c589_cs); diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in new file mode 100644 index 000000000..cc4efbf88 --- /dev/null +++ b/drivers/net/pcmcia/Config.in @@ -0,0 +1,16 @@ +# +# PCMCIA Network device configuration +# + +mainmenu_option next_comment +comment 'PCMCIA network devices' + +dep_tristate 'PCMCIA ethernet cards (NE2000 compatibles: DE-650, ...)' CONFIG_PCMCIA_PCNET $CONFIG_PCMCIA +dep_tristate '3Com 3c589 PCMCIA card' CONFIG_PCMCIA_3C589 $CONFIG_PCMCIA +dep_tristate 'Aviator/Raytheon 2.4MHz wireless' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA + +if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_RAYCS" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" ]; then + define_bool CONFIG_PCMCIA_NETCARD y +fi + +endmenu diff --git a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile new file mode 100644 index 000000000..3b59b1b93 --- /dev/null +++ b/drivers/net/pcmcia/Makefile @@ -0,0 +1,40 @@ +# +# drivers/net/pcmcia/Makefile +# +# Makefile for the Linux PCMCIA network device drivers. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + +O_TARGET := pcmcia_net.o +O_OBJS := +M_OBJS := +MOD_LIST_NAME := PCMCIA_MODULES + +ifeq ($(CONFIG_PCMCIA_PCNET),y) + O_OBJS += pcnet_cs.o +else + ifeq ($(CONFIG_PCMCIA_PCNET),m) + MX_OBJS += pcnet_cs.o + endif +endif + +ifeq ($(CONFIG_PCMCIA_3C589),y) + O_OBJS += 3c589_cs.o +else + ifeq ($(CONFIG_PCMCIA_3C589),m) + MX_OBJS += 3c589_cs.o + endif +endif + +ifeq ($(CONFIG_PCMCIA_RAYCS),y) + OX_OBJS += ray_cs.o +else + ifeq ($(CONFIG_PCMCIA_RAYCS),m) + MX_OBJS += ray_cs.o + endif +endif + +include $(TOPDIR)/Rules.make diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c new file mode 100644 index 000000000..f5d4b3c49 --- /dev/null +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -0,0 +1,1403 @@ +/*====================================================================== + + A PCMCIA ethernet driver for NS8390-based cards + + This driver supports the D-Link DE-650 and Linksys EthernetCard + cards, the newer D-Link and Linksys combo cards, Accton EN2212 + cards, the RPTI EP400, and the PreMax PE-200 in non-shared-memory + mode, and the IBM Credit Card Adapter, the NE4100, the Thomas + Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory + mode. It will also handle the Socket EA card in either mode. + + Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu + + pcnet_cs.c 1.99 1999/09/15 15:33:09 + + The network driver code is based on Donald Becker's NE2000 code: + + Written 1992,1993 by Donald Becker. + Copyright 1993 United States Government as represented by the + Director, National Security Agency. This software may be used and + distributed according to the terms of the GNU Public License, + incorporated herein by reference. + Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov + + Based also on Keith Moore's changes to Don Becker's code, for IBM + CCAE support. Drivers merged back together, and shared-memory + Socket EA support added, by Ken Raeburn, September 1995. + +======================================================================*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <asm/system.h> + +#include <linux/netdevice.h> +#include <../drivers/net/8390.h> + +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/ciscode.h> +#include <pcmcia/ds.h> +#include <pcmcia/cisreg.h> + +#define PCNET_CMD 0x00 +#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ +#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ +#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ + +#define PCNET_START_PG 0x40 /* First page of TX buffer */ +#define PCNET_STOP_PG 0x80 /* Last page +1 of RX ring */ + +/* Socket EA cards have a larger packet buffer */ +#define SOCKET_START_PG 0x01 +#define SOCKET_STOP_PG 0xff + +#define PCNET_RDC_TIMEOUT 0x02 /* Max wait in jiffies for Tx RDC */ + +static char *if_names[] = { "auto", "10baseT", "10base2"}; + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +static char *version = +"pcnet_cs.c 1.99 1999/09/15 15:33:09 (David Hinds)"; +#else +#define DEBUG(n, args...) +#endif + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* Bit map of interrupts to choose from */ +static u_int irq_mask = 0xdeb8; +static int irq_list[4] = { -1 }; + +/* Transceiver type, for Socket EA and IBM CC cards. */ +static int if_port = 1; + +/* Use 64K packet buffer, for Socket EA cards. */ +static int use_big_buf = 1; + +/* Shared memory speed, in ns */ +static int mem_speed = 0; + +/* Insert a pause in block_output after sending a packet */ +static int delay_output = 0; + +/* Length of delay, in microseconds */ +static int delay_time = 4; + +/* Use shared memory, if available? */ +static int use_shmem = -1; + +/* Ugh! Let the user hardwire the hardware address for queer cards */ +static int hw_addr[6] = { 0, /* ... */ }; + +MODULE_PARM(irq_mask, "i"); +MODULE_PARM(irq_list, "1-4i"); +MODULE_PARM(if_port, "i"); +MODULE_PARM(use_big_buf, "i"); +MODULE_PARM(mem_speed, "i"); +MODULE_PARM(delay_output, "i"); +MODULE_PARM(delay_time, "i"); +MODULE_PARM(use_shmem, "i"); +MODULE_PARM(hw_addr, "6i"); + +/*====================================================================*/ + +static void pcnet_config(dev_link_t *link); +static void pcnet_release(u_long arg); +static int pcnet_event(event_t event, int priority, + event_callback_args_t *args); + +static int pcnet_open(struct net_device *dev); +static int pcnet_close(struct net_device *dev); +static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); +static void ei_watchdog(u_long arg); + +static void pcnet_reset_8390(struct net_device *dev); + +static int set_config(struct net_device *dev, struct ifmap *map); + +static int setup_shmem_window(dev_link_t *link, int start_pg, + int stop_pg, int cm_offset); +static int setup_dma_config(dev_link_t *link, int start_pg, + int stop_pg); + +static dev_info_t dev_info = "pcnet_cs"; + +static dev_link_t *pcnet_attach(void); +static void pcnet_detach(dev_link_t *); + +static dev_link_t *dev_list; + +/*====================================================================*/ + +typedef struct hw_info_t { + u_long offset; + u_char a0, a1, a2; + u_long flags; +} hw_info_t; + +#define DELAY_OUTPUT 0x01 +#define HAS_MISC_REG 0x02 +#define USE_BIG_BUF 0x04 +#define HAS_IBM_MISC 0x08 +#define IS_DL10019A 0x10 +#define USE_SHMEM 0x80 /* autodetected */ + +static hw_info_t hw_info[] = { + { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, + { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, + { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, + { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, + DELAY_OUTPUT | HAS_IBM_MISC }, + { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, + { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, + { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, + { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, + { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, + { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, + { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, + { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, + { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, + { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, + { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, + { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, + { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, + { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, + { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, + HAS_MISC_REG | HAS_IBM_MISC }, + { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, + { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, + { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, + { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, + DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, + { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, + { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 } +}; + +#define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) + +static hw_info_t default_info = +{ /* Unknown NE2000 Clone */ 0x00, 0x00, 0x00, 0x00, 0 }; +static hw_info_t dl_fast_info = +{ /* D-Link EtherFast */ 0x00, 0x00, 0x00, 0x00, IS_DL10019A }; + +typedef struct pcnet_dev_t { + struct net_device dev; + dev_node_t node; + u_long flags; + caddr_t base; + struct timer_list watchdog; + int stale; + u_short fast_poll; +} pcnet_dev_t; + +/*====================================================================== + + This bit of code is used to avoid unregistering network devices + at inappropriate times. 2.2 and later kernels are fairly picky + about when this can happen. + +======================================================================*/ + +static void flush_stale_links(void) +{ + dev_link_t *link, *next; + for (link = dev_list; link; link = next) { + next = link->next; + if (link->state & DEV_STALE_LINK) + pcnet_detach(link); + } +} + +/*====================================================================*/ + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/*====================================================================== + + We never need to do anything when a pcnet device is "initialized" + by the net software, because we only register already-found cards. + +======================================================================*/ + +static int pcnet_init(struct net_device *dev) +{ + return 0; +} + +/*====================================================================== + + pcnet_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + +======================================================================*/ + +static dev_link_t *pcnet_attach(void) +{ + client_reg_t client_reg; + dev_link_t *link; + pcnet_dev_t *info; + struct net_device *dev; + int i, ret; + + DEBUG(0, "pcnet_attach()\n"); + flush_stale_links(); + + /* Create new ethernet device */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + memset(link, 0, sizeof(struct dev_link_t)); + link->release.function = &pcnet_release; + link->release.data = (u_long)link; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + + info = kmalloc(sizeof(struct pcnet_dev_t), GFP_KERNEL); + memset(info, 0, sizeof(struct pcnet_dev_t)); + dev = &info->dev; + ethdev_init(dev); + dev->name = info->node.dev_name; + dev->init = &pcnet_init; + dev->open = &pcnet_open; + dev->stop = &pcnet_close; + dev->set_config = &set_config; + dev->tbusy = 1; + link->priv = info; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &pcnet_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + pcnet_detach(link); + return NULL; + } + + return link; +} /* pcnet_attach */ + +/*====================================================================== + + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. + +======================================================================*/ + +static void pcnet_detach(dev_link_t *link) +{ + dev_link_t **linkp; + long flags; + + DEBUG(0, "pcnet_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + save_flags(flags); + cli(); + if (link->state & DEV_RELEASE_PENDING) { + del_timer(&link->release); + link->state &= ~DEV_RELEASE_PENDING; + } + restore_flags(flags); + + if (link->state & DEV_CONFIG) { + pcnet_release((u_long)link); + if (link->state & DEV_STALE_CONFIG) { + link->state |= DEV_STALE_LINK; + return; + } + } + + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, free bits */ + *linkp = link->next; + if (link->priv) { + struct net_device *dev = link->priv; + if (link->dev != NULL) + unregister_netdev(dev); + if (dev->priv) + kfree_s(dev->priv, sizeof(struct ei_device)); + kfree_s(dev, sizeof(struct pcnet_dev_t)); + } + kfree_s(link, sizeof(struct dev_link_t)); + +} /* pcnet_detach */ + +/*====================================================================== + + For the Linksys EtherFast 10/100 card + +======================================================================*/ + +static hw_info_t *get_dl_fast(dev_link_t *link) +{ + struct net_device *dev = link->priv; + int i; + u_char sum; + + for (sum = 0, i = 0x14; i < 0x1c; i++) + sum += inb_p(dev->base_addr + i); + if (sum != 0xff) + return NULL; + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i); + return &dl_fast_info; +} + +/*====================================================================== + + This probes for a card's hardware address, for card types that + encode this information in their CIS. + +======================================================================*/ + +static hw_info_t *get_hwinfo(dev_link_t *link) +{ + struct net_device *dev = link->priv; + win_req_t req; + memreq_t mem; + u_char *base, *virt; + int i, j; + + /* Allocate a small memory window */ + req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; + req.Base = 0; req.Size = 0; + req.AccessSpeed = 0; + link->win = (window_handle_t)link->handle; + i = CardServices(RequestWindow, &link->win, &req); + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestWindow, i); + return NULL; + } + + virt = ioremap(req.Base, req.Size); + mem.Page = 0; + for (i = 0; i < NR_INFO; i++) { + mem.CardOffset = hw_info[i].offset & ~(req.Size-1); + CardServices(MapMemPage, link->win, &mem); + base = &virt[hw_info[i].offset & (req.Size-1)]; + if ((readb(base+0) == hw_info[i].a0) && + (readb(base+2) == hw_info[i].a1) && + (readb(base+4) == hw_info[i].a2)) + break; + } + if (i < NR_INFO) { + for (j = 0; j < 6; j++) + dev->dev_addr[j] = readb(base + (j<<1)); + } + + iounmap(virt); + j = CardServices(ReleaseWindow, link->win); + if (j != CS_SUCCESS) + cs_error(link->handle, ReleaseWindow, j); + return (i < NR_INFO) ? hw_info+i : NULL; +} /* get_hwinfo */ + +/*====================================================================== + + This probes for a card's hardware address by reading the PROM. + It checks the address against a list of known types, then falls + back to a simple NE2000 clone signature check. + +======================================================================*/ + +static hw_info_t *get_prom(dev_link_t *link) +{ + struct net_device *dev = link->priv; + unsigned char prom[32]; + int i, j, ioaddr; + + /* This is lifted straight from drivers/net/ne.c */ + struct { + unsigned char value, offset; + } program_seq[] = { + {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ + {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ + {0x00, EN0_RCNTLO}, /* Clear the count regs. */ + {0x00, EN0_RCNTHI}, + {0x00, EN0_IMR}, /* Mask completion irq. */ + {0xFF, EN0_ISR}, + {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ + {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ + {32, EN0_RCNTLO}, + {0x00, EN0_RCNTHI}, + {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ + {0x00, EN0_RSARHI}, + {E8390_RREAD+E8390_START, E8390_CMD}, + }; + + ioaddr = dev->base_addr; + + pcnet_reset_8390(dev); + udelay(10000); + + for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) + outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); + + for (i = 0; i < 32; i++) + prom[i] = inb(ioaddr + PCNET_DATAPORT); + for (i = 0; i < NR_INFO; i++) { + if ((prom[0] == hw_info[i].a0) && + (prom[2] == hw_info[i].a1) && + (prom[4] == hw_info[i].a2)) + break; + } + if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { + for (j = 0; j < 6; j++) + dev->dev_addr[j] = prom[j<<1]; + return (i < NR_INFO) ? hw_info+i : &default_info; + } + return NULL; +} /* get_prom */ + +/*====================================================================== + + This should be totally unnecessary... but when we can't figure + out the hardware address any other way, we'll let the user hard + wire it when the module is initialized. + +======================================================================*/ + +static hw_info_t *get_hwired(dev_link_t *link) +{ + struct net_device *dev = link->priv; + int i; + + for (i = 0; i < 6; i++) + if (hw_addr[i] != 0) break; + if (i == 6) + return NULL; + + for (i = 0; i < 6; i++) + dev->dev_addr[i] = hw_addr[i]; + + return &default_info; +} /* get_hwired */ + +/*====================================================================== + + pcnet_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + ethernet device available to the system. + +======================================================================*/ + +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed + +#define CFG_CHECK(fn, args...) \ +if (CardServices(fn, args) != 0) goto next_entry + +static int try_io_port(dev_link_t *link) +{ + int j, ret; + if (link->io.NumPorts1 == 32) { + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (link->io.NumPorts2 > 0) { + /* for master/slave multifunction cards */ + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->irq.Attributes = + IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + } + } else { + /* This should be two 16-port windows */ + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; + } + if (link->io.BasePort1 == 0) { + for (j = 0; j < 0x400; j += 0x20) { + link->io.BasePort1 = j ^ 0x300; + link->io.BasePort2 = (j ^ 0x300) + 0x10; + ret = CardServices(RequestIO, link->handle, &link->io); + if (ret == CS_SUCCESS) return ret; + } + return ret; + } else { + return CardServices(RequestIO, link->handle, &link->io); + } +} + +static void pcnet_config(dev_link_t *link) +{ + client_handle_t handle; + tuple_t tuple; + cisparse_t parse; + pcnet_dev_t *info; + struct net_device *dev; + int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; + int manfid = 0, prodid = 0, has_shmem = 0; + u_short buf[64]; + hw_info_t *hw_info; + + handle = link->handle; + info = link->priv; + dev = &info->dev; + + DEBUG(0, "pcnet_config(0x%p)\n", link); + + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + tuple.DesiredTuple = CISTPL_MANFID; + tuple.Attributes = TUPLE_RETURN_COMMON; + if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && + (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) { + manfid = le16_to_cpu(buf[0]); + prodid = le16_to_cpu(buf[1]); + } + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, handle, &tuple); + while (last_ret == CS_SUCCESS) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + cistpl_io_t *io = &(parse.cftable_entry.io); + + CFG_CHECK(GetTupleData, handle, &tuple); + CFG_CHECK(ParseTuple, handle, &tuple, &parse); + if ((cfg->index == 0) || (cfg->io.nwin == 0)) + goto next_entry; + + link->conf.ConfigIndex = cfg->index; + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + link->io.BasePort2 = io->win[1-i].base; + link->io.NumPorts2 = io->win[1-i].len; + } else { + i = link->io.NumPorts2 = 0; + } + has_shmem = ((cfg->mem.nwin == 1) && + (cfg->mem.win[0].len >= 0x4000)); + link->io.BasePort1 = io->win[i].base; + link->io.NumPorts1 = io->win[i].len; + if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { + last_ret = try_io_port(link); + if (last_ret == CS_SUCCESS) break; + } + next_entry: + last_ret = CardServices(GetNextTuple, handle, &tuple); + } + if (last_ret != CS_SUCCESS) { + cs_error(handle, RequestIO, last_ret); + goto failed; + } + + CS_CHECK(RequestIRQ, handle, &link->irq); + + if (link->io.NumPorts2 == 8) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + if ((manfid == MANFID_IBM) && + (prodid == PRODID_IBM_HOME_AND_AWAY)) + link->conf.ConfigIndex |= 0x10; + + CS_CHECK(RequestConfiguration, handle, &link->conf); + dev->irq = link->irq.AssignedIRQ; + dev->base_addr = link->io.BasePort1; + if ((if_port == 1) || (if_port == 2)) + dev->if_port = if_port; + else + printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n"); + dev->tbusy = 0; + if (register_netdev(dev) != 0) { + printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); + goto failed; + } + + hw_info = get_hwinfo(link); + if (hw_info == NULL) + hw_info = get_prom(link); + if (hw_info == NULL) + hw_info = get_dl_fast(link); + if (hw_info == NULL) + hw_info = get_hwired(link); + + if (hw_info == NULL) { + printk(KERN_NOTICE "pcnet_cs: unable to read hardware net address\n"); + goto config_undo; + } + + info->flags = hw_info->flags; + /* Check for user overrides */ + info->flags |= (delay_output) ? DELAY_OUTPUT : 0; + if ((manfid == MANFID_SOCKET) && (prodid == PRODID_SOCKET_LPE)) + info->flags &= ~USE_BIG_BUF; + if (!use_big_buf) + info->flags &= ~USE_BIG_BUF; + + if (info->flags & USE_BIG_BUF) { + start_pg = SOCKET_START_PG; + stop_pg = SOCKET_STOP_PG; + cm_offset = 0x10000; + } else { + start_pg = PCNET_START_PG; + stop_pg = PCNET_STOP_PG; + cm_offset = 0; + } + + /* has_shmem is ignored if use_shmem != -1 */ + if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) || + (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0)) + setup_dma_config(link, start_pg, stop_pg); + + ei_status.name = "NE2000"; + ei_status.word16 = 1; + ei_status.reset_8390 = &pcnet_reset_8390; + + link->dev = &info->node; + link->state &= ~DEV_CONFIG_PENDING; + + printk(KERN_INFO "%s: NE2000 Compatible: io %#3lx, irq %d,", + dev->name, dev->base_addr, dev->irq); + if (info->flags & USE_SHMEM) + printk (" mem %#5lx,", dev->mem_start); + if (info->flags & HAS_MISC_REG) + printk(" %s xcvr,", if_names[dev->if_port]); + printk(" hw_addr "); + for (i = 0; i < 6; i++) + printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + return; + +config_undo: + unregister_netdev(dev); + goto failed; +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + pcnet_release((u_long)link); + return; +} /* pcnet_config */ + +/*====================================================================== + + After a card is removed, pcnet_release() will unregister the net + device, and release the PCMCIA configuration. If the device is + still open, this will be postponed until it is closed. + +======================================================================*/ + +static void pcnet_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *)arg; + pcnet_dev_t *info = link->priv; + + DEBUG(0, "pcnet_release(0x%p)\n", link); + + if (link->open) { + DEBUG(1, "pcnet_cs: release postponed, '%s' still open\n", + info->node.dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + + if (info->flags & USE_SHMEM) { + iounmap(info->base); + CardServices(ReleaseWindow, link->win); + } + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + + link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); + +} /* pcnet_release */ + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the net drivers from trying + to talk to the card any more. + +======================================================================*/ + +static int pcnet_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + pcnet_dev_t *info = link->priv; + + DEBUG(2, "pcnet_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + info->dev.tbusy = 1; info->dev.start = 0; + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT; + pcnet_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) { + if (link->open) { + info->dev.tbusy = 1; info->dev.start = 0; + } + CardServices(ReleaseConfiguration, link->handle); + } + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) { + CardServices(RequestConfiguration, link->handle, &link->conf); + if (link->open) { + pcnet_reset_8390(&info->dev); + NS8390_init(&info->dev, 1); + info->dev.tbusy = 0; info->dev.start = 1; + } + } + break; + } + return 0; +} /* pcnet_event */ + +/*====================================================================*/ + +static void set_misc_reg(struct net_device *dev) +{ + int nic_base = dev->base_addr; + pcnet_dev_t *info = (pcnet_dev_t *)dev; + u_char tmp; + + if (info->flags & HAS_MISC_REG) { + tmp = inb_p(nic_base + PCNET_MISC) & ~3; + if (dev->if_port == 2) + tmp |= 1; + if (info->flags & USE_BIG_BUF) + tmp |= 2; + if (info->flags & HAS_IBM_MISC) + tmp |= 8; + outb_p(tmp, nic_base + PCNET_MISC); + } +} + +/*====================================================================*/ + +static int pcnet_open(struct net_device *dev) +{ + pcnet_dev_t *info = (pcnet_dev_t *)dev; + dev_link_t *link; + + DEBUG(2, "pcnet_open('%s')\n", dev->name); + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (!DEV_OK(link)) + return -ENODEV; + + link->open++; + MOD_INC_USE_COUNT; + + /* For D-Link EtherFast, wait for something(?) to happen */ + if (info->flags & IS_DL10019A) { + int i; + for (i = 0; i < 20; i++) { + if ((inb(dev->base_addr+0x1c) & 0x01) == 0) break; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/10); + } + } + + set_misc_reg(dev); + request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); + + info->watchdog.function = &ei_watchdog; + info->watchdog.data = (u_long)info; + info->watchdog.expires = jiffies + HZ; + add_timer(&info->watchdog); + + return ei_open(dev); +} /* pcnet_open */ + +/*====================================================================*/ + +static int pcnet_close(struct net_device *dev) +{ + dev_link_t *link; + + DEBUG(2, "pcnet_close('%s')\n", dev->name); + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (link == NULL) + return -ENODEV; + free_irq(dev->irq, dev); + + link->open--; dev->start = 0; + del_timer(&((pcnet_dev_t *)dev)->watchdog); + if (link->state & DEV_STALE_CONFIG) { + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + + MOD_DEC_USE_COUNT; + + return 0; +} /* pcnet_close */ + +/*====================================================================== + + Hard reset the card. This used to pause for the same period that + a 8390 reset command required, but that shouldn't be necessary. + +======================================================================*/ + +static void pcnet_reset_8390(struct net_device *dev) +{ + int nic_base = dev->base_addr; + int i; + + ei_status.txing = ei_status.dmaing = 0; + + outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET); + + for (i = 0; i < 100; i++) { + if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) + break; + udelay(100L); + } + outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ + + if (i == 100) + printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n", + dev->name); + set_misc_reg(dev); + +} /* pcnet_reset_8390 */ + +/* ======================================================================= */ + +static int set_config(struct net_device *dev, struct ifmap *map) +{ + pcnet_dev_t *info = (pcnet_dev_t *)dev; + if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { + if ((map->port != 0) && !(info->flags & HAS_MISC_REG)) { + printk(KERN_NOTICE "%s: transceiver selection not " + "implemented\n", dev->name); + return -EINVAL; + } + if ((map->port == 1) || (map->port == 2)) { + dev->if_port = map->port; + printk(KERN_INFO "%s: switched to %s port\n", + dev->name, if_names[dev->if_port]); + } else + return -EINVAL; + } + return 0; +} + +/* ======================================================================= */ + +static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs) +{ + pcnet_dev_t *info = dev_id; + info->stale = 0; + ei_interrupt(irq, dev_id, regs); +} + +static void ei_watchdog(u_long arg) +{ + pcnet_dev_t *info = (pcnet_dev_t *)(arg); + struct net_device *dev = &info->dev; + int nic_base = dev->base_addr; + + if (dev->start == 0) goto reschedule; + + /* Check for pending interrupt with expired latency timer: with + this, we can limp along even if the interrupt is blocked */ + outb_p(E8390_NODMA+E8390_PAGE0, nic_base + E8390_CMD); + if (info->stale++ && inb_p(nic_base + EN0_ISR)) { + if (!info->fast_poll) + printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + ei_irq_wrapper(dev->irq, dev, NULL); + info->fast_poll = HZ; + } + if (info->fast_poll) { + info->fast_poll--; + info->watchdog.expires = jiffies + 1; + add_timer(&info->watchdog); + return; + } + +reschedule: + info->watchdog.expires = jiffies + HZ; + add_timer(&info->watchdog); +} + +/* ======================================================================= */ + +static void dma_get_8390_hdr(struct net_device *dev, + struct e8390_pkt_hdr *hdr, + int ring_page) +{ + int nic_base = dev->base_addr; + + if (ei_status.dmaing) { + printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + (long)dev->interrupt); + return; + } + + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); + outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); + outb_p(0, nic_base + EN0_RCNTHI); + outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ + outb_p(ring_page, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); + + insw(nic_base + PCNET_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)>>1); + /* Fix for big endian systems */ + hdr->count = le16_to_cpu(hdr->count); + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +/* ======================================================================= */ + +static void dma_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset) +{ + int nic_base = dev->base_addr; + int xfer_count = count; + char *buf = skb->data; + +#ifdef PCMCIA_DEBUG + if ((ei_debug > 4) && (count != 4)) + printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4); +#endif + if (ei_status.dmaing) { + printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + (long)dev->interrupt); + return; + } + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); + outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); + + insw(nic_base + PCNET_DATAPORT,buf,count>>1); + if (count & 0x01) + buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++; + + /* This was for the ALPHA version only, but enough people have + encountering problems that it is still here. */ +#ifdef PCMCIA_DEBUG + if (ei_debug > 4) { /* DMA termination address check... */ + int addr, tries = 20; + do { + /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here + -- it's broken for Rx on some cards! */ + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff)) + break; + } while (--tries > 0); + if (tries <= 0) + printk(KERN_NOTICE "%s: RX transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, ring_offset + xfer_count, addr); + } +#endif + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} /* dma_block_input */ + +/*====================================================================*/ + +static void dma_block_output(struct net_device *dev, int count, + const unsigned char *buf, + const int start_page) +{ + int nic_base = dev->base_addr; + pcnet_dev_t *info = (pcnet_dev_t *)dev; +#ifdef PCMCIA_DEBUG + int retries = 0; +#endif + u_long dma_start; + +#ifdef PCMCIA_DEBUG + if (ei_debug > 4) + printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count); +#endif + + /* Round the count up for word writes. Do we need to do this? + What effect will an odd byte count have on the 8390? + I should check someday. */ + if (count & 0x01) + count++; + if (ei_status.dmaing) { + printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output." + "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + (long)dev->interrupt); + return; + } + ei_status.dmaing |= 0x01; + /* We should already be in page 0, but to be safe... */ + outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD); + +#ifdef PCMCIA_DEBUG + retry: +#endif + + outb_p(ENISR_RDC, nic_base + EN0_ISR); + + /* Now the normal output. */ + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(0x00, nic_base + EN0_RSARLO); + outb_p(start_page, nic_base + EN0_RSARHI); + + outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD); + outsw(nic_base + PCNET_DATAPORT, buf, count>>1); + + dma_start = jiffies; + +#ifdef PCMCIA_DEBUG + /* This was for the ALPHA version only, but enough people have + encountering problems that it is still here. */ + if (ei_debug > 4) { /* DMA termination address check... */ + int addr, tries = 20; + do { + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if ((start_page << 8) + count == addr) + break; + } while (--tries > 0); + if (tries <= 0) { + printk(KERN_NOTICE "%s: Tx packet transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, (start_page << 8) + count, addr); + if (retries++ == 0) + goto retry; + } + } +#endif + + while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) + if (jiffies - dma_start > PCNET_RDC_TIMEOUT) { + printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n", + dev->name); + pcnet_reset_8390(dev); + NS8390_init(dev, 1); + break; + } + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + if (info->flags & DELAY_OUTPUT) + udelay((long)delay_time); + ei_status.dmaing &= ~0x01; +} + +/*====================================================================*/ + +static int setup_dma_config(dev_link_t *link, int start_pg, + int stop_pg) +{ + struct net_device *dev = link->priv; + + ei_status.tx_start_page = start_pg; + ei_status.rx_start_page = start_pg + TX_PAGES; + ei_status.stop_page = stop_pg; + + /* set up block i/o functions */ + ei_status.get_8390_hdr = &dma_get_8390_hdr; + ei_status.block_input = &dma_block_input; + ei_status.block_output = &dma_block_output; + + return 0; +} + +/*====================================================================*/ + +static void copyin(unsigned char *dest, unsigned char *src, int c) +{ + unsigned short *d = (unsigned short *) dest; + unsigned short *s = (unsigned short *) src; + int odd; + + if (c <= 0) + return; + odd = (c & 01); c >>= 1; + + if (c) { + do { *d++ = __raw_readw(s++); } while (--c); + } + /* get last byte by fetching a word and masking */ + if (odd) + *((unsigned char *)d) = readw(s) & 0xff; +} + +static void copyout(unsigned char *dest, const unsigned char *src, int c) +{ + volatile unsigned short *d = (unsigned short *) dest; + unsigned short *s = (unsigned short *) src; + int odd; + + if (c <= 0) + return; + odd = (c & 01); c >>= 1; + + if (c) { + do { __raw_writew(*s++, d++); } while (--c); + } + /* copy last byte doing a read-modify-write */ + if (odd) + writew((readw(d) & 0xff00) | *(u_char *)s, d); +} + +/*====================================================================*/ + +static void shmem_get_8390_hdr(struct net_device *dev, + struct e8390_pkt_hdr *hdr, + int ring_page) +{ + void *xfer_start = (void *)(dev->rmem_start + (ring_page << 8) + - (ei_status.rx_start_page << 8)); + + copyin((void *)hdr, xfer_start, sizeof(struct e8390_pkt_hdr)); + /* Fix for big endian systems */ + hdr->count = le16_to_cpu(hdr->count); +} + +/*====================================================================*/ + +static void shmem_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset) +{ + void *xfer_start = (void *)(dev->rmem_start + ring_offset + - (ei_status.rx_start_page << 8)); + char *buf = skb->data; + + if (xfer_start + count > (void *)dev->rmem_end) { + /* We must wrap the input move. */ + int semi_count = (void*)dev->rmem_end - xfer_start; + copyin(buf, xfer_start, semi_count); + buf += semi_count; + ring_offset = ei_status.rx_start_page << 8; + xfer_start = (void *)dev->rmem_start; + count -= semi_count; + } + copyin(buf, xfer_start, count); +} + +/*====================================================================*/ + +static void shmem_block_output(struct net_device *dev, int count, + const unsigned char *buf, + const int start_page) +{ + void *shmem = (void *)dev->mem_start + (start_page << 8); + shmem -= ei_status.tx_start_page << 8; + + if (ei_debug > 4) + printk(KERN_DEBUG "[bo=%d @ %x]\n", count, start_page); + + copyout(shmem, buf, count); +} + +/*====================================================================*/ + +static int setup_shmem_window(dev_link_t *link, int start_pg, + int stop_pg, int cm_offset) +{ + struct net_device *dev = link->priv; + pcnet_dev_t *info = link->priv; + win_req_t req; + memreq_t mem; + int i, window_size, offset, last_ret, last_fn; + + window_size = (stop_pg - start_pg) << 8; + if (window_size > 32 * 1024) + window_size = 32 * 1024; + + /* Make sure it's a power of two. */ + while ((window_size & (window_size - 1)) != 0) + window_size += window_size & ~(window_size - 1); + + /* Allocate a memory window */ + req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; + req.Attributes |= WIN_USE_WAIT; + req.Base = 0; req.Size = window_size; + req.AccessSpeed = mem_speed; + link->win = (window_handle_t)link->handle; + CS_CHECK(RequestWindow, &link->win, &req); + + mem.CardOffset = (start_pg << 8) + cm_offset; + offset = mem.CardOffset % window_size; + mem.CardOffset -= offset; + mem.Page = 0; + CS_CHECK(MapMemPage, link->win, &mem); + + /* Try scribbling on the buffer */ + info->base = ioremap(req.Base, window_size); + for (i = 0; i < (TX_PAGES<<8); i += 2) + __raw_writew((i>>1), info->base+offset+i); + udelay(100); + for (i = 0; i < (TX_PAGES<<8); i += 2) + if (__raw_readw(info->base+offset+i) != (i>>1)) break; + pcnet_reset_8390(dev); + if (i != (TX_PAGES<<8)) { + iounmap(info->base); + CardServices(ReleaseWindow, link->win); + info->base = NULL; link->win = NULL; + goto failed; + } + + dev->mem_start = (u_long)info->base + offset; + dev->rmem_start = dev->mem_start + (TX_PAGES<<8); + dev->mem_end = dev->rmem_end = (u_long)info->base + req.Size; + + ei_status.tx_start_page = start_pg; + ei_status.rx_start_page = start_pg + TX_PAGES; + ei_status.stop_page = start_pg + ((req.Size - offset) >> 8); + + /* set up block i/o functions */ + ei_status.get_8390_hdr = &shmem_get_8390_hdr; + ei_status.block_input = &shmem_block_input; + ei_status.block_output = &shmem_block_output; + + info->flags |= USE_SHMEM; + return 0; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + return 1; +} + +/*====================================================================*/ + +static int __init init_pcnet_cs(void) +{ + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "pcnet_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &pcnet_attach, &pcnet_detach); + return 0; +} + +static void __exit exit_pcnet_cs(void) +{ + DEBUG(0, "pcnet_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + pcnet_detach(dev_list); +} + +module_init(init_pcnet_cs); +module_exit(exit_pcnet_cs); diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c new file mode 100644 index 000000000..8af63739c --- /dev/null +++ b/drivers/net/pcmcia/ray_cs.c @@ -0,0 +1,2352 @@ +/*============================================================================= + * + * A PCMCIA client driver for the Raylink wireless LAN card. + * The starting point for this module was the skeleton.c in the + * PCMCIA 2.9.12 package written by David Hinds, dhinds@allegro.stanford.edu + * + * + * Copyright (c) 1998 Corey Thomas (corey@world.std.com) + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of version 2 only of the GNU General Public License as + * published by the Free Software Foundation. + * + * It is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * +=============================================================================*/ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/system.h> +#include <asm/byteorder.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ioport.h> +#include <linux/skbuff.h> + +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/cisreg.h> +#include <pcmcia/ds.h> +#include <pcmcia/mem_op.h> + +#include "rayctl.h" +#include "ray_cs.h" + +/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If + you do not define PCMCIA_DEBUG at all, all the debug code will be + left out. If you compile with PCMCIA_DEBUG=0, the debug code will + be present but disabled -- but it can then be enabled for specific + modules at load time with a 'pc_debug=#' option to insmod. + + I found that adding -DPCMCIA_DEBUG to the compile options during + the 'make config' resulted in cardmgr not finding any sockets. + Therefore, this module uses RAYLINK_DEBUG instead. + The module option to use is ray_debug=# + where # is 1 for modest output + 2 for more output + ... +*/ + +#ifdef RAYLINK_DEBUG +static int ray_debug = RAYLINK_DEBUG; +MODULE_PARM(ray_debug, "i"); +/* #define DEBUG(n, args...) if (ray_debug>(n)) printk(KERN_DEBUG args); */ +#define DEBUG(n, args...) if (ray_debug>(n)) printk(args); +#else +#define DEBUG(n, args...) +#endif +/** Prototypes based on PCMCIA skeleton driver *******************************/ +void ray_config(dev_link_t *link); +void ray_release(u_long arg); +int ray_event(event_t event, int priority, event_callback_args_t *args); +dev_link_t *ray_attach(void); +void ray_detach(dev_link_t *); + +/***** Prototypes indicated by device structure ******************************/ +int ray_dev_close(struct net_device *dev); +int ray_dev_config(struct net_device *dev, struct ifmap *map); +struct enet_statistics *ray_get_stats(struct net_device *dev); +int ray_dev_init(struct net_device *dev); +int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +int ray_open(struct net_device *dev); +int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static void ray_update_multi_list(struct net_device *dev, int all); +int encapsulate_frame(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, + unsigned char *data, int len); +int translate_frame(ray_dev_t *local, struct tx_msg *ptx, + unsigned char *data, int len); +void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, + unsigned char *data); +void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); + +/***** Prototypes for raylink functions **************************************/ +int asc_to_int(char a); +void authenticate(ray_dev_t *local); +int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type); +void authenticate_timeout(u_long); +int get_free_ccs(ray_dev_t *local); +int get_free_tx_ccs(ray_dev_t *local); +void init_startup_params(ray_dev_t *local); +int parse_addr(char *in_str, UCHAR *out); +int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type); +int ray_init(struct net_device *dev); +int interrupt_ecf(ray_dev_t *local, int ccs); +void ray_reset(struct net_device *dev); +void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len); +void verify_dl_startup(u_long); + +/* Prototypes for interrpt time functions **********************************/ +void ray_interrupt(int reg, void *dev_id, struct pt_regs *regs); +void clear_interrupt(ray_dev_t *local); +void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, + unsigned int pkt_addr, int rx_len); +int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len); +void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs); +void release_frag_chain(ray_dev_t *local, struct rcs *prcs); +void rx_authenticate(ray_dev_t *local, struct rcs *prcs, + unsigned int pkt_addr, int rx_len); +void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, + int rx_len); +void associate(ray_dev_t *local); + +/* Card command functions */ +int dl_startup_params(struct net_device *dev); +void join_net(u_long local); +void start_net(u_long local); +/* void start_net(ray_dev_t *local); */ + +int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare); + +/* Create symbol table for registering with kernel in init_module */ +EXPORT_SYMBOL(ray_dev_ioctl); +EXPORT_SYMBOL(ray_rx); + +/*===========================================================================*/ +/* Parameters that can be set with 'insmod' */ +/* Bit map of interrupts to choose from */ +/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ +static u_long irq_mask = 0xdeb8; +MODULE_PARM(irq_mask,"i"); + +/* ADHOC=0, Infrastructure=1 */ +static int net_type = ADHOC; +MODULE_PARM(net_type,"i"); + +/* Hop dwell time in Kus (1024 us units defined by 802.11) */ +static int hop_dwell = 128; +MODULE_PARM(hop_dwell,"i"); + +/* Beacon period in Kus */ +static int beacon_period = 256; +MODULE_PARM(beacon_period,"i"); + +/* power save mode (0 = off, 1 = save power) */ +static int psm = 0; +MODULE_PARM(psm,"i"); + +/* String for network's Extended Service Set ID. 32 Characters max */ +static char *essid = NULL; +MODULE_PARM(essid,"s"); + +/* Default to encapsulation unless translation requested */ +static int translate = 1; +MODULE_PARM(translate,"i"); + +static int country = USA; +MODULE_PARM(country,"i"); + +static int sniffer = 0; +MODULE_PARM(sniffer,"i"); + +static int bc = 0; +MODULE_PARM(bc,"i"); + +/* 48 bit physical card address if overriding card's real physical + * address is required. Since IEEE 802.11 addresses are 48 bits + * like ethernet, an int can't be used, so a string is used. To + * allow use of addresses starting with a decimal digit, the first + * character must be a letter and will be ignored. This letter is + * followed by up to 12 hex digits which are the address. If less + * than 12 digits are used, the address will be left filled with 0's. + * Note that bit 0 of the first byte is the broadcast bit, and evil + * things will happen if it is not 0 in a card address. + */ +static char *phy_addr = NULL; +MODULE_PARM(phy_addr,"s"); + + +/* The dev_info variable is the "key" that is used to match up this + device driver with appropriate cards, through the card configuration + database. +*/ +static dev_info_t dev_info = "ray_cs"; + +/* A linked list of "instances" of the ray device. Each actual + PCMCIA card corresponds to one device instance, and is described + by one dev_link_t structure (defined in ds.h). +*/ +static dev_link_t *dev_list = NULL; + +/* A dev_link_t structure has fields for most things that are needed + to keep track of a socket, but there will usually be some device + specific information that also needs to be kept track of. The + 'priv' pointer in a dev_link_t structure can be used to point to + a device-specific private data structure, like this. +*/ +static const unsigned int ray_mem_speed = 0x2A; + +static UCHAR b5_default_startup_parms[] = { + 0, 0, /* Adhoc station */ + 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, /* Active scan, CA Mode */ + 0, 0, 0, 0, 0, 0, /* No default MAC addr */ + 0x7f, 0xff, /* Frag threshold */ + 0x00, 0x80, /* Hop time 128 Kus*/ + 0x01, 0x00, /* Beacon period 256 Kus */ + 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/ + 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */ + 0x7f, 0xff, /* RTS threshold */ + 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */ + 0x05, /* assoc resp timeout thresh */ + 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max*/ + 0, /* Promiscuous mode */ + 0x0c, 0x0bd, /* Unique word */ + 0x32, /* Slot time */ + 0xff, 0xff, /* roam-low snr, low snr count */ + 0x05, 0xff, /* Infra, adhoc missed bcn thresh */ + 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */ +/* b4 - b5 differences start here */ + 0x00, 0x3f, /* CW max */ + 0x00, 0x0f, /* CW min */ + 0x04, 0x08, /* Noise gain, limit offset */ + 0x28, 0x28, /* det rssi, med busy offsets */ + 7, /* det sync thresh */ + 0, 2, 2, /* test mode, min, max */ + 0, /* allow broadcast SSID probe resp */ + 0, 0, /* privacy must start, can join */ + 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */ +}; + +static UCHAR b4_default_startup_parms[] = { + 0, 0, /* Adhoc station */ + 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, /* Active scan, CA Mode */ + 0, 0, 0, 0, 0, 0, /* No default MAC addr */ + 0x7f, 0xff, /* Frag threshold */ + 0x02, 0x00, /* Hop time */ + 0x00, 0x01, /* Beacon period */ + 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/ + 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */ + 0x7f, 0xff, /* RTS threshold */ + 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */ + 0x05, /* assoc resp timeout thresh */ + 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max*/ + 0, /* Promiscuous mode */ + 0x0c, 0x0bd, /* Unique word */ + 0x4e, /* Slot time (TBD seems wrong)*/ + 0xff, 0xff, /* roam-low snr, low snr count */ + 0x05, 0xff, /* Infra, adhoc missed bcn thresh */ + 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */ +/* b4 - b5 differences start here */ + 0x3f, 0x0f, /* CW max, min */ + 0x04, 0x08, /* Noise gain, limit offset */ + 0x28, 0x28, /* det rssi, med busy offsets */ + 7, /* det sync thresh */ + 0, 2, 2 /* test mode, min, max*/ +}; +/*===========================================================================*/ +static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0}; + +static char rcsid[] = " $Id: ray_cs.c,v 1.60 1999/09/01 20:58:45 corey Exp $ - Corey Thomas corey@world.std.com"; + +#ifdef CONFIG_PROC_FS +struct proc_dir_entry ray_cs_proc_entry = { + 0, /* Dynamic inode # */ + 6,"ray_cs", /* name length and name */ + S_IFREG | S_IRUGO, /* mode */ + 1, 0, 0, /* nlinks, owner, group */ + 0, /* size (unused) */ + NULL, /* operations (default) */ + &ray_cs_proc_read, /* function to read data */ + /* The end ?? */ +}; +#endif +/*===========================================================================*/ +void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} +/*============================================================================= + ray_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + The dev_link structure is initialized, but we don't actually + configure the card at this point -- we wait until we receive a + card insertion event. +=============================================================================*/ +dev_link_t *ray_attach(void) +{ + client_reg_t client_reg; + dev_link_t *link; + ray_dev_t *local; + int ret; + struct net_device *dev; + + DEBUG(1, "ray_attach()\n"); + + /* Initialize the dev_link_t structure */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + memset(link, 0, sizeof(struct dev_link_t)); + link->release.function = &ray_release; + link->release.data = (u_long)link; + + /* The io structure describes IO port mapping. None used here */ + link->io.NumPorts1 = 0; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 5; + + /* Interrupt setup. For PCMCIA, driver takes what's given */ + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; + link->irq.IRQInfo2 = irq_mask; + link->irq.Handler = &ray_interrupt; + + /* General socket configuration */ + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + /* Allocate space for private device-specific data */ + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + memset(dev, 0, sizeof(struct net_device)); + link->priv = dev; + link->irq.Instance = dev; + + local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL); + memset(local, 0, sizeof(ray_dev_t)); + dev->priv = local; + local->finder = link; + link->dev = &local->node; + local->card_status = CARD_INSERTED; + local->authentication_state = UNAUTHENTICATED; + local->num_multi = 0; + DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", + link,dev,local,&ray_interrupt); + + /* Raylink entries in the device structure */ + dev->hard_start_xmit = &ray_dev_start_xmit; + dev->set_config = &ray_dev_config; + dev->get_stats = &ray_get_stats; + dev->do_ioctl = &ray_dev_ioctl; + + dev->set_multicast_list = &set_multicast_list; + + DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n"); + ether_setup(dev); + dev->name = local->node.dev_name; + dev->init = &ray_dev_init; + dev->open = &ray_open; + dev->stop = &ray_dev_close; + dev->tbusy = 1; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &ray_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + + DEBUG(2,"ray_cs ray_attach calling CardServices(RegisterClient...)\n"); + + init_timer(&local->timer); + + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != 0) { + printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); + cs_error(link->handle, RegisterClient, ret); + ray_detach(link); + return NULL; + } + DEBUG(2,"ray_cs ray_attach ending\n"); + return link; +} /* ray_attach */ +/*============================================================================= + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. +=============================================================================*/ +void ray_detach(dev_link_t *link) +{ + dev_link_t **linkp; + struct net_device *dev; + long flags; + + DEBUG(1, "ray_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + save_flags(flags); + cli(); + if (link->state & DEV_RELEASE_PENDING) { + del_timer(&link->release); + link->state &= ~DEV_RELEASE_PENDING; + } + restore_flags(flags); + + /* If the device is currently configured and active, we won't + actually delete it yet. Instead, it is marked so that when + the release() function is called, that will trigger a proper + detach(). + */ + if (link->state & DEV_CONFIG) { + ray_release((u_long)link); + if(link->state & DEV_STALE_CONFIG) { + DEBUG(0,"ray_cs: detach postponed, '%s' " + "still locked\n", link->dev->dev_name); + link->state |= DEV_STALE_LINK; + return; + } + } + + /* Break the link with Card Services */ + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, free pieces */ + *linkp = link->next; + if (link->priv) { + dev = link->priv; + if (dev->priv) + kfree_s(dev->priv, sizeof(ray_dev_t)); + + kfree_s(link->priv, sizeof(struct net_device)); + } + kfree_s(link, sizeof(struct dev_link_t)); + DEBUG(2,"ray_cs ray_detach ending\n"); +} /* ray_detach */ +/*============================================================================= + ray_config() is run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + ethernet device available to the system. +=============================================================================*/ +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed +#define MAX_TUPLE_SIZE 80 +void ray_config(dev_link_t *link) +{ + client_handle_t handle = link->handle; + tuple_t tuple; + cisparse_t parse; + int last_fn, last_ret; + int i; + u_char buf[80]; + win_req_t req; + memreq_t mem; + struct net_device *dev = (struct net_device *)link->priv; + ray_dev_t *local = (ray_dev_t *)dev->priv; + + DEBUG(1, "ray_config(0x%p)\n", link); + + /* This reads the card's CONFIG tuple to find its configuration regs */ + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + tuple.TupleData = buf; + tuple.TupleDataMax = MAX_TUPLE_SIZE; + tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Now allocate an interrupt line. Note that this does not + actually assign a handler to the interrupt. + */ + CS_CHECK(RequestIRQ, link->handle, &link->irq); + dev->irq = link->irq.AssignedIRQ; + + /* This actually configures the PCMCIA socket -- setting up + the I/O windows and the interrupt mapping. + */ + CS_CHECK(RequestConfiguration, link->handle, &link->conf); + +/*** Set up 32k window for shared memory (transmit and control) ************/ + req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; + req.Base = 0; + req.Size = 0x8000; + req.AccessSpeed = ray_mem_speed; + link->win = (window_handle_t)link->handle; + CS_CHECK(RequestWindow, &link->win, &req); + mem.CardOffset = 0x0000; mem.Page = 0; + CS_CHECK(MapMemPage, link->win, &mem); + local->sram = (UCHAR *)(ioremap(req.Base,req.Size)); + +/*** Set up 16k window for shared memory (receive buffer) ***************/ + req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; + req.Base = 0; + req.Size = 0x4000; + req.AccessSpeed = ray_mem_speed; + local->rmem_handle = (window_handle_t)link->handle; + CS_CHECK(RequestWindow, &local->rmem_handle, &req); + mem.CardOffset = 0x8000; mem.Page = 0; + CS_CHECK(MapMemPage, local->rmem_handle, &mem); + local->rmem = (UCHAR *)(ioremap(req.Base,req.Size)); + +/*** Set up window for attribute memory ***********************************/ + req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT; + req.Base = 0; + req.Size = 0x1000; + req.AccessSpeed = ray_mem_speed; + local->amem_handle = (window_handle_t)link->handle; + CS_CHECK(RequestWindow, &local->amem_handle, &req); + mem.CardOffset = 0x0000; mem.Page = 0; + CS_CHECK(MapMemPage, local->amem_handle, &mem); + local->amem = (UCHAR *)(ioremap(req.Base,req.Size)); + + DEBUG(3,"ray_config sram=%p\n",local->sram); + DEBUG(3,"ray_config rmem=%p\n",local->rmem); + DEBUG(3,"ray_config amem=%p\n",local->amem); + if (ray_init(dev) < 0) { + ray_release((u_long)link); + return; + } + + i = register_netdev(dev); + if (i != 0) { + printk("ray_config register_netdev() failed\n"); + ray_release((u_long)link); + return; + } + + link->state &= ~DEV_CONFIG_PENDING; + DEBUG(0, "ray_cs device loaded\n"); + + return; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); + + ray_release((u_long)link); +} /* ray_config */ +/*===========================================================================*/ +int ray_init(struct net_device *dev) +{ + int i; + UCHAR *p; + struct ccs *pccs; + ray_dev_t *local = (ray_dev_t *)dev->priv; + dev_link_t *link = local->finder; + DEBUG(1, "ray_init(0x%p)\n", dev); + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_init - device not present\n"); + return -1; + } + + local->net_type = net_type; + local->sta_type = TYPE_STA; + + /* Copy the startup results to local memory */ + memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\ + sizeof(struct startup_res_6)); + + /* Check Power up test status and get mac address from card */ + if (local->startup_res.startup_word != 0x80) { +DEBUG(0,"ray_init ERROR card status = %2x\n", local->startup_res.startup_word); + local->card_status = CARD_INIT_ERROR; + return -1; + } + + local->fw_ver = local->startup_res.firmware_version[0]; + local->fw_bld = local->startup_res.firmware_version[1]; + local->fw_var = local->startup_res.firmware_version[2]; + DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld); + + local->tib_length = 0x20; + if ((local->fw_ver == 5) && (local->fw_bld >= 30)) + local->tib_length = local->startup_res.tib_length; + DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length); + /* Initialize CCS's to buffer free state */ + pccs = (struct ccs *)(local->sram + CCS_BASE); + for (i=0; i<NUMBER_OF_CCS; i++) { + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + } + init_startup_params(local); + + /* copy mac address to startup parameters */ + if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) + { + p = local->sparm.b4.a_mac_addr; + DEBUG(1,"ray_cs phy address overridden = %2x %2x %2x %2x %2x %2x\n",\ + p[0],p[1],p[2],p[3],p[4],p[5]); + } + else + { + memcpy(&local->sparm.b4.a_mac_addr, + &local->startup_res.station_addr, ADDRLEN); + p = local->sparm.b4.a_mac_addr; + DEBUG(1,"ray_cs phy addr= %2x %2x %2x %2x %2x %2x\n",\ + p[0],p[1],p[2],p[3],p[4],p[5]); + } + + clear_interrupt(local); /* Clear any interrupt from the card */ + local->card_status = CARD_AWAITING_PARAM; + DEBUG(2,"ray_init ending\n"); + return 0; +} /* ray_init */ +/*===========================================================================*/ +/* Download startup parameters to the card and command it to read them */ +int dl_startup_params(struct net_device *dev) +{ + int ccsindex; + ray_dev_t *local = (ray_dev_t *)dev->priv; + struct ccs *pccs; + dev_link_t *link = local->finder; + + DEBUG(1,"dl_startup_params entered\n"); + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs dl_startup_params - device not present\n"); + return -1; + } + + /* Copy parameters to host to ECF area */ + if (local->fw_ver == 0x55) + memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4, + sizeof(struct b4_startup_params)); + else + memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5, + sizeof(struct b5_startup_params)); + + + /* Fill in the CCS fields for the ECF */ + if ((ccsindex = get_free_ccs(local)) == -1) return -1; + local->dl_param_ccs = ccsindex; + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd); + DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs); + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(0,"ray dl_startup_params failed - ECF not ready for intr\n"); + local->card_status = CARD_DL_PARAM_ERROR; + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + return -2; + } + local->card_status = CARD_DL_PARAM; + /* Start kernel timer to wait for dl startup to complete. */ + local->timer.expires = jiffies + HZ/2; + local->timer.data = (long)local; + local->timer.function = &verify_dl_startup; + add_timer(&local->timer); + DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n"); + return 0; +} /* dl_startup_params */ +/*===========================================================================*/ +void init_startup_params(ray_dev_t *local) +{ + int i; + static char hop_pattern_length[] = { 1, + USA_HOP_MOD, EUROPE_HOP_MOD, + JAPAN_HOP_MOD, KOREA_HOP_MOD, + SPAIN_HOP_MOD, FRANCE_HOP_MOD, + ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD, + JAPAN_TEST_HOP_MOD + }; + + if (country > JAPAN_TEST) country = USA; + else + if (country < USA) country = USA; + /* structure for hop time and beacon period is defined here using + * New 802.11D6.1 format. Card firmware is still using old format + * until version 6. + * Before After + * a_hop_time ms byte a_hop_time ms byte + * a_hop_time 2s byte a_hop_time ls byte + * a_hop_time ls byte a_beacon_period ms byte + * a_beacon_period a_beacon_period ls byte + * + * a_hop_time = uS a_hop_time = KuS + * a_beacon_period = hops a_beacon_period = KuS + */ /* 64ms = 010000 */ + if (local->fw_ver == 0x55) { + memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms, + sizeof(struct b4_startup_params)); + /* Translate sane kus input values to old build 4/5 format */ + /* i = hop time in uS truncated to 3 bytes */ + i = (hop_dwell * 1024) & 0xffffff; + local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff; + local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff; + local->sparm.b4.a_beacon_period[0] = 0; + local->sparm.b4.a_beacon_period[1] = + ((beacon_period/hop_dwell) - 1) & 0xff; + local->sparm.b4.a_curr_country_code = country; + local->sparm.b4.a_hop_pattern_length = + hop_pattern_length[(int)country] - 1; + if (bc) + { + local->sparm.b4.a_ack_timeout = 0x50; + local->sparm.b4.a_sifs = 0x3f; + } + } + else { /* Version 5 uses real kus values */ + memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms, + sizeof(struct b5_startup_params)); + + local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff; + local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff; + local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff; + local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff; + if (psm) + local->sparm.b5.a_power_mgt_state = 1; + local->sparm.b5.a_curr_country_code = country; + local->sparm.b5.a_hop_pattern_length = + hop_pattern_length[(int)country]; + } + + local->sparm.b4.a_network_type = net_type & 0x01; + local->sparm.b4.a_acting_as_ap_status = TYPE_STA; + + if (essid != NULL) + strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE); +} /* init_startup_params */ +/*===========================================================================*/ +void verify_dl_startup(u_long data) +{ + ray_dev_t *local = (ray_dev_t *)data; + struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs; + UCHAR status; +/* UCHAR *p = local->sram + HOST_TO_ECF_BASE; */ + dev_link_t *link = local->finder; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs verify_dl_startup - device not present\n"); + return; + } +#ifdef RAYLINK_DEBUG + { + int i; + DEBUG(2,"verify_dl_startup parameters sent via ccs %d:\n",\ + local->dl_param_ccs); + for (i=0; i<sizeof(struct b5_startup_params); i++) + { + DEBUG(1," %2x ", readb(local->sram + HOST_TO_ECF_BASE + i)); + } + DEBUG(1,"\n"); + } +#endif + + status = readb(&pccs->buffer_status); + if (status!= CCS_BUFFER_FREE) + { + DEBUG(0,"Download startup params failed. Status = %d\n",status); + local->card_status = CARD_DL_PARAM_ERROR; + return; + } + if (local->sparm.b4.a_network_type == ADHOC) + start_net((u_long)local); + else + join_net((u_long)local); + + return; +} /* end verify_dl_startup */ +/*===========================================================================*/ +/* Command card to start a network */ +void start_net(u_long data) +{ + ray_dev_t *local = (ray_dev_t *)data; + struct ccs *pccs; + int ccsindex; + dev_link_t *link = local->finder; + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs start_net - device not present\n"); + return; + } + /* Fill in the CCS fields for the ECF */ + if ((ccsindex = get_free_ccs(local)) == -1) return; + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + writeb(CCS_START_NETWORK, &pccs->cmd); + writeb(0, &pccs->var.start_network.update_param); + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(1,"ray start net failed - card not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + return; + } + local->card_status = CARD_DOING_ACQ; + return; +} /* end start_net */ +/*===========================================================================*/ +/* Command card to join a network */ +void join_net(u_long data) +{ + ray_dev_t *local = (ray_dev_t *)data; + + struct ccs *pccs; + int ccsindex; + dev_link_t *link = local->finder; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs join_net - device not present\n"); + return; + } + /* Fill in the CCS fields for the ECF */ + if ((ccsindex = get_free_ccs(local)) == -1) return; + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + writeb(CCS_JOIN_NETWORK, &pccs->cmd); + writeb(0, &pccs->var.join_network.update_param); + writeb(0, &pccs->var.join_network.net_initiated); + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(1,"ray join net failed - card not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + return; + } + local->card_status = CARD_DOING_ACQ; + return; +} +/*============================================================================ + After a card is removed, ray_release() will unregister the net + device, and release the PCMCIA configuration. If the device is + still open, this will be postponed until it is closed. +=============================================================================*/ +void ray_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *)arg; + struct net_device *dev = link->priv; + ray_dev_t *local = dev->priv; + int i; + + DEBUG(1, "ray_release(0x%p)\n", link); + /* If the device is currently in use, we won't release until it + is actually closed. + */ + if (link->open) { + DEBUG(1, "ray_cs: release postponed, '%s' still open\n", + link->dev->dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + del_timer(&local->timer); + if (link->dev != '\0') unregister_netdev(dev); + /* Unlink the device chain */ + link->dev = NULL; + + iounmap(local->sram); + iounmap(local->rmem); + iounmap(local->amem); + /* Do bother checking to see if these succeed or not */ + i = CardServices(ReleaseWindow, link->win); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i); + i = CardServices(ReleaseWindow, local->amem_handle); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); + i = CardServices(ReleaseWindow, local->rmem_handle); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); + i = CardServices(ReleaseConfiguration, link->handle); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i); + i = CardServices(ReleaseIRQ, link->handle, &link->irq); + if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i); + + link->state &= ~DEV_CONFIG; + if (link->state & DEV_STALE_LINK) ray_detach(link); + DEBUG(2,"ray_release ending\n"); +} /* ray_release */ +/*============================================================================= + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the net drivers from trying + to talk to the card any more. + + When a CARD_REMOVAL event is received, we immediately set a flag + to block future accesses to this device. All the functions that + actually access the device should check this flag to make sure + the card is still present. +=============================================================================*/ +int ray_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + struct net_device *dev = link->priv; + ray_dev_t *local = (ray_dev_t *)dev->priv; + DEBUG(1, "ray_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + dev->tbusy = 1; dev->start = 0; + if (link->state & DEV_CONFIG) { + link->release.expires = jiffies + HZ/20; + add_timer(&link->release); + del_timer(&local->timer); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + ray_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) { + if (link->open) { + dev->tbusy = 1; + dev->start = 0; + } + CardServices(ReleaseConfiguration, link->handle); + } + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) { + CardServices(RequestConfiguration, link->handle, &link->conf); + if (link->open) { + ray_reset(dev); + dev->tbusy = 0; + dev->start = 1; + } + } + break; + } + return 0; + DEBUG(2,"ray_event ending\n"); +} /* ray_event */ +/*===========================================================================*/ +int ray_dev_init(struct net_device *dev) +{ + int i; + ray_dev_t *local = dev->priv; + dev_link_t *link = local->finder; + + DEBUG(1,"ray_dev_init(dev=%p)\n",dev); + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_dev_init - device not present\n"); + return -1; + } + /* Download startup parameters */ + if ( (i = dl_startup_params(dev)) < 0) + { + DEBUG(0,"ray_dev_init dl_startup_params failed - returns 0x%x/n",i); + return -1; + } + + /* copy mac and broadcast addresses to linux device */ + memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN); + memset(dev->broadcast, 0xff, ETH_ALEN); + +#ifdef RAYLINK_DEBUG + { + UCHAR *p; + p = (UCHAR *)(local->startup_res.station_addr); + DEBUG(1,"ray_dev_init card hardware mac addr = %2x %2x %2x %2x %2x %2x\n",\ + p[0],p[1],p[2],p[3],p[4],p[5]); + } +#endif + + DEBUG(2,"ray_dev_init ending\n"); + return 0; +} +/*===========================================================================*/ +int ray_dev_config(struct net_device *dev, struct ifmap *map) +{ + ray_dev_t *local = dev->priv; + dev_link_t *link = local->finder; + /* Dummy routine to satisfy device structure */ + DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map); + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_dev_config - device not present\n"); + return -1; + } + + return 0; +} +/*===========================================================================*/ +int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + ray_dev_t *local = dev->priv; + dev_link_t *link = local->finder; + short length; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_dev_start_xmit - device not present\n"); + return -1; + } + DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev); + if (dev->tbusy) + { + DEBUG(2,"ray_dev_start_xmit busy\n"); + return 1; + } + if (local->authentication_state == NEED_TO_AUTH) { + DEBUG(0,"ray_cs Sending authentication request.\n"); + if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) { + local->authentication_state = AUTHENTICATED; + dev->tbusy = 1; + return 1; + } + } + + length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) { + case XMIT_NO_CCS: + case XMIT_NEED_AUTH: + dev->tbusy = 1; + return 1; + case XMIT_NO_INTR: + case XMIT_MSG_BAD: + case XMIT_OK: + default: + dev->trans_start = jiffies; + dev_kfree_skb(skb); + return 0; + } + return 0; +} /* ray_dev_start_xmit */ +/*===========================================================================*/ +int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, + UCHAR msg_type) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + struct ccs *pccs; + int ccsindex; + int offset; + struct tx_msg *ptx; /* Address of xmit buffer in PC space */ + short int addr; /* Address of xmit buffer in card space */ + + DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev); + if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) + { + DEBUG(0,"ray_hw_xmit packet to large %d bytes\n",len); + return XMIT_MSG_BAD; + } + if ((ccsindex = get_free_tx_ccs(local)) == -1) + { + DEBUG(2,"ray_hw_xmit - No free tx ccs\n"); + dev->tbusy = 1; + return XMIT_NO_CCS; + } + addr = TX_BUF_BASE + (ccsindex << 11); + + if (msg_type == DATA_TYPE) { + local->stats.tx_bytes += len; + local->stats.tx_packets++; + } + + ptx = (struct tx_msg *)(local->sram + addr); + + ray_build_header(local, ptx, msg_type, data); + if (translate) { + offset = translate_frame(local, ptx, data, len); + } + else { /* Encapsulate frame */ + /* TBD TIB length will move address of ptx->var */ + memcpy( (UCHAR *)&ptx->var, data, len); + offset = 0; + } + + /* fill in the CCS */ + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + len += TX_HEADER_LENGTH + offset; + writeb(CCS_TX_REQUEST, &pccs->cmd); + writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]); + writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]); + writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]); + writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]); +/* TBD still need psm_cam? */ + writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode); + writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate); + writeb(0, &pccs->var.tx_request.antenna); + DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\ + local->net_default_tx_rate); + + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n"); +/* TBD very inefficient to copy packet to buffer, and then not + send it, but the alternative is to queue the messages and that + won't be done for a while. Maybe set tbusy until a CCS is free? +*/ + writeb(CCS_BUFFER_FREE, &pccs->buffer_status); + return XMIT_NO_INTR; + } + return XMIT_OK; +} /* end ray_hw_xmit */ +/*===========================================================================*/ +int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, + int len) +{ + unsigned short int proto = ((struct ethhdr *)data)->h_proto; + if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */ + DEBUG(3,"ray_cs translate_frame DIX II\n"); + /* Copy LLC header to card buffer */ + memcpy_toio((UCHAR *)&ptx->var, eth2_llc, sizeof(eth2_llc)); + memcpy_toio( ((UCHAR *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2); + if ((proto == 0xf380) || (proto == 0x3781)) { + /* This is the selective translation table, only 2 entries */ + writeb(0xf8, (UCHAR *) &((struct snaphdr_t *)ptx->var)->org[3]); + } + /* Copy body of ethernet packet without ethernet header */ + memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \ + data + ETH_HLEN, len - ETH_HLEN); + return sizeof(struct snaphdr_t) - ETH_HLEN; + } + else { /* already 802 type, and proto is length */ + DEBUG(3,"ray_cs translate_frame 802\n"); + if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */ + DEBUG(3,"ray_cs translate_frame evil IPX\n"); + memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN); + return 0 - ETH_HLEN; + } + memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN); + return 0 - ETH_HLEN; + } + /* TBD do other frame types */ +} /* end translate_frame */ +/*===========================================================================*/ +void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, + unsigned char *data) +{ + writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1); +/*** IEEE 802.11 Address field assignments ************* + addr_1 addr_2 addr_3 + AP destination AP(BSSID) source + Infra Terminal AP terminal destination + Adhoc destination terminal BSSID +*******************************************************/ + if (local->net_type == ADHOC) { + writeb(0, &ptx->mac.frame_ctl_2); + memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN); + memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN); + } + else /* infrastructure */ + { + if (local->sparm.b4.a_acting_as_ap_status) + { + writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);; + memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN); + memcpy_toio(ptx->mac.addr_2, local->bss_id, 6); + memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN); + } + else /* Terminal */ + { + writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2); + memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN); + memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN); + memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN); + } + } +} /* end encapsulate_frame */ +/*===========================================================================*/ +int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + dev_link_t *link = local->finder; + int err = 0; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_dev_ioctl - device not present\n"); + return -1; + } + DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); + /* Validate the command */ + switch (cmd) + { + default: + DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); + err = -EOPNOTSUPP; + } + return err; +} /* end ray_dev_ioctl */ +/*===========================================================================*/ +int ray_open(struct net_device *dev) +{ + dev_link_t *link; + ray_dev_t *local = (ray_dev_t *)dev->priv; + + DEBUG(1, "ray_open('%s')\n", dev->name); + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (!DEV_OK(link)) + return -ENODEV; + + if (link->open == 0) local->num_multi = 0; + link->open++; + MOD_INC_USE_COUNT; + + dev->interrupt = 0; + if (sniffer) dev->tbusy = 1; + else dev->tbusy = 0; + dev->start = 1; + + DEBUG(2,"ray_open ending\n"); + return 0; +} /* end ray_open */ +/*===========================================================================*/ +int ray_dev_close(struct net_device *dev) +{ + dev_link_t *link; + + DEBUG(1, "ray_dev_close('%s')\n", dev->name); + + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; + if (link == NULL) + return -ENODEV; + + link->open--; dev->start = 0; + if (link->state & DEV_STALE_CONFIG) { + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + + MOD_DEC_USE_COUNT; + + return 0; +} /* end ray_dev_close */ +/*===========================================================================*/ +void ray_reset(struct net_device *dev) { + DEBUG(1,"ray_reset entered\n"); + return; +} +/*===========================================================================*/ +/* Cause a firmware interrupt if it is ready for one */ +/* Return nonzero if not ready */ +int interrupt_ecf(ray_dev_t *local, int ccs) +{ + int i = 50; +/* UCHAR *p = (local->amem + CIS_OFFSET + ECF_INTR_OFFSET); */ + dev_link_t *link = local->finder; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs interrupt_ecf - device not present\n"); + return -1; + } + DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs); + +/* while ( i && (*p & ECF_INTR_SET)) i--; */ + while ( i && + (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET)) + i--; + if (i == 0) { + DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n"); + return -1; + } + + *(local->sram + SCB_BASE) = ccs; + writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET); + return 0; +} /* interrupt_ecf */ +/*===========================================================================*/ +/* Get next free transmit CCS */ +/* Return - index of current tx ccs */ +int get_free_tx_ccs(ray_dev_t *local) +{ + int i; + struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); + dev_link_t *link = local->finder; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs get_free_tx_ccs - device not present\n"); + return -1; + } + + for (i=0; i < NUMBER_OF_TX_CCS; i++) { + if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { + writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); + writeb(CCS_END_LIST, &(pccs+i)->link); + return i; + } + } + DEBUG(1,"ray_cs ERROR no free tx CCS for raylink card\n"); + return -1; +} /* get_free_tx_ccs */ +/*===========================================================================*/ +/* Get next free CCS */ +/* Return - index of current ccs */ +int get_free_ccs(ray_dev_t *local) +{ + int i; + struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); + dev_link_t *link = local->finder; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs get_free_ccs - device not present\n"); + return -1; + } + for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) { + if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { + writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); + writeb(CCS_END_LIST, &(pccs+i)->link); + return i; + } + } + DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n"); + return -1; +} /* get_free_ccs */ +/*===========================================================================*/ +void authenticate_timeout(u_long data) +{ + ray_dev_t *local = (ray_dev_t *)data; + del_timer(&local->timer); + DEBUG(0,"ray_cs Authentication with access point failed - timeout\n"); + join_net((u_long)local); +} +/*===========================================================================*/ +int asc_to_int(char a) +{ + if (a < '0') return -1; + if (a <= '9') return (a - '0'); + if (a < 'A') return -1; + if (a <= 'F') return (10 + a - 'A'); + if (a < 'a') return -1; + if (a <= 'f') return (10 + a - 'a'); + return -1; +} +/*===========================================================================*/ +int parse_addr(char *in_str, UCHAR *out) +{ + int len; + int i,j,k; + int status; + + if (in_str == NULL) return 0; + if ((len = strlen(in_str)) < 2) return 0; + memset(out, 0, ADDRLEN); + + status = 1; + j = len - 1; + if (j > 12) j = 12; + i = 5; + + while (j > 0) + { + if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k; + else return 0; + + if (j == 0) break; + if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4; + else return 0; + if (!i--) break; + } + return status; +} +/*===========================================================================*/ +struct enet_statistics *ray_get_stats(struct net_device *dev) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + dev_link_t *link = local->finder; + struct status *p = (struct status *)(local->sram + STATUS_BASE); + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_cs enet_statistics - device not present\n"); + return &local->stats; + } + if (p->mrx_overflow_for_host) + { + local->stats.rx_over_errors += ntohs(p->mrx_overflow); + p->mrx_overflow = 0; + p->mrx_overflow_for_host = 0; + } + if (p->mrx_checksum_error_for_host) + { + local->stats.rx_crc_errors += ntohs(p->mrx_checksum_error); + p->mrx_checksum_error = 0; + p->mrx_checksum_error_for_host = 0; + } + if (p->rx_hec_error_for_host) + { + local->stats.rx_frame_errors += ntohs(p->rx_hec_error); + p->rx_hec_error = 0; + p->rx_hec_error_for_host = 0; + } + return &local->stats; +} +/*===========================================================================*/ +void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + dev_link_t *link = local->finder; + int ccsindex; + int i; + struct ccs *pccs; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(0,"ray_update_parm - device not present\n"); + return; + } + + if ((ccsindex = get_free_ccs(local)) == -1) + { + DEBUG(0,"ray_update_parm - No free ccs\n"); + return; + } + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + writeb(CCS_UPDATE_PARAMS, &pccs->cmd); + writeb(objid, &pccs->var.update_param.object_id); + writeb(1, &pccs->var.update_param.number_objects); + writeb(0, &pccs->var.update_param.failure_cause); + for (i=0; i<len; i++) { + writeb(value[i], local->sram + HOST_TO_ECF_BASE); + } + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + } +} +/*===========================================================================*/ +static void ray_update_multi_list(struct net_device *dev, int all) +{ + struct dev_mc_list *dmi, **dmip; + int ccsindex; + struct ccs *pccs; + int i = 0; + ray_dev_t *local = (ray_dev_t *)dev->priv; + dev_link_t *link = local->finder; + UCHAR *p = local->sram + HOST_TO_ECF_BASE; + + if (!(link->state & DEV_PRESENT)) { + DEBUG(1,"ray_update_multi_list - device not present\n"); + return; + } + else + DEBUG(1,"ray_update_multi_list(%p)\n",dev); + if ((ccsindex = get_free_ccs(local)) == -1) + { + DEBUG(1,"ray_update_multi - No free ccs\n"); + return; + } + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd); + + if (all) { + writeb(0xff, &pccs->var); + local->num_multi = 0xff; + } + else { + /* Copy the kernel's list of MC addresses to card */ + for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) { + memcpy_toio(p, dmi->dmi_addr, ETH_ALEN); + DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]); + p += ETH_ALEN; + i++; + } + if (i > 256/ADDRLEN) i = 256/ADDRLEN; + writeb((UCHAR)i, &pccs->var); + DEBUG(1,"ray_cs update_multi %d addresses in list\n", i); + /* Interrupt the firmware to process the command */ + local->num_multi = i; + } + if (interrupt_ecf(local, ccsindex)) { + DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + } +} /* end ray_update_multi_list */ +/*===========================================================================*/ +static void set_multicast_list(struct net_device *dev) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + UCHAR promisc; + + DEBUG(1,"ray_cs set_multicast_list(%p)\n",dev); + + if (dev->flags & IFF_PROMISC) + { + if (local->sparm.b5.a_promiscuous_mode == 0) { + DEBUG(1,"ray_cs set_multicast_list promisc on\n"); + local->sparm.b5.a_promiscuous_mode = 1; + promisc = 1; + ray_update_parm(dev, OBJID_promiscuous_mode, \ + &promisc, sizeof(promisc)); + } + } + else { + if (local->sparm.b5.a_promiscuous_mode == 1) { + DEBUG(1,"ray_cs set_multicast_list promisc off\n"); + local->sparm.b5.a_promiscuous_mode = 0; + promisc = 0; + ray_update_parm(dev, OBJID_promiscuous_mode, \ + &promisc, sizeof(promisc)); + } + } + + if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1); + else + { + if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0); + } +} /* end set_multicast_list */ +/*============================================================================= + * All routines below here are run at interrupt time. +=============================================================================*/ +void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct net_device *dev = (struct net_device *)dev_id; + dev_link_t *link; + ray_dev_t *local; + struct ccs *pccs; + struct rcs *prcs; + UCHAR rcsindex; + UCHAR tmp; + UCHAR cmd; + UCHAR status; + + if (dev == NULL) { + link = dev_list; + dev = (struct net_device *)link->priv; + DEBUG(4,"ray_cs interrupt dev = %p, link = %p\n",dev,link); + if (dev->irq != irq) + { + DEBUG(0,"ray_cs interrupt irq %d for unknown device.\n", irq); + return; + } + } + DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); + + if (dev->interrupt) { + printk("ray_cs Reentering interrupt handler not allowed\n"); + return; + } + dev->interrupt = 1; + local = (ray_dev_t *)dev->priv; + link = (dev_link_t *)local->finder; + if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) { + DEBUG(1,"ray_cs interrupt from device not present or suspended.\n"); + return; + } + rcsindex = ((struct scb *)(local->sram))->rcs_index; + + if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) + { + DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex); + clear_interrupt(local); + dev->interrupt = 0; + return; + } + if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */ + { + pccs = ((struct ccs *) (local->sram + CCS_BASE)) + rcsindex; + cmd = readb(&pccs->cmd); + status = readb(&pccs->buffer_status); + switch (cmd) + { + case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */ + del_timer(&local->timer); + if (status == CCS_COMMAND_COMPLETE) { + DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n"); + } + else { + DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n"); + } + break; + case CCS_UPDATE_PARAMS: + DEBUG(1,"ray_cs interrupt update params done\n"); + if (status != CCS_COMMAND_COMPLETE) { + tmp = readb(&pccs->var.update_param.failure_cause); + DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp); + } + break; + case CCS_REPORT_PARAMS: + DEBUG(1,"ray_cs interrupt report params done\n"); + break; + case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */ + DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n"); + break; + case CCS_UPDATE_POWER_SAVINGS_MODE: + DEBUG(1,"ray_cs interrupt update power save mode done\n"); + break; + case CCS_START_NETWORK: + case CCS_JOIN_NETWORK: + if (status == CCS_COMMAND_COMPLETE) { + if (readb(&pccs->var.start_network.net_initiated) == 1) { + DEBUG(0,"ray_cs interrupt network \"%s\"started\n",\ + local->sparm.b4.a_current_ess_id); + } + else { + DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\ + local->sparm.b4.a_current_ess_id); + } + memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN); + + if (local->fw_ver == 0x55) local->net_default_tx_rate = 3; + else local->net_default_tx_rate = + readb(&pccs->var.start_network.net_default_tx_rate); + local->encryption = readb(&pccs->var.start_network.encryption); + if (!sniffer && (local->net_type == INFRA) + && !(local->sparm.b4.a_acting_as_ap_status)) { + authenticate(local); + } + local->card_status = CARD_ACQ_COMPLETE; + } + else { + local->card_status = CARD_ACQ_FAILED; + + del_timer(&local->timer); + local->timer.expires = jiffies + HZ*5; + local->timer.data = (long)local; + if (status == CCS_START_NETWORK) { + DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\ + local->sparm.b4.a_current_ess_id); + local->timer.function = &start_net; + } + else { + DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\ + local->sparm.b4.a_current_ess_id); + local->timer.function = &join_net; + } + add_timer(&local->timer); + } + break; + case CCS_START_ASSOCIATION: + if (status == CCS_COMMAND_COMPLETE) { + local->card_status = CARD_ASSOC_COMPLETE; + DEBUG(0,"ray_cs association successful\n"); + } + else + { + DEBUG(0,"ray_cs association failed,\n"); + local->card_status = CARD_ASSOC_FAILED; + join_net((u_long)local); + } + break; + case CCS_TX_REQUEST: + if (status == CCS_COMMAND_COMPLETE) { + DEBUG(3,"ray_cs interrupt tx request complete\n"); + } + else { + DEBUG(1,"ray_cs interrupt tx request failed\n"); + } + if (!sniffer) dev->tbusy = 0; + mark_bh(NET_BH); + break; + case CCS_TEST_MEMORY: + DEBUG(1,"ray_cs interrupt mem test done\n"); + break; + case CCS_SHUTDOWN: + DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n"); + break; + case CCS_DUMP_MEMORY: + DEBUG(1,"ray_cs interrupt dump memory done\n"); + break; + case CCS_START_TIMER: + DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n"); + break; + default: + DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\ + rcsindex, cmd); + } + writeb(CCS_BUFFER_FREE, &pccs->buffer_status); + } + else /* It's an RCS */ + { + prcs = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex; + + switch (readb(&prcs->interrupt_id)) + { + case PROCESS_RX_PACKET: + ray_rx(dev, local, prcs); + break; + case REJOIN_NET_COMPLETE: + DEBUG(1,"ray_cs interrupt rejoin net complete\n"); + local->card_status = CARD_ACQ_COMPLETE; + /* do we need to clear tx buffers CCS's? */ + if (local->sparm.b4.a_network_type == ADHOC) { + if (!sniffer) dev->tbusy = 0; + } + else { + memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN); + DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\ + local->bss_id[0], local->bss_id[1], local->bss_id[2],\ + local->bss_id[3], local->bss_id[4], local->bss_id[5]); + if (!sniffer) authenticate(local); + } + break; + case ROAMING_INITIATED: + DEBUG(1,"ray_cs interrupt roaming initiated\n"); + dev->tbusy = 1; + local->card_status = CARD_DOING_ACQ; + break; + case JAPAN_CALL_SIGN_RXD: + DEBUG(1,"ray_cs interrupt japan call sign rx\n"); + break; + default: + DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\ + rcsindex, readb(&prcs->interrupt_id)); + break; + } + writeb(CCS_BUFFER_FREE, &prcs->buffer_status); + } + clear_interrupt(local); + dev->interrupt = 0; +} /* ray_interrupt */ +/*===========================================================================*/ +void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) +{ + int rx_len; + unsigned int pkt_addr; + UCHAR *pmsg; + DEBUG(4,"ray_rx process rx packet\n"); + + /* Calculate address of packet within Rx buffer */ + pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8) + + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END; + /* Length of first packet fragment */ + rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8) + + readb(&prcs->var.rx_packet.rx_data_length[1]); + + pmsg = local->rmem + pkt_addr; + switch(readb(pmsg)) + { + case DATA_TYPE: + DEBUG(4,"ray_rx data type\n"); + rx_data(dev, prcs, pkt_addr, rx_len); + break; + case AUTHENTIC_TYPE: + DEBUG(4,"ray_rx authentic type\n"); + if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); + else rx_authenticate(local, prcs, pkt_addr, rx_len); + break; + case DEAUTHENTIC_TYPE: + DEBUG(4,"ray_rx deauth type\n"); + if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); + else rx_deauthenticate(local, prcs, pkt_addr, rx_len); + break; + case NULL_MSG_TYPE: + DEBUG(3,"ray_cs rx NULL msg\n"); + break; + case BEACON_TYPE: + DEBUG(4,"ray_rx beacon type\n"); + if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); + + copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr, + rx_len < sizeof(struct beacon_rx) ? + rx_len : sizeof(struct beacon_rx)); + + /* Get the statistics so the card counters never overflow */ + ray_get_stats(dev); + break; + default: + DEBUG(0,"ray_cs unknown pkt type %2x\n", readb(pmsg)); + break; + } + +} /* end ray_rx */ +/*===========================================================================*/ +void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, + int rx_len) +{ + struct sk_buff *skb = NULL; + struct rcs *prcslink = prcs; + ray_dev_t *local = dev->priv; + UCHAR *rx_ptr; + int total_len; + int tmp; + + if (!sniffer) { + if (translate) { +/* TBD length needs fixing for translated header */ + if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) || + rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN)) + { + DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len); + return; + } + } + else /* encapsulated ethernet */ { + if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) || + rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN)) + { + DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len); + return; + } + } + } + DEBUG(4,"ray_cs rx_data packet\n"); + /* If fragmented packet, verify sizes of fragments add up */ + if (prcs->var.rx_packet.next_frag_rcs_index != 0xFF) { + DEBUG(1,"ray_cs rx'ed fragment\n"); + tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8) + + readb(&prcs->var.rx_packet.totalpacketlength[1]); + total_len = tmp; + prcslink = prcs; + do { + tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8) + + readb(&prcslink->var.rx_packet.rx_data_length[1]); + if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF + || tmp < 0) break; + prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + + readb(&prcslink->link_field); + } while (1); + + if (tmp < 0) + { + DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n"); + local->stats.rx_dropped++; + release_frag_chain(local, prcs); + return; + } + } + else { /* Single unfragmented packet */ + total_len = rx_len; + } + + skb = dev_alloc_skb( total_len+5 ); + if (skb == NULL) + { + DEBUG(0,"ray_cs rx_data could not allocate skb\n"); + local->stats.rx_dropped++; + if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) + release_frag_chain(local, prcs); + return; + } + skb_reserve( skb, 2); /* Align IP on 16 byte (TBD check this)*/ + skb->dev = dev; + + DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len); + +/************************/ + /* Reserve enough room for the whole damn packet. */ + rx_ptr = skb_put( skb, total_len); + /* Copy the whole packet to sk_buff */ + rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len); + + /* Now, deal with encapsulation/translation/sniffer */ + if (!sniffer) { + if (!translate) { + /* Encapsulated ethernet, so just lop off 802.11 MAC header */ +/* TBD reserve skb_reserve( skb, RX_MAC_HEADER_LENGTH); */ + skb_pull( skb, RX_MAC_HEADER_LENGTH); + } + else { + /* Do translation */ + untranslate(local, skb, total_len); + } + } + else + { /* sniffer mode, so just pass whole packet */ }; + +/************************/ + /* Now pick up the rest of the fragments if any */ + tmp = 17; + if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) { + prcslink = prcs; + DEBUG(1,"ray_cs rx_data in fragment loop\n"); + do { + prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + + readb(&prcslink->var.rx_packet.next_frag_rcs_index); + rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8) + + readb(&prcslink->var.rx_packet.rx_data_length[1])) + & RX_BUFF_END; + pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8) + + readb(&prcslink->var.rx_packet.rx_data_ptr[1])) + & RX_BUFF_END; + + rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len); + + } while (tmp-- && + readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF); + release_frag_chain(local, prcs); + } + + skb->protocol = eth_type_trans(skb,dev); + netif_rx(skb); + + local->stats.rx_packets++; + local->stats.rx_bytes += skb->len; +} /* end rx_data */ +/*===========================================================================*/ +void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) +{ + snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH); + struct mac_header *pmac = (struct mac_header *)skb->data; + unsigned short type = *(unsigned short *)psnap->ethertype; + unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff; + unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff; + int delta; + struct ethhdr *peth; + UCHAR srcaddr[ADDRLEN]; + UCHAR destaddr[ADDRLEN]; + int i; + + if (local->sparm.b5.a_acting_as_ap_status != TYPE_STA) + memcpy(destaddr, pmac->addr_3, ADDRLEN); + else + memcpy(destaddr, pmac->addr_1, ADDRLEN); + memcpy(srcaddr, pmac->addr_2, ADDRLEN); + + DEBUG(3,"skb->data before untranslate"); + for (i=0;i<64;i++) + DEBUG(3,"%02x ",skb->data[i]); + DEBUG(3,"\ntype = %08x, xsap = %08x, org = %08x\n",type,xsap,org); + DEBUG(3,"untranslate skb->data = %p\n",skb->data); + + if ( xsap != SNAP_ID) { + /* not a snap type so leave it alone */ + DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff); + + delta = RX_MAC_HEADER_LENGTH - ETH_HLEN; + peth = (struct ethhdr *)(skb->data + delta); + peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH); + } + else { /* Its a SNAP */ + if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC */ + DEBUG(3,"ray_cs untranslate Bridge encap\n"); + delta = RX_MAC_HEADER_LENGTH + + sizeof(struct snaphdr_t) - ETH_HLEN; + peth = (struct ethhdr *)(skb->data + delta); + peth->h_proto = type; + } + else { + if (org == RFC1042_ENCAP) { + switch (type) { + case RAY_IPX_TYPE: + case APPLEARP_TYPE: + DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n"); + delta = RX_MAC_HEADER_LENGTH - ETH_HLEN; + peth = (struct ethhdr *)(skb->data + delta); + peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH); + break; + default: + DEBUG(3,"ray_cs untranslate RFC default\n"); + delta = RX_MAC_HEADER_LENGTH + + sizeof(struct snaphdr_t) - ETH_HLEN; + peth = (struct ethhdr *)(skb->data + delta); + peth->h_proto = type; + break; + } + } + else { + printk("ray_cs untranslate very confused by packet\n"); + delta = RX_MAC_HEADER_LENGTH - ETH_HLEN; + peth = (struct ethhdr *)(skb->data + delta); + peth->h_proto = type; + } + } + } +/* TBD reserve skb_reserve(skb, delta); */ + skb_pull(skb, delta); + DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data); + memcpy(peth->h_dest, destaddr, ADDRLEN); + memcpy(peth->h_source, srcaddr, ADDRLEN); + DEBUG(3,"skb->data after untranslate:"); + for (i=0;i<64;i++) + DEBUG(3,"%02x ",skb->data[i]); + DEBUG(3,"\n"); +} /* end untranslate */ +/*===========================================================================*/ +/* Copy data from circular receive buffer to PC memory. + * dest = destination address in PC memory + * pkt_addr = source address in receive buffer + * len = length of packet to copy + */ +int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length) +{ + int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1); + if (wrap_bytes <= 0) + { + memcpy_fromio(dest,local->rmem + pkt_addr,length); + } + else /* Packet wrapped in circular buffer */ + { + memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes); + memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes); + } + return length; +} +/*===========================================================================*/ +void release_frag_chain(ray_dev_t *local, struct rcs* prcs) +{ + struct rcs *prcslink = prcs; + int tmp = 17; + unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index); + + while (tmp--) { + writeb(CCS_BUFFER_FREE, &prcslink->buffer_status); + if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) { + DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex); + break; + } + prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex; + rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index); + } + writeb(CCS_BUFFER_FREE, &prcslink->buffer_status); +} +/*===========================================================================*/ +void authenticate(ray_dev_t *local) +{ + dev_link_t *link = local->finder; + DEBUG(0,"ray_cs Starting authentication.\n"); + if (!(link->state & DEV_PRESENT)) { + DEBUG(1,"ray_cs authenticate - device not present\n"); + return; + } + + del_timer(&local->timer); + if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) { + local->timer.function = &join_net; + } + else { + local->timer.function = &authenticate_timeout; + } + local->timer.expires = jiffies + HZ*2; + local->timer.data = (long)local; + add_timer(&local->timer); + local->authentication_state = AWAITING_RESPONSE; +} /* end authenticate */ +/*===========================================================================*/ +void rx_authenticate(ray_dev_t *local, struct rcs *prcs, + unsigned int pkt_addr, int rx_len) +{ + UCHAR buff[256]; + struct rx_msg *msg = (struct rx_msg *)buff; + + del_timer(&local->timer); + + copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); + /* if we are trying to get authenticated */ + if (local->sparm.b4.a_network_type == ADHOC) { + DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]); + if (msg->var[2] == 1) { + DEBUG(0,"ray_cs Sending authentication response.\n"); + if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) { + local->authentication_state = NEED_TO_AUTH; + memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN); + } + } + } + else /* Infrastructure network */ + { + if (local->authentication_state == AWAITING_RESPONSE) { + /* Verify authentication sequence #2 and success */ + if (msg->var[2] == 2) { + if ((msg->var[3] | msg->var[4]) == 0) { + DEBUG(1,"Authentication successful\n"); + local->card_status = CARD_AUTH_COMPLETE; + associate(local); + local->authentication_state = AUTHENTICATED; + } + else { + DEBUG(0,"Authentication refused\n"); + local->card_status = CARD_AUTH_REFUSED; + join_net((u_long)local); + local->authentication_state = UNAUTHENTICATED; + } + } + } + } + +} /* end rx_authenticate */ +/*===========================================================================*/ +void associate(ray_dev_t *local) +{ + struct ccs *pccs; + dev_link_t *link = local->finder; + struct net_device *dev = link->priv; + int ccsindex; + if (!(link->state & DEV_PRESENT)) { + DEBUG(1,"ray_cs associate - device not present\n"); + return; + } + /* If no tx buffers available, return*/ + if ((ccsindex = get_free_ccs(local)) == -1) + { +/* TBD should never be here but... what if we are? */ + DEBUG(1,"ray_cs associate - No free ccs\n"); + return; + } + DEBUG(1,"ray_cs Starting association with access point\n"); + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + /* fill in the CCS */ + writeb(CCS_START_ASSOCIATION, &pccs->cmd); + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + + del_timer(&local->timer); + local->timer.expires = jiffies + HZ*2; + local->timer.data = (long)local; + local->timer.function = &join_net; + add_timer(&local->timer); + local->card_status = CARD_ASSOC_FAILED; + return; + } + if (!sniffer) dev->tbusy = 0; + +} /* end associate */ +/*===========================================================================*/ +void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, + unsigned int pkt_addr, int rx_len) +{ +/* UCHAR buff[256]; + struct rx_msg *msg = (struct rx_msg *)buff; +*/ + DEBUG(0,"Deauthentication frame received\n"); + local->authentication_state = UNAUTHENTICATED; + /* Need to reauthenticate or rejoin depending on reason code */ +/* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); + */ +} +/*===========================================================================*/ +void clear_interrupt(ray_dev_t *local) +{ + writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET); +} +/*===========================================================================*/ +#ifdef CONFIG_PROC_FS +#define MAXDATA (PAGE_SIZE - 80) + +static char *card_status[] = { + "Card inserted - uninitialized", /* 0 */ + "Card not downloaded", /* 1 */ + "Waiting for download parameters", /* 2 */ + "Card doing acquisition", /* 3 */ + "Acquisition complete", /* 4 */ + "Authentication complete", /* 5 */ + "Association complete", /* 6 */ + "???", "???", "???", "???", /* 7 8 9 10 undefined */ + "Card init error", /* 11 */ + "Download parameters error", /* 12 */ + "???", /* 13 */ + "Acquisition failed", /* 14 */ + "Authentication refused", /* 15 */ + "Association failed" /* 16 */ +}; + +static char *nettype[] = {"Adhoc", "Infra "}; +static char *framing[] = {"Encapsulation", "Translation"} +; +/*===========================================================================*/ +int ray_cs_proc_read(char *buf, char **start, off_t offset, + int len, int unused) +{ +/* Print current values which are not available via other means + * eg ifconfig + */ + int i; + dev_link_t *link = dev_list; + struct net_device *dev = (struct net_device *)link->priv; + ray_dev_t *local = (ray_dev_t *)dev->priv; + UCHAR *p; + struct freq_hop_element *pfh; + UCHAR c[33]; + + len = 0; + + len += sprintf(buf + len, "Raylink Wireless LAN driver status\n"); + len += sprintf(buf + len, "%s\n", rcsid); + /* build 4 does not report version, and field is 0x55 after memtest */ + len += sprintf(buf + len, "Firmware version = "); + if (local->fw_ver == 0x55) + len += sprintf(buf + len, "4 - Use dump_cis for more details\n"); + else + len += sprintf(buf + len, "%2d.%02d.%02d\n", + local->fw_ver, local->fw_bld, local->fw_var); + + for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i]; + c[32] = 0; + len += sprintf(buf + len, "%s network ESSID = \"%s\"\n", + nettype[local->sparm.b5.a_network_type], c); + + p = local->bss_id; + len += sprintf(buf + len, + "BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", + p[0],p[1],p[2],p[3],p[4],p[5]); + + len += sprintf(buf + len, "Country code = %d\n", + local->sparm.b5.a_curr_country_code); + + i = local->card_status; + if (i < 0) i = 10; + if (i > 16) i = 10; + len += sprintf(buf + len, "Card status = %s\n", card_status[i]); + + len += sprintf(buf + len, "Framing mode = %s\n",framing[translate]); + + /* Pull some fields out of last beacon received */ + len += sprintf(buf + len, "Beacon Interval = %d Kus\n", + local->last_bcn.beacon_intvl[0] + + 256 * local->last_bcn.beacon_intvl[1]); + + p = local->last_bcn.elements; + if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2; + else { + len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]); + return len; + } + + if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) { + len += sprintf(buf + len, "Supported rate codes = "); + for (i=2; i<p[1] + 2; i++) + len += sprintf(buf + len, "0x%02x ", p[i]); + len += sprintf(buf + len, "\n"); + p += p[1] + 2; + } + else { + len += sprintf(buf + len, "Parse beacon failed at rates element\n"); + return len; + } + + if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) { + pfh = (struct freq_hop_element *)p; + len += sprintf(buf + len, "Hop dwell = %d Kus\n", + pfh->dwell_time[0] + 256 * pfh->dwell_time[1]); + len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set); + len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern); + len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index); + p += p[1] + 2; + } + else { + len += sprintf(buf + len, "Parse beacon failed at FH param element\n"); + return len; + } + return len; +} + +#endif +/*===========================================================================*/ +int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) +{ + int addr; + struct ccs *pccs; + struct tx_msg *ptx; + int ccsindex; + + /* If no tx buffers available, return */ + if ((ccsindex = get_free_tx_ccs(local)) == -1) + { +/* TBD should never be here but... what if we are? */ + DEBUG(1,"ray_cs send authenticate - No free tx ccs\n"); + return -1; + } + + pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; + + /* Address in card space */ + addr = TX_BUF_BASE + (ccsindex << 11); + /* fill in the CCS */ + writeb(CCS_TX_REQUEST, &pccs->cmd); + writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr); + writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1); + writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length); + writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1); + writeb(0, &pccs->var.tx_request.pow_sav_mode); + + ptx = (struct tx_msg *)(local->sram + addr); + /* fill in the mac header */ + writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1); + writeb(0, &ptx->mac.frame_ctl_2); + + memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN); + memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN); + memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN); + + /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */ + memset_io(ptx->var, 0, 6); + writeb(auth_type & 0xff, ptx->var + 2); + + /* Interrupt the firmware to process the command */ + if (interrupt_ecf(local, ccsindex)) { + DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n"); + writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); + return -1; + } + return 0; +} /* End build_auth_frame */ +/*===========================================================================*/ +static int __init init_ray_cs(void) +{ + int rc; + servinfo_t serv; + + DEBUG(1, "%s\n", rcsid); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "ray: Card Services release does not match!\n"); + return -1; + } + rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach); + DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc); +#ifdef CONFIG_PROC_FS + proc_register(&proc_root, &ray_cs_proc_entry); +#endif + if (translate != 0) translate = 1; + return 0; +} /* init_ray_cs */ + +#ifndef MODULE + +static char init_ess_id[ESSID_SIZE]; +static int __init essid_setup(char *str) +{ + strncpy(init_ess_id, str, ESSID_SIZE); + essid = init_ess_id; + return 1; +} +__setup("essid=", essid_setup); + +#endif + +/*===========================================================================*/ + +static void __exit exit_ray_cs(void) +{ + DEBUG(0, "ray_cs: cleanup_module\n"); + + unregister_pcmcia_driver(&dev_info); + while (dev_list != NULL) { + if (dev_list->state & DEV_CONFIG) ray_release((u_long)dev_list); + ray_detach(dev_list); + } +#ifdef CONFIG_PROC_FS + proc_unregister(&proc_root, ray_cs_proc_entry.low_ino); +#endif +} /* exit_ray_cs */ + +module_init(init_ray_cs); +module_exit(exit_ray_cs); + +/*===========================================================================*/ diff --git a/drivers/net/pcmcia/ray_cs.h b/drivers/net/pcmcia/ray_cs.h new file mode 100644 index 000000000..28502954e --- /dev/null +++ b/drivers/net/pcmcia/ray_cs.h @@ -0,0 +1,60 @@ +/* Raytheon wireless LAN PCMCIA card driver for Linux + A PCMCIA client driver for the Raylink wireless network card + Written by Corey Thomas +*/ + +#ifndef RAYLINK_H + +struct beacon_rx { + struct mac_header mac; + UCHAR timestamp[8]; + UCHAR beacon_intvl[2]; + UCHAR capability[2]; + UCHAR elements[sizeof(struct essid_element) + + sizeof(struct rates_element) + + sizeof(struct freq_hop_element) + + sizeof(struct japan_call_sign_element) + + sizeof(struct tim_element)]; +}; + +typedef struct ray_dev_t { + int card_status; + int authentication_state; + dev_node_t node; + window_handle_t amem_handle; /* handle to window for attribute memory */ + window_handle_t rmem_handle; /* handle to window for rx buffer on card */ + UCHAR *sram; /* pointer to beginning of shared RAM */ + UCHAR *amem; /* pointer to attribute mem window */ + UCHAR *rmem; /* pointer to receive buffer window */ + dev_link_t *finder; /* pointer back to dev_link_t for card */ + struct timer_list timer; + int dl_param_ccs; + union { + struct b4_startup_params b4; + struct b5_startup_params b5; + } sparm; + int timeout_flag; + UCHAR supported_rates[8]; + UCHAR japan_call_sign[12]; + struct startup_res_6 startup_res; + int num_multi; + /* Network parameters from start/join */ + UCHAR bss_id[6]; + UCHAR auth_id[6]; + UCHAR net_default_tx_rate; + UCHAR encryption; + struct enet_statistics stats; + + UCHAR net_type; + UCHAR sta_type; + UCHAR fw_ver; + UCHAR fw_bld; + UCHAR fw_var; + UCHAR ASIC_version; + UCHAR assoc_id[2]; + UCHAR tib_length; + struct beacon_rx last_bcn; +} ray_dev_t; +/*****************************************************************************/ + +#endif /* RAYLINK_H */ diff --git a/drivers/net/pcmcia/rayctl.h b/drivers/net/pcmcia/rayctl.h new file mode 100644 index 000000000..a301b0bd2 --- /dev/null +++ b/drivers/net/pcmcia/rayctl.h @@ -0,0 +1,725 @@ +#ifndef RAYLINK_H + +typedef unsigned char UCHAR; + +/****** IEEE 802.11 constants ************************************************/ +#define ADDRLEN 6 +/* Frame control 1 bit fields */ +#define PROTOCOL_VER 0x00 +#define DATA_TYPE 0x08 +#define ASSOC_REQ_TYPE 0x00 +#define ASSOC_RESP_TYPE 0x10 +#define REASSOC_REQ_TYPE 0x20 +#define REASSOC_RESP_TYPE 0x30 +#define NULL_MSG_TYPE 0x48 +#define BEACON_TYPE 0x80 +#define DISASSOC_TYPE 0xA0 +#define PSPOLL_TYPE 0xA4 +#define AUTHENTIC_TYPE 0xB0 +#define DEAUTHENTIC_TYPE 0xC0 +/* Frame control 2 bit fields */ +#define FC2_TO_DS 0x01 +#define FC2_FROM_DS 0x02 +#define FC2_MORE_FRAG 0x04 +#define FC2_RETRY 0x08 +#define FC2_PSM 0x10 +#define FC2_MORE_DATA 0x20 +#define FC2_WEP 0x40 +#define FC2_ORDER 0x80 +/*****************************************************************************/ +/* 802.11 element ID's and lengths */ +#define C_BP_CAPABILITY_ESS 0x01 +#define C_BP_CAPABILITY_IBSS 0x02 +#define C_BP_CAPABILITY_CF_POLLABLE 0x04 +#define C_BP_CAPABILITY_CF_POLL_REQUEST 0x08 +#define C_BP_CAPABILITY_PRIVACY 0x10 + +#define C_ESSID_ELEMENT_ID 0 +#define C_ESSID_ELEMENT_MAX_LENGTH 32 + +#define C_SUPPORTED_RATES_ELEMENT_ID 1 +#define C_SUPPORTED_RATES_ELEMENT_LENGTH 2 + +#define C_FH_PARAM_SET_ELEMENT_ID 2 +#define C_FH_PARAM_SET_ELEMENT_LNGTH 5 + +#define C_CF_PARAM_SET_ELEMENT_ID 4 +#define C_CF_PARAM_SET_ELEMENT_LNGTH 6 + +#define C_TIM_ELEMENT_ID 5 +#define C_TIM_BITMAP_LENGTH 251 +#define C_TIM_BMCAST_BIT 0x01 + +#define C_IBSS_ELEMENT_ID 6 +#define C_IBSS_ELEMENT_LENGTH 2 + +#define C_JAPAN_CALL_SIGN_ELEMENT_ID 51 +#define C_JAPAN_CALL_SIGN_ELEMENT_LNGTH 12 + +#define C_DISASSOC_REASON_CODE_LEN 2 +#define C_DISASSOC_REASON_CODE_DEFAULT 8 + +#define C_CRC_LEN 4 +#define C_NUM_SUPPORTED_RATES 8 +/****** IEEE 802.11 mac header for type data packets *************************/ +struct mac_header { + UCHAR frame_ctl_1; + UCHAR frame_ctl_2; + UCHAR duration_lsb; + UCHAR duration_msb; + UCHAR addr_1[ADDRLEN]; + UCHAR addr_2[ADDRLEN]; + UCHAR addr_3[ADDRLEN]; + UCHAR seq_frag_num[2]; +/* UCHAR addr_4[ADDRLEN]; *//* only present for AP to AP (TO DS and FROM DS */ +}; +/****** IEEE 802.11 frame element structures *********************************/ +struct essid_element +{ + UCHAR id; + UCHAR length; + UCHAR text[C_ESSID_ELEMENT_MAX_LENGTH]; +}; +struct rates_element +{ + UCHAR id; + UCHAR length; + UCHAR value[8]; +}; +struct freq_hop_element +{ + UCHAR id; + UCHAR length; + UCHAR dwell_time[2]; + UCHAR hop_set; + UCHAR hop_pattern; + UCHAR hop_index; +}; +struct tim_element +{ + UCHAR id; + UCHAR length; + UCHAR dtim_count; + UCHAR dtim_period; + UCHAR bitmap_control; + UCHAR tim[C_TIM_BITMAP_LENGTH]; +}; +struct ibss_element +{ + UCHAR id; + UCHAR length; + UCHAR atim_window[2]; +}; +struct japan_call_sign_element +{ + UCHAR id; + UCHAR length; + UCHAR call_sign[12]; +}; +/****** Beacon message structures ********************************************/ +/* .elements is a large lump of max size because elements are variable size */ +struct infra_beacon +{ + UCHAR timestamp[8]; + UCHAR beacon_intvl[2]; + UCHAR capability[2]; + UCHAR elements[sizeof(struct essid_element) + + sizeof(struct rates_element) + + sizeof(struct freq_hop_element) + + sizeof(struct japan_call_sign_element) + + sizeof(struct tim_element)]; +}; +struct adhoc_beacon +{ + UCHAR timestamp[8]; + UCHAR beacon_intvl[2]; + UCHAR capability[2]; + UCHAR elements[sizeof(struct essid_element) + + sizeof(struct rates_element) + + sizeof(struct freq_hop_element) + + sizeof(struct japan_call_sign_element) + + sizeof(struct ibss_element)]; +}; +/*****************************************************************************/ +/*****************************************************************************/ + + +/* #define C_MAC_HDR_2_WEP 0x40 */ +/* TX/RX CCS constants */ +#define TX_HEADER_LENGTH 0x1C +#define RX_MAC_HEADER_LENGTH 0x18 +#define TX_AUTHENTICATE_LENGTH (TX_HEADER_LENGTH + 6) +#define TX_AUTHENTICATE_LENGTH_MSB (TX_AUTHENTICATE_LENGTH >> 8) +#define TX_AUTHENTICATE_LENGTH_LSB (TX_AUTHENTICATE_LENGTH & 0xff) +#define FCS_LEN 4 + +#define ADHOC 0 +#define INFRA 1 + +#define TYPE_STA 0 +#define TYPE_AP 1 + +#define PASSIVE_SCAN 1 +#define ACTIVE_SCAN 1 + +#define PSM_CAM 0 + +/* Country codes */ +#define USA 1 +#define EUROPE 2 +#define JAPAN 3 +#define KOREA 4 +#define SPAIN 5 +#define FRANCE 6 +#define ISRAEL 7 +#define AUSTRALIA 8 +#define JAPAN_TEST 9 + +/* Hop pattern lengths */ +#define USA_HOP_MOD 79 +#define EUROPE_HOP_MOD 79 +#define JAPAN_HOP_MOD 23 +#define KOREA_HOP_MOD 23 +#define SPAIN_HOP_MOD 27 +#define FRANCE_HOP_MOD 35 +#define ISRAEL_HOP_MOD 35 +#define AUSTRALIA_HOP_MOD 47 +#define JAPAN_TEST_HOP_MOD 23 + +#define ESSID_SIZE 32 +/**********************************************************************/ +/* CIS Register Constants */ +#define CIS_OFFSET 0x0f00 +/* Configuration Option Register (0x0F00) */ +#define COR_OFFSET 0x00 +#define COR_SOFT_RESET 0x80 +#define COR_LEVEL_IRQ 0x40 +#define COR_CONFIG_NUM 0x01 +#define COR_DEFAULT (COR_LEVEL_IRQ | COR_CONFIG_NUM) + +/* Card Configuration and Status Register (0x0F01) */ +#define CCSR_OFFSET 0x01 +#define CCSR_HOST_INTR_PENDING 0x01 +#define CCSR_POWER_DOWN 0x04 + +/* HCS Interrupt Register (0x0F05) */ +#define HCS_INTR_OFFSET 0x05 +/* #define HCS_INTR_OFFSET 0x0A */ +#define HCS_INTR_CLEAR 0x00 + +/* ECF Interrupt Register (0x0F06) */ +#define ECF_INTR_OFFSET 0x06 +/* #define ECF_INTR_OFFSET 0x0C */ +#define ECF_INTR_SET 0x01 + +/* Authorization Register 0 (0x0F08) */ +#define AUTH_0_ON 0x57 + +/* Authorization Register 1 (0x0F09) */ +#define AUTH_1_ON 0x82 + +/* Program Mode Register (0x0F0A) */ +#define PC2PM 0x02 +#define PC2CAL 0x10 +#define PC2MLSE 0x20 + +/* PC Test Mode Register (0x0F0B) */ +#define PC_TEST_MODE 0x08 + +/* Frequency Control Word (0x0F10) */ +/* Range 0x02 - 0xA6 */ + +/* Test Mode Control 1-4 (0x0F14 - 0x0F17) */ + +/**********************************************************************/ + +/* Shared RAM Area */ +#define SCB_BASE 0x0000 +#define STATUS_BASE 0x0100 +#define HOST_TO_ECF_BASE 0x0200 +#define ECF_TO_HOST_BASE 0x0300 +#define CCS_BASE 0x0400 +#define RCS_BASE 0x0800 +#define INFRA_TIM_BASE 0x0C00 +#define SSID_LIST_BASE 0x0D00 +#define TX_BUF_BASE 0x1000 +#define RX_BUF_BASE 0x8000 + +#define NUMBER_OF_CCS 64 +#define NUMBER_OF_RCS 64 +/*#define NUMBER_OF_TX_CCS 14 */ +#define NUMBER_OF_TX_CCS 14 + +#define TX_BUF_SIZE (2048 - sizeof(struct tx_msg)) +#define RX_BUFF_END 0x3FFF +/* Values for buffer_status */ +#define CCS_BUFFER_FREE 0 +#define CCS_BUFFER_BUSY 1 +#define CCS_COMMAND_COMPLETE 2 +#define CCS_COMMAND_FAILED 3 + +/* Values for cmd */ +#define CCS_DOWNLOAD_STARTUP_PARAMS 1 +#define CCS_UPDATE_PARAMS 2 +#define CCS_REPORT_PARAMS 3 +#define CCS_UPDATE_MULTICAST_LIST 4 +#define CCS_UPDATE_POWER_SAVINGS_MODE 5 +#define CCS_START_NETWORK 6 +#define CCS_JOIN_NETWORK 7 +#define CCS_START_ASSOCIATION 8 +#define CCS_TX_REQUEST 9 +#define CCS_TEST_MEMORY 0xa +#define CCS_SHUTDOWN 0xb +#define CCS_DUMP_MEMORY 0xc +#define CCS_START_TIMER 0xe +#define CCS_LAST_CMD CCS_START_TIMER + +/* Values for link field */ +#define CCS_END_LIST 0xff + +/* values for buffer_status field */ +#define RCS_BUFFER_FREE 0 +#define RCS_BUFFER_BUSY 1 +#define RCS_COMPLETE 2 +#define RCS_FAILED 3 +#define RCS_BUFFER_RELEASE 0xFF + +/* values for interrupt_id field */ +#define PROCESS_RX_PACKET 0x80 /* */ +#define REJOIN_NET_COMPLETE 0x81 /* RCS ID: Rejoin Net Complete */ +#define ROAMING_INITIATED 0x82 /* RCS ID: Roaming Initiated */ +#define JAPAN_CALL_SIGN_RXD 0x83 /* RCS ID: New Japan Call Sign */ + +/*****************************************************************************/ +/* Memory types for dump memory command */ +#define C_MEM_PROG 0 +#define C_MEM_XDATA 1 +#define C_MEM_SFR 2 +#define C_MEM_IDATA 3 + +/*** Return values for hw_xmit **********/ +#define XMIT_OK (0) +#define XMIT_MSG_BAD (-1) +#define XMIT_NO_CCS (-2) +#define XMIT_NO_INTR (-3) +#define XMIT_NEED_AUTH (-4) + +/*** Values for card status */ +#define CARD_INSERTED (0) + +#define CARD_AWAITING_PARAM (1) +#define CARD_INIT_ERROR (11) + +#define CARD_DL_PARAM (2) +#define CARD_DL_PARAM_ERROR (12) + +#define CARD_DOING_ACQ (3) + +#define CARD_ACQ_COMPLETE (4) +#define CARD_ACQ_FAILED (14) + +#define CARD_AUTH_COMPLETE (5) +#define CARD_AUTH_REFUSED (15) + +#define CARD_ASSOC_COMPLETE (6) +#define CARD_ASSOC_FAILED (16) + +/*** Values for authentication_state */ +#define UNAUTHENTICATED (0) +#define AWAITING_RESPONSE (1) +#define AUTHENTICATED (2) +#define NEED_TO_AUTH (3) + +/*** Values for authentication type */ +#define OPEN_AUTH_REQUEST (1) +#define OPEN_AUTH_RESPONSE (2) + + +/***********************************************************************/ +/* Parameter passing structure for update/report parameter CCS's */ +struct object_id { + void *object_addr; + unsigned char object_length; +}; + +#define OBJID_network_type 0 +#define OBJID_acting_as_ap_status 1 +#define OBJID_current_ess_id 2 +#define OBJID_scanning_mode 3 +#define OBJID_power_mgt_state 4 +#define OBJID_mac_address 5 +#define OBJID_frag_threshold 6 +#define OBJID_hop_time 7 +#define OBJID_beacon_period 8 +#define OBJID_dtim_period 9 +#define OBJID_retry_max 10 +#define OBJID_ack_timeout 11 +#define OBJID_sifs 12 +#define OBJID_difs 13 +#define OBJID_pifs 14 +#define OBJID_rts_threshold 15 +#define OBJID_scan_dwell_time 16 +#define OBJID_max_scan_dwell_time 17 +#define OBJID_assoc_resp_timeout 18 +#define OBJID_adhoc_scan_cycle_max 19 +#define OBJID_infra_scan_cycle_max 20 +#define OBJID_infra_super_cycle_max 21 +#define OBJID_promiscuous_mode 22 +#define OBJID_unique_word 23 +#define OBJID_slot_time 24 +#define OBJID_roaming_low_snr 25 +#define OBJID_low_snr_count_thresh 26 +#define OBJID_infra_missed_bcn 27 +#define OBJID_adhoc_missed_bcn 28 +#define OBJID_curr_country_code 29 +#define OBJID_hop_pattern 30 +#define OBJID_reserved 31 +#define OBJID_cw_max_msb 32 +#define OBJID_cw_min_msb 33 +#define OBJID_noise_filter_gain 34 +#define OBJID_noise_limit_offset 35 +#define OBJID_det_rssi_thresh_offset 36 +#define OBJID_med_busy_thresh_offset 37 +#define OBJID_det_sync_thresh 38 +#define OBJID_test_mode 39 +#define OBJID_test_min_chan_num 40 +#define OBJID_test_max_chan_num 41 +#define OBJID_allow_bcast_ID_prbrsp 42 +#define OBJID_privacy_must_start 43 +#define OBJID_privacy_can_join 44 +#define OBJID_basic_rate_set 45 + +/**** Configuration/Status/Control Area ***************************/ +/* System Control Block (SCB) Area + * Located at Shared RAM offset 0 + */ +struct scb { + UCHAR ccs_index; + UCHAR rcs_index; +}; + +/****** Status area at Shared RAM offset 0x0100 ******************************/ +struct status { + UCHAR mrx_overflow_for_host; /* 0=ECF may write, 1=host may write*/ + UCHAR mrx_checksum_error_for_host; /* 0=ECF may write, 1=host may write*/ + UCHAR rx_hec_error_for_host; /* 0=ECF may write, 1=host may write*/ + UCHAR reserved1; + short mrx_overflow; /* ECF increments on rx overflow */ + short mrx_checksum_error; /* ECF increments on rx CRC error */ + short rx_hec_error; /* ECF incs on mac header CRC error */ + UCHAR rxnoise; /* Average RSL measurement */ +}; + +/****** Host-to-ECF Data Area at Shared RAM offset 0x200 *********************/ +struct host_to_ecf_area { + +}; + +/****** ECF-to-Host Data Area at Shared RAM offset 0x0300 ********************/ +struct startup_res_518 { + UCHAR startup_word; + UCHAR station_addr[ADDRLEN]; + UCHAR calc_prog_chksum; + UCHAR calc_cis_chksum; + UCHAR ecf_spare[7]; + UCHAR japan_call_sign[12]; +}; + +struct startup_res_6 { + UCHAR startup_word; + UCHAR station_addr[ADDRLEN]; + UCHAR reserved; + UCHAR supp_rates[8]; + UCHAR japan_call_sign[12]; + UCHAR calc_prog_chksum; + UCHAR calc_cis_chksum; + UCHAR firmware_version[3]; + UCHAR asic_version; + UCHAR tib_length; +}; + +struct start_join_net_params { + UCHAR net_type; + UCHAR ssid[ESSID_SIZE]; + UCHAR reserved; + UCHAR privacy_can_join; +}; + +/****** Command Control Structure area at Shared ram offset 0x0400 ***********/ +/* Structures for command specific parameters (ccs.var) */ +struct update_param_cmd { + UCHAR object_id; + UCHAR number_objects; + UCHAR failure_cause; +}; +struct report_param_cmd { + UCHAR object_id; + UCHAR number_objects; + UCHAR failure_cause; + UCHAR length; +}; +struct start_network_cmd { + UCHAR update_param; + UCHAR bssid[ADDRLEN]; + UCHAR net_initiated; + UCHAR net_default_tx_rate; + UCHAR encryption; +}; +struct join_network_cmd { + UCHAR update_param; + UCHAR bssid[ADDRLEN]; + UCHAR net_initiated; + UCHAR net_default_tx_rate; + UCHAR encryption; +}; +struct tx_requested_cmd { + + UCHAR tx_data_ptr[2]; + UCHAR tx_data_length[2]; + UCHAR host_reserved[2]; + UCHAR reserved[3]; + UCHAR tx_rate; + UCHAR pow_sav_mode; + UCHAR retries; + UCHAR antenna; +}; +struct tx_requested_cmd_4 { + + UCHAR tx_data_ptr[2]; + UCHAR tx_data_length[2]; + UCHAR dest_addr[ADDRLEN]; + UCHAR pow_sav_mode; + UCHAR retries; + UCHAR station_id; +}; +struct memory_dump_cmd { + UCHAR memory_type; + UCHAR memory_ptr[2]; + UCHAR length; +}; +struct update_association_cmd { + UCHAR status; + UCHAR aid[2]; +}; +struct start_timer_cmd { + UCHAR duration[2]; +}; + +struct ccs { + UCHAR buffer_status; /* 0 = buffer free, 1 = buffer busy */ + /* 2 = command complete, 3 = failed */ + UCHAR cmd; /* command to ECF */ + UCHAR link; /* link to next CCS, FF=end of list */ + /* command specific parameters */ + union { + char reserved[13]; + struct update_param_cmd update_param; + struct report_param_cmd report_param; + UCHAR nummulticast; + UCHAR mode; + struct start_network_cmd start_network; + struct join_network_cmd join_network; + struct tx_requested_cmd tx_request; + struct memory_dump_cmd memory_dump; + struct update_association_cmd update_assoc; + struct start_timer_cmd start_timer; + } var; +}; + +/*****************************************************************************/ +/* Transmit buffer structures */ +struct tib_structure { + UCHAR ccs_index; + UCHAR psm; + UCHAR pass_fail; + UCHAR retry_count; + UCHAR max_retries; + UCHAR frags_remaining; + UCHAR no_rb; + UCHAR rts_reqd; + UCHAR csma_tx_cntrl_2; + UCHAR sifs_tx_cntrl_2; + UCHAR tx_dma_addr_1[2]; + UCHAR tx_dma_addr_2[2]; + UCHAR var_dur_2mhz[2]; + UCHAR var_dur_1mhz[2]; + UCHAR max_dur_2mhz[2]; + UCHAR max_dur_1mhz[2]; + UCHAR hdr_len; + UCHAR max_frag_len[2]; + UCHAR var_len[2]; + UCHAR phy_hdr_4; + UCHAR mac_hdr_1; + UCHAR mac_hdr_2; + UCHAR sid[2]; +}; + +struct phy_header { + UCHAR sfd[2]; + UCHAR hdr_3; + UCHAR hdr_4; +}; +struct rx_msg { + struct mac_header mac; + UCHAR var[1]; +}; + +struct tx_msg { + struct tib_structure tib; + struct phy_header phy; + struct mac_header mac; + UCHAR var[1]; +}; + +/****** ECF Receive Control Stucture (RCS) Area at Shared RAM offset 0x0800 */ +/* Structures for command specific parameters (rcs.var) */ +struct rx_packet_cmd { + UCHAR rx_data_ptr[2]; + UCHAR rx_data_length[2]; + UCHAR rx_sig_lev; + UCHAR next_frag_rcs_index; + UCHAR totalpacketlength[2]; +}; +struct rejoin_net_cmplt_cmd { + UCHAR reserved; + UCHAR bssid[ADDRLEN]; +}; +struct japan_call_sign_rxd { + UCHAR rxd_call_sign[8]; + UCHAR reserved[5]; +}; + +struct rcs { + UCHAR buffer_status; + UCHAR interrupt_id; + UCHAR link_field; + /* command specific parameters */ + union { + UCHAR reserved[13]; + struct rx_packet_cmd rx_packet; + struct rejoin_net_cmplt_cmd rejoin_net_complete; + struct japan_call_sign_rxd japan_call_sign; + } var; +}; + +/****** Startup parameter structures for both versions of firmware ***********/ +struct b4_startup_params { + UCHAR a_network_type; /* C_ADHOC, C_INFRA */ + UCHAR a_acting_as_ap_status; /* C_TYPE_STA, C_TYPE_AP */ + UCHAR a_current_ess_id[ESSID_SIZE]; /* Null terminated unless 32 long */ + UCHAR a_scanning_mode; /* passive 0, active 1 */ + UCHAR a_power_mgt_state; /* CAM 0, */ + UCHAR a_mac_addr[ADDRLEN]; /* */ + UCHAR a_frag_threshold[2]; /* 512 */ + UCHAR a_hop_time[2]; /* 16k * 2**n, n=0-4 in Kus */ + UCHAR a_beacon_period[2]; /* n * a_hop_time in Kus */ + UCHAR a_dtim_period; /* in beacons */ + UCHAR a_retry_max; /* */ + UCHAR a_ack_timeout; /* */ + UCHAR a_sifs; /* */ + UCHAR a_difs; /* */ + UCHAR a_pifs; /* */ + UCHAR a_rts_threshold[2]; /* */ + UCHAR a_scan_dwell_time[2]; /* */ + UCHAR a_max_scan_dwell_time[2]; /* */ + UCHAR a_assoc_resp_timeout_thresh; /* */ + UCHAR a_adhoc_scan_cycle_max; /* */ + UCHAR a_infra_scan_cycle_max; /* */ + UCHAR a_infra_super_scan_cycle_max; /* */ + UCHAR a_promiscuous_mode; /* */ + UCHAR a_unique_word[2]; /* */ + UCHAR a_slot_time; /* */ + UCHAR a_roaming_low_snr_thresh; /* */ + UCHAR a_low_snr_count_thresh; /* */ + UCHAR a_infra_missed_bcn_thresh; /* */ + UCHAR a_adhoc_missed_bcn_thresh; /* */ + UCHAR a_curr_country_code; /* C_USA */ + UCHAR a_hop_pattern; /* */ + UCHAR a_hop_pattern_length; /* */ +/* b4 - b5 differences start here */ + UCHAR a_cw_max; /* */ + UCHAR a_cw_min; /* */ + UCHAR a_noise_filter_gain; /* */ + UCHAR a_noise_limit_offset; /* */ + UCHAR a_det_rssi_thresh_offset; /* */ + UCHAR a_med_busy_thresh_offset; /* */ + UCHAR a_det_sync_thresh; /* */ + UCHAR a_test_mode; /* */ + UCHAR a_test_min_chan_num; /* */ + UCHAR a_test_max_chan_num; /* */ + UCHAR a_rx_tx_delay; /* */ + UCHAR a_current_bss_id[ADDRLEN]; /* */ + UCHAR a_hop_set; /* */ +}; +struct b5_startup_params { + UCHAR a_network_type; /* C_ADHOC, C_INFRA */ + UCHAR a_acting_as_ap_status; /* C_TYPE_STA, C_TYPE_AP */ + UCHAR a_current_ess_id[ESSID_SIZE]; /* Null terminated unless 32 long */ + UCHAR a_scanning_mode; /* passive 0, active 1 */ + UCHAR a_power_mgt_state; /* CAM 0, */ + UCHAR a_mac_addr[ADDRLEN]; /* */ + UCHAR a_frag_threshold[2]; /* 512 */ + UCHAR a_hop_time[2]; /* 16k * 2**n, n=0-4 in Kus */ + UCHAR a_beacon_period[2]; /* n * a_hop_time in Kus */ + UCHAR a_dtim_period; /* in beacons */ + UCHAR a_retry_max; /* 4 */ + UCHAR a_ack_timeout; /* */ + UCHAR a_sifs; /* */ + UCHAR a_difs; /* */ + UCHAR a_pifs; /* */ + UCHAR a_rts_threshold[2]; /* */ + UCHAR a_scan_dwell_time[2]; /* */ + UCHAR a_max_scan_dwell_time[2]; /* */ + UCHAR a_assoc_resp_timeout_thresh; /* */ + UCHAR a_adhoc_scan_cycle_max; /* */ + UCHAR a_infra_scan_cycle_max; /* */ + UCHAR a_infra_super_scan_cycle_max; /* */ + UCHAR a_promiscuous_mode; /* */ + UCHAR a_unique_word[2]; /* */ + UCHAR a_slot_time; /* */ + UCHAR a_roaming_low_snr_thresh; /* */ + UCHAR a_low_snr_count_thresh; /* */ + UCHAR a_infra_missed_bcn_thresh; /* */ + UCHAR a_adhoc_missed_bcn_thresh; /* */ + UCHAR a_curr_country_code; /* C_USA */ + UCHAR a_hop_pattern; /* */ + UCHAR a_hop_pattern_length; /* */ +/* b4 - b5 differences start here */ + UCHAR a_cw_max[2]; /* */ + UCHAR a_cw_min[2]; /* */ + UCHAR a_noise_filter_gain; /* */ + UCHAR a_noise_limit_offset; /* */ + UCHAR a_det_rssi_thresh_offset; /* */ + UCHAR a_med_busy_thresh_offset; /* */ + UCHAR a_det_sync_thresh; /* */ + UCHAR a_test_mode; /* */ + UCHAR a_test_min_chan_num; /* */ + UCHAR a_test_max_chan_num; /* */ + UCHAR a_allow_bcast_SSID_probe_rsp; + UCHAR a_privacy_must_start; + UCHAR a_privacy_can_join; + UCHAR a_basic_rate_set[8]; +}; + +/*****************************************************************************/ +#define RAY_IOCG_PARMS (SIOCDEVPRIVATE) +#define RAY_IOCS_PARMS (SIOCDEVPRIVATE + 1) +#define RAY_DO_CMD (SIOCDEVPRIVATE + 2) + +/****** ethernet <-> 802.11 translation **************************************/ +typedef struct snaphdr_t +{ + UCHAR dsap; + UCHAR ssap; + UCHAR ctrl; + UCHAR org[3]; + UCHAR ethertype[2]; +} snaphdr_t; + +#define BRIDGE_ENCAP 0xf80000 +#define RFC1042_ENCAP 0 +#define SNAP_ID 0x0003aaaa +#define RAY_IPX_TYPE 0x8137 +#define APPLEARP_TYPE 0x80f3 +/*****************************************************************************/ +#endif /* #ifndef RAYLINK_H */ diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 8f13de814..9d9a8029f 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -13,13 +13,10 @@ * This driver is for PCnet32 and PCnetPCI based ethercards */ -static const char *version = "pcnet32.c:v1.21 31.3.99 tsbogend@alpha.franken.de\n"; +static const char *version = "pcnet32.c:v1.23ac 21.9.1999 tsbogend@alpha.franken.de\n"; #include <linux/config.h> #include <linux/module.h> -#ifdef MODVERSIONS -#include <linux/modversions.h> -#endif #include <linux/kernel.h> #include <linux/sched.h> @@ -44,13 +41,14 @@ static const char *version = "pcnet32.c:v1.21 31.3.99 tsbogend@alpha.franken.de\ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/spinlock.h> static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; static int pcnet32_debug = 1; #ifdef MODULE -static struct device *pcnet32_dev = NULL; +static struct net_device *pcnet32_dev = NULL; #endif static const int max_interrupt_work = 20; @@ -154,6 +152,14 @@ static int full_duplex[MAX_UNITS] = {0, }; * rewritten PCI card detection * added dwio mode to get driver working on some PPC machines * v1.21: added mii selection and mii ioctl + * v1.22: changed pci scanning code to make PPC people happy + * fixed switching to 32bit mode in pcnet32_open() (thanks + * to Michael Richard <mcr@solidum.com> for noticing this one) + * added sub vendor/device id matching (thanks again to + * Michael Richard <mcr@solidum.com>) + * added chip id for 79c973/975 (thanks to Zach Brown <zab@zabbo.net>) + * v1.23 fixed small bug, when manual selecting MII speed/duplex + * v1.23ac Added SMP spinlocking - Alan Cox <alan@redhat.com> */ @@ -190,6 +196,16 @@ static int full_duplex[MAX_UNITS] = {0, }; #define PCNET32_TOTAL_SIZE 0x20 +/* some PCI ids */ +#ifndef PCI_DEVICE_ID_AMD_LANCE +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#endif +#ifndef PCI_DEVICE_ID_AMD_PCNETHOME +#define PCI_DEVICE_ID_AMD_PCNETHOME 0x2001 +#endif + + #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ /* The PCNET32 Rx and Tx ring descriptors. */ @@ -243,31 +259,32 @@ struct pcnet32_private { struct sk_buff *rx_skbuff[RX_RING_SIZE]; struct pcnet32_access a; void *origmem; - int cur_rx, cur_tx; /* The next free ring entry */ - int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + spinlock_t lock; /* Guard lock */ + int cur_rx, cur_tx; /* The next free ring entry */ + int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ struct net_device_stats stats; char tx_full; int options; - int shared_irq:1, /* shared irq possible */ - full_duplex:1, /* full duplex possible */ - mii:1; /* mii port available */ + int shared_irq:1, /* shared irq possible */ + full_duplex:1, /* full duplex possible */ + mii:1; /* mii port available */ #ifdef MODULE - struct device *next; + struct net_device *next; #endif }; -int pcnet32_probe(struct device *); -static int pcnet32_probe1(struct device *, unsigned long, unsigned char, int, int); -static int pcnet32_open(struct device *); -static int pcnet32_init_ring(struct device *); -static int pcnet32_start_xmit(struct sk_buff *, struct device *); -static int pcnet32_rx(struct device *); +int pcnet32_probe(struct net_device *); +static int pcnet32_probe1(struct net_device *, unsigned long, unsigned char, int, int); +static int pcnet32_open(struct net_device *); +static int pcnet32_init_ring(struct net_device *); +static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); +static int pcnet32_rx(struct net_device *); static void pcnet32_interrupt(int, void *, struct pt_regs *); -static int pcnet32_close(struct device *); -static struct net_device_stats *pcnet32_get_stats(struct device *); -static void pcnet32_set_multicast_list(struct device *); +static int pcnet32_close(struct net_device *); +static struct net_device_stats *pcnet32_get_stats(struct net_device *); +static void pcnet32_set_multicast_list(struct net_device *); #ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct device *, struct ifreq *, int); +static int pcnet32_mii_ioctl(struct net_device *, struct ifreq *, int); #endif enum pci_flags_bit { @@ -277,14 +294,19 @@ enum pci_flags_bit { struct pcnet32_pci_id_info { const char *name; - u16 vendor_id, device_id, device_id_mask, flags; + u16 vendor_id, device_id, svid, sdid, flags; int io_size; - int (*probe1) (struct device *, unsigned long, unsigned char, int, int); + int (*probe1) (struct net_device *, unsigned long, unsigned char, int, int); }; static struct pcnet32_pci_id_info pcnet32_tbl[] = { { "AMD PCnetPCI series", - 0x1022, 0x2000, 0xfffe, PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, + PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0, + PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, + pcnet32_probe1}, + { "AMD PCnetHome series", + PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0, + PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, pcnet32_probe1}, {0,} }; @@ -402,7 +424,7 @@ static struct pcnet32_access pcnet32_dwio = { -int __init pcnet32_probe (struct device *dev) +int __init pcnet32_probe (struct net_device *dev) { unsigned long ioaddr = dev ? dev->base_addr: 0; unsigned int irq_line = dev ? dev->irq : 0; @@ -423,34 +445,28 @@ int __init pcnet32_probe (struct device *dev) #if defined(CONFIG_PCI) if (pci_present()) { - struct pci_dev *pdev; - unsigned char pci_bus, pci_device_fn; - int pci_index; + struct pci_dev *pdev = NULL; printk("pcnet32.c: PCI bios is present, checking for devices...\n"); - for (pci_index = 0; pci_index < 0xff; pci_index++) { - u16 vendor, device, pci_command; + while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) { + u16 pci_command; int chip_idx; + u16 sdid,svid; - if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, - pci_index, &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL) - break; - - pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device); - + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &sdid); + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &svid); for (chip_idx = 0; pcnet32_tbl[chip_idx].vendor_id; chip_idx++) - if (vendor == pcnet32_tbl[chip_idx].vendor_id && - (device & pcnet32_tbl[chip_idx].device_id_mask) == pcnet32_tbl[chip_idx].device_id) + if ((pdev->vendor == pcnet32_tbl[chip_idx].vendor_id) && + (pdev->device == pcnet32_tbl[chip_idx].device_id) && + (pcnet32_tbl[chip_idx].svid == 0 || + (svid == pcnet32_tbl[chip_idx].svid)) && + (pcnet32_tbl[chip_idx].sdid == 0 || + (sdid == pcnet32_tbl[chip_idx].sdid))) break; if (pcnet32_tbl[chip_idx].vendor_id == 0) continue; - pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; -#if defined(ADDR_64BITS) && defined(__alpha__) - ioaddr |= ((long)pdev->base_address[1]) << 32; -#endif + ioaddr = pdev->resource[0].start; irq_line = pdev->irq; /* Avoid already found cards from previous pcnet32_probe() calls */ @@ -501,10 +517,10 @@ int __init pcnet32_probe (struct device *dev) /* pcnet32_probe1 */ static int __init -pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) +pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) { struct pcnet32_private *lp; - int i,media,fdx = 0, mii = 0; + int i,media,fdx = 0, mii = 0, fset = 0; int chip_version; char *chipname; char *priv; @@ -545,10 +561,14 @@ pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, break; case 0x2623: chipname = "PCnet/FAST 79C971"; - fdx = 1; mii = 1; + fdx = 1; mii = 1; fset = 1; break; case 0x2624: chipname = "PCnet/FAST+ 79C972"; + fdx = 1; mii = 1; fset = 1; + break; + case 0x2625: + chipname = "PCnet/FAST III 79C973"; fdx = 1; mii = 1; break; case 0x2626: @@ -571,10 +591,26 @@ pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, printk("pcnet32: pcnet32 media reset to %#x.\n", media); a->write_bcr (ioaddr, 49, media); break; + case 0x2627: + chipname = "PCnet/FAST III 79C975"; + fdx = 1; mii = 1; default: printk("pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version); return ENODEV; } + + /* + * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit + * starting until the packet is loaded. Strike one for reliability, lose + * one for latency - although on PCI this isnt a big loss. Older chips + * have FIFO's smaller than a packet, so you can't do this. + */ + + if(fset) + { + a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800)); + a->write_csr(ioaddr, 80, a->read_csr(ioaddr, 80) | 0x0c00); + } dev = init_etherdev(dev, 0); @@ -608,6 +644,9 @@ pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, #endif memset(lp, 0, sizeof(*lp)); + + spin_lock_init(&lp->lock); + dev->priv = lp; lp->name = chipname; lp->shared_irq = shared; @@ -696,7 +735,7 @@ pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, static int -pcnet32_open(struct device *dev) +pcnet32_open(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; @@ -713,7 +752,7 @@ pcnet32_open(struct device *dev) lp->a.reset (ioaddr); /* switch pcnet32 to 32bit mode */ - lp->a.write_csr (ioaddr, 20, 2); + lp->a.write_bcr (ioaddr, 20, 2); if (pcnet32_debug > 1) printk("%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", @@ -745,7 +784,7 @@ pcnet32_open(struct device *dev) val |= 0x10; lp->a.write_csr (ioaddr, 124, val); - if (lp->mii & (lp->options & PORT_ASEL)) { + if (lp->mii & !(lp->options & PORT_ASEL)) { val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */ if (lp->options & PORT_FD) val |= 0x10; @@ -804,7 +843,7 @@ pcnet32_open(struct device *dev) */ static void -pcnet32_purge_tx_ring(struct device *dev) +pcnet32_purge_tx_ring(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int i; @@ -820,7 +859,7 @@ pcnet32_purge_tx_ring(struct device *dev) /* Initialize the PCNET32 Rx and Tx rings. */ static int -pcnet32_init_ring(struct device *dev) +pcnet32_init_ring(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int i; @@ -858,7 +897,7 @@ pcnet32_init_ring(struct device *dev) } static void -pcnet32_restart(struct device *dev, unsigned int csr0_bits) +pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; @@ -879,7 +918,7 @@ pcnet32_restart(struct device *dev, unsigned int csr0_bits) } static int -pcnet32_start_xmit(struct sk_buff *skb, struct device *dev) +pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned int ioaddr = dev->base_addr; @@ -930,9 +969,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct device *dev) return 1; } - save_flags (flags); - cli (); - + spin_lock_irqsave(&lp->lock, flags); /* Fill in a Tx ring entry */ /* Mask to ring buffer boundary. */ @@ -964,7 +1001,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct device *dev) clear_bit (0, (void *)&dev->tbusy); else lp->tx_full = 1; - restore_flags(flags); + spin_unlock_irqrestore(&lp->lock, flags); return 0; } @@ -972,10 +1009,10 @@ pcnet32_start_xmit(struct sk_buff *skb, struct device *dev) static void pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct pcnet32_private *lp; unsigned long ioaddr; - u16 csr0; + u16 csr0,rap; int boguscnt = max_interrupt_work; int must_restart; @@ -986,11 +1023,15 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) ioaddr = dev->base_addr; lp = (struct pcnet32_private *)dev->priv; + + spin_lock(&lp->lock); + if (dev->interrupt) printk("%s: Re-entering the interrupt handler.\n", dev->name); dev->interrupt = 1; + rap = lp->a.read_rap(ioaddr); while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) { /* Acknowledge all of the current interrupt sources ASAP. */ lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f); @@ -1092,17 +1133,20 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* Clear any other interrupt, and set interrupt enable. */ lp->a.write_csr (ioaddr, 0, 0x7940); - + lp->a.write_rap(ioaddr,rap); + if (pcnet32_debug > 4) printk("%s: exiting interrupt, csr0=%#4.4x.\n", dev->name, lp->a.read_csr (ioaddr, 0)); dev->interrupt = 0; + + spin_unlock(&lp->lock); return; } static int -pcnet32_rx(struct device *dev) +pcnet32_rx(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1195,7 +1239,7 @@ pcnet32_rx(struct device *dev) } static int -pcnet32_close(struct device *dev) +pcnet32_close(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1241,25 +1285,24 @@ pcnet32_close(struct device *dev) } static struct net_device_stats * -pcnet32_get_stats(struct device *dev) +pcnet32_get_stats(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; u16 saved_addr; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&lp->lock, flags); saved_addr = lp->a.read_rap(ioaddr); lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); lp->a.write_rap(ioaddr, saved_addr); - restore_flags(flags); + spin_unlock_irqrestore(&lp->lock, flags); return &lp->stats; } /* taken from the sunlance driver, which it took from the depca driver */ -static void pcnet32_load_multicast (struct device *dev) +static void pcnet32_load_multicast (struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *) dev->priv; volatile struct pcnet32_init_block *ib = &lp->init_block; @@ -1311,7 +1354,7 @@ static void pcnet32_load_multicast (struct device *dev) /* * Set or clear the multicast filter for this adaptor. */ -static void pcnet32_set_multicast_list(struct device *dev) +static void pcnet32_set_multicast_list(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1331,7 +1374,7 @@ static void pcnet32_set_multicast_list(struct device *dev) } #ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int pcnet32_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1387,7 +1430,7 @@ init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (pcnet32_dev) { diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 4bf73f81e..a3b04feab 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -2,17 +2,22 @@ /* PLIP: A parallel port "network" driver for Linux. */ /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */ /* - * Authors: Donald Becker, <becker@super.org> - * Tommy Thorn, <thorn@daimi.aau.dk> - * Tanabe Hiroyasu, <hiro@sanpo.t.u-tokyo.ac.jp> - * Alan Cox, <gw4pts@gw4pts.ampr.org> - * Peter Bauer, <100136.3530@compuserve.com> - * Niibe Yutaka, <gniibe@mri.co.jp> + * Authors: Donald Becker <becker@super.org> + * Tommy Thorn <thorn@daimi.aau.dk> + * Tanabe Hiroyasu <hiro@sanpo.t.u-tokyo.ac.jp> + * Alan Cox <gw4pts@gw4pts.ampr.org> + * Peter Bauer <100136.3530@compuserve.com> + * Niibe Yutaka <gniibe@mri.co.jp> + * Nimrod Zimerman <zimerman@mailandnews.com> * + * Enhancements: * Modularization and ifreq/ifmap support by Alan Cox. * Rewritten by Niibe Yutaka. - * parport-sharing awareness code by Philip Blundell. + * parport-sharing awareness code by Philip Blundell. * SMP locking by Niibe Yutaka. + * Support for parallel ports with no IRQ (poll mode), + * Modifications to use the parallel port API + * by Nimrod Zimerman. * * Fixes: * Niibe Yutaka @@ -49,7 +54,7 @@ * To use with DOS box, please do (Turn on ARP switch): * # ifconfig plip[0-2] arp */ -static const char *version = "NET3 PLIP version 2.3-parport gniibe@mri.co.jp\n"; +static const char *version = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n"; /* Sources: @@ -57,7 +62,7 @@ static const char *version = "NET3 PLIP version 2.3-parport gniibe@mri.co.jp\n"; "parallel.asm" parallel port packet driver. The "Crynwr" parallel port standard specifies the following protocol: - Trigger by sending '0x08' (this cause interrupt on other end) + Trigger by sending nibble '0x8' (this causes interrupt on other end) count-low octet count-high octet ... data octets @@ -93,7 +98,6 @@ static const char *version = "NET3 PLIP version 2.3-parport gniibe@mri.co.jp\n"; #include <linux/ptrace.h> #include <linux/if_ether.h> #include <asm/system.h> -#include <asm/io.h> #include <linux/in.h> #include <linux/errno.h> #include <linux/delay.h> @@ -105,13 +109,15 @@ static const char *version = "NET3 PLIP version 2.3-parport gniibe@mri.co.jp\n"; #include <linux/inetdevice.h> #include <linux/skbuff.h> #include <linux/if_plip.h> +#include <net/neighbour.h> #include <linux/tqueue.h> #include <linux/ioport.h> +#include <linux/spinlock.h> #include <asm/bitops.h> #include <asm/irq.h> #include <asm/byteorder.h> -#include <asm/spinlock.h> +#include <asm/semaphore.h> #include <linux/parport.h> @@ -124,8 +130,8 @@ static const char *version = "NET3 PLIP version 2.3-parport gniibe@mri.co.jp\n"; #endif static unsigned int net_debug = NET_DEBUG; -#define ENABLE(irq) enable_irq(irq) -#define DISABLE(irq) disable_irq(irq) +#define ENABLE(irq) if (irq != -1) enable_irq(irq) +#define DISABLE(irq) if (irq != -1) disable_irq(irq) /* In micro second */ #define PLIP_DELAY_UNIT 1 @@ -136,27 +142,26 @@ static unsigned int net_debug = NET_DEBUG; /* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */ #define PLIP_NIBBLE_WAIT 3000 -#define PAR_INTR_ON (LP_PINITP|LP_PSELECP|LP_PINTEN) -#define PAR_INTR_OFF (LP_PINITP|LP_PSELECP) -#define PAR_DATA(dev) ((dev)->base_addr+0) -#define PAR_STATUS(dev) ((dev)->base_addr+1) -#define PAR_CONTROL(dev) ((dev)->base_addr+2) - -/* Bottom halfs */ -static void plip_kick_bh(struct device *dev); -static void plip_bh(struct device *dev); +/* Bottom halves */ +static void plip_kick_bh(struct net_device *dev); +static void plip_bh(struct net_device *dev); +static void plip_timer_bh(struct net_device *dev); /* Interrupt handler */ static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* Functions for DEV methods */ -static int plip_rebuild_header(struct sk_buff *skb); -static int plip_tx_packet(struct sk_buff *skb, struct device *dev); -static int plip_open(struct device *dev); -static int plip_close(struct device *dev); -static struct net_device_stats *plip_get_stats(struct device *dev); -static int plip_config(struct device *dev, struct ifmap *map); -static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd); +static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev); +static int plip_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, + void *saddr, unsigned len); +static int plip_hard_header_cache(struct neighbour *neigh, + struct hh_cache *hh); +static int plip_open(struct net_device *dev); +static int plip_close(struct net_device *dev); +static struct net_device_stats *plip_get_stats(struct net_device *dev); +static int plip_config(struct net_device *dev, struct ifmap *map); +static int plip_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int plip_preempt(void *handle); static void plip_wakeup(void *handle); @@ -210,6 +215,7 @@ struct net_local { struct net_device_stats enet_stats; struct tq_struct immediate; struct tq_struct deferred; + struct tq_struct timer; struct plip_local snd_data; struct plip_local rcv_data; struct pardevice *pardev; @@ -220,21 +226,63 @@ struct net_local { int is_deferred; int port_owner; int should_relinquish; - int (*orig_rebuild_header)(struct sk_buff *skb); + int (*orig_hard_header)(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, + void *saddr, unsigned len); + int (*orig_hard_header_cache)(struct neighbour *neigh, + struct hh_cache *hh); spinlock_t lock; + atomic_t kill_timer; + struct semaphore killed_timer_sem; }; +inline static void enable_parport_interrupts (struct net_device *dev) +{ + if (dev->irq != -1) + { + struct parport *port = + ((struct net_local *)dev->priv)->pardev->port; + port->ops->enable_irq (port); + } +} + +inline static void disable_parport_interrupts (struct net_device *dev) +{ + if (dev->irq != -1) + { + struct parport *port = + ((struct net_local *)dev->priv)->pardev->port; + port->ops->disable_irq (port); + } +} + +inline static void write_data (struct net_device *dev, unsigned char data) +{ + struct parport *port = + ((struct net_local *)dev->priv)->pardev->port; + + port->ops->write_data (port, data); +} + +inline static unsigned char read_status (struct net_device *dev) +{ + struct parport *port = + ((struct net_local *)dev->priv)->pardev->port; + + return port->ops->read_status (port); +} + /* Entry point of PLIP driver. Probe the hardware, and register/initialize the driver. PLIP is rather weird, because of the way it interacts with the parport system. It is _not_ initialised from Space.c. Instead, plip_init() - is called, and that function makes up a "struct device" for each port, and + is called, and that function makes up a "struct net_device" for each port, and then calls us here. */ -__initfunc(int -plip_init_dev(struct device *dev, struct parport *pb)) +int __init +plip_init_dev(struct net_device *dev, struct parport *pb) { struct net_local *nl; struct pardevice *pardev; @@ -243,8 +291,8 @@ plip_init_dev(struct device *dev, struct parport *pb)) dev->base_addr = pb->base; if (pb->irq == -1) { - printk(KERN_INFO "plip: %s has no IRQ.\n", pb->name); - return -ENODEV; + printk(KERN_INFO "plip: %s has no IRQ. Using IRQ-less mode," + "which is fairly inefficient!\n", pb->name); } pardev = parport_register_device(pb, dev->name, plip_preempt, @@ -255,21 +303,26 @@ plip_init_dev(struct device *dev, struct parport *pb)) return -ENODEV; printk(KERN_INFO "%s", version); - printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d\n", dev->name, - dev->base_addr, dev->irq); + if (dev->irq != -1) + printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d.\n", + dev->name, dev->base_addr, dev->irq); + else + printk(KERN_INFO "%s: Parallel port at %#3lx, not using IRQ.\n", + dev->name, dev->base_addr); /* Fill in the generic fields of the device structure. */ ether_setup(dev); /* Then, override parts of it */ - dev->hard_start_xmit = plip_tx_packet; - dev->open = plip_open; - dev->stop = plip_close; - dev->get_stats = plip_get_stats; - dev->set_config = plip_config; - dev->do_ioctl = plip_ioctl; - dev->tx_queue_len = 10; - dev->flags = IFF_POINTOPOINT|IFF_NOARP; + dev->hard_start_xmit = plip_tx_packet; + dev->open = plip_open; + dev->stop = plip_close; + dev->get_stats = plip_get_stats; + dev->set_config = plip_config; + dev->do_ioctl = plip_ioctl; + dev->header_cache_update = NULL; + dev->tx_queue_len = 10; + dev->flags = IFF_POINTOPOINT|IFF_NOARP; memset(dev->dev_addr, 0xfc, ETH_ALEN); /* Set the private structure */ @@ -282,8 +335,12 @@ plip_init_dev(struct device *dev, struct parport *pb)) memset(dev->priv, 0, sizeof(struct net_local)); nl = (struct net_local *) dev->priv; - nl->orig_rebuild_header = dev->rebuild_header; - dev->rebuild_header = plip_rebuild_header; + nl->orig_hard_header = dev->hard_header; + dev->hard_header = plip_hard_header; + + nl->orig_hard_header_cache = dev->hard_header_cache; + dev->hard_header_cache = plip_hard_header_cache; + nl->pardev = pardev; nl->port_owner = 0; @@ -295,13 +352,21 @@ plip_init_dev(struct device *dev, struct parport *pb)) /* Initialize task queue structures */ nl->immediate.next = NULL; nl->immediate.sync = 0; - nl->immediate.routine = (void *)(void *)plip_bh; + nl->immediate.routine = (void (*)(void *))plip_bh; nl->immediate.data = dev; nl->deferred.next = NULL; nl->deferred.sync = 0; - nl->deferred.routine = (void *)(void *)plip_kick_bh; + nl->deferred.routine = (void (*)(void *))plip_kick_bh; nl->deferred.data = dev; + + if (dev->irq == -1) { + nl->timer.next = NULL; + nl->timer.sync = 0; + nl->timer.routine = (void (*)(void *))plip_timer_bh; + nl->timer.data = dev; + } + spin_lock_init(&nl->lock); return 0; @@ -311,7 +376,7 @@ plip_init_dev(struct device *dev, struct parport *pb)) This routine is kicked by do_timer(). Request `plip_bh' to be invoked. */ static void -plip_kick_bh(struct device *dev) +plip_kick_bh(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; @@ -322,17 +387,17 @@ plip_kick_bh(struct device *dev) } /* Forward declarations of internal routines */ -static int plip_none(struct device *, struct net_local *, +static int plip_none(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_receive_packet(struct device *, struct net_local *, +static int plip_receive_packet(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_send_packet(struct device *, struct net_local *, +static int plip_send_packet(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_connection_close(struct device *, struct net_local *, +static int plip_connection_close(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_error(struct device *, struct net_local *, +static int plip_error(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_bh_timeout_error(struct device *dev, struct net_local *nl, +static int plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv, int error); @@ -342,7 +407,7 @@ static int plip_bh_timeout_error(struct device *dev, struct net_local *nl, #define ERROR 2 #define HS_TIMEOUT 3 -typedef int (*plip_func)(struct device *dev, struct net_local *nl, +typedef int (*plip_func)(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv); static plip_func connection_state_table[] = @@ -356,7 +421,7 @@ static plip_func connection_state_table[] = /* Bottom half handler of PLIP. */ static void -plip_bh(struct device *dev) +plip_bh(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -373,8 +438,24 @@ plip_bh(struct device *dev) } } +static void +plip_timer_bh(struct net_device *dev) +{ + struct net_local *nl = (struct net_local *)dev->priv; + + if (!(atomic_read (&nl->kill_timer))) { + if (!dev->interrupt) + plip_interrupt (-1, dev, NULL); + + queue_task (&nl->timer, &tq_timer); + } + else { + up (&nl->killed_timer_sem); + } +} + static int -plip_bh_timeout_error(struct device *dev, struct net_local *nl, +plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv, int error) { @@ -401,7 +482,7 @@ plip_bh_timeout_error(struct device *dev, struct net_local *nl, /* Try again later */ return TIMEOUT; } - c0 = inb(PAR_STATUS(dev)); + c0 = read_status(dev); printk(KERN_WARNING "%s: transmit timeout(%d,%02x)\n", dev->name, snd->state, c0); } else @@ -420,7 +501,7 @@ plip_bh_timeout_error(struct device *dev, struct net_local *nl, /* Try again later */ return TIMEOUT; } - c0 = inb(PAR_STATUS(dev)); + c0 = read_status(dev); printk(KERN_WARNING "%s: receive timeout(%d,%02x)\n", dev->name, rcv->state, c0); } @@ -441,16 +522,16 @@ plip_bh_timeout_error(struct device *dev, struct net_local *nl, DISABLE(dev->irq); synchronize_irq(); } - outb(PAR_INTR_OFF, PAR_CONTROL(dev)); + disable_parport_interrupts (dev); dev->tbusy = 1; nl->connection = PLIP_CN_ERROR; - outb(0x00, PAR_DATA(dev)); + write_data (dev, 0x00); return TIMEOUT; } static int -plip_none(struct device *dev, struct net_local *nl, +plip_none(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { return OK; @@ -459,7 +540,7 @@ plip_none(struct device *dev, struct net_local *nl, /* PLIP_RECEIVE --- receive a byte(two nibbles) Returns OK on success, TIMEOUT on timeout */ inline static int -plip_receive(unsigned short nibble_timeout, unsigned short status_addr, +plip_receive(unsigned short nibble_timeout, struct net_device *dev, enum plip_nibble_state *ns_p, unsigned char *data_p) { unsigned char c0, c1; @@ -469,10 +550,10 @@ plip_receive(unsigned short nibble_timeout, unsigned short status_addr, case PLIP_NB_BEGIN: cx = nibble_timeout; while (1) { - c0 = inb(status_addr); + c0 = read_status(dev); udelay(PLIP_DELAY_UNIT); if ((c0 & 0x80) == 0) { - c1 = inb(status_addr); + c1 = read_status(dev); if (c0 == c1) break; } @@ -480,17 +561,16 @@ plip_receive(unsigned short nibble_timeout, unsigned short status_addr, return TIMEOUT; } *data_p = (c0 >> 3) & 0x0f; - outb(0x10, --status_addr); /* send ACK */ - status_addr++; + write_data (dev, 0x10); /* send ACK */ *ns_p = PLIP_NB_1; case PLIP_NB_1: cx = nibble_timeout; while (1) { - c0 = inb(status_addr); + c0 = read_status(dev); udelay(PLIP_DELAY_UNIT); if (c0 & 0x80) { - c1 = inb(status_addr); + c1 = read_status(dev); if (c0 == c1) break; } @@ -498,8 +578,7 @@ plip_receive(unsigned short nibble_timeout, unsigned short status_addr, return TIMEOUT; } *data_p |= (c0 << 1) & 0xf0; - outb(0x00, --status_addr); /* send ACK */ - status_addr++; + write_data (dev, 0x00); /* send ACK */ *ns_p = PLIP_NB_BEGIN; case PLIP_NB_2: break; @@ -509,10 +588,9 @@ plip_receive(unsigned short nibble_timeout, unsigned short status_addr, /* PLIP_RECEIVE_PACKET --- receive a packet */ static int -plip_receive_packet(struct device *dev, struct net_local *nl, +plip_receive_packet(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { - unsigned short status_addr = PAR_STATUS(dev); unsigned short nibble_timeout = nl->nibble; unsigned char *lbuf; @@ -520,9 +598,9 @@ plip_receive_packet(struct device *dev, struct net_local *nl, case PLIP_PK_TRIGGER: DISABLE(dev->irq); /* Don't need to synchronize irq, as we can safely ignore it */ - outb(PAR_INTR_OFF, PAR_CONTROL(dev)); + disable_parport_interrupts (dev); dev->interrupt = 0; - outb(0x01, PAR_DATA(dev)); /* send ACK */ + write_data (dev, 0x01); /* send ACK */ if (net_debug > 2) printk(KERN_DEBUG "%s: receive start\n", dev->name); rcv->state = PLIP_PK_LENGTH_LSB; @@ -530,26 +608,26 @@ plip_receive_packet(struct device *dev, struct net_local *nl, case PLIP_PK_LENGTH_LSB: if (snd->state != PLIP_PK_DONE) { - if (plip_receive(nl->trigger, status_addr, + if (plip_receive(nl->trigger, dev, &rcv->nibble, &rcv->length.b.lsb)) { /* collision, here dev->tbusy == 1 */ rcv->state = PLIP_PK_DONE; nl->is_deferred = 1; nl->connection = PLIP_CN_SEND; queue_task(&nl->deferred, &tq_timer); - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); ENABLE(dev->irq); return OK; } } else { - if (plip_receive(nibble_timeout, status_addr, + if (plip_receive(nibble_timeout, dev, &rcv->nibble, &rcv->length.b.lsb)) return TIMEOUT; } rcv->state = PLIP_PK_LENGTH_MSB; case PLIP_PK_LENGTH_MSB: - if (plip_receive(nibble_timeout, status_addr, + if (plip_receive(nibble_timeout, dev, &rcv->nibble, &rcv->length.b.msb)) return TIMEOUT; if (rcv->length.h > dev->mtu + dev->hard_header_len @@ -572,7 +650,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl, case PLIP_PK_DATA: lbuf = rcv->skb->data; do - if (plip_receive(nibble_timeout, status_addr, + if (plip_receive(nibble_timeout, dev, &rcv->nibble, &lbuf[rcv->byte])) return TIMEOUT; while (++rcv->byte < rcv->length.h); @@ -582,7 +660,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl, rcv->state = PLIP_PK_CHECKSUM; case PLIP_PK_CHECKSUM: - if (plip_receive(nibble_timeout, status_addr, + if (plip_receive(nibble_timeout, dev, &rcv->nibble, &rcv->data)) return TIMEOUT; if (rcv->data != rcv->checksum) { @@ -604,20 +682,20 @@ plip_receive_packet(struct device *dev, struct net_local *nl, printk(KERN_DEBUG "%s: receive end\n", dev->name); /* Close the connection. */ - outb (0x00, PAR_DATA(dev)); + write_data (dev, 0x00); spin_lock_irq(&nl->lock); if (snd->state != PLIP_PK_DONE) { nl->connection = PLIP_CN_SEND; spin_unlock_irq(&nl->lock); queue_task(&nl->immediate, &tq_immediate); mark_bh(IMMEDIATE_BH); - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); ENABLE(dev->irq); return OK; } else { nl->connection = PLIP_CN_NONE; spin_unlock_irq(&nl->lock); - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); ENABLE(dev->irq); return OK; } @@ -628,7 +706,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl, /* PLIP_SEND --- send a byte (two nibbles) Returns OK on success, TIMEOUT when timeout */ inline static int -plip_send(unsigned short nibble_timeout, unsigned short data_addr, +plip_send(unsigned short nibble_timeout, struct net_device *dev, enum plip_nibble_state *ns_p, unsigned char data) { unsigned char c0; @@ -636,37 +714,34 @@ plip_send(unsigned short nibble_timeout, unsigned short data_addr, switch (*ns_p) { case PLIP_NB_BEGIN: - outb((data & 0x0f), data_addr); + write_data (dev, data & 0x0f); *ns_p = PLIP_NB_1; case PLIP_NB_1: - outb(0x10 | (data & 0x0f), data_addr); + write_data (dev, 0x10 | (data & 0x0f)); cx = nibble_timeout; - data_addr++; while (1) { - c0 = inb(data_addr); + c0 = read_status(dev); if ((c0 & 0x80) == 0) break; if (--cx == 0) return TIMEOUT; udelay(PLIP_DELAY_UNIT); } - outb(0x10 | (data >> 4), --data_addr); + write_data (dev, 0x10 | (data >> 4)); *ns_p = PLIP_NB_2; case PLIP_NB_2: - outb((data >> 4), data_addr); - data_addr++; + write_data (dev, (data >> 4)); cx = nibble_timeout; while (1) { - c0 = inb(data_addr); + c0 = read_status(dev); if (c0 & 0x80) break; if (--cx == 0) return TIMEOUT; udelay(PLIP_DELAY_UNIT); } - data_addr--; *ns_p = PLIP_NB_BEGIN; return OK; } @@ -675,10 +750,9 @@ plip_send(unsigned short nibble_timeout, unsigned short data_addr, /* PLIP_SEND_PACKET --- send a packet */ static int -plip_send_packet(struct device *dev, struct net_local *nl, +plip_send_packet(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { - unsigned short data_addr = PAR_DATA(dev); unsigned short nibble_timeout = nl->nibble; unsigned char *lbuf; unsigned char c0; @@ -693,11 +767,11 @@ plip_send_packet(struct device *dev, struct net_local *nl, switch (snd->state) { case PLIP_PK_TRIGGER: - if ((inb(PAR_STATUS(dev)) & 0xf8) != 0x80) + if ((read_status(dev) & 0xf8) != 0x80) return HS_TIMEOUT; /* Trigger remote rx interrupt. */ - outb(0x08, data_addr); + write_data (dev, 0x08); cx = nl->trigger; while (1) { udelay(PLIP_DELAY_UNIT); @@ -708,7 +782,7 @@ plip_send_packet(struct device *dev, struct net_local *nl, nl->enet_stats.collisions++; return OK; } - c0 = inb(PAR_STATUS(dev)); + c0 = read_status(dev); if (c0 & 0x08) { spin_unlock_irq(&nl->lock); DISABLE(dev->irq); @@ -724,7 +798,7 @@ plip_send_packet(struct device *dev, struct net_local *nl, nl->enet_stats.collisions++; return OK; } - outb(PAR_INTR_OFF, PAR_CONTROL(dev)); + disable_parport_interrupts (dev); if (net_debug > 2) printk(KERN_DEBUG "%s: send start\n", dev->name); snd->state = PLIP_PK_LENGTH_LSB; @@ -734,19 +808,19 @@ plip_send_packet(struct device *dev, struct net_local *nl, } spin_unlock_irq(&nl->lock); if (--cx == 0) { - outb(0x00, data_addr); + write_data (dev, 0x00); return HS_TIMEOUT; } } case PLIP_PK_LENGTH_LSB: - if (plip_send(nibble_timeout, data_addr, + if (plip_send(nibble_timeout, dev, &snd->nibble, snd->length.b.lsb)) return TIMEOUT; snd->state = PLIP_PK_LENGTH_MSB; case PLIP_PK_LENGTH_MSB: - if (plip_send(nibble_timeout, data_addr, + if (plip_send(nibble_timeout, dev, &snd->nibble, snd->length.b.msb)) return TIMEOUT; snd->state = PLIP_PK_DATA; @@ -755,7 +829,7 @@ plip_send_packet(struct device *dev, struct net_local *nl, case PLIP_PK_DATA: do - if (plip_send(nibble_timeout, data_addr, + if (plip_send(nibble_timeout, dev, &snd->nibble, lbuf[snd->byte])) return TIMEOUT; while (++snd->byte < snd->length.h); @@ -765,7 +839,7 @@ plip_send_packet(struct device *dev, struct net_local *nl, snd->state = PLIP_PK_CHECKSUM; case PLIP_PK_CHECKSUM: - if (plip_send(nibble_timeout, data_addr, + if (plip_send(nibble_timeout, dev, &snd->nibble, snd->checksum)) return TIMEOUT; @@ -776,14 +850,14 @@ plip_send_packet(struct device *dev, struct net_local *nl, case PLIP_PK_DONE: /* Close the connection */ - outb (0x00, data_addr); + write_data (dev, 0x00); snd->skb = NULL; if (net_debug > 2) printk(KERN_DEBUG "%s: send end\n", dev->name); nl->connection = PLIP_CN_CLOSING; nl->is_deferred = 1; queue_task(&nl->deferred, &tq_timer); - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); ENABLE(dev->irq); return OK; } @@ -791,7 +865,7 @@ plip_send_packet(struct device *dev, struct net_local *nl, } static int -plip_connection_close(struct device *dev, struct net_local *nl, +plip_connection_close(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { spin_lock_irq(&nl->lock); @@ -810,12 +884,12 @@ plip_connection_close(struct device *dev, struct net_local *nl, /* PLIP_ERROR --- wait till other end settled */ static int -plip_error(struct device *dev, struct net_local *nl, +plip_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { unsigned char status; - status = inb(PAR_STATUS(dev)); + status = read_status(dev); if ((status & 0xf8) == 0x80) { if (net_debug > 2) printk(KERN_DEBUG "%s: reset interface.\n", dev->name); @@ -823,7 +897,7 @@ plip_error(struct device *dev, struct net_local *nl, nl->should_relinquish = 0; dev->tbusy = 0; dev->interrupt = 0; - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); ENABLE(dev->irq); mark_bh(NET_BH); } else { @@ -838,7 +912,7 @@ plip_error(struct device *dev, struct net_local *nl, static void plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *nl; struct plip_local *rcv; unsigned char c0; @@ -854,9 +928,9 @@ plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) if (dev->interrupt) return; - c0 = inb(PAR_STATUS(dev)); + c0 = read_status(dev); if ((c0 & 0xf8) != 0xc0) { - if (net_debug > 1) + if ((dev->irq != -1) && (net_debug > 1)) printk(KERN_DEBUG "%s: spurious interrupt\n", dev->name); return; } @@ -893,24 +967,8 @@ plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) } } -/* We don't need to send arp, for plip is point-to-point. */ -static int -plip_rebuild_header(struct sk_buff *skb) -{ - struct device *dev = skb->dev; - struct net_local *nl = (struct net_local *)dev->priv; - struct ethhdr *eth = (struct ethhdr *)skb->data; - - if ((dev->flags & IFF_NOARP)==0) - return nl->orig_rebuild_header(skb); - - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - memcpy(eth->h_dest, dev->broadcast, dev->addr_len); - return 0; -} - static int -plip_tx_packet(struct sk_buff *skb, struct device *dev) +plip_tx_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -955,6 +1013,51 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev) return 0; } +static void +plip_rewrite_address(struct net_device *dev, struct ethhdr *eth) +{ + struct in_device *in_dev; + + if ((in_dev=dev->ip_ptr) != NULL) { + /* Any address will do - we take the first */ + struct in_ifaddr *ifa=in_dev->ifa_list; + if (ifa != NULL) { + memcpy(eth->h_source, dev->dev_addr, 6); + memset(eth->h_dest, 0xfc, 2); + memcpy(eth->h_dest+2, &ifa->ifa_address, 4); + } + } +} + +static int +plip_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, + void *saddr, unsigned len) +{ + struct net_local *nl = (struct net_local *)dev->priv; + int ret; + + if ((ret = nl->orig_hard_header(skb, dev, type, daddr, saddr, len)) >= 0) + plip_rewrite_address (dev, (struct ethhdr *)skb->data); + + return ret; +} + +int plip_hard_header_cache(struct neighbour *neigh, + struct hh_cache *hh) +{ + struct net_local *nl = (struct net_local *)neigh->dev->priv; + int ret; + + if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0) + { + struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2); + plip_rewrite_address (neigh->dev, eth); + } + + return ret; +} + /* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. @@ -962,7 +1065,7 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev) its IRQ line. */ static int -plip_open(struct device *dev) +plip_open(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct in_device *in_dev; @@ -976,10 +1079,15 @@ plip_open(struct device *dev) nl->should_relinquish = 0; /* Clear the data port. */ - outb (0x00, PAR_DATA(dev)); + write_data (dev, 0x00); /* Enable rx interrupt. */ - outb(PAR_INTR_ON, PAR_CONTROL(dev)); + enable_parport_interrupts (dev); + if (dev->irq == -1) + { + atomic_set (&nl->kill_timer, 0); + queue_task (&nl->timer, &tq_timer); + } /* Initialize the state machine. */ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE; @@ -988,21 +1096,24 @@ plip_open(struct device *dev) nl->is_deferred = 0; /* Fill in the MAC-level header. - (ab)Use "dev->broadcast" to store point-to-point MAC address. - - PLIP doesn't have a real mac address, but we need to create one - to be DOS compatible. */ - memset(dev->dev_addr, 0xfc, ETH_ALEN); - memset(dev->broadcast, 0xfc, ETH_ALEN); + We used to abuse dev->broadcast to store the point-to-point + MAC address, but we no longer do it. Instead, we fetch the + interface address whenever it is needed, which is cheap enough + because we use the hh_cache. Actually, abusing dev->broadcast + didn't work, because when using plip_open the point-to-point + address isn't yet known. + PLIP doesn't have a real MAC address, but we need it to be + DOS compatible, and to properly support taps (otherwise, + when the device address isn't identical to the address of a + received frame, the kernel incorrectly drops it). */ if ((in_dev=dev->ip_ptr) != NULL) { - /* - * Any address will do - we take the first - */ + /* Any address will do - we take the first. We already + have the first two bytes filled with 0xfc, from + plip_init_dev(). */ struct in_ifaddr *ifa=in_dev->ifa_list; if (ifa != NULL) { memcpy(dev->dev_addr+2, &ifa->ifa_local, 4); - memcpy(dev->broadcast+2, &ifa->ifa_address, 4); } } @@ -1016,7 +1127,7 @@ plip_open(struct device *dev) /* The inverse routine to plip_open (). */ static int -plip_close(struct device *dev) +plip_close(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -1027,6 +1138,13 @@ plip_close(struct device *dev) DISABLE(dev->irq); synchronize_irq(); + if (dev->irq == -1) + { + init_MUTEX_LOCKED (&nl->killed_timer_sem); + atomic_set (&nl->kill_timer, 1); + down (&nl->killed_timer_sem); + } + #ifdef NOTDEF outb(0x00, PAR_DATA(dev)); #endif @@ -1059,7 +1177,7 @@ plip_close(struct device *dev) static int plip_preempt(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct net_local *nl = (struct net_local *)dev->priv; /* Stand our ground if a datagram is on the wire */ @@ -1075,7 +1193,7 @@ plip_preempt(void *handle) static void plip_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct net_local *nl = (struct net_local *)dev->priv; if (nl->port_owner) { @@ -1095,14 +1213,14 @@ plip_wakeup(void *handle) if (!parport_claim(nl->pardev)) { nl->port_owner = 1; /* Clear the data port. */ - outb (0x00, PAR_DATA(dev)); + write_data (dev, 0x00); } return; } static struct net_device_stats * -plip_get_stats(struct device *dev) +plip_get_stats(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct net_device_stats *r = &nl->enet_stats; @@ -1111,7 +1229,7 @@ plip_get_stats(struct device *dev) } static int -plip_config(struct device *dev, struct ifmap *map) +plip_config(struct net_device *dev, struct ifmap *map) { struct net_local *nl = (struct net_local *) dev->priv; struct pardevice *pardev = nl->pardev; @@ -1132,7 +1250,7 @@ plip_config(struct device *dev, struct ifmap *map) } static int -plip_ioctl(struct device *dev, struct ifreq *rq, int cmd) +plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct net_local *nl = (struct net_local *) dev->priv; struct plipconf *pc = (struct plipconf *) &rq->ifr_data; @@ -1158,7 +1276,7 @@ static int timid = 0; MODULE_PARM(parport, "1-" __MODULE_STRING(PLIP_MAX) "i"); MODULE_PARM(timid, "1i"); -static struct device *dev_plip[PLIP_MAX] = { NULL, }; +static struct net_device *dev_plip[PLIP_MAX] = { NULL, }; #ifdef MODULE void @@ -1223,8 +1341,8 @@ plip_searchfor(int list[], int a) return 0; } -__initfunc(int -plip_init(void)) +int __init +plip_init(void) { struct parport *pb = parport_enumerate(); int i=0; @@ -1245,13 +1363,13 @@ plip_init(void)) printk(KERN_ERR "plip: too many devices\n"); break; } - dev_plip[i] = kmalloc(sizeof(struct device), + dev_plip[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev_plip[i]) { printk(KERN_ERR "plip: memory squeeze\n"); break; } - memset(dev_plip[i], 0, sizeof(struct device)); + memset(dev_plip[i], 0, sizeof(struct net_device)); dev_plip[i]->name = kmalloc(strlen("plipXXX"), GFP_KERNEL); if (!dev_plip[i]->name) { diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c deleted file mode 100644 index 42514f2bd..000000000 --- a/drivers/net/ppp.c +++ /dev/null @@ -1,3153 +0,0 @@ -/* PPP for Linux - * - * Michael Callahan <callahan@maths.ox.ac.uk> - * Al Longyear <longyear@netcom.com> - * Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au> - * - * ==FILEVERSION 990510== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the number above to the - * date of the modification as YYMMDD (year month day). - * ppp.c is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new ppp.c - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -/* - Sources: - - slip.c - - RFC1331: The Point-to-Point Protocol (PPP) for the Transmission of - Multi-protocol Datagrams over Point-to-Point Links - - RFC1332: IPCP - - ppp-2.0 - - Flags for this module (any combination is acceptable for testing.): - - OPTIMIZE_FLAG_TIME - Number of jiffies to force sending of leading flag - character. This is normally set to ((HZ * 3) / 2). - This is 1.5 seconds. If zero then the leading - flag is always sent. - - CHECK_CHARACTERS - Enable the checking on all received characters for - 8 data bits, no parity. This adds a small amount of - processing for each received character. -*/ - -#define OPTIMIZE_FLAG_TIME ((HZ * 3)/2) -#define CHECK_CHARACTERS 1 - -#define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */ - -/* $Id: ppp.c,v 1.24 1999/03/31 06:07:57 paulus Exp $ */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/interrupt.h> -#include <linux/ptrace.h> -#include <linux/poll.h> -#include <linux/in.h> -#include <linux/malloc.h> -#include <linux/tty.h> -#include <linux/errno.h> -#include <linux/string.h> /* used in new tty drivers */ -#include <linux/signal.h> /* used in new tty drivers */ -#include <asm/system.h> -#include <asm/bitops.h> -#include <asm/uaccess.h> - -#include <linux/if.h> -#include <linux/if_ether.h> -#include <linux/netdevice.h> -#include <linux/skbuff.h> -#include <linux/inet.h> -#include <linux/ioctl.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/if_arp.h> -#include <net/slhc_vj.h> - -#define fcstab ppp_crc16_table /* Name of the table in the kernel */ -#include <linux/ppp_defs.h> - -#include <linux/socket.h> -#include <linux/if_ppp.h> -#include <linux/if_pppvar.h> -#include <linux/ppp-comp.h> - -#ifdef CONFIG_KMOD -#include <linux/kmod.h> -#endif - -/* - * Local functions - */ - -#ifdef CONFIG_MODULES -static int ppp_register_compressor (struct compressor *cp); -static void ppp_unregister_compressor (struct compressor *cp); -#endif - -static void ppp_async_init(struct ppp *ppp); -static void ppp_async_release(struct ppp *ppp); -static int ppp_tty_sync_push(struct ppp *ppp); -static int ppp_tty_push(struct ppp *ppp); -static int ppp_async_encode(struct ppp *ppp); -static int ppp_async_send(struct ppp *, struct sk_buff *); -static int ppp_sync_send(struct ppp *, struct sk_buff *); -static void ppp_tty_flush_output(struct ppp *); - -static int ppp_ioctl(struct ppp *, unsigned int, unsigned long); -static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp); -static void ppp_proto_ccp(struct ppp *ppp, __u8 *dp, int len, int rcvd); -static void ppp_ccp_closed(struct ppp *ppp); -static int ppp_receive_frame(struct ppp *, struct sk_buff *); -static void ppp_receive_error(struct ppp *ppp); -static void ppp_output_wakeup(struct ppp *ppp); -static void ppp_send_ctrl(struct ppp *ppp, struct sk_buff *skb); -static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); -static void ppp_send_frames(struct ppp *ppp); -static struct sk_buff *ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb); - -static struct ppp *ppp_find (int pid_value); -static struct ppp *ppp_alloc (void); -static void ppp_generic_init(struct ppp *ppp); -static void ppp_release(struct ppp *ppp); -static void ppp_print_buffer (const char *, const __u8 *, int); -static struct compressor *find_compressor (int type); - -#ifndef OPTIMIZE_FLAG_TIME -#define OPTIMIZE_FLAG_TIME 0 -#endif - -/* - * Parameters which may be changed via insmod. - */ - -static int flag_time = OPTIMIZE_FLAG_TIME; -MODULE_PARM(flag_time, "i"); - -#define CHECK_PPP_MAGIC(ppp) do { \ - if (ppp->magic != PPP_MAGIC) { \ - printk(ppp_magic_warn, ppp, __FILE__, __LINE__); \ - } \ -} while (0) -#define CHECK_PPP(a) do { \ - CHECK_PPP_MAGIC(ppp); \ - if (!ppp->inuse) { \ - printk(ppp_warning, __LINE__); \ - return a; \ - } \ -} while (0) -#define CHECK_PPP_VOID() do { \ - CHECK_PPP_MAGIC(ppp); \ - if (!ppp->inuse) { \ - printk(ppp_warning, __LINE__); \ - return; \ - } \ -} while (0) - -#define tty2ppp(tty) ((struct ppp *) ((tty)->disc_data)) -#define dev2ppp(dev) ((struct ppp *) ((dev)->priv)) -#define ppp2tty(ppp) ((ppp)->tty) -#define ppp2dev(ppp) (&(ppp)->dev) - -static struct ppp *ppp_list = NULL; -static struct ppp *ppp_last = NULL; - -/* Define these strings only once for all macro invocations */ -static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n"; -static char ppp_magic_warn[] = KERN_WARNING "bad magic for ppp %p at %s:%d\n"; - -static char szVersion[] = PPP_VERSION; - -EXPORT_SYMBOL(ppp_register_compressor); -EXPORT_SYMBOL(ppp_unregister_compressor); - -/************************************************************* - * LINE DISCIPLINE SUPPORT - * The following code implements the PPP line discipline - * and supports using PPP on an async serial line. - *************************************************************/ - -#define in_xmap(ppp,c) (ppp->xmit_async_map[(c) >> 5] & (1 << ((c) & 0x1f))) -#define in_rmap(ppp,c) ((((unsigned int) (__u8) (c)) < 0x20) && \ - ppp->recv_async_map & (1 << (c))) - -/* - * TTY callbacks - */ - -static ssize_t ppp_tty_read(struct tty_struct *, struct file *, __u8 *, - size_t); -static ssize_t ppp_tty_write(struct tty_struct *, struct file *, const __u8 *, - size_t); -static int ppp_tty_ioctl(struct tty_struct *, struct file *, unsigned int, - unsigned long); -static unsigned int ppp_tty_poll(struct tty_struct *tty, struct file *filp, - poll_table * wait); -static int ppp_tty_open (struct tty_struct *); -static void ppp_tty_close (struct tty_struct *); -static int ppp_tty_room (struct tty_struct *tty); -static void ppp_tty_receive (struct tty_struct *tty, const __u8 * cp, - char *fp, int count); -static void ppp_tty_wakeup (struct tty_struct *tty); - -__u16 ppp_crc16_table[256] = -{ - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; -EXPORT_SYMBOL(ppp_crc16_table); - -#ifdef CHECK_CHARACTERS -static __u32 paritytab[8] = -{ - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; -#endif - -/* - * This procedure is called at initialization time to register - * the PPP line discipline. - */ -static int -ppp_first_time(void) -{ - static struct tty_ldisc ppp_ldisc; - int status; - - printk(KERN_INFO - "PPP: version %s (demand dialling)" - "\n", szVersion); - -#ifndef MODULE /* slhc module logic has its own copyright announcement */ - printk(KERN_INFO - "TCP compression code copyright 1989 Regents of the " - "University of California\n"); -#endif - - /* - * Register the tty discipline - */ - (void) memset (&ppp_ldisc, 0, sizeof (ppp_ldisc)); - ppp_ldisc.magic = TTY_LDISC_MAGIC; - ppp_ldisc.name = "ppp"; - ppp_ldisc.open = ppp_tty_open; - ppp_ldisc.close = ppp_tty_close; - ppp_ldisc.read = ppp_tty_read; - ppp_ldisc.write = ppp_tty_write; - ppp_ldisc.ioctl = ppp_tty_ioctl; - ppp_ldisc.poll = ppp_tty_poll; - ppp_ldisc.receive_room = ppp_tty_room; - ppp_ldisc.receive_buf = ppp_tty_receive; - ppp_ldisc.write_wakeup = ppp_tty_wakeup; - - status = tty_register_ldisc (N_PPP, &ppp_ldisc); - if (status == 0) - printk(KERN_INFO "PPP line discipline registered.\n"); - else - printk(KERN_ERR "error registering line discipline: %d\n", - status); - return status; -} - - -#ifndef MODULE -/* - * Called at boot time if the PPP driver is compiled into the kernel. - */ -int -ppp_init(struct device *dev) -{ - static int first_time = 1; - int answer = 0; - - if (first_time) { - first_time = 0; - answer = ppp_first_time(); - } - if (answer == 0) - answer = -ENODEV; - return answer; -} -#endif - -/* - * Initialize the async-specific parts of the ppp structure. - */ -static void -ppp_async_init(struct ppp *ppp) -{ - ppp->escape = 0; - ppp->toss = 0xE0; - ppp->tty_pushing = 0; - - memset (ppp->xmit_async_map, 0, sizeof (ppp->xmit_async_map)); - ppp->xmit_async_map[0] = 0xffffffff; - ppp->xmit_async_map[3] = 0x60000000; - ppp->recv_async_map = 0xffffffff; - - ppp->tpkt = NULL; - ppp->tfcs = PPP_INITFCS; - ppp->optr = ppp->obuf; - ppp->olim = ppp->obuf; - - ppp->rpkt = NULL; - ppp->rfcs = PPP_INITFCS; - - ppp->tty = NULL; - ppp->backup_tty = NULL; - - ppp->bytes_sent = 0; - ppp->bytes_rcvd = 0; -} - -/* - * Clean up the async-specific parts of the ppp structure. - */ -static void -ppp_async_release(struct ppp *ppp) -{ - struct sk_buff *skb; - - if ((skb = ppp->rpkt) != NULL) - kfree_skb(skb); - ppp->rpkt = NULL; - if ((skb = ppp->tpkt) != NULL) - kfree_skb(skb); - ppp->tpkt = NULL; -} - -/* - * TTY callback. - * - * Called when the tty discipline is switched to PPP. - */ - -static int -ppp_tty_open (struct tty_struct *tty) -{ - struct ppp *ppp; - - /* - * Allocate a ppp structure to use. - */ - tty->disc_data = NULL; - ppp = ppp_find(current->pid); - if (ppp != NULL) { - /* - * If we are taking over a ppp unit which is currently - * connected to a loopback pty, there's not much to do. - */ - CHECK_PPP(-EINVAL); - - } else { - ppp = ppp_alloc(); - if (ppp == NULL) { - printk(KERN_ERR "ppp_alloc failed\n"); - return -ENFILE; - } - - /* - * Initialize the control block - */ - ppp_generic_init(ppp); - ppp_async_init(ppp); - - MOD_INC_USE_COUNT; - } - - tty->disc_data = ppp; - ppp->tty = tty; - - /* - * Flush any pending characters in the driver - */ - if (tty->driver.flush_buffer) - tty->driver.flush_buffer (tty); - - return ppp->line; -} - -/* - * TTY callback. - * - * Called when the line discipline is changed to something - * else, the tty is closed, or the tty detects a hangup. - */ - -static void -ppp_tty_close (struct tty_struct *tty) -{ - struct ppp *ppp = tty2ppp(tty); - - if (ppp == NULL) - return; - tty->disc_data = NULL; - if (ppp->magic != PPP_MAGIC) { - printk(KERN_WARNING "ppp_tty_close: bogus\n"); - return; - } - if (!ppp->inuse) { - printk(KERN_WARNING "ppp_tty_close: not inuse\n"); - ppp->tty = ppp->backup_tty = 0; - return; - } - if (tty == ppp->backup_tty) - ppp->backup_tty = 0; - if (tty != ppp->tty) - return; - if (ppp->backup_tty) { - ppp->tty = ppp->backup_tty; - if (ppp_tty_push(ppp)) - ppp_output_wakeup(ppp); - wake_up_interruptible(&ppp->read_wait); - } else { - ppp->tty = 0; - ppp->sc_xfer = 0; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO "ppp: channel %s closing.\n", - ppp2dev(ppp)->name); - - ppp_async_release(ppp); - ppp_release(ppp); - MOD_DEC_USE_COUNT; - } -} - -/* - * Read a PPP frame from the rcv_q list, - * waiting if necessary - */ -static ssize_t -ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf, - size_t nr) -{ - struct ppp *ppp = tty2ppp (tty); - struct sk_buff *skb; - ssize_t len, err; - - /* - * Validate the pointers - */ - if (!ppp) - return -EIO; - CHECK_PPP(-ENXIO); - - /* - * Before we attempt to write the frame to the user, ensure that the - * user has access to the pages for the total buffer length. - */ - err = verify_area(VERIFY_WRITE, buf, nr); - if (err != 0) - return (err); - - /* - * Wait for a frame to arrive if necessary. - * We increment the module use count so that the module - * can't go away while we're sleeping. - */ - MOD_INC_USE_COUNT; - skb = NULL; - for (;;) { - ppp = tty2ppp(tty); - err = 0; - if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse - || tty != ppp->tty) - break; - - skb = skb_dequeue(&ppp->rcv_q); - if (skb != 0) - break; - - /* - * If no frame is available, return -EAGAIN or wait. - */ - err = -EAGAIN; - if (file->f_flags & O_NONBLOCK) - break; - - interruptible_sleep_on(&ppp->read_wait); - err = -EINTR; - if (signal_pending(current)) - break; - } - MOD_DEC_USE_COUNT; - if (skb == 0) - return err; - - /* - * Ensure that the frame will fit within the caller's buffer. - * If not, just discard the frame. - */ - len = skb->len; - if (len > nr) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG - "ppp: read of %lu bytes too small for %ld " - "frame\n", (unsigned long) nr, (long) len); - ppp->stats.ppp_ierrors++; - err = -EOVERFLOW; - goto out; - } - - /* - * Copy the received data from the buffer to the caller's area. - */ - err = len; - if (copy_to_user(buf, skb->data, len)) - err = -EFAULT; - -out: - kfree_skb(skb); - return err; -} - -/* - * Writing to a tty in ppp line discipline sends a PPP frame. - * Used by pppd to send control packets (LCP, etc.). - */ -static ssize_t -ppp_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data, - size_t count) -{ - struct ppp *ppp = tty2ppp (tty); - __u8 *new_data; - struct sk_buff *skb; - - /* - * Verify the pointers. - */ - if (!ppp) - return -EIO; - - if (ppp->magic != PPP_MAGIC) - return -EIO; - - CHECK_PPP(-ENXIO); - - /* - * Ensure that the caller does not wish to send too much. - */ - if (count > PPP_MTU + PPP_HDRLEN) { - if (ppp->flags & SC_DEBUG) - printk(KERN_WARNING - "ppp_tty_write: truncating user packet " - "from %lu to mtu %d\n", (unsigned long) count, - PPP_MTU + PPP_HDRLEN); - count = PPP_MTU + PPP_HDRLEN; - } - - /* - * Allocate a buffer for the data and fetch it from the user space. - */ - skb = alloc_skb(count, GFP_KERNEL); - if (skb == NULL) { - printk(KERN_ERR "ppp_tty_write: no memory\n"); - return 0; - } - new_data = skb_put(skb, count); - - /* - * Retrieve the user's buffer - */ - if (copy_from_user(new_data, data, count)) { - kfree_skb(skb); - return -EFAULT; - } - - /* - * Send the frame - */ - ppp_send_ctrl(ppp, skb); - - return (ssize_t) count; -} - -/* - * Process the IOCTL call for the tty device. - * Only the ioctls that relate to using ppp on async serial lines - * are processed here; the rest are handled by ppp_ioctl. - */ -static int -ppp_tty_ioctl (struct tty_struct *tty, struct file * file, - unsigned int param2, unsigned long param3) -{ - struct ppp *ppp = tty2ppp (tty); - register int temp_i = 0; - int error = -EFAULT; - - /* - * Verify the status of the PPP device. - */ - if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse) - return -ENXIO; - - /* - * The user must have an euid of root to do these requests. - */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - switch (param2) { - case PPPIOCGASYNCMAP: - /* - * Retrieve the transmit async map - */ - if (put_user(ppp->xmit_async_map[0], (int *) param3)) - break; - error = 0; - break; - - case PPPIOCSASYNCMAP: - /* - * Set the transmit async map - */ - if (get_user(temp_i, (int *) param3)) - break; - ppp->xmit_async_map[0] = temp_i; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO - "ppp_tty_ioctl: set xmit asyncmap %x\n", - ppp->xmit_async_map[0]); - error = 0; - break; - - case PPPIOCSRASYNCMAP: - /* - * Set the receive async map - */ - if (get_user(temp_i, (int *) param3)) - break; - ppp->recv_async_map = temp_i; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO - "ppp_tty_ioctl: set rcv asyncmap %x\n", - ppp->recv_async_map); - error = 0; - break; - - case PPPIOCGXASYNCMAP: - /* - * Get the map of characters to be escaped on transmission. - */ - if (copy_to_user((void *) param3, ppp->xmit_async_map, - sizeof (ppp->xmit_async_map))) - break; - error = 0; - break; - - case PPPIOCSXASYNCMAP: - /* - * Set the map of characters to be escaped on transmission. - */ - { - __u32 temp_tbl[8]; - - if (copy_from_user(temp_tbl, (void *) param3, - sizeof (temp_tbl))) - break; - - temp_tbl[1] = 0x00000000; - temp_tbl[2] &= ~0x40000000; - temp_tbl[3] |= 0x60000000; - - memcpy(ppp->xmit_async_map, temp_tbl, - sizeof (ppp->xmit_async_map)); - - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO - "ppp_tty_ioctl: set xasyncmap\n"); - error = 0; - } - break; - - case PPPIOCXFERUNIT: - /* - * Set up this PPP unit to be used next time this - * process sets a tty to PPP line discipline. - */ - ppp->backup_tty = tty; - ppp->sc_xfer = current->pid; - error = 0; - break; - - case TCGETS: - case TCGETA: - /* - * Allow users to read, but not set, the serial port parameters - */ - error = n_tty_ioctl (tty, file, param2, param3); - break; - - case TCFLSH: - /* - * Flush our buffers, then call the generic code to - * flush the serial port's buffer. - */ - if (param3 == TCIFLUSH || param3 == TCIOFLUSH) { - struct sk_buff *skb; - while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL) - kfree_skb(skb); - } - if (param3 == TCIOFLUSH || param3 == TCOFLUSH) - ppp_tty_flush_output(ppp); - error = n_tty_ioctl (tty, file, param2, param3); - break; - - case FIONREAD: - /* - * Returns how many bytes are available for a read(). - */ - { - unsigned long flags; - struct sk_buff *skb; - int count = 0; - - save_flags(flags); - cli(); - skb = skb_peek(&ppp->rcv_q); - if (skb != 0) - count = skb->len; - restore_flags(flags); - if (put_user(count, (int *) param3)) - break; - error = 0; - } - break; - - default: - /* - * All other ioctl() events will come here. - */ - error = ppp_ioctl(ppp, param2, param3); - break; - } - return error; -} - -/* - * TTY callback. - * - * Process the poll() statement for the PPP device. - */ - -static unsigned int -ppp_tty_poll(struct tty_struct *tty, struct file *filp, poll_table * wait) -{ - struct ppp *ppp = tty2ppp(tty); - unsigned int mask = 0; - - if (ppp && ppp->magic == PPP_MAGIC && tty == ppp->tty) { - CHECK_PPP(0); - - poll_wait(filp, &ppp->read_wait, wait); - - if (skb_peek(&ppp->rcv_q) != NULL) - mask |= POLLIN | POLLRDNORM; - if (tty->flags & (1 << TTY_OTHER_CLOSED) - || tty_hung_up_p(filp)) - mask |= POLLHUP; - mask |= POLLOUT | POLLWRNORM; - } - return mask; -} - -/* - * This function is called by the tty driver when the transmit buffer has - * additional space. It is used by the ppp code to continue to transmit - * the current buffer should the buffer have been partially sent. - */ -static void -ppp_tty_wakeup (struct tty_struct *tty) -{ - struct ppp *ppp = tty2ppp (tty); - - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - if (!ppp) - return; - CHECK_PPP_VOID(); - if (tty != ppp->tty) - return; - - if (ppp_tty_push(ppp)) - ppp_output_wakeup(ppp); -} - -/* - * Send a packet to the peer over a synchronous tty line. - * All encoding and FCS are handled by hardware. - * Addr/Ctrl and Protocol field compression implemented. - * Returns -1 iff the packet could not be accepted at present, - * 0 if the packet was accepted but we can't accept another yet, or - * 1 if we can accept another packet immediately. - * If this procedure returns 0, ppp_output_wakeup will be called - * exactly once. - */ -static int -ppp_sync_send(struct ppp *ppp, struct sk_buff *skb) -{ - unsigned char *data; - int islcp; - - CHECK_PPP(0); - - if (ppp->tpkt != NULL) - return -1; - ppp->tpkt = skb; - - data = ppp->tpkt->data; - - /* - * LCP packets with code values between 1 (configure-reqest) - * and 7 (code-reject) must be sent as though no options - * had been negotiated. - */ - islcp = PPP_PROTOCOL(data) == PPP_LCP - && 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7; - - /* only reset idle time for data packets */ - if (PPP_PROTOCOL(data) < 0x8000) - ppp->last_xmit = jiffies; - ++ppp->stats.ppp_opackets; - ppp->stats.ppp_ooctects += ppp->tpkt->len; - - if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) { - /* compress protocol field */ - data[2] = data[1]; - data[1] = data[0]; - skb_pull(ppp->tpkt,1); - data = ppp->tpkt->data; - } - - /* - * Do address/control compression - */ - if ((ppp->flags & SC_COMP_AC) && !islcp - && PPP_ADDRESS(data) == PPP_ALLSTATIONS - && PPP_CONTROL(data) == PPP_UI) { - /* strip addr and control field */ - skb_pull(ppp->tpkt,2); - } - - return ppp_tty_sync_push(ppp); -} - -/* - * Push a synchronous frame out to the tty. - * Returns 1 if frame accepted (or discarded), 0 otherwise. - */ -static int -ppp_tty_sync_push(struct ppp *ppp) -{ - int sent; - struct tty_struct *tty = ppp2tty(ppp); - unsigned long flags; - - CHECK_PPP(0); - - if (ppp->tpkt == NULL) - return 0; - - /* prevent reentrancy with tty_pushing flag */ - save_flags(flags); - cli(); - if (ppp->tty_pushing) { - /* record wakeup attempt so we don't lose */ - /* a wakeup call while doing push processing */ - ppp->woke_up=1; - restore_flags(flags); - return 0; - } - ppp->tty_pushing = 1; - restore_flags(flags); - - if (tty == NULL || tty->disc_data != (void *) ppp) - goto flush; - - for(;;){ - ppp->woke_up=0; - - /* Note: Sync driver accepts complete frame or nothing */ - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); - sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len); - if (sent < 0) { - /* write error (possible loss of CD) */ - /* record error and discard current packet */ - ppp->stats.ppp_oerrors++; - break; - } - ppp->stats.ppp_obytes += sent; - if (sent < ppp->tpkt->len) { - /* driver unable to accept frame just yet */ - save_flags(flags); - cli(); - if (ppp->woke_up) { - /* wake up called while processing */ - /* try to send the frame again */ - restore_flags(flags); - continue; - } - /* wait for wakeup callback to try send again */ - ppp->tty_pushing = 0; - restore_flags(flags); - return 0; - } - break; - } -flush: - /* done with current packet (sent or discarded) */ - kfree_skb(ppp->tpkt); - ppp->tpkt = 0; - ppp->tty_pushing = 0; - return 1; -} - -/* - * Send a packet to the peer over an async tty line. - * Returns -1 iff the packet could not be accepted at present, - * 0 if the packet was accepted but we can't accept another yet, or - * 1 if we can accept another packet immediately. - * If this procedure returns 0, ppp_output_wakeup will be called - * exactly once. - */ -static int -ppp_async_send(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - - ppp_tty_push(ppp); - - if (ppp->tpkt != NULL) - return -1; - ppp->tpkt = skb; - ppp->tpkt_pos = 0; - - return ppp_tty_push(ppp); -} - -/* - * Push as much data as possible out to the tty. - * Returns 1 if we finished encoding the current frame, 0 otherwise. - */ -static int -ppp_tty_push(struct ppp *ppp) -{ - int avail, sent, done = 0; - struct tty_struct *tty = ppp2tty(ppp); - - if (ppp->flags & SC_SYNC) - return ppp_tty_sync_push(ppp); - - CHECK_PPP(0); - if (ppp->tty_pushing) { - ppp->woke_up = 1; - return 0; - } - if (tty == NULL || tty->disc_data != (void *) ppp) - goto flush; - while (ppp->optr < ppp->olim || ppp->tpkt != 0) { - ppp->tty_pushing = 1; - mb(); - ppp->woke_up = 0; - avail = ppp->olim - ppp->optr; - if (avail > 0) { - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); - sent = tty->driver.write(tty, 0, ppp->optr, avail); - if (sent < 0) - goto flush; /* error, e.g. loss of CD */ - ppp->stats.ppp_obytes += sent; - ppp->optr += sent; - if (sent < avail) { - wmb(); - ppp->tty_pushing = 0; - mb(); - if (ppp->woke_up) - continue; - return done; - } - } - if (ppp->tpkt != 0) - done = ppp_async_encode(ppp); - wmb(); - ppp->tty_pushing = 0; - } - return done; - -flush: - ppp->tty_pushing = 1; - mb(); - ppp->stats.ppp_oerrors++; - if (ppp->tpkt != 0) { - kfree_skb(ppp->tpkt); - ppp->tpkt = 0; - done = 1; - } - ppp->optr = ppp->olim; - wmb(); - ppp->tty_pushing = 0; - return done; -} - -/* - * Procedure to encode the data for async serial transmission. - * Does octet stuffing (escaping) and address/control - * and protocol compression. - * Assumes ppp->opkt != 0 on entry. - * Returns 1 if we finished the current frame, 0 otherwise. - */ -static int -ppp_async_encode(struct ppp *ppp) -{ - int fcs, i, count, c; - unsigned char *buf, *buflim; - unsigned char *data; - int islcp; - - CHECK_PPP(0); - - buf = ppp->obuf; - ppp->olim = buf; - ppp->optr = buf; - i = ppp->tpkt_pos; - data = ppp->tpkt->data; - count = ppp->tpkt->len; - fcs = ppp->tfcs; - - /* - * LCP packets with code values between 1 (configure-reqest) - * and 7 (code-reject) must be sent as though no options - * had been negotiated. - */ - islcp = PPP_PROTOCOL(data) == PPP_LCP - && 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7; - - if (i == 0) { - /* - * Start of a new packet - insert the leading FLAG - * character if necessary. - */ - if (islcp || flag_time == 0 - || jiffies - ppp->last_xmit >= flag_time) - *buf++ = PPP_FLAG; - /* only reset idle time for data packets */ - if (PPP_PROTOCOL(data) < 0x8000) - ppp->last_xmit = jiffies; - fcs = PPP_INITFCS; - ++ppp->stats.ppp_opackets; - ppp->stats.ppp_ooctects += count; - - /* - * Do address/control compression - */ - if ((ppp->flags & SC_COMP_AC) != 0 && !islcp - && PPP_ADDRESS(data) == PPP_ALLSTATIONS - && PPP_CONTROL(data) == PPP_UI) - i += 2; - } - - /* - * Once we put in the last byte, we need to put in the FCS - * and closing flag, so make sure there is at least 7 bytes - * of free space in the output buffer. - */ - buflim = buf + OBUFSIZE - 6; - while (i < count && buf < buflim) { - c = data[i++]; - if (i == 3 && c == 0 && (ppp->flags & SC_COMP_PROT)) - continue; /* compress protocol field */ - fcs = PPP_FCS(fcs, c); - if (in_xmap(ppp, c) || (islcp && c < 0x20)) { - *buf++ = PPP_ESCAPE; - c ^= 0x20; - } - *buf++ = c; - } - - if (i == count) { - /* - * We have finished the packet. Add the FCS and flag. - */ - fcs = ~fcs; - c = fcs & 0xff; - if (in_xmap(ppp, c) || (islcp && c < 0x20)) { - *buf++ = PPP_ESCAPE; - c ^= 0x20; - } - *buf++ = c; - c = (fcs >> 8) & 0xff; - if (in_xmap(ppp, c) || (islcp && c < 0x20)) { - *buf++ = PPP_ESCAPE; - c ^= 0x20; - } - *buf++ = c; - *buf++ = PPP_FLAG; - ppp->olim = buf; - - kfree_skb(ppp->tpkt); - ppp->tpkt = 0; - return 1; - } - - /* - * Remember where we are up to in this packet. - */ - ppp->olim = buf; - ppp->tpkt_pos = i; - ppp->tfcs = fcs; - return 0; -} - -/* - * Flush output from our internal buffers. - * Called for the TCFLSH ioctl. - */ -static void -ppp_tty_flush_output(struct ppp *ppp) -{ - struct sk_buff *skb; - int done = 0; - - while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL) - kfree_skb(skb); - ppp->tty_pushing = 1; - mb(); - ppp->optr = ppp->olim; - if (ppp->tpkt != NULL) { - kfree_skb(ppp->tpkt); - ppp->tpkt = 0; - done = 1; - } - wmb(); - ppp->tty_pushing = 0; - if (done) - ppp_output_wakeup(ppp); -} - -/* - * Callback function from tty driver. Return the amount of space left - * in the receiver's buffer to decide if remote transmitter is to be - * throttled. - */ -static int -ppp_tty_room (struct tty_struct *tty) -{ - return 65536; /* We can handle an infinite amount of data. :-) */ -} - -/* - * Callback function when data is available at the tty driver. - */ -static void -ppp_tty_receive (struct tty_struct *tty, const __u8 * data, - char *flags, int count) -{ - register struct ppp *ppp = tty2ppp (tty); - struct sk_buff *skb; - int chr, flg; - unsigned char *p; - - if (ppp != 0) - CHECK_PPP_VOID(); - /* - * This can happen if stuff comes in on the backup tty. - */ - if (ppp == 0 || tty != ppp->tty) - return; - /* - * Verify the table pointer and ensure that the line is - * still in PPP discipline. - */ - if (ppp->magic != PPP_MAGIC) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG - "PPP: tty_receive called but couldn't find " - "PPP struct.\n"); - return; - } - /* - * Print the buffer if desired - */ - if (ppp->flags & SC_LOG_RAWIN) - ppp_print_buffer ("receive buffer", data, count); - - ppp->stats.ppp_ibytes += count; - skb = ppp->rpkt; - - if ( ppp->flags & SC_SYNC ) { - /* synchronous mode */ - - if (ppp->toss==0xE0) { - /* this is the 1st frame, reset vj comp */ - ppp_receive_error(ppp); - ppp->toss = 0; - } - - /* - * Allocate an skbuff for frame. - * The 128 is room for VJ header expansion. - */ - - if (skb == NULL) - skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN); - - if (skb == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "couldn't " - "alloc skb for recv\n"); - } else { - /* - * Decompress A/C and protocol compression here. - */ - p = skb_put(skb, 2); - p[0] = PPP_ALLSTATIONS; - p[1] = PPP_UI; - if (*data == PPP_ALLSTATIONS) { - data += 2; - count -= 2; - } - if ((*data & 1) != 0) { - p = skb_put(skb, 1); - p[0] = 0; - } - - /* copy frame to socket buffer */ - p = skb_put(skb, count); - memcpy(p,data,count); - - /* - * Check if we've overflowed the MRU - */ - if (skb->len >= ppp->mru + PPP_HDRLEN + 2 - || skb_tailroom(skb) <= 0) { - ++ppp->estats.rx_length_errors; - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "rcv frame too long: " - "len=%d mru=%d hroom=%d troom=%d\n", - skb->len, ppp->mru, skb_headroom(skb), - skb_tailroom(skb)); - } else { - if (!ppp_receive_frame(ppp, skb)) { - kfree_skb(skb); - ppp_receive_error(ppp); - } - } - - /* Reset for the next frame */ - skb = NULL; - } - ppp->rpkt = skb; - return; - } - - while (count-- > 0) { - /* - * Collect the character and error condition for the character. - * Set the toss flag for the first character error. - */ - chr = *data++; - if (flags) { - flg = *flags++; - if (flg) { - if (ppp->toss == 0) - ppp->toss = flg; - switch (flg) { - case TTY_OVERRUN: - ++ppp->estats.rx_fifo_errors; - break; - case TTY_FRAME: - case TTY_BREAK: - ++ppp->estats.rx_frame_errors; - break; - } - continue; - } - } - - /* - * Set the flags for d7 being 0/1 and parity being - * even/odd so that the normal processing would have - * all flags set at the end of the session. A - * missing flag bit indicates an error condition. - */ - -#ifdef CHECK_CHARACTERS - if (chr & 0x80) - ppp->flags |= SC_RCV_B7_1; - else - ppp->flags |= SC_RCV_B7_0; - - if (paritytab[chr >> 5] & (1 << (chr & 0x1F))) - ppp->flags |= SC_RCV_ODDP; - else - ppp->flags |= SC_RCV_EVNP; -#endif - - if (chr == PPP_FLAG) { - /* - * FLAG. This is the end of the block. If the block - * ends with ESC FLAG, then the block is to be ignored. - */ - if (ppp->escape) - ppp->toss |= 0x80; - /* - * Process the frame if it was received correctly. - * If there was an error, let the VJ decompressor know. - * There are 4 cases here: - * skb != NULL, toss != 0: error in frame - * skb != NULL, toss == 0: frame ok - * skb == NULL, toss != 0: very first frame, - * error on 1st char, or alloc_skb failed - * skb == NULL, toss == 0: empty frame (~~) - */ - if (ppp->toss || !ppp_receive_frame(ppp, skb)) { - if (ppp->toss && (ppp->flags & SC_DEBUG)) - printk(KERN_DEBUG - "ppp: tossing frame (%x)\n", - ppp->toss); - if (skb != NULL) - kfree_skb(skb); - if (!(ppp->toss == 0xE0 || ppp->toss == 0x80)) - ++ppp->stats.ppp_ierrors; - ppp_receive_error(ppp); - } - /* - * Reset for the next frame. - */ - skb = NULL; - ppp->rfcs = PPP_INITFCS; - ppp->escape = 0; - ppp->toss = 0; - continue; - } - - /* If we're tossing, look no further. */ - if (ppp->toss != 0) - continue; - - /* If this is a control char to be ignored, do so */ - if (in_rmap(ppp, chr)) - continue; - - /* - * Modify the next character if preceded by escape. - * The escape character (0x7d) could be an escaped - * 0x5d, if it follows an escape :-) - */ - if (ppp->escape) { - chr ^= PPP_TRANS; - ppp->escape = 0; - } else if (chr == PPP_ESCAPE) { - ppp->escape = PPP_TRANS; - continue; - } - - /* - * Allocate an skbuff on the first character received. - * The 128 is room for VJ header expansion and FCS. - */ - if (skb == NULL) { - skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN); - if (skb == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "couldn't " - "alloc skb for recv\n"); - ppp->toss = 1; - continue; - } - } - - /* - * Decompress A/C and protocol compression here. - */ - if (skb->len == 0 && chr != PPP_ALLSTATIONS) { - p = skb_put(skb, 2); - p[0] = PPP_ALLSTATIONS; - p[1] = PPP_UI; - } - if (skb->len == 2 && (chr & 1) != 0) { - p = skb_put(skb, 1); - p[0] = 0; - } - - /* - * Check if we've overflowed the MRU - */ - if (skb->len >= ppp->mru + PPP_HDRLEN + 2 - || skb_tailroom(skb) <= 0) { - ++ppp->estats.rx_length_errors; - ppp->toss = 0xC0; - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "rcv frame too long: " - "len=%d mru=%d hroom=%d troom=%d\n", - skb->len, ppp->mru, skb_headroom(skb), - skb_tailroom(skb)); - continue; - } - - /* - * Store the character and update the FCS. - */ - p = skb_put(skb, 1); - *p = chr; - ppp->rfcs = PPP_FCS(ppp->rfcs, chr); - } - ppp->rpkt = skb; -} - -/************************************************************* - * PPP NETWORK INTERFACE SUPPORT - * The following code implements the PPP network - * interface device and handles those parts of - * the PPP processing which are independent of the - * type of hardware link being used, including - * VJ and packet compression. - *************************************************************/ - -/* - * Network device driver callback routines - */ - -static int ppp_init_dev(struct device *dev); -static int ppp_dev_open(struct device *); -static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int ppp_dev_close(struct device *); -static int ppp_dev_xmit(struct sk_buff *, struct device *); -static struct net_device_stats *ppp_dev_stats (struct device *); - -/* - * Information for the protocol decoder - */ - -typedef int (*pfn_proto) (struct ppp *, struct sk_buff *); - -typedef struct ppp_proto_struct { - int proto; - pfn_proto func; -} ppp_proto_type; - -static int rcv_proto_ip (struct ppp *, struct sk_buff *); -static int rcv_proto_ipv6 (struct ppp *, struct sk_buff *); -static int rcv_proto_ipx (struct ppp *, struct sk_buff *); -static int rcv_proto_at (struct ppp *, struct sk_buff *); -static int rcv_proto_vjc_comp (struct ppp *, struct sk_buff *); -static int rcv_proto_vjc_uncomp (struct ppp *, struct sk_buff *); -static int rcv_proto_ccp (struct ppp *, struct sk_buff *); -static int rcv_proto_unknown (struct ppp *, struct sk_buff *); - -static -ppp_proto_type proto_list[] = { - { PPP_IP, rcv_proto_ip }, - { PPP_IPV6, rcv_proto_ipv6 }, - { PPP_IPX, rcv_proto_ipx }, - { PPP_AT, rcv_proto_at }, - { PPP_VJC_COMP, rcv_proto_vjc_comp }, - { PPP_VJC_UNCOMP, rcv_proto_vjc_uncomp }, - { PPP_CCP, rcv_proto_ccp }, - { 0, rcv_proto_unknown } /* !!! MUST BE LAST !!! */ -}; - -/* - * Called when the PPP network interface device is actually created. - */ -static int -ppp_init_dev (struct device *dev) -{ - dev->hard_header_len = PPP_HDRLEN; - - /* device INFO */ - dev->mtu = PPP_MTU; - dev->hard_start_xmit = ppp_dev_xmit; - dev->open = ppp_dev_open; - dev->stop = ppp_dev_close; - dev->get_stats = ppp_dev_stats; - dev->do_ioctl = ppp_dev_ioctl; - dev->addr_len = 0; - dev->tx_queue_len = 10; - dev->type = ARPHRD_PPP; - - dev_init_buffers(dev); - - dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; - - return 0; -} - -/* - * Callback from the network layer when the device goes up. - */ - -static int -ppp_dev_open (struct device *dev) -{ - struct ppp *ppp = dev2ppp(dev); - - if (!ppp->inuse || ppp2tty(ppp) == NULL) { - printk(KERN_ERR "ppp: %s not active\n", dev->name); - return -ENXIO; - } - - MOD_INC_USE_COUNT; - - return 0; -} - -/* - * Callback from the network layer when the ppp device goes down. - */ - -static int -ppp_dev_close (struct device *dev) -{ - struct ppp *ppp = dev2ppp (dev); - - CHECK_PPP_MAGIC(ppp); - - MOD_DEC_USE_COUNT; - - return 0; -} - -static inline void -get_vj_stats(struct vjstat *vj, struct slcompress *slc) -{ - vj->vjs_packets = slc->sls_o_compressed + slc->sls_o_uncompressed; - vj->vjs_compressed = slc->sls_o_compressed; - vj->vjs_searches = slc->sls_o_searches; - vj->vjs_misses = slc->sls_o_misses; - vj->vjs_errorin = slc->sls_i_error; - vj->vjs_tossed = slc->sls_i_tossed; - vj->vjs_uncompressedin = slc->sls_i_uncompressed; - vj->vjs_compressedin = slc->sls_i_compressed; -} - -/* - * Callback from the network layer to process the sockioctl functions. - */ -static int -ppp_dev_ioctl (struct device *dev, struct ifreq *ifr, int cmd) -{ - struct ppp *ppp = dev2ppp(dev); - int nb; - union { - struct ppp_stats stats; - struct ppp_comp_stats cstats; - char vers[32]; - } u; - - CHECK_PPP_MAGIC(ppp); - - memset(&u, 0, sizeof(u)); - switch (cmd) { - case SIOCGPPPSTATS: - u.stats.p = ppp->stats; - if (ppp->slcomp != NULL) - get_vj_stats(&u.stats.vj, ppp->slcomp); - nb = sizeof(u.stats); - break; - - case SIOCGPPPCSTATS: - if (ppp->sc_xc_state != NULL) - (*ppp->sc_xcomp->comp_stat) - (ppp->sc_xc_state, &u.cstats.c); - if (ppp->sc_rc_state != NULL) - (*ppp->sc_rcomp->decomp_stat) - (ppp->sc_rc_state, &u.cstats.d); - nb = sizeof(u.cstats); - break; - - case SIOCGPPPVER: - strcpy(u.vers, szVersion); - nb = strlen(u.vers) + 1; - break; - - default: - return -EINVAL; - } - - if (copy_to_user((void *) ifr->ifr_ifru.ifru_data, &u, nb)) - return -EFAULT; - return 0; -} - -/* - * Process the generic PPP ioctls, i.e. those which are not specific - * to any particular type of hardware link. - */ -static int -ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3) -{ - register int temp_i = 0, oldflags; - int error = -EFAULT; - unsigned long flags; - struct ppp_idle cur_ddinfo; - struct npioctl npi; - - CHECK_PPP(-ENXIO); - - /* - * The user must have an euid of root to do these requests. - */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - switch (param2) { - case PPPIOCSMRU: - /* - * Set the MRU value - */ - if (get_user(temp_i, (int *) param3)) - break; - if (temp_i < PPP_MRU) - temp_i = PPP_MRU; - ppp->mru = temp_i; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO - "ppp_ioctl: set mru to %x\n", temp_i); - error = 0; - break; - - case PPPIOCGFLAGS: - /* - * Fetch the current flags - */ - temp_i = ppp->flags & SC_MASK; -#ifndef CHECK_CHARACTERS /* Don't generate errors if we don't check chars. */ - temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 | - SC_RCV_ODDP | SC_RCV_EVNP; -#endif - if (put_user(temp_i, (int *) param3)) - break; - error = 0; - break; - - case PPPIOCSFLAGS: - /* - * Set the flags for the various options - */ - if (get_user(temp_i, (int *) param3)) - break; - - if (ppp->flags & ~temp_i & SC_CCP_OPEN) - ppp_ccp_closed(ppp); - - save_flags(flags); - cli(); - oldflags = ppp->flags; - temp_i = (temp_i & SC_MASK) | (oldflags & ~SC_MASK); - ppp->flags = temp_i; - restore_flags(flags); - - if ((oldflags | temp_i) & SC_DEBUG) - printk(KERN_INFO - "ppp_ioctl: set flags to %x\n", temp_i); - error = 0; - break; - - case PPPIOCSCOMPRESS: - /* - * Set the compression mode - */ - error = ppp_set_compression - (ppp, (struct ppp_option_data *) param3); - break; - - case PPPIOCGUNIT: - /* - * Obtain the unit number for this device. - */ - if (put_user(ppp->line, (int *) param3)) - break; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO - "ppp_ioctl: get unit: %d\n", ppp->line); - error = 0; - break; - - case PPPIOCSDEBUG: - /* - * Set the debug level - */ - if (get_user(temp_i, (int *) param3)) - break; - temp_i = (temp_i & 0x1F) << 16; - - if ((ppp->flags | temp_i) & SC_DEBUG) - printk(KERN_INFO - "ppp_ioctl: set dbg flags to %x\n", temp_i); - - save_flags(flags); - cli(); - ppp->flags = (ppp->flags & ~0x1F0000) | temp_i; - restore_flags(flags); - error = 0; - break; - - case PPPIOCGDEBUG: - /* - * Get the debug level - */ - temp_i = (ppp->flags >> 16) & 0x1F; - if (put_user(temp_i, (int *) param3)) - break; - error = 0; - break; - - case PPPIOCGIDLE: - /* - * Get the times since the last send/receive frame operation - */ - /* change absolute times to relative times. */ - cur_ddinfo.xmit_idle = (jiffies - ppp->last_xmit) / HZ; - cur_ddinfo.recv_idle = (jiffies - ppp->last_recv) / HZ; - if (copy_to_user((void *) param3, &cur_ddinfo, - sizeof (cur_ddinfo))) - break; - error = 0; - break; - - case PPPIOCSMAXCID: - /* - * Set the maximum VJ header compression slot number. - */ - if (get_user(temp_i, (int *) param3)) - break; - error = -EINVAL; - if (temp_i < 2 || temp_i > 255) - break; - ++temp_i; - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO "ppp_ioctl: set maxcid to %d\n", - temp_i); - if (ppp->slcomp != NULL) - slhc_free(ppp->slcomp); - ppp->slcomp = slhc_init(16, temp_i); - - error = -ENOMEM; - if (ppp->slcomp == NULL) { - printk(KERN_ERR "ppp: no memory for VJ compression\n"); - break; - } - error = 0; - break; - - case PPPIOCGNPMODE: - case PPPIOCSNPMODE: - if (copy_from_user(&npi, (void *) param3, sizeof(npi))) - break; - - switch (npi.protocol) { - case PPP_IP: - npi.protocol = NP_IP; - break; - case PPP_IPX: - npi.protocol = NP_IPX; - break; - case PPP_AT: - npi.protocol = NP_AT; - break; - default: - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "pppioc[gs]npmode: " - "invalid proto %d\n", npi.protocol); - error = -EINVAL; - goto out; - } - - if (param2 == PPPIOCGNPMODE) { - npi.mode = ppp->sc_npmode[npi.protocol]; - if (copy_to_user((void *) param3, &npi, sizeof(npi))) - break; - } else { - ppp->sc_npmode[npi.protocol] = npi.mode; - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "ppp: set np %d to %d\n", - npi.protocol, npi.mode); - mark_bh(NET_BH); - } - error = 0; - break; - - default: - /* - * All other ioctl() events will come here. - */ - if (ppp->flags & SC_DEBUG) - printk(KERN_ERR - "ppp_ioctl: invalid ioctl: %x, addr %lx\n", - param2, param3); - - error = -ENOIOCTLCMD; - break; - } -out: - return error; -} - -/* - * Process the set-compression ioctl. - */ -static int -ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp) -{ - struct compressor *cp; - int error, nb; - unsigned long flags; - __u8 *ptr; - __u8 ccp_option[CCP_MAX_OPTION_LENGTH]; - struct ppp_option_data data; - - /* - * Fetch the compression parameters - */ - error = -EFAULT; - if (copy_from_user(&data, odp, sizeof (data))) - goto out; - - nb = data.length; - ptr = data.ptr; - if ((unsigned) nb >= CCP_MAX_OPTION_LENGTH) - nb = CCP_MAX_OPTION_LENGTH; - - if (copy_from_user(ccp_option, ptr, nb)) - goto out; - - error = -EINVAL; - if (ccp_option[1] < 2) /* preliminary check on the length byte */ - goto out; - - save_flags(flags); - cli(); - ppp->flags &= ~(data.transmit? SC_COMP_RUN: SC_DECOMP_RUN); - restore_flags(flags); - - cp = find_compressor (ccp_option[0]); -#ifdef CONFIG_KMOD - if (cp == NULL) { - char modname[32]; - sprintf(modname, "ppp-compress-%d", ccp_option[0]); - request_module(modname); - cp = find_compressor(ccp_option[0]); - } -#endif /* CONFIG_KMOD */ - - if (cp == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG - "%s: no compressor for [%x %x %x], %x\n", - ppp->name, ccp_option[0], ccp_option[1], - ccp_option[2], nb); - goto out; /* compressor not loaded */ - } - - /* - * Found a handler for the protocol - try to allocate - * a compressor or decompressor. - */ - error = 0; - if (data.transmit) { - if (ppp->sc_xc_state != NULL) - (*ppp->sc_xcomp->comp_free)(ppp->sc_xc_state); - ppp->sc_xc_state = NULL; - - ppp->sc_xcomp = cp; - ppp->sc_xc_state = cp->comp_alloc(ccp_option, nb); - if (ppp->sc_xc_state == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: comp_alloc failed\n", - ppp->name); - error = -ENOBUFS; - } - } else { - if (ppp->sc_rc_state != NULL) - (*ppp->sc_rcomp->decomp_free)(ppp->sc_rc_state); - ppp->sc_rc_state = NULL; - - ppp->sc_rcomp = cp; - ppp->sc_rc_state = cp->decomp_alloc(ccp_option, nb); - if (ppp->sc_rc_state == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: decomp_alloc failed\n", - ppp->name); - error = -ENOBUFS; - } - } -out: - return error; -} - -/* - * Handle a CCP packet. - * - * The CCP packet is passed along to the pppd process just like any - * other PPP frame. The difference is that some processing needs to be - * immediate or the compressors will become confused on the peer. - */ - -static void ppp_proto_ccp(struct ppp *ppp, __u8 *dp, int len, int rcvd) -{ - int slen = CCP_LENGTH(dp); - __u8 *opt = dp + CCP_HDRLEN; - int opt_len = slen - CCP_HDRLEN; - unsigned long flags; - - if (slen > len) - return; - - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "ppp_proto_ccp rcvd=%d code=%x flags=%x\n", - rcvd, CCP_CODE(dp), ppp->flags); - save_flags(flags); - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - /* - * CCP must be going down - disable compression - */ - if (ppp->flags & SC_CCP_UP) { - cli(); - ppp->flags &= ~(SC_CCP_UP | - SC_COMP_RUN | - SC_DECOMP_RUN); - } - break; - - case CCP_CONFACK: - if ((ppp->flags & SC_CCP_OPEN) == 0) - break; - if (ppp->flags & SC_CCP_UP) - break; - if (slen < (CCP_HDRLEN + CCP_OPT_MINLEN)) - break; - if (slen < (CCP_OPT_LENGTH (opt) + CCP_HDRLEN)) - break; - if (!rcvd) { - /* - * we're agreeing to send compressed packets. - */ - if (ppp->sc_xc_state == NULL) - break; - - if ((*ppp->sc_xcomp->comp_init) - (ppp->sc_xc_state, - opt, opt_len, - ppp->line, 0, ppp->flags & SC_DEBUG)) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: comp running\n", - ppp->name); - cli(); - ppp->flags |= SC_COMP_RUN; - } - break; - } - - /* - * peer is agreeing to send compressed packets. - */ - if (ppp->sc_rc_state == NULL) - break; - - if ((*ppp->sc_rcomp->decomp_init) - (ppp->sc_rc_state, - opt, opt_len, - ppp->line, 0, ppp->mru, ppp->flags & SC_DEBUG)) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: decomp running\n", - ppp->name); - cli(); - ppp->flags |= SC_DECOMP_RUN; - ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); - } - break; - - case CCP_RESETACK: - /* - * CCP Reset-ack resets compressors and decompressors - * as it passes through. - */ - if ((ppp->flags & SC_CCP_UP) == 0) - break; - - if (!rcvd) { - if (ppp->sc_xc_state && (ppp->flags & SC_COMP_RUN)) { - (*ppp->sc_xcomp->comp_reset)(ppp->sc_xc_state); - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: comp reset\n", - ppp->name); - } - } else { - if (ppp->sc_rc_state && (ppp->flags & SC_DECOMP_RUN)) { - (*ppp->sc_rcomp->decomp_reset)(ppp->sc_rc_state); - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: decomp reset\n", - ppp->name); - cli(); - ppp->flags &= ~SC_DC_ERROR; - } - } - break; - } - restore_flags(flags); -} - -/* - * CCP is down; free (de)compressor state if necessary. - */ - -static void -ppp_ccp_closed(struct ppp *ppp) -{ - unsigned long flags; - - save_flags(flags); - cli(); - ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); - restore_flags(flags); - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: ccp closed\n", ppp->name); - if (ppp->sc_xc_state) { - (*ppp->sc_xcomp->comp_free) (ppp->sc_xc_state); - ppp->sc_xc_state = NULL; - } - - if (ppp->sc_rc_state) { - (*ppp->sc_rcomp->decomp_free) (ppp->sc_rc_state); - ppp->sc_rc_state = NULL; - } -} - -/************************************************************* - * RECEIVE-SIDE ROUTINES - *************************************************************/ - -/* - * On entry, a received frame is in skb. - * Check it and dispose as appropriate. - */ -static int -ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) -{ - __u8 *data; - int count; - int proto; - int new_count; - struct sk_buff *new_skb; - ppp_proto_type *proto_ptr; - - /* - * An empty frame is ignored. This occurs if the FLAG sequence - * precedes and follows each frame. - */ - if (skb == NULL) - return 1; - if (skb->len == 0) { - kfree_skb(skb); - return 1; - } - data = skb->data; - count = skb->len; - - /* - * Generate an error if the frame is too small. - */ - if (count < PPP_HDRLEN + 2) { - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG - "ppp: got runt ppp frame, %d chars\n", count); - ++ppp->estats.rx_length_errors; - return 0; - } - - if ( !(ppp->flags & SC_SYNC) ) { - /* - * Verify the FCS of the frame and discard the FCS characters - * from the end of the buffer. - */ - if (ppp->rfcs != PPP_GOODFCS) { - if (ppp->flags & SC_DEBUG) { - printk(KERN_DEBUG - "ppp: frame with bad fcs, length = %d\n", - count); - ppp_print_buffer("bad frame", data, count); - } - ++ppp->estats.rx_crc_errors; - return 0; - } - count -= 2; /* ignore the fcs characters */ - skb_trim(skb, count); - } - - /* - * Process the active decompressor. - */ - if (ppp->sc_rc_state != NULL && - (ppp->flags & SC_DECOMP_RUN) && - ((ppp->flags & (SC_DC_FERROR | SC_DC_ERROR)) == 0)) { - if (PPP_PROTOCOL(data) == PPP_COMP) { - /* - * If the frame is compressed then decompress it. - */ - new_skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN); - if (new_skb == NULL) { - printk(KERN_ERR "ppp_recv_frame: no memory\n"); - new_count = DECOMP_ERROR; - } else { - new_count = (*ppp->sc_rcomp->decompress) - (ppp->sc_rc_state, data, count, - new_skb->data, ppp->mru + PPP_HDRLEN); - } - if (new_count > 0) { - /* Frame was decompressed OK */ - kfree_skb(skb); - skb = new_skb; - count = new_count; - data = skb_put(skb, count); - - } else { - /* - * On a decompression error, we pass the - * compressed frame up to pppd as an - * error indication. - */ - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO "%s: decomp err %d\n", - ppp->name, new_count); - if (new_skb != 0) - kfree_skb(new_skb); - if (ppp->slcomp != 0) - slhc_toss(ppp->slcomp); - ++ppp->stats.ppp_ierrors; - if (new_count == DECOMP_FATALERROR) { - ppp->flags |= SC_DC_FERROR; - } else { - ppp->flags |= SC_DC_ERROR; - } - } - - - } else { - /* - * The frame is not compressed. Pass it to the - * decompression code so it can update its - * dictionary if necessary. - */ - (*ppp->sc_rcomp->incomp)(ppp->sc_rc_state, - data, count); - } - } - else if (PPP_PROTOCOL(data) == PPP_COMP && (ppp->flags & SC_DEBUG)) - printk(KERN_INFO "%s: not decomp, rc_state=%p flags=%x\n", - ppp->name, ppp->sc_rc_state, ppp->flags); - - /* - * Count the frame and print it - */ - ++ppp->stats.ppp_ipackets; - ppp->stats.ppp_ioctects += count; - if (ppp->flags & SC_LOG_INPKT) - ppp_print_buffer ("receive frame", data, count); - - /* - * Find the procedure to handle this protocol. - * The last one is marked as protocol 0 which is the 'catch-all' - * to feed it to the pppd daemon. - */ - proto = PPP_PROTOCOL(data); - proto_ptr = proto_list; - while (proto_ptr->proto != 0 && proto_ptr->proto != proto) - ++proto_ptr; - - /* - * Update the appropriate statistic counter. - */ - if (!(*proto_ptr->func)(ppp, skb)) { - kfree_skb(skb); - ++ppp->stats.ppp_discards; - } - - return 1; -} - -/* - * An input error has been detected, so we need to inform - * the VJ decompressor. - */ -static void -ppp_receive_error(struct ppp *ppp) -{ - CHECK_PPP_VOID(); - - if (ppp->slcomp != 0) - slhc_toss(ppp->slcomp); -} - -/* - * Put the input frame into the networking system for the indicated protocol - */ -static int -ppp_rcv_rx(struct ppp *ppp, __u16 proto, struct sk_buff *skb) -{ - - /* - * Fill in a few fields of the skb and give it to netif_rx(). - */ - skb->dev = ppp2dev(ppp); /* We are the device */ - skb->protocol = htons(proto); - skb_pull(skb, PPP_HDRLEN); /* pull off ppp header */ - skb->mac.raw = skb->data; - ppp->last_recv = jiffies; - netif_rx (skb); - return 1; -} - -/* - * Process the receipt of an IP frame - */ -static int -rcv_proto_ip(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - if ((ppp2dev(ppp)->flags & IFF_UP) && (skb->len > 0) - && ppp->sc_npmode[NP_IP] == NPMODE_PASS) - return ppp_rcv_rx(ppp, ETH_P_IP, skb); - return 0; -} - -/* - * Process the receipt of an IPv6 frame - */ -static int -rcv_proto_ipv6(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - if ((ppp2dev(ppp)->flags & IFF_UP) && (skb->len > 0) - && ppp->sc_npmode[NP_IPV6] == NPMODE_PASS) - return ppp_rcv_rx(ppp, ETH_P_IPV6, skb); - return 0; -} - -/* - * Process the receipt of an IPX frame - */ -static int -rcv_proto_ipx(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - if (((ppp2dev(ppp)->flags & IFF_UP) != 0) && (skb->len > 0) - && ppp->sc_npmode[NP_IPX] == NPMODE_PASS) - return ppp_rcv_rx(ppp, ETH_P_IPX, skb); - return 0; -} - -/* - * Process the receipt of an Appletalk frame - */ -static int -rcv_proto_at(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - if ((ppp2dev(ppp)->flags & IFF_UP) && (skb->len > 0) - && ppp->sc_npmode[NP_AT] == NPMODE_PASS) - return ppp_rcv_rx(ppp, ETH_P_PPPTALK, skb); - return 0; -} - -/* - * Process the receipt of an VJ Compressed frame - */ -static int -rcv_proto_vjc_comp(struct ppp *ppp, struct sk_buff *skb) -{ - int new_count; - - CHECK_PPP(0); - if ((ppp->flags & SC_REJ_COMP_TCP) || ppp->slcomp == NULL) - return 0; - new_count = slhc_uncompress(ppp->slcomp, skb->data + PPP_HDRLEN, - skb->len - PPP_HDRLEN); - if (new_count <= 0) { - if (ppp->flags & SC_DEBUG) - printk(KERN_NOTICE - "ppp: error in VJ decompression\n"); - return 0; - } - new_count += PPP_HDRLEN; - if (new_count > skb->len) - skb_put(skb, new_count - skb->len); - else - skb_trim(skb, new_count); - return rcv_proto_ip(ppp, skb); -} - -/* - * Process the receipt of an VJ Un-compressed frame - */ -static int -rcv_proto_vjc_uncomp(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - if ((ppp->flags & SC_REJ_COMP_TCP) || ppp->slcomp == NULL) - return 0; - if (slhc_remember(ppp->slcomp, skb->data + PPP_HDRLEN, - skb->len - PPP_HDRLEN) <= 0) { - if (ppp->flags & SC_DEBUG) - printk(KERN_NOTICE "ppp: error in VJ memorizing\n"); - return 0; - } - return rcv_proto_ip(ppp, skb); -} - -static int -rcv_proto_ccp(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - ppp_proto_ccp (ppp, skb->data + PPP_HDRLEN, skb->len - PPP_HDRLEN, 1); - return rcv_proto_unknown(ppp, skb); -} - -/* - * Receive all unclassified protocols. - */ -static int -rcv_proto_unknown(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP(0); - - /* - * Limit queue length by dropping old frames. - */ - skb_queue_tail(&ppp->rcv_q, skb); - while (ppp->rcv_q.qlen > PPP_MAX_RCV_QLEN) { - struct sk_buff *skb = skb_dequeue(&ppp->rcv_q); - if (skb) - kfree_skb(skb); - } - - wake_up_interruptible (&ppp->read_wait); - if (ppp->tty->fasync != NULL) - kill_fasync (ppp->tty->fasync, SIGIO); - - return 1; -} - -/************************************************************* - * TRANSMIT-SIDE ROUTINES - *************************************************************/ - -/* local function to store a value into the LQR frame */ -extern inline __u8 * store_long (register __u8 *p, register int value) { - *p++ = (__u8) (value >> 24); - *p++ = (__u8) (value >> 16); - *p++ = (__u8) (value >> 8); - *p++ = (__u8) value; - return p; -} - -/* - * Compress and send an frame to the peer. - * Should be called with xmit_busy == 1, having been set by the caller. - * That is, we use xmit_busy as a lock to prevent reentry of this - * procedure. - */ -static void -ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) -{ - int proto; - __u8 *data; - int count; - __u8 *p; - int ret; - - CHECK_PPP_VOID(); - data = skb->data; - count = skb->len; - - /* dump the buffer */ - if (ppp->flags & SC_LOG_OUTPKT) - ppp_print_buffer ("write frame", data, count); - - /* - * Handle various types of protocol-specific compression - * and other processing, including: - * - VJ TCP header compression - * - updating LQR packets - * - updating CCP state on CCP packets - */ - proto = PPP_PROTOCOL(data); - switch (proto) { - case PPP_IP: - if ((ppp->flags & SC_COMP_TCP) && ppp->slcomp != NULL) - skb = ppp_vj_compress(ppp, skb); - break; - - case PPP_LQR: - /* - * Update the LQR frame with the current MIB information. - * This way the information is accurate and up-to-date. - */ - if (count < 48) - break; - p = data + 40; /* Point to last two items. */ - p = store_long(p, ppp->stats.ppp_opackets + 1); - p = store_long(p, ppp->stats.ppp_ooctects + count); - ++ppp->stats.ppp_olqrs; - break; - - case PPP_CCP: - /* - * Outbound compression control frames - */ - ppp_proto_ccp(ppp, data + PPP_HDRLEN, count - PPP_HDRLEN, 0); - break; - } - data = skb->data; - count = skb->len; - - /* - * Compress the whole frame if possible. - */ - if (((ppp->flags & SC_COMP_RUN) != 0) && - (ppp->sc_xc_state != (void *) 0) && - (proto != PPP_LCP) && - (proto != PPP_CCP)) { - struct sk_buff *new_skb; - int new_count; - - /* Allocate an skb for the compressed frame. */ - new_skb = alloc_skb(ppp->mtu + PPP_HDRLEN, GFP_ATOMIC); - if (new_skb == NULL) { - printk(KERN_ERR "ppp_send_frame: no memory\n"); - kfree_skb(skb); - ppp->xmit_busy = 0; - return; - } - - /* Compress the frame. */ - new_count = (*ppp->sc_xcomp->compress) - (ppp->sc_xc_state, data, new_skb->data, - count, ppp->mtu + PPP_HDRLEN); - - /* Did it compress? */ - if (new_count > 0 && (ppp->flags & SC_CCP_UP)) { - skb_put(new_skb, new_count); - kfree_skb(skb); - skb = new_skb; - } else { - /* - * The frame could not be compressed, or it could not - * be sent in compressed form because CCP is down. - */ - kfree_skb(new_skb); - } - } - - /* - * Send the frame - */ - if ( ppp->flags & SC_SYNC ) - ret = ppp_sync_send(ppp, skb); - else - ret = ppp_async_send(ppp, skb); - if (ret > 0) { - /* we can release the lock */ - ppp->xmit_busy = 0; - } else if (ret < 0) { - /* can't happen, since the caller got the xmit_busy lock */ - printk(KERN_ERR "ppp: ppp_async_send didn't accept pkt\n"); - } -} - -/* - * Apply VJ TCP header compression to a packet. - */ -static struct sk_buff * -ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb) -{ - __u8 *orig_data, *data; - struct sk_buff *new_skb; - int len, proto; - - new_skb = alloc_skb(skb->len, GFP_ATOMIC); - if (new_skb == NULL) { - printk(KERN_ERR "ppp: no memory for vj compression\n"); - return skb; - } - - orig_data = data = skb->data + PPP_HDRLEN; - len = slhc_compress(ppp->slcomp, data, skb->len - PPP_HDRLEN, - new_skb->data + PPP_HDRLEN, &data, - (ppp->flags & SC_NO_TCP_CCID) == 0); - - if (data == orig_data) { - /* Couldn't compress the data */ - kfree_skb(new_skb); - return skb; - } - - /* The data has been changed */ - if (data[0] & SL_TYPE_COMPRESSED_TCP) { - proto = PPP_VJC_COMP; - data[0] ^= SL_TYPE_COMPRESSED_TCP; - } else { - if (data[0] >= SL_TYPE_UNCOMPRESSED_TCP) - proto = PPP_VJC_UNCOMP; - else - proto = PPP_IP; - data[0] = orig_data[0]; - } - - data = skb_put(new_skb, len + PPP_HDRLEN); - data[0] = PPP_ALLSTATIONS; - data[1] = PPP_UI; - data[2] = 0; - data[3] = proto; - - kfree_skb(skb); - return new_skb; -} - -static inline void -ppp_send_frames(struct ppp *ppp) -{ - struct sk_buff *skb; - - while (!test_and_set_bit(0, &ppp->xmit_busy)) { - skb = skb_dequeue(&ppp->xmt_q); - if (skb == NULL) { - ppp->xmit_busy = 0; - break; - } - ppp_send_frame(ppp, skb); - } - if (!ppp->xmit_busy && ppp->dev.tbusy) { - ppp->dev.tbusy = 0; - mark_bh(NET_BH); - } -} - -/* - * Called from the hardware (tty) layer when it can accept - * another packet. - */ -static void -ppp_output_wakeup(struct ppp *ppp) -{ - CHECK_PPP_VOID(); - - if (!ppp->xmit_busy) { - printk(KERN_ERR "ppp_output_wakeup called but xmit_busy==0\n"); - return; - } - ppp->xmit_busy = 0; - ppp_send_frames(ppp); -} - -/* - * Send a control frame (from pppd). - */ -static void -ppp_send_ctrl(struct ppp *ppp, struct sk_buff *skb) -{ - CHECK_PPP_VOID(); - - /* - * Put the packet on the queue, then send as many as we can. - */ - skb_queue_tail(&ppp->xmt_q, skb); - ppp_send_frames(ppp); -} - - -/************************************************************* - * NETWORK OUTPUT - * This routine accepts requests from the network layer - * and attempts to deliver the packets. - *************************************************************/ -/* - * Send a frame to the peer. - * Returns 1 iff the frame was not accepted. - */ -static int -ppp_dev_xmit(struct sk_buff *skb, struct device *dev) -{ - struct ppp *ppp = dev2ppp(dev); - struct tty_struct *tty = ppp2tty(ppp); - enum NPmode npmode; - int proto; - unsigned char *hdr; - - /* just a little sanity check. */ - if (skb == NULL) - return 0; - if (skb->data == NULL) { - kfree_skb(skb); - return 0; - } - - /* - * Avoid timing problem should tty hangup while data is - * queued to be sent. - */ - if (!ppp->inuse) { - dev_kfree_skb(skb); - return 0; - } - - /* - * Validate the tty interface - */ - if (tty == NULL) { - if (ppp->flags & SC_DEBUG) - printk(KERN_ERR - "ppp_dev_xmit: %s not connected to a TTY!\n", - dev->name); - dev_kfree_skb(skb); - return 0; - } - - /* - * Work out the appropriate network-protocol mode for this packet. - */ - npmode = NPMODE_PASS; /* default */ - switch (ntohs(skb->protocol)) { - case ETH_P_IP: - proto = PPP_IP; - npmode = ppp->sc_npmode[NP_IP]; - break; - case ETH_P_IPV6: - proto = PPP_IPV6; - npmode = ppp->sc_npmode[NP_IPV6]; - break; - case ETH_P_IPX: - proto = PPP_IPX; - npmode = ppp->sc_npmode[NP_IPX]; - break; - case ETH_P_PPPTALK: - case ETH_P_ATALK: - proto = PPP_AT; - npmode = ppp->sc_npmode[NP_AT]; - break; - default: - if (ppp->flags & SC_DEBUG) - printk(KERN_INFO "%s: packet for unknown proto %x\n", - ppp->name, ntohs(skb->protocol)); - dev_kfree_skb(skb); - return 0; - } - - /* - * Drop, accept or reject the packet depending on the mode. - */ - switch (npmode) { - case NPMODE_PASS: - break; - - case NPMODE_QUEUE: - /* - * We may not send the packet now, so drop it. - * XXX It would be nice to be able to return it to the - * network system to be queued and retransmitted later. - */ - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s: returning frame\n", ppp->name); - dev_kfree_skb(skb); - return 0; - - case NPMODE_ERROR: - case NPMODE_DROP: - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG - "ppp_dev_xmit: dropping (npmode = %d) on %s\n", - npmode, ppp->name); - dev_kfree_skb(skb); - return 0; - } - - /* - * The dev->tbusy field acts as a lock to allow only - * one packet to be processed at a time. If we can't - * get the lock, try again later. - * We deliberately queue as little as possible inside - * the ppp driver in order to minimize the latency - * for high-priority packets. - */ - if (test_and_set_bit(0, &ppp->xmit_busy)) { - dev->tbusy = 1; /* can't take it now */ - return 1; - } - dev->tbusy = 0; - - /* - * Put the 4-byte PPP header on the packet. - * If there isn't room for it, we have to copy the packet. - */ - if (skb_headroom(skb) < PPP_HDRLEN) { - struct sk_buff *new_skb; - - new_skb = alloc_skb(skb->len + PPP_HDRLEN, GFP_ATOMIC); - if (new_skb == NULL) { - printk(KERN_ERR "%s: skb hdr alloc failed\n", - ppp->name); - dev_kfree_skb(skb); - ppp->xmit_busy = 0; - ppp_send_frames(ppp); - return 0; - } - skb_reserve(new_skb, PPP_HDRLEN); - memcpy(skb_put(new_skb, skb->len), skb->data, skb->len); - dev_kfree_skb(skb); - skb = new_skb; - } - - hdr = skb_push(skb, PPP_HDRLEN); - hdr[0] = PPP_ALLSTATIONS; - hdr[1] = PPP_UI; - hdr[2] = proto >> 8; - hdr[3] = proto; - - ppp_send_frame(ppp, skb); - if (!ppp->xmit_busy) - ppp_send_frames(ppp); - return 0; -} - -/* - * Generate the statistic information for the /proc/net/dev listing. - */ -static struct net_device_stats * -ppp_dev_stats (struct device *dev) -{ - struct ppp *ppp = dev2ppp (dev); - - ppp->estats.rx_packets = ppp->stats.ppp_ipackets; - ppp->estats.rx_errors = ppp->stats.ppp_ierrors; - ppp->estats.tx_packets = ppp->stats.ppp_opackets; - ppp->estats.tx_errors = ppp->stats.ppp_oerrors; - ppp->estats.rx_bytes = ppp->stats.ppp_ibytes; - ppp->estats.tx_bytes = ppp->stats.ppp_obytes; - - return &ppp->estats; -} - -/************************************************************* - * UTILITIES - * Miscellany called by various functions above. - *************************************************************/ - -/* Locate the previous instance of the PPP channel */ -static struct ppp * -ppp_find(int pid_value) -{ - struct ppp *ppp; - - /* try to find the device which this pid is already using */ - for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { - if (ppp->inuse && ppp->sc_xfer == pid_value) { - ppp->sc_xfer = 0; - break; - } - } - return ppp; -} - -/* allocate or create a PPP channel */ -static struct ppp * -ppp_alloc(void) -{ - int if_num; - int status; - struct device *dev; - struct ppp *ppp; - - /* try to find an free device */ - for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { - if (!test_and_set_bit(0, &ppp->inuse)) { - dev = ppp2dev(ppp); - if (dev->flags & IFF_UP) { - clear_bit(0, &ppp->inuse); - continue; - } - /* Reregister device */ - unregister_netdev(dev); - if (register_netdev(dev) == 0) - return ppp; - printk(KERN_DEBUG "could not reregister ppp device\n"); - /* leave inuse set in this case */ - } - } - - /* - * There are no available units, so make a new one. - */ - ppp = (struct ppp *) kmalloc(sizeof(struct ppp), GFP_KERNEL); - if (ppp == 0) { - printk(KERN_ERR "ppp: struct ppp allocation failed\n"); - return 0; - } - memset(ppp, 0, sizeof(*ppp)); - - /* initialize channel control data */ - ppp->magic = PPP_MAGIC; - ppp->next = NULL; - ppp->inuse = 1; - init_waitqueue_head(&ppp->read_wait); - - /* - * Make up a suitable name for this device - */ - dev = ppp2dev(ppp); - dev->name = ppp->name; - if_num = dev_alloc_name(dev, "ppp%d"); - if (if_num < 0) { - printk(KERN_ERR "ppp: dev_alloc_name failed (%d)\n", if_num); - kfree(ppp); - return 0; - } - ppp->line = if_num; - ppp->slcomp = NULL; - - dev->next = NULL; - dev->init = ppp_init_dev; - dev->name = ppp->name; - dev->priv = (void *) ppp; - - /* register device so that we can be ifconfig'd */ - /* ppp_init_dev() will be called as a side-effect */ - status = register_netdev (dev); - if (status == 0) { - printk(KERN_INFO "registered device %s\n", dev->name); - } else { - printk(KERN_ERR - "ppp_alloc - register_netdev(%s) = %d failure.\n", - dev->name, status); - kfree(ppp); - ppp = NULL; - } - - /* link this unit into our list */ - if (ppp_list == 0) - ppp_list = ppp; - else - ppp_last->next = ppp; - ppp_last = ppp; - - return ppp; -} - -/* - * Initialize the generic parts of the ppp structure. - */ -static void -ppp_generic_init(struct ppp *ppp) -{ - int indx; - - ppp->flags = 0; - ppp->mtu = PPP_MTU; - ppp->mru = PPP_MRU; - - skb_queue_head_init(&ppp->xmt_q); - skb_queue_head_init(&ppp->rcv_q); - - ppp->last_xmit = jiffies; - ppp->last_recv = jiffies; - ppp->xmit_busy = 0; - - /* clear statistics */ - memset(&ppp->stats, 0, sizeof (struct pppstat)); - memset(&ppp->estats, 0, sizeof(struct net_device_stats)); - - /* PPP compression data */ - ppp->sc_xc_state = NULL; - ppp->sc_rc_state = NULL; - - for (indx = 0; indx < NUM_NP; ++indx) - ppp->sc_npmode[indx] = NPMODE_PASS; -} - -/* - * Called to clean up the generic parts of the ppp structure. - */ -static void -ppp_release(struct ppp *ppp) -{ - struct sk_buff *skb; - - CHECK_PPP_MAGIC(ppp); - - if (ppp->flags & SC_DEBUG) - printk(KERN_DEBUG "%s released\n", ppp->name); - - ppp_ccp_closed(ppp); - - /* Ensure that the pppd process is not hanging on select()/poll() */ - wake_up_interruptible(&ppp->read_wait); - - if (ppp->slcomp) { - slhc_free(ppp->slcomp); - ppp->slcomp = NULL; - } - - while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL) - kfree_skb(skb); - while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL) - kfree_skb(skb); - - ppp->inuse = 0; - if (ppp->dev.tbusy) { - ppp->dev.tbusy = 0; - mark_bh(NET_BH); - } -} - -/* - * Utility procedures to print a buffer in hex/ascii - */ -static void -ppp_print_hex (register __u8 * out, const __u8 * in, int count) -{ - register __u8 next_ch; - static char hex[] = "0123456789ABCDEF"; - - while (count-- > 0) { - next_ch = *in++; - *out++ = hex[(next_ch >> 4) & 0x0F]; - *out++ = hex[next_ch & 0x0F]; - ++out; - } -} - -static void -ppp_print_char (register __u8 * out, const __u8 * in, int count) -{ - register __u8 next_ch; - - while (count-- > 0) { - next_ch = *in++; - - if (next_ch < 0x20 || next_ch > 0x7e) - *out++ = '.'; - else { - *out++ = next_ch; - if (next_ch == '%') /* printk/syslogd has a bug !! */ - *out++ = '%'; - } - } - *out = '\0'; -} - -static void -ppp_print_buffer (const char *name, const __u8 *buf, int count) -{ - __u8 line[44]; - - if (name != NULL) - printk(KERN_DEBUG "ppp: %s, count = %d\n", name, count); - - while (count > 8) { - memset (line, 32, 44); - ppp_print_hex (line, buf, 8); - ppp_print_char (&line[8 * 3], buf, 8); - printk(KERN_DEBUG "%s\n", line); - count -= 8; - buf += 8; - } - - if (count > 0) { - memset (line, 32, 44); - ppp_print_hex (line, buf, count); - ppp_print_char (&line[8 * 3], buf, count); - printk(KERN_DEBUG "%s\n", line); - } -} - -/************************************************************* - * Compressor module interface - *************************************************************/ - -struct compressor_link { - struct compressor_link *next; - struct compressor *comp; -}; - -static struct compressor_link *ppp_compressors = (struct compressor_link *) 0; - -static struct compressor *find_compressor (int type) -{ - struct compressor_link *lnk; - unsigned long flags; - - save_flags(flags); - cli(); - - lnk = ppp_compressors; - while (lnk != (struct compressor_link *) 0) { - if ((int) (__u8) lnk->comp->compress_proto == type) { - restore_flags(flags); - return lnk->comp; - } - lnk = lnk->next; - } - - restore_flags(flags); - return (struct compressor *) 0; -} - -#ifdef CONFIG_MODULES -static int ppp_register_compressor (struct compressor *cp) -{ - struct compressor_link *new; - unsigned long flags; - - new = (struct compressor_link *) - kmalloc (sizeof (struct compressor_link), GFP_KERNEL); - - if (new == (struct compressor_link *) 0) - return 1; - - save_flags(flags); - cli(); - - if (find_compressor (cp->compress_proto)) { - restore_flags(flags); - kfree (new); - return 0; - } - - new->next = ppp_compressors; - new->comp = cp; - ppp_compressors = new; - - restore_flags(flags); - return 0; -} - -static void ppp_unregister_compressor (struct compressor *cp) -{ - struct compressor_link *prev = (struct compressor_link *) 0; - struct compressor_link *lnk; - unsigned long flags; - - save_flags(flags); - cli(); - - lnk = ppp_compressors; - while (lnk != (struct compressor_link *) 0) { - if (lnk->comp == cp) { - if (prev) - prev->next = lnk->next; - else - ppp_compressors = lnk->next; - kfree (lnk); - break; - } - prev = lnk; - lnk = lnk->next; - } - restore_flags(flags); -} -#endif - -/************************************************************* - * Module support routines - *************************************************************/ - -#ifdef MODULE -int -init_module(void) -{ - int status; - - /* register our line disciplines */ - status = ppp_first_time(); - if (status != 0) - printk(KERN_INFO "PPP: ppp_init() failure %d\n", status); - - return status; -} - -void -cleanup_module(void) -{ - int status; - struct ppp *ppp, *next_ppp; - int busy = 0; - - /* - * Ensure that the devices are not in operation. - */ - for (ppp = ppp_list; ppp != 0; ppp = ppp->next) { - CHECK_PPP_MAGIC(ppp); - if (ppp->inuse || (ppp->dev.flags & IFF_UP)) - ++busy; - } - if (busy) - printk(KERN_CRIT "PPP: removing despite %d units in use!\n", - busy); - - /* - * Release the tty registration of the line discipline so that - * ttys can no longer be put into PPP line discipline. - */ - status = tty_register_ldisc (N_PPP, NULL); - if (status != 0) - printk(KERN_ERR - "PPP: Unable to unregister ppp line discipline " - "(err = %d)\n", status); - else - printk(KERN_INFO - "PPP: ppp line discipline successfully unregistered\n"); - - /* - * De-register the devices so that there is no problem with them - */ - for (ppp = ppp_list; ppp != 0; ppp = next_ppp) { - next_ppp = ppp->next; - unregister_netdev(&ppp->dev); - kfree (ppp); - } -} -#endif diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c new file mode 100644 index 000000000..552061da1 --- /dev/null +++ b/drivers/net/ppp_async.c @@ -0,0 +1,956 @@ +/* + * PPP async serial channel driver for Linux. + * + * Copyright 1999 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This driver provides the encapsulation and framing for sending + * and receiving PPP frames over async serial lines. It relies on + * the generic PPP layer to give it frames to send and to process + * received frames. It implements the PPP line discipline. + * + * Part of the code in this driver was inspired by the old async-only + * PPP driver, written by Michael Callahan and Al Longyear, and + * subsequently hacked by Paul Mackerras. + * + * ==FILEVERSION 990806== + */ + +/* $Id: ppp_async.c,v 1.3 1999/09/02 05:30:10 paulus Exp $ */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> +#include <linux/tty.h> +#include <linux/netdevice.h> +#include <linux/poll.h> +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> +#include <linux/ppp_channel.h> +#include <asm/uaccess.h> + +#define PPP_VERSION "2.4.0" + +#define OBUFSIZE 256 + +/* Structure for storing local state. */ +struct asyncppp { + struct tty_struct *tty; + unsigned int flags; + unsigned int state; + unsigned int rbits; + int mru; + unsigned long busy; + u32 xaccm[8]; + u32 raccm; + unsigned int bytes_sent; + unsigned int bytes_rcvd; + + struct sk_buff *tpkt; + int tpkt_pos; + u16 tfcs; + unsigned char *optr; + unsigned char *olim; + struct sk_buff_head xq; + unsigned long last_xmit; + + struct sk_buff *rpkt; + struct sk_buff_head rq; + wait_queue_head_t rwait; + + struct ppp_channel chan; /* interface to generic ppp layer */ + int connected; + unsigned char obuf[OBUFSIZE]; +}; + +/* Bit numbers in busy */ +#define XMIT_BUSY 0 +#define RECV_BUSY 1 +#define XMIT_WAKEUP 2 +#define XMIT_FULL 3 + +/* State bits */ +#define SC_TOSS 0x20000000 +#define SC_ESCAPE 0x40000000 + +/* Bits in rbits */ +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +#define PPPASYNC_MAX_RQLEN 32 /* arbitrary */ + +static int flag_time = HZ; +MODULE_PARM(flag_time, "i"); + +/* + * Prototypes. + */ +static int ppp_async_encode(struct asyncppp *ap); +static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb); +static int ppp_async_push(struct asyncppp *ap); +static void ppp_async_flush_output(struct asyncppp *ap); +static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, + char *flags, int count); + +struct ppp_channel_ops async_ops = { + ppp_async_send +}; + +/* + * Routines for locking and unlocking the transmit and receive paths. + */ +static inline void +lock_path(struct asyncppp *ap, int bit) +{ + do { + while (test_bit(bit, &ap->busy)) + mb(); + } while (test_and_set_bit(bit, &ap->busy)); + mb(); +} + +static inline int +trylock_path(struct asyncppp *ap, int bit) +{ + if (test_and_set_bit(bit, &ap->busy)) + return 0; + mb(); + return 1; +} + +static inline void +unlock_path(struct asyncppp *ap, int bit) +{ + mb(); + clear_bit(bit, &ap->busy); +} + +#define lock_xmit_path(ap) lock_path(ap, XMIT_BUSY) +#define trylock_xmit_path(ap) trylock_path(ap, XMIT_BUSY) +#define unlock_xmit_path(ap) unlock_path(ap, XMIT_BUSY) +#define lock_recv_path(ap) lock_path(ap, RECV_BUSY) +#define trylock_recv_path(ap) trylock_path(ap, RECV_BUSY) +#define unlock_recv_path(ap) unlock_path(ap, RECV_BUSY) + +static inline void +flush_skb_queue(struct sk_buff_head *q) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(q)) != 0) + kfree_skb(skb); +} + +/* + * Routines implementing the PPP line discipline. + */ + +/* + * Called when a tty is put into PPP line discipline. + */ +static int +ppp_async_open(struct tty_struct *tty) +{ + struct asyncppp *ap; + + ap = kmalloc(sizeof(*ap), GFP_KERNEL); + if (ap == 0) + return -ENOMEM; + + MOD_INC_USE_COUNT; + + /* initialize the asyncppp structure */ + memset(ap, 0, sizeof(*ap)); + ap->tty = tty; + ap->mru = PPP_MRU; + ap->xaccm[0] = ~0U; + ap->xaccm[3] = 0x60000000U; + ap->raccm = ~0U; + ap->optr = ap->obuf; + ap->olim = ap->obuf; + skb_queue_head_init(&ap->xq); + skb_queue_head_init(&ap->rq); + init_waitqueue_head(&ap->rwait); + + tty->disc_data = ap; + + return 0; +} + +/* + * Called when the tty is put into another line discipline + * (or it hangs up). + */ +static void +ppp_async_close(struct tty_struct *tty) +{ + struct asyncppp *ap = tty->disc_data; + + if (ap == 0) + return; + tty->disc_data = 0; + lock_xmit_path(ap); + lock_recv_path(ap); + if (ap->rpkt != 0) + kfree_skb(ap->rpkt); + flush_skb_queue(&ap->rq); + if (ap->tpkt != 0) + kfree_skb(ap->tpkt); + flush_skb_queue(&ap->xq); + if (ap->connected) + ppp_unregister_channel(&ap->chan); + kfree(ap); + MOD_DEC_USE_COUNT; +} + +/* + * Read a PPP frame. pppd can use this to negotiate over the + * channel before it joins it to a bundle. + */ +static ssize_t +ppp_async_read(struct tty_struct *tty, struct file *file, + unsigned char *buf, size_t count) +{ + struct asyncppp *ap = tty->disc_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + struct sk_buff *skb = 0; + + ret = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + + add_wait_queue(&ap->rwait, &wait); + current->state = TASK_INTERRUPTIBLE; + for (;;) { + ret = -EAGAIN; + skb = skb_dequeue(&ap->rq); + if (skb) + break; + if (file->f_flags & O_NONBLOCK) + break; + ret = -ERESTARTSYS; + if (signal_pending(current)) + break; + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&ap->rwait, &wait); + + if (skb == 0) + goto out; + + ret = -EOVERFLOW; + if (skb->len > count) + goto outf; + ret = -EFAULT; + if (copy_to_user(buf, skb->data, skb->len)) + goto outf; + ret = skb->len; + + outf: + kfree_skb(skb); + out: + return ret; +} + +/* + * Write a ppp frame. pppd can use this to send frames over + * this particular channel. + */ +static ssize_t +ppp_async_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t count) +{ + struct asyncppp *ap = tty->disc_data; + struct sk_buff *skb; + ssize_t ret; + + ret = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + + ret = -ENOMEM; + skb = alloc_skb(count + 2, GFP_KERNEL); + if (skb == 0) + goto out; + skb_reserve(skb, 2); + ret = -EFAULT; + if (copy_from_user(skb_put(skb, count), buf, count)) { + kfree_skb(skb); + goto out; + } + + skb_queue_tail(&ap->xq, skb); + ppp_async_push(ap); + + ret = count; + + out: + return ret; +} + +static int +ppp_async_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct asyncppp *ap = tty->disc_data; + int err, val; + u32 accm[8]; + struct sk_buff *skb; + + err = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + err = -EPERM; + if (!capable(CAP_NET_ADMIN)) + goto out; + + err = -EFAULT; + switch (cmd) { + case PPPIOCGFLAGS: + val = ap->flags | ap->rbits; + if (put_user(val, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSFLAGS: + if (get_user(val, (int *) arg)) + break; + ap->flags = val & ~SC_RCV_BITS; + ap->rbits = val & SC_RCV_BITS; + err = 0; + break; + + case PPPIOCGASYNCMAP: + if (put_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSASYNCMAP: + if (get_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + + case PPPIOCGRASYNCMAP: + if (put_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSRASYNCMAP: + if (get_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + + case PPPIOCGXASYNCMAP: + if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm))) + break; + err = 0; + break; + case PPPIOCSXASYNCMAP: + if (copy_from_user(accm, (void *) arg, sizeof(accm))) + break; + accm[2] &= ~0x40000000U; /* can't escape 0x5e */ + accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ + memcpy(ap->xaccm, accm, sizeof(ap->xaccm)); + err = 0; + break; + + case PPPIOCGMRU: + if (put_user(ap->mru, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSMRU: + if (get_user(val, (int *) arg)) + break; + if (val < PPP_MRU) + val = PPP_MRU; + ap->mru = val; + err = 0; + break; + + case PPPIOCATTACH: + if (get_user(val, (int *) arg)) + break; + err = -EALREADY; + if (ap->connected) + break; + ap->chan.private = ap; + ap->chan.ops = &async_ops; + err = ppp_register_channel(&ap->chan, val); + if (err != 0) + break; + ap->connected = 1; + break; + case PPPIOCDETACH: + err = -ENXIO; + if (!ap->connected) + break; + ppp_unregister_channel(&ap->chan); + ap->connected = 0; + err = 0; + break; + + case TCGETS: + case TCGETA: + err = n_tty_ioctl(tty, file, cmd, arg); + break; + + case TCFLSH: + /* flush our buffers and the serial port's buffer */ + if (arg == TCIFLUSH || arg == TCIOFLUSH) + flush_skb_queue(&ap->rq); + if (arg == TCIOFLUSH || arg == TCOFLUSH) + ppp_async_flush_output(ap); + err = n_tty_ioctl(tty, file, cmd, arg); + break; + + case FIONREAD: + val = 0; + if ((skb = skb_peek(&ap->rq)) != 0) + val = skb->len; + if (put_user(val, (int *) arg)) + break; + err = 0; + break; + + default: + err = -ENOIOCTLCMD; + } + out: + return err; +} + +static unsigned int +ppp_async_poll(struct tty_struct *tty, struct file *file, poll_table *wait) +{ + struct asyncppp *ap = tty->disc_data; + unsigned int mask; + + if (ap == 0) + return 0; /* should never happen */ + poll_wait(file, &ap->rwait, wait); + mask = POLLOUT | POLLWRNORM; + if (skb_peek(&ap->rq)) + mask |= POLLIN | POLLRDNORM; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags) || tty_hung_up_p(file)) + mask |= POLLHUP; + return mask; +} + +static int +ppp_async_room(struct tty_struct *tty) +{ + return 65535; +} + +static void +ppp_async_receive(struct tty_struct *tty, const unsigned char *buf, + char *flags, int count) +{ + struct asyncppp *ap = tty->disc_data; + + if (ap == 0) + return; + trylock_recv_path(ap); + ppp_async_input(ap, buf, flags, count); + unlock_recv_path(ap); + if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) + && tty->driver.unthrottle) + tty->driver.unthrottle(tty); +} + +static void +ppp_async_wakeup(struct tty_struct *tty) +{ + struct asyncppp *ap = tty->disc_data; + + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + if (ap == 0) + return; + if (ppp_async_push(ap) && ap->connected) + ppp_output_wakeup(&ap->chan); +} + + +static struct tty_ldisc ppp_ldisc = { + magic: TTY_LDISC_MAGIC, + name: "ppp", + open: ppp_async_open, + close: ppp_async_close, + read: ppp_async_read, + write: ppp_async_write, + ioctl: ppp_async_ioctl, + poll: ppp_async_poll, + receive_room: ppp_async_room, + receive_buf: ppp_async_receive, + write_wakeup: ppp_async_wakeup, +}; + +int +ppp_async_init(void) +{ + int err; + + err = tty_register_ldisc(N_PPP, &ppp_ldisc); + if (err != 0) + printk(KERN_ERR "PPP_async: error %d registering line disc.\n", + err); + return err; +} + +/* + * Procedures for encapsulation and framing. + */ + +u16 ppp_crc16_table[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; +EXPORT_SYMBOL(ppp_crc16_table); +#define fcstab ppp_crc16_table /* for PPP_FCS macro */ + +/* + * Procedure to encode the data for async serial transmission. + * Does octet stuffing (escaping), puts the address/control bytes + * on if A/C compression is disabled, and does protocol compression. + * Assumes ap->tpkt != 0 on entry. + * Returns 1 if we finished the current frame, 0 otherwise. + */ + +#define PUT_BYTE(ap, buf, c, islcp) do { \ + if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\ + *buf++ = PPP_ESCAPE; \ + *buf++ = c ^ 0x20; \ + } else \ + *buf++ = c; \ +} while (0) + +static int +ppp_async_encode(struct asyncppp *ap) +{ + int fcs, i, count, c, proto; + unsigned char *buf, *buflim; + unsigned char *data; + int islcp; + + buf = ap->obuf; + ap->olim = buf; + ap->optr = buf; + i = ap->tpkt_pos; + data = ap->tpkt->data; + count = ap->tpkt->len; + fcs = ap->tfcs; + proto = (data[0] << 8) + data[1]; + + /* + * LCP packets with code values between 1 (configure-reqest) + * and 7 (code-reject) must be sent as though no options + * had been negotiated. + */ + islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; + + if (i == 0) { + /* + * Start of a new packet - insert the leading FLAG + * character if necessary. + */ + if (islcp || flag_time == 0 + || jiffies - ap->last_xmit >= flag_time) + *buf++ = PPP_FLAG; + ap->last_xmit = jiffies; + fcs = PPP_INITFCS; + + /* + * Put in the address/control bytes if necessary + */ + if ((ap->flags & SC_COMP_AC) == 0 || islcp) { + PUT_BYTE(ap, buf, 0xff, islcp); + fcs = PPP_FCS(fcs, 0xff); + PUT_BYTE(ap, buf, 0x03, islcp); + fcs = PPP_FCS(fcs, 0x03); + } + } + + /* + * Once we put in the last byte, we need to put in the FCS + * and closing flag, so make sure there is at least 7 bytes + * of free space in the output buffer. + */ + buflim = ap->obuf + OBUFSIZE - 6; + while (i < count && buf < buflim) { + c = data[i++]; + if (i == 1 && c == 0 && (ap->flags & SC_COMP_PROT)) + continue; /* compress protocol field */ + fcs = PPP_FCS(fcs, c); + PUT_BYTE(ap, buf, c, islcp); + } + + if (i < count) { + /* + * Remember where we are up to in this packet. + */ + ap->olim = buf; + ap->tpkt_pos = i; + ap->tfcs = fcs; + return 0; + } + + /* + * We have finished the packet. Add the FCS and flag. + */ + fcs = ~fcs; + c = fcs & 0xff; + PUT_BYTE(ap, buf, c, islcp); + c = (fcs >> 8) & 0xff; + PUT_BYTE(ap, buf, c, islcp); + *buf++ = PPP_FLAG; + ap->olim = buf; + + kfree_skb(ap->tpkt); + ap->tpkt = 0; + return 1; +} + +/* + * Transmit-side routines. + */ + +/* + * Send a packet to the peer over an async tty line. + * Returns 1 iff the packet was accepted. + * If the packet was not accepted, we will call ppp_output_wakeup + * at some later time. + */ +static int +ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb) +{ + struct asyncppp *ap = chan->private; + + ppp_async_push(ap); + + if (test_and_set_bit(XMIT_FULL, &ap->busy)) + return 0; /* already full */ + ap->tpkt = skb; + ap->tpkt_pos = 0; + + ppp_async_push(ap); + return 1; +} + +/* + * Push as much data as possible out to the tty. + */ +static int +ppp_async_push(struct asyncppp *ap) +{ + int avail, sent, done = 0; + struct tty_struct *tty = ap->tty; + int tty_stuffed = 0; + + if (!trylock_xmit_path(ap)) { + set_bit(XMIT_WAKEUP, &ap->busy); + return 0; + } + for (;;) { + if (test_and_clear_bit(XMIT_WAKEUP, &ap->busy)) + tty_stuffed = 0; + if (!tty_stuffed && ap->optr < ap->olim) { + avail = ap->olim - ap->optr; + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + sent = tty->driver.write(tty, 0, ap->optr, avail); + if (sent < 0) + goto flush; /* error, e.g. loss of CD */ + ap->optr += sent; + if (sent < avail) + tty_stuffed = 1; + continue; + } + if (ap->optr == ap->olim && ap->tpkt != 0) { + if (ppp_async_encode(ap)) { + /* finished processing ap->tpkt */ + struct sk_buff *skb = skb_dequeue(&ap->xq); + if (skb != 0) { + ap->tpkt = skb; + } else { + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + } + continue; + } + /* haven't made any progress */ + unlock_xmit_path(ap); + if (!(test_bit(XMIT_WAKEUP, &ap->busy) + || (!tty_stuffed && ap->tpkt != 0))) + break; + if (!trylock_xmit_path(ap)) + break; + } + return done; + +flush: + if (ap->tpkt != 0) { + kfree_skb(ap->tpkt); + ap->tpkt = 0; + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + ap->optr = ap->olim; + unlock_xmit_path(ap); + return done; +} + +/* + * Flush output from our internal buffers. + * Called for the TCFLSH ioctl. + */ +static void +ppp_async_flush_output(struct asyncppp *ap) +{ + int done = 0; + + flush_skb_queue(&ap->xq); + lock_xmit_path(ap); + ap->optr = ap->olim; + if (ap->tpkt != NULL) { + kfree_skb(ap->tpkt); + ap->tpkt = 0; + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + unlock_xmit_path(ap); + if (done && ap->connected) + ppp_output_wakeup(&ap->chan); +} + +/* + * Receive-side routines. + */ + +/* see how many ordinary chars there are at the start of buf */ +static inline int +scan_ordinary(struct asyncppp *ap, const unsigned char *buf, int count) +{ + int i, c; + + for (i = 0; i < count; ++i) { + c = buf[i]; + if (c == PPP_ESCAPE || c == PPP_FLAG + || (c < 0x20 && (ap->raccm & (1 << c)) != 0)) + break; + } + return i; +} + +/* called when a flag is seen - do end-of-packet processing */ +static inline void +process_input_packet(struct asyncppp *ap) +{ + struct sk_buff *skb; + unsigned char *p; + unsigned int len, fcs; + int code = 0; + + skb = ap->rpkt; + ap->rpkt = 0; + if ((ap->state & (SC_TOSS | SC_ESCAPE)) || skb == 0) { + ap->state &= ~(SC_TOSS | SC_ESCAPE); + if (skb != 0) + kfree_skb(skb); + return; + } + + /* check the FCS */ + p = skb->data; + len = skb->len; + if (len < 3) + goto err; /* too short */ + fcs = PPP_INITFCS; + for (; len > 0; --len) + fcs = PPP_FCS(fcs, *p++); + if (fcs != PPP_GOODFCS) + goto err; /* bad FCS */ + skb_trim(skb, skb->len - 2); + + /* check for address/control and protocol compression */ + p = skb->data; + if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto err; + p = skb_pull(skb, 2); + } + if (p[0] & 1) { + /* protocol is compressed */ + skb_push(skb, 1)[0] = 0; + } else if (skb->len < 2) + goto err; + + /* all OK, give it to the generic layer or queue it */ + if (ap->connected) { + ppp_input(&ap->chan, skb); + } else { + skb_queue_tail(&ap->rq, skb); + /* drop old frames if queue too long */ + while (ap->rq.qlen > PPPASYNC_MAX_RQLEN + && (skb = skb_dequeue(&ap->rq)) != 0) + kfree(skb); + wake_up_interruptible(&ap->rwait); + } + return; + + err: + kfree_skb(skb); + if (ap->connected) + ppp_input_error(&ap->chan, code); +} + +static inline void +input_error(struct asyncppp *ap, int code) +{ + ap->state |= SC_TOSS; + if (ap->connected) + ppp_input_error(&ap->chan, code); +} + +/* called when the tty driver has data for us. */ +static void +ppp_async_input(struct asyncppp *ap, const unsigned char *buf, + char *flags, int count) +{ + struct sk_buff *skb; + int c, i, j, n, s, f; + unsigned char *sp; + + /* update bits used for 8-bit cleanness detection */ + if (~ap->rbits & SC_RCV_BITS) { + s = 0; + for (i = 0; i < count; ++i) { + c = buf[i]; + if (flags != 0 && flags[i] != 0) + continue; + s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0; + c = ((c >> 4) ^ c) & 0xf; + s |= (0x6996 & (1 << c))? SC_RCV_ODDP: SC_RCV_EVNP; + } + ap->rbits |= s; + } + + while (count > 0) { + /* scan through and see how many chars we can do in bulk */ + if ((ap->state & SC_ESCAPE) && buf[0] == PPP_ESCAPE) + n = 1; + else + n = scan_ordinary(ap, buf, count); + + f = 0; + if (flags != 0 && (ap->state & SC_TOSS) == 0) { + /* check the flags to see if any char had an error */ + for (j = 0; j < n; ++j) + if ((f = flags[j]) != 0) + break; + } + if (f != 0) { + /* start tossing */ + input_error(ap, f); + + } else if (n > 0 && (ap->state & SC_TOSS) == 0) { + /* stuff the chars in the skb */ + skb = ap->rpkt; + if (skb == 0) { + skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); + if (skb == 0) + goto nomem; + /* Try to get the payload 4-byte aligned */ + if (buf[0] != PPP_ALLSTATIONS) + skb_reserve(skb, 2 + (buf[0] & 1)); + ap->rpkt = skb; + } + if (n > skb_tailroom(skb)) { + /* packet overflowed MRU */ + input_error(ap, 1); + } else { + sp = skb_put(skb, n); + memcpy(sp, buf, n); + if (ap->state & SC_ESCAPE) { + sp[0] ^= 0x20; + ap->state &= ~SC_ESCAPE; + } + } + } + + if (n >= count) + break; + + c = buf[n]; + if (c == PPP_FLAG) { + process_input_packet(ap); + } else if (c == PPP_ESCAPE) { + ap->state |= SC_ESCAPE; + } + /* otherwise it's a char in the recv ACCM */ + ++n; + + buf += n; + if (flags != 0) + flags += n; + count -= n; + } + return; + + nomem: + printk(KERN_ERR "PPPasync: no memory (input pkt)\n"); + input_error(ap, 0); +} + +#ifdef MODULE +int +init_module(void) +{ + return ppp_async_init(); +} + +void +cleanup_module(void) +{ + if (tty_register_ldisc(N_PPP, NULL) != 0) + printk(KERN_ERR "failed to unregister PPP line discipline\n"); +} +#endif /* MODULE */ diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c new file mode 100644 index 000000000..32851a5d8 --- /dev/null +++ b/drivers/net/ppp_generic.c @@ -0,0 +1,1614 @@ +/* + * Generic PPP layer for Linux. + * + * Copyright 1999 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * The generic PPP layer handles the PPP network interfaces, the + * /dev/ppp device, packet and VJ compression, and multilink. + * It talks to PPP `channels' via the interface defined in + * include/linux/ppp_channel.h. Channels provide the basic means for + * sending and receiving PPP frames on some kind of communications + * channel. + * + * Part of the code in this driver was inspired by the old async-only + * PPP driver, written by Michael Callahan and Al Longyear, and + * subsequently hacked by Paul Mackerras. + * + * ==FILEVERSION 990806== + */ + +/* $Id: ppp_generic.c,v 1.3 1999/09/02 05:30:12 paulus Exp $ */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/kmod.h> +#include <linux/list.h> +#include <linux/netdevice.h> +#include <linux/poll.h> +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> +#include <linux/ppp_channel.h> +#include <linux/ppp-comp.h> +#include <linux/skbuff.h> +#include <linux/rtnetlink.h> +#include <linux/if_arp.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/spinlock.h> +#include <net/slhc_vj.h> + +#define PPP_VERSION "2.4.0" + +EXPORT_SYMBOL(ppp_register_channel); +EXPORT_SYMBOL(ppp_unregister_channel); +EXPORT_SYMBOL(ppp_input); +EXPORT_SYMBOL(ppp_input_error); +EXPORT_SYMBOL(ppp_output_wakeup); +EXPORT_SYMBOL(ppp_register_compressor); +EXPORT_SYMBOL(ppp_unregister_compressor); + +/* + * Network protocols we support. + */ +#define NP_IP 0 /* Internet Protocol V4 */ +#define NP_IPV6 1 /* Internet Protocol V6 */ +#define NP_IPX 2 /* IPX protocol */ +#define NP_AT 3 /* Appletalk protocol */ +#define NUM_NP 4 /* Number of NPs. */ + +/* + * Data structure describing one ppp unit. + * A ppp unit corresponds to a ppp network interface device + * and represents a multilink bundle. + * It may have 0 or more ppp channels connected to it. + */ +struct ppp { + struct list_head list; /* link in list of ppp units */ + int index; /* interface unit number */ + char name[16]; /* unit name */ + int refcnt; /* # open /dev/ppp attached */ + unsigned long busy; /* lock and other bits */ + struct list_head channels; /* list of attached channels */ + int n_channels; /* how many channels are attached */ + int mru; /* max receive unit */ + unsigned int flags; /* control bits */ + unsigned int xstate; /* transmit state bits */ + unsigned int rstate; /* receive state bits */ + int debug; /* debug flags */ + struct slcompress *vj; /* state for VJ header compression */ + struct sk_buff_head xq; /* pppd transmit queue */ + struct sk_buff_head rq; /* receive queue for pppd */ + wait_queue_head_t rwait; /* for poll on reading /dev/ppp */ + enum NPmode npmode[NUM_NP]; /* what to do with each net proto */ + struct sk_buff *xmit_pending; /* a packet ready to go out */ + struct sk_buff_head recv_pending;/* pending input packets */ + struct compressor *xcomp; /* transmit packet compressor */ + void *xc_state; /* its internal state */ + struct compressor *rcomp; /* receive decompressor */ + void *rc_state; /* its internal state */ + unsigned long last_xmit; /* jiffies when last pkt sent */ + unsigned long last_recv; /* jiffies when last pkt rcvd */ + struct net_device *dev; /* network interface device */ + struct net_device_stats stats; /* statistics */ +}; + +static LIST_HEAD(all_ppp_units); +static spinlock_t all_ppp_lock = SPIN_LOCK_UNLOCKED; + +/* + * Private data structure for each channel. + * Ultimately this will have multilink stuff etc. in it. + */ +struct channel { + struct list_head list; /* link in list of channels per unit */ + struct ppp_channel *chan; /* public channel data structure */ + int blocked; /* if channel refused last packet */ + struct ppp *ppp; /* ppp unit we're connected to */ +}; + +/* Bit numbers in busy */ +#define XMIT_BUSY 0 +#define RECV_BUSY 1 +#define XMIT_WAKEUP 2 + +/* + * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC. + * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR. + * Bits in xstate: SC_COMP_RUN + */ +#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC) + +/* Get the PPP protocol number from a skb */ +#define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1]) + +/* We limit the length of ppp->rq to this (arbitrary) value */ +#define PPP_MAX_RQLEN 32 + +/* Prototypes. */ +static void ppp_xmit_unlock(struct ppp *ppp); +static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); +static void ppp_push(struct ppp *ppp); +static void ppp_recv_unlock(struct ppp *ppp); +static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb); +static struct sk_buff *ppp_decompress_frame(struct ppp *ppp, + struct sk_buff *skb); +static int ppp_set_compress(struct ppp *ppp, unsigned long arg); +static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound); +static void ppp_ccp_closed(struct ppp *ppp); +static struct compressor *find_compressor(int type); +static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st); +static struct ppp *ppp_create_unit(int unit, int *retp); +static void ppp_release_unit(struct ppp *ppp); +static struct ppp *ppp_find_unit(int unit); + +/* Translates a PPP protocol number to a NP index (NP == network protocol) */ +static inline int proto_to_npindex(int proto) +{ + switch (proto) { + case PPP_IP: + return NP_IP; + case PPP_IPV6: + return NP_IPV6; + case PPP_IPX: + return NP_IPX; + case PPP_AT: + return NP_AT; + } + return -EINVAL; +} + +/* Translates an NP index into a PPP protocol number */ +static const int npindex_to_proto[NUM_NP] = { + PPP_IP, + PPP_IPV6, + PPP_IPX, + PPP_AT, +}; + +/* Translates an ethertype into an NP index */ +static inline int ethertype_to_npindex(int ethertype) +{ + switch (ethertype) { + case ETH_P_IP: + return NP_IP; + case ETH_P_IPV6: + return NP_IPV6; + case ETH_P_IPX: + return NP_IPX; + case ETH_P_PPPTALK: + case ETH_P_ATALK: + return NP_AT; + } + return -1; +} + +/* Translates an NP index into an ethertype */ +static const int npindex_to_ethertype[NUM_NP] = { + ETH_P_IP, + ETH_P_IPV6, + ETH_P_IPX, + ETH_P_PPPTALK, +}; + +/* + * Routines for locking and unlocking the transmit and receive paths + * of each unit. + */ +static inline void +lock_path(struct ppp *ppp, int bit) +{ + int timeout = 1000000; + + do { + while (test_bit(bit, &ppp->busy)) { + mb(); + if (--timeout == 0) { + printk(KERN_ERR "lock_path timeout ppp=%p bit=%x\n", ppp, bit); + return; + } + } + } while (test_and_set_bit(bit, &ppp->busy)); + mb(); +} + +static inline int +trylock_path(struct ppp *ppp, int bit) +{ + if (test_and_set_bit(bit, &ppp->busy)) + return 0; + mb(); + return 1; +} + +static inline void +unlock_path(struct ppp *ppp, int bit) +{ + mb(); + clear_bit(bit, &ppp->busy); +} + +#define lock_xmit_path(ppp) lock_path(ppp, XMIT_BUSY) +#define trylock_xmit_path(ppp) trylock_path(ppp, XMIT_BUSY) +#define unlock_xmit_path(ppp) unlock_path(ppp, XMIT_BUSY) +#define lock_recv_path(ppp) lock_path(ppp, RECV_BUSY) +#define trylock_recv_path(ppp) trylock_path(ppp, RECV_BUSY) +#define unlock_recv_path(ppp) unlock_path(ppp, RECV_BUSY) + +static inline void +free_skbs(struct sk_buff_head *head) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(head)) != 0) + kfree_skb(skb); +} + +/* + * /dev/ppp device routines. + * The /dev/ppp device is used by pppd to control the ppp unit. + * It supports the read, write, ioctl and poll functions. + */ +static int ppp_open(struct inode *inode, struct file *file) +{ + /* + * This could (should?) be enforced by the permissions on /dev/ppp. + */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + MOD_INC_USE_COUNT; + return 0; +} + +static int ppp_release(struct inode *inode, struct file *file) +{ + struct ppp *ppp = (struct ppp *) file->private_data; + + if (ppp != 0) { + file->private_data = 0; + ppp_release_unit(ppp); + } + MOD_DEC_USE_COUNT; + return 0; +} + +static ssize_t ppp_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct ppp *ppp = (struct ppp *) file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + struct sk_buff *skb = 0; + + ret = -ENXIO; + if (ppp == 0) + goto out; /* not currently attached */ + + add_wait_queue(&ppp->rwait, &wait); + current->state = TASK_INTERRUPTIBLE; + for (;;) { + ret = -EAGAIN; + skb = skb_dequeue(&ppp->rq); + if (skb) + break; + if (file->f_flags & O_NONBLOCK) + break; + ret = -ERESTARTSYS; + if (signal_pending(current)) + break; + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&ppp->rwait, &wait); + + if (skb == 0) + goto out; + + ret = -EOVERFLOW; + if (skb->len > count) + goto outf; + ret = -EFAULT; + if (copy_to_user(buf, skb->data, skb->len)) + goto outf; + ret = skb->len; + + outf: + kfree_skb(skb); + out: + return ret; +} + +static ssize_t ppp_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + struct ppp *ppp = (struct ppp *) file->private_data; + struct sk_buff *skb; + ssize_t ret; + + ret = -ENXIO; + if (ppp == 0) + goto out; + + ret = -ENOMEM; + skb = alloc_skb(count + 2, GFP_KERNEL); + if (skb == 0) + goto out; + skb_reserve(skb, 2); + ret = -EFAULT; + if (copy_from_user(skb_put(skb, count), buf, count)) { + kfree_skb(skb); + goto out; + } + + skb_queue_tail(&ppp->xq, skb); + if (trylock_xmit_path(ppp)) + ppp_xmit_unlock(ppp); + + ret = count; + + out: + return ret; +} + +static unsigned int ppp_poll(struct file *file, poll_table *wait) +{ + struct ppp *ppp = (struct ppp *) file->private_data; + unsigned int mask; + + if (ppp == 0) + return 0; + poll_wait(file, &ppp->rwait, wait); + mask = POLLOUT | POLLWRNORM; + if (skb_peek(&ppp->rq) != 0) + mask |= POLLIN | POLLRDNORM; + return mask; +} + +static int ppp_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct ppp *ppp = (struct ppp *) file->private_data; + int err, val, val2, i; + struct ppp_idle idle; + struct npioctl npi; + + if (cmd == PPPIOCNEWUNIT) { + /* Create a new ppp unit */ + int unit, ret; + + if (ppp != 0) + return -EINVAL; + if (get_user(unit, (int *) arg)) + return -EFAULT; + ppp = ppp_create_unit(unit, &ret); + if (ppp == 0) + return ret; + file->private_data = ppp; + if (put_user(ppp->index, (int *) arg)) + return -EFAULT; + return 0; + } + if (cmd == PPPIOCATTACH) { + /* Attach to an existing ppp unit */ + int unit; + + if (ppp != 0) + return -EINVAL; + if (get_user(unit, (int *) arg)) + return -EFAULT; + spin_lock(&all_ppp_lock); + ppp = ppp_find_unit(unit); + if (ppp != 0) + ++ppp->refcnt; + spin_unlock(&all_ppp_lock); + if (ppp == 0) + return -ENXIO; + file->private_data = ppp; + return 0; + } + + if (ppp == 0) + return -ENXIO; + err = -EFAULT; + switch (cmd) { + case PPPIOCDETACH: + file->private_data = 0; + ppp_release_unit(ppp); + err = 0; + break; + + case PPPIOCSMRU: + if (get_user(val, (int *) arg)) + break; + ppp->mru = val; + err = 0; + break; + + case PPPIOCSFLAGS: + if (get_user(val, (int *) arg)) + break; + if (ppp->flags & ~val & SC_CCP_OPEN) + ppp_ccp_closed(ppp); + ppp->flags = val & SC_FLAG_BITS; + err = 0; + break; + + case PPPIOCGFLAGS: + val = ppp->flags | ppp->xstate | ppp->rstate; + if (put_user(val, (int *) arg)) + break; + err = 0; + break; + + case PPPIOCSCOMPRESS: + err = ppp_set_compress(ppp, arg); + break; + + case PPPIOCGUNIT: + if (put_user(ppp->index, (int *) arg)) + break; + err = 0; + break; + + case PPPIOCSDEBUG: + if (get_user(val, (int *) arg)) + break; + ppp->debug = val; + err = 0; + break; + + case PPPIOCGDEBUG: + if (put_user(ppp->debug, (int *) arg)) + break; + err = 0; + break; + + case PPPIOCGIDLE: + idle.xmit_idle = (jiffies - ppp->last_xmit) / HZ; + idle.recv_idle = (jiffies - ppp->last_recv) / HZ; + if (copy_to_user((void *) arg, &idle, sizeof(idle))) + break; + err = 0; + break; + + case PPPIOCSMAXCID: + if (get_user(val, (int *) arg)) + break; + val2 = 15; + if ((val >> 16) != 0) { + val2 = val >> 16; + val &= 0xffff; + } + lock_xmit_path(ppp); + lock_recv_path(ppp); + if (ppp->vj != 0) + slhc_free(ppp->vj); + ppp->vj = slhc_init(val2+1, val+1); + ppp_recv_unlock(ppp); + ppp_xmit_unlock(ppp); + err = -ENOMEM; + if (ppp->vj == 0) { + printk(KERN_ERR "PPP: no memory (VJ compressor)\n"); + break; + } + err = 0; + break; + + case PPPIOCGNPMODE: + case PPPIOCSNPMODE: + if (copy_from_user(&npi, (void *) arg, sizeof(npi))) + break; + err = proto_to_npindex(npi.protocol); + if (err < 0) + break; + i = err; + if (cmd == PPPIOCGNPMODE) { + err = -EFAULT; + npi.mode = ppp->npmode[i]; + if (copy_to_user((void *) arg, &npi, sizeof(npi))) + break; + } else { + ppp->npmode[i] = npi.mode; + /* we may be able to transmit more packets now (??) */ + mark_bh(NET_BH); + } + err = 0; + break; + + default: + err = -ENOTTY; + } + return err; +} + +static struct file_operations ppp_device_fops = { + NULL, /* seek */ + ppp_read, + ppp_write, + NULL, /* readdir */ + ppp_poll, + ppp_ioctl, + NULL, /* mmap */ + ppp_open, + NULL, /* flush */ + ppp_release +}; + +#define PPP_MAJOR 108 + +/* Called at boot time if ppp is compiled into the kernel, + or at module load time (from init_module) if compiled as a module. */ +int +ppp_init(struct net_device *dev) +{ + int err; +#ifndef MODULE + extern struct compressor ppp_deflate, ppp_deflate_draft; + extern int ppp_async_init(void); +#endif + + printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); + err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); + if (err) + printk(KERN_ERR "failed to register PPP device (%d)\n", err); +#ifndef MODULE +#ifdef CONFIG_PPP_ASYNC + ppp_async_init(); +#endif +#ifdef CONFIG_PPP_DEFLATE + if (ppp_register_compressor(&ppp_deflate) == 0) + printk(KERN_INFO "PPP Deflate compression module registered\n"); + ppp_register_compressor(&ppp_deflate_draft); +#endif +#endif /* MODULE */ + + return -ENODEV; +} + +/* + * Network interface unit routines. + */ +static int +ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ppp *ppp = (struct ppp *) dev->priv; + int npi, proto; + unsigned char *pp; + + if (skb == 0) + return 0; + /* can skb->data ever be 0? */ + + npi = ethertype_to_npindex(ntohs(skb->protocol)); + if (npi < 0) + goto outf; + + /* Drop, accept or reject the packet */ + switch (ppp->npmode[npi]) { + case NPMODE_PASS: + break; + case NPMODE_QUEUE: + /* it would be nice to have a way to tell the network + system to queue this one up for later. */ + goto outf; + case NPMODE_DROP: + case NPMODE_ERROR: + goto outf; + } + + /* The transmit side of the ppp interface is serialized by + the XMIT_BUSY bit in ppp->busy. */ + if (!trylock_xmit_path(ppp)) { + dev->tbusy = 1; + return 1; + } + if (ppp->xmit_pending) + ppp_push(ppp); + if (ppp->xmit_pending) { + dev->tbusy = 1; + ppp_xmit_unlock(ppp); + return 1; + } + dev->tbusy = 0; + + /* Put the 2-byte PPP protocol number on the front, + making sure there is room for the address and control fields. */ + if (skb_headroom(skb) < PPP_HDRLEN) { + struct sk_buff *ns; + + ns = alloc_skb(skb->len + PPP_HDRLEN, GFP_ATOMIC); + if (ns == 0) + goto outnbusy; + skb_reserve(ns, PPP_HDRLEN); + memcpy(skb_put(ns, skb->len), skb->data, skb->len); + kfree_skb(skb); + skb = ns; + } + pp = skb_push(skb, 2); + proto = npindex_to_proto[npi]; + pp[0] = proto >> 8; + pp[1] = proto; + + ppp_send_frame(ppp, skb); + ppp_xmit_unlock(ppp); + return 0; + + outnbusy: + ppp_xmit_unlock(ppp); + + outf: + kfree_skb(skb); + return 0; +} + +static struct net_device_stats * +ppp_net_stats(struct net_device *dev) +{ + struct ppp *ppp = (struct ppp *) dev->priv; + + return &ppp->stats; +} + +static int +ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ppp *ppp = dev->priv; + int err = -EFAULT; + void *addr = (void *) ifr->ifr_ifru.ifru_data; + struct ppp_stats stats; + struct ppp_comp_stats cstats; + char *vers; + + switch (cmd) { + case SIOCGPPPSTATS: + ppp_get_stats(ppp, &stats); + if (copy_to_user(addr, &stats, sizeof(stats))) + break; + err = 0; + break; + + case SIOCGPPPCSTATS: + memset(&cstats, 0, sizeof(cstats)); + if (ppp->xc_state != 0) + ppp->xcomp->comp_stat(ppp->xc_state, &cstats.c); + if (ppp->rc_state != 0) + ppp->rcomp->decomp_stat(ppp->rc_state, &cstats.d); + if (copy_to_user(addr, &cstats, sizeof(cstats))) + break; + err = 0; + break; + + case SIOCGPPPVER: + vers = PPP_VERSION; + if (copy_to_user(addr, vers, strlen(vers) + 1)) + break; + err = 0; + break; + + default: + err = -EINVAL; + } + + return err; +} + +int +ppp_net_init(struct net_device *dev) +{ + dev->hard_header_len = PPP_HDRLEN; + dev->mtu = PPP_MTU; + dev->hard_start_xmit = ppp_start_xmit; + dev->get_stats = ppp_net_stats; + dev->do_ioctl = ppp_net_ioctl; + dev->addr_len = 0; + dev->tx_queue_len = 3; + dev->type = ARPHRD_PPP; + dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; + + dev_init_buffers(dev); + return 0; +} + +/* + * Transmit-side routines. + */ + +/* + * Called to unlock the transmit side of the ppp unit, + * making sure that any work queued up gets done. + */ +static void +ppp_xmit_unlock(struct ppp *ppp) +{ + struct sk_buff *skb; + + for (;;) { + if (test_and_clear_bit(XMIT_WAKEUP, &ppp->busy)) + ppp_push(ppp); + while (ppp->xmit_pending == 0 + && (skb = skb_dequeue(&ppp->xq)) != 0) + ppp_send_frame(ppp, skb); + unlock_xmit_path(ppp); + if (!(test_bit(XMIT_WAKEUP, &ppp->busy) + || (ppp->xmit_pending == 0 && skb_peek(&ppp->xq)))) + break; + if (!trylock_xmit_path(ppp)) + break; + } +} + +/* + * Compress and send a frame. + * The caller should have locked the xmit path, + * and xmit_pending should be 0. + */ +static void +ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) +{ + int proto = PPP_PROTO(skb); + struct sk_buff *new_skb; + int len; + unsigned char *cp; + + ++ppp->stats.tx_packets; + ppp->stats.tx_bytes += skb->len - 2; + + switch (proto) { + case PPP_IP: + if (ppp->vj == 0 || (ppp->flags & SC_COMP_TCP) == 0) + break; + /* try to do VJ TCP header compression */ + new_skb = alloc_skb(skb->len + 2, GFP_ATOMIC); + if (new_skb == 0) { + printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n"); + goto drop; + } + skb_reserve(new_skb, 2); + cp = skb->data + 2; + len = slhc_compress(ppp->vj, cp, skb->len - 2, + new_skb->data + 2, &cp, + !(ppp->flags & SC_NO_TCP_CCID)); + if (cp == skb->data + 2) { + /* didn't compress */ + kfree_skb(new_skb); + } else { + if (cp[0] & SL_TYPE_COMPRESSED_TCP) { + proto = PPP_VJC_COMP; + cp[0] &= ~SL_TYPE_COMPRESSED_TCP; + } else { + proto = PPP_VJC_UNCOMP; + cp[0] = skb->data[2]; + } + kfree_skb(skb); + skb = new_skb; + cp = skb_put(skb, len + 2); + cp[0] = 0; + cp[1] = proto; + } + break; + + case PPP_CCP: + /* peek at outbound CCP frames */ + ppp_ccp_peek(ppp, skb, 0); + break; + } + + /* try to do packet compression */ + if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 + && proto != PPP_LCP && proto != PPP_CCP) { + new_skb = alloc_skb(ppp->dev->mtu + PPP_HDRLEN, GFP_ATOMIC); + if (new_skb == 0) { + printk(KERN_ERR "PPP: no memory (comp pkt)\n"); + goto drop; + } + + /* compressor still expects A/C bytes in hdr */ + len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2, + new_skb->data, skb->len + 2, + ppp->dev->mtu + PPP_HDRLEN); + if (len > 0 && (ppp->flags & SC_CCP_UP)) { + kfree_skb(skb); + skb = new_skb; + skb_put(skb, len); + skb_pull(skb, 2); /* pull off A/C bytes */ + } else { + /* didn't compress, or CCP not up yet */ + kfree_skb(new_skb); + } + } + + /* for data packets, record the time */ + if (proto < 0x8000) + ppp->last_xmit = jiffies; + + /* + * If we are waiting for traffic (demand dialling), + * queue it up for pppd to receive. + */ + if (ppp->flags & SC_LOOP_TRAFFIC) { + if (ppp->rq.qlen > PPP_MAX_RQLEN) + goto drop; + skb_queue_tail(&ppp->rq, skb); + wake_up_interruptible(&ppp->rwait); + return; + } + + ppp->xmit_pending = skb; + ppp_push(ppp); + return; + + drop: + kfree_skb(skb); + ++ppp->stats.tx_errors; +} + +/* + * Try to send the frame in xmit_pending. + * The caller should have the xmit path locked. + */ +static void +ppp_push(struct ppp *ppp) +{ + struct list_head *list; + struct channel *chan; + struct sk_buff *skb = ppp->xmit_pending; + + if (skb == 0) + return; + + list = &ppp->channels; + if (list_empty(list)) { + /* nowhere to send the packet, just drop it */ + ppp->xmit_pending = 0; + kfree_skb(skb); + return; + } + + /* If we are doing multilink, decide which channel gets the + packet, and/or fragment the packet over several links. */ + /* XXX for now, just take the first channel */ + list = list->next; + chan = list_entry(list, struct channel, list); + + if (chan->chan->ops->start_xmit(chan->chan, skb)) { + ppp->xmit_pending = 0; + chan->blocked = 0; + } else + chan->blocked = 1; +} + +/* + * Receive-side routines. + */ +static inline void +ppp_do_recv(struct ppp *ppp, struct sk_buff *skb) +{ + skb_queue_tail(&ppp->recv_pending, skb); + if (trylock_recv_path(ppp)) + ppp_recv_unlock(ppp); +} + +void +ppp_input(struct ppp_channel *chan, struct sk_buff *skb) +{ + struct channel *pch = chan->ppp; + + if (pch == 0 || skb->len == 0) { + kfree_skb(skb); + return; + } + ppp_do_recv(pch->ppp, skb); +} + +/* Put a 0-length skb in the receive queue as an error indication */ +void +ppp_input_error(struct ppp_channel *chan, int code) +{ + struct channel *pch = chan->ppp; + struct sk_buff *skb; + + if (pch == 0) + return; + skb = alloc_skb(0, GFP_ATOMIC); + if (skb == 0) + return; + skb->len = 0; /* probably unnecessary */ + skb->cb[0] = code; + ppp_do_recv(pch->ppp, skb); +} + +static void +ppp_recv_unlock(struct ppp *ppp) +{ + struct sk_buff *skb; + + for (;;) { + while ((skb = skb_dequeue(&ppp->recv_pending)) != 0) + ppp_receive_frame(ppp, skb); + unlock_recv_path(ppp); + if (skb_peek(&ppp->recv_pending) == 0) + break; + if (!trylock_recv_path(ppp)) + break; + } +} + +static void +ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) +{ + struct sk_buff *ns; + int proto, len, npi; + + if (skb->len == 0) { + /* XXX should do something with code in skb->cb[0] */ + goto err; /* error indication */ + } + + if (skb->len < 2) { + ++ppp->stats.rx_length_errors; + goto err; + } + + /* Decompress the frame, if compressed. */ + if (ppp->rc_state != 0 && (ppp->rstate & SC_DECOMP_RUN) + && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) + skb = ppp_decompress_frame(ppp, skb); + + proto = PPP_PROTO(skb); + switch (proto) { + case PPP_VJC_COMP: + /* decompress VJ compressed packets */ + if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) + goto err; + if (skb_tailroom(skb) < 124) { + /* copy to a new sk_buff with more tailroom */ + ns = dev_alloc_skb(skb->len + 128); + if (ns == 0) { + printk(KERN_ERR"PPP: no memory (VJ decomp)\n"); + goto err; + } + skb_reserve(ns, 2); + memcpy(skb_put(ns, skb->len), skb->data, skb->len); + kfree_skb(skb); + skb = ns; + } + len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); + if (len <= 0) { + printk(KERN_ERR "PPP: VJ decompression error\n"); + goto err; + } + len += 2; + if (len > skb->len) + skb_put(skb, len - skb->len); + else if (len < skb->len) + skb_trim(skb, len); + proto = PPP_IP; + break; + + case PPP_VJC_UNCOMP: + if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) + goto err; + if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) { + printk(KERN_ERR "PPP: VJ uncompressed error\n"); + goto err; + } + proto = PPP_IP; + break; + + case PPP_CCP: + ppp_ccp_peek(ppp, skb, 1); + break; + } + + ++ppp->stats.rx_packets; + ppp->stats.rx_bytes += skb->len - 2; + + npi = proto_to_npindex(proto); + if (npi < 0) { + /* control or unknown frame - pass it to pppd */ + skb_queue_tail(&ppp->rq, skb); + /* limit queue length by dropping old frames */ + while (ppp->rq.qlen > PPP_MAX_RQLEN) { + skb = skb_dequeue(&ppp->rq); + if (skb) + kfree_skb(skb); + } + /* wake up any process polling or blocking on read */ + wake_up_interruptible(&ppp->rwait); + + } else { + /* network protocol frame - give it to the kernel */ + ppp->last_recv = jiffies; + if ((ppp->dev->flags & IFF_UP) == 0 + || ppp->npmode[npi] != NPMODE_PASS) { + kfree_skb(skb); + } else { + skb_pull(skb, 2); /* chop off protocol */ + skb->dev = ppp->dev; + skb->protocol = htons(npindex_to_ethertype[npi]); + skb->mac.raw = skb->data; + netif_rx(skb); + } + } + return; + + err: + ++ppp->stats.rx_errors; + if (ppp->vj != 0) + slhc_toss(ppp->vj); + kfree_skb(skb); +} + +static struct sk_buff * +ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) +{ + int proto = PPP_PROTO(skb); + struct sk_buff *ns; + int len; + + if (proto == PPP_COMP) { + ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN); + if (ns == 0) { + printk(KERN_ERR "ppp_receive: no memory\n"); + goto err; + } + /* the decompressor still expects the A/C bytes in the hdr */ + len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, + skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + if (len < 0) { + /* Pass the compressed frame to pppd as an + error indication. */ + if (len == DECOMP_FATALERROR) + ppp->rstate |= SC_DC_FERROR; + goto err; + } + + kfree_skb(skb); + skb = ns; + skb_put(skb, len); + skb_pull(skb, 2); /* pull off the A/C bytes */ + + } else { + /* Uncompressed frame - pass to decompressor so it + can update its dictionary if necessary. */ + if (ppp->rcomp->incomp) + ppp->rcomp->incomp(ppp->rc_state, skb->data - 2, + skb->len + 2); + } + + return skb; + + err: + ppp->rstate |= SC_DC_ERROR; + if (ppp->vj != 0) + slhc_toss(ppp->vj); + ++ppp->stats.rx_errors; + return skb; +} + +/* + * Channel interface. + */ + +/* + * Connect a channel to a given PPP unit. + * The channel MUST NOT be connected to a PPP unit already. + */ +int +ppp_register_channel(struct ppp_channel *chan, int unit) +{ + struct ppp *ppp; + struct channel *pch; + int ret = -ENXIO; + + spin_lock(&all_ppp_lock); + ppp = ppp_find_unit(unit); + if (ppp == 0) + goto out; + pch = kmalloc(sizeof(struct channel), GFP_ATOMIC); + ret = -ENOMEM; + if (pch == 0) + goto out; + memset(pch, 0, sizeof(struct channel)); + pch->ppp = ppp; + pch->chan = chan; + list_add(&pch->list, &ppp->channels); + chan->ppp = pch; + ++ppp->n_channels; + ret = 0; + out: + spin_unlock(&all_ppp_lock); + return ret; +} + +/* + * Disconnect a channel from its PPP unit. + */ +void +ppp_unregister_channel(struct ppp_channel *chan) +{ + struct channel *pch; + + spin_lock(&all_ppp_lock); + if ((pch = chan->ppp) != 0) { + chan->ppp = 0; + list_del(&pch->list); + --pch->ppp->n_channels; + kfree(pch); + } + spin_unlock(&all_ppp_lock); +} + +/* + * Callback from a channel when it can accept more to transmit. + * This should ideally be called at BH level, not interrupt level. + */ +void +ppp_output_wakeup(struct ppp_channel *chan) +{ + struct channel *pch = chan->ppp; + struct ppp *ppp; + + if (pch == 0) + return; + ppp = pch->ppp; + pch->blocked = 0; + set_bit(XMIT_WAKEUP, &ppp->busy); + if (trylock_xmit_path(ppp)) + ppp_xmit_unlock(ppp); + if (ppp->xmit_pending == 0) { + ppp->dev->tbusy = 0; + mark_bh(NET_BH); + } +} + +/* + * Compression control. + */ + +/* Process the PPPIOCSCOMPRESS ioctl. */ +static int +ppp_set_compress(struct ppp *ppp, unsigned long arg) +{ + int err; + struct compressor *cp; + struct ppp_option_data data; + unsigned char ccp_option[CCP_MAX_OPTION_LENGTH]; +#ifdef CONFIG_KMOD + char modname[32]; +#endif + + err = -EFAULT; + if (copy_from_user(&data, (void *) arg, sizeof(data)) + || (data.length <= CCP_MAX_OPTION_LENGTH + && copy_from_user(ccp_option, data.ptr, data.length))) + goto out; + err = -EINVAL; + if (data.length > CCP_MAX_OPTION_LENGTH + || ccp_option[1] < 2 || ccp_option[1] > data.length) + goto out; + + cp = find_compressor(ccp_option[0]); +#ifdef CONFIG_KMOD + if (cp == 0) { + sprintf(modname, "ppp-compress-%d", ccp_option[0]); + request_module(modname); + cp = find_compressor(ccp_option[0]); + } +#endif /* CONFIG_KMOD */ + if (cp == 0) + goto out; + + err = -ENOBUFS; + if (data.transmit) { + lock_xmit_path(ppp); + ppp->xstate &= ~SC_COMP_RUN; + if (ppp->xc_state != 0) { + ppp->xcomp->comp_free(ppp->xc_state); + ppp->xc_state = 0; + } + + ppp->xcomp = cp; + ppp->xc_state = cp->comp_alloc(ccp_option, data.length); + ppp_xmit_unlock(ppp); + if (ppp->xc_state == 0) + goto out; + + } else { + lock_recv_path(ppp); + ppp->rstate &= ~SC_DECOMP_RUN; + if (ppp->rc_state != 0) { + ppp->rcomp->decomp_free(ppp->rc_state); + ppp->rc_state = 0; + } + + ppp->rcomp = cp; + ppp->rc_state = cp->decomp_alloc(ccp_option, data.length); + ppp_recv_unlock(ppp); + if (ppp->rc_state == 0) + goto out; + } + err = 0; + + out: + return err; +} + +/* + * Look at a CCP packet and update our state accordingly. + * We assume the caller has the xmit or recv path locked. + */ +static void +ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound) +{ + unsigned char *dp = skb->data + 2; + int len; + + if (skb->len < CCP_HDRLEN + 2 + || skb->len < (len = CCP_LENGTH(dp)) + 2) + return; /* too short */ + + switch (CCP_CODE(dp)) { + case CCP_CONFREQ: + case CCP_TERMREQ: + case CCP_TERMACK: + /* + * CCP is going down - disable compression. + */ + if (inbound) + ppp->rstate &= ~SC_DECOMP_RUN; + else + ppp->xstate &= ~SC_COMP_RUN; + break; + + case CCP_CONFACK: + if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN) + break; + dp += CCP_HDRLEN; + len -= CCP_HDRLEN; + if (len < CCP_OPT_MINLEN || len < CCP_OPT_LENGTH(dp)) + break; + if (inbound) { + /* we will start receiving compressed packets */ + if (ppp->rc_state == 0) + break; + if (ppp->rcomp->decomp_init(ppp->rc_state, dp, len, + ppp->index, 0, ppp->mru, ppp->debug)) { + ppp->rstate |= SC_DECOMP_RUN; + ppp->rstate &= ~(SC_DC_ERROR | SC_DC_FERROR); + } + } else { + /* we will soon start sending compressed packets */ + if (ppp->xc_state == 0) + break; + if (ppp->xcomp->comp_init(ppp->xc_state, dp, len, + ppp->index, 0, ppp->debug)) + ppp->xstate |= SC_COMP_RUN; + } + break; + + case CCP_RESETACK: + /* reset the [de]compressor */ + if ((ppp->flags & SC_CCP_UP) == 0) + break; + if (inbound) { + if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)) { + ppp->rcomp->decomp_reset(ppp->rc_state); + ppp->rstate &= ~SC_DC_ERROR; + } + } else { + if (ppp->xc_state && (ppp->xstate & SC_COMP_RUN)) + ppp->xcomp->comp_reset(ppp->xc_state); + } + break; + } +} + +/* Free up compression resources. */ +static void +ppp_ccp_closed(struct ppp *ppp) +{ + ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP); + + lock_xmit_path(ppp); + ppp->xstate &= ~SC_COMP_RUN; + if (ppp->xc_state) { + ppp->xcomp->comp_free(ppp->xc_state); + ppp->xc_state = 0; + } + ppp_xmit_unlock(ppp); + + lock_recv_path(ppp); + ppp->xstate &= ~SC_DECOMP_RUN; + if (ppp->rc_state) { + ppp->rcomp->decomp_free(ppp->rc_state); + ppp->rc_state = 0; + } + ppp_recv_unlock(ppp); +} + +/* List of compressors. */ +static LIST_HEAD(compressor_list); +static spinlock_t compressor_list_lock = SPIN_LOCK_UNLOCKED; + +struct compressor_entry { + struct list_head list; + struct compressor *comp; +}; + +static struct compressor_entry * +find_comp_entry(int proto) +{ + struct compressor_entry *ce; + struct list_head *list = &compressor_list; + + while ((list = list->next) != &compressor_list) { + ce = list_entry(list, struct compressor_entry, list); + if (ce->comp->compress_proto == proto) + return ce; + } + return 0; +} + +/* Register a compressor */ +int +ppp_register_compressor(struct compressor *cp) +{ + struct compressor_entry *ce; + int ret; + + spin_lock(&compressor_list_lock); + ret = -EEXIST; + if (find_comp_entry(cp->compress_proto) != 0) + goto out; + ret = -ENOMEM; + ce = kmalloc(sizeof(struct compressor_entry), GFP_KERNEL); + if (ce == 0) + goto out; + ret = 0; + ce->comp = cp; + list_add(&ce->list, &compressor_list); + out: + spin_unlock(&compressor_list_lock); + return ret; +} + +/* Unregister a compressor */ +void +ppp_unregister_compressor(struct compressor *cp) +{ + struct compressor_entry *ce; + + spin_lock(&compressor_list_lock); + ce = find_comp_entry(cp->compress_proto); + if (ce != 0 && ce->comp == cp) { + list_del(&ce->list); + kfree(ce); + } + spin_unlock(&compressor_list_lock); +} + +/* Find a compressor. */ +static struct compressor * +find_compressor(int type) +{ + struct compressor_entry *ce; + struct compressor *cp = 0; + + spin_lock(&compressor_list_lock); + ce = find_comp_entry(type); + if (ce != 0) + cp = ce->comp; + spin_unlock(&compressor_list_lock); + return cp; +} + +/* + * Miscelleneous stuff. + */ + +static void +ppp_get_stats(struct ppp *ppp, struct ppp_stats *st) +{ + struct slcompress *vj = ppp->vj; + + memset(st, 0, sizeof(*st)); + st->p.ppp_ipackets = ppp->stats.rx_packets; + st->p.ppp_ierrors = ppp->stats.rx_errors; + st->p.ppp_ibytes = ppp->stats.rx_bytes; + st->p.ppp_opackets = ppp->stats.tx_packets; + st->p.ppp_oerrors = ppp->stats.tx_errors; + st->p.ppp_obytes = ppp->stats.tx_bytes; + if (vj == 0) + return; + st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed; + st->vj.vjs_compressed = vj->sls_o_compressed; + st->vj.vjs_searches = vj->sls_o_searches; + st->vj.vjs_misses = vj->sls_o_misses; + st->vj.vjs_errorin = vj->sls_i_error; + st->vj.vjs_tossed = vj->sls_i_tossed; + st->vj.vjs_uncompressedin = vj->sls_i_uncompressed; + st->vj.vjs_compressedin = vj->sls_i_compressed; +} + +/* + * Stuff for handling the list of ppp units and for initialization. + */ + +/* + * Create a new ppp unit. Fails if it can't allocate memory or + * if there is already a unit with the requested number. + * unit == -1 means allocate a new number. + */ +static struct ppp * +ppp_create_unit(int unit, int *retp) +{ + struct ppp *ppp; + struct net_device *dev; + struct list_head *list; + int last_unit = -1; + int ret = -EEXIST; + int i; + + spin_lock(&all_ppp_lock); + list = &all_ppp_units; + while ((list = list->next) != &all_ppp_units) { + ppp = list_entry(list, struct ppp, list); + if ((unit < 0 && ppp->index > last_unit + 1) + || (unit >= 0 && unit < ppp->index)) + break; + if (unit == ppp->index) + goto out; /* unit already exists */ + last_unit = ppp->index; + } + if (unit < 0) + unit = last_unit + 1; + + /* Create a new ppp structure and link it before `list'. */ + ret = -ENOMEM; + ppp = kmalloc(sizeof(struct ppp), GFP_KERNEL); + if (ppp == 0) + goto out; + memset(ppp, 0, sizeof(struct ppp)); + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + if (dev == 0) { + kfree(ppp); + goto out; + } + memset(dev, 0, sizeof(struct net_device)); + + ppp->index = unit; + sprintf(ppp->name, "ppp%d", unit); + ppp->mru = PPP_MRU; + skb_queue_head_init(&ppp->xq); + skb_queue_head_init(&ppp->rq); + init_waitqueue_head(&ppp->rwait); + ppp->refcnt = 1; + for (i = 0; i < NUM_NP; ++i) + ppp->npmode[i] = NPMODE_PASS; + INIT_LIST_HEAD(&ppp->channels); + skb_queue_head_init(&ppp->recv_pending); + + ppp->dev = dev; + dev->init = ppp_net_init; + dev->name = ppp->name; + dev->priv = ppp; + dev->new_style = 1; + + rtnl_lock(); + ret = register_netdevice(dev); + rtnl_unlock(); + if (ret != 0) { + printk(KERN_ERR "PPP: couldn't register device (%d)\n", ret); + kfree(dev); + kfree(ppp); + goto out; + } + + list_add(&ppp->list, list->prev); + out: + spin_unlock(&all_ppp_lock); + *retp = ret; + if (ret != 0) + ppp = 0; + return ppp; +} + +/* + * Remove a reference to a ppp unit, and destroy it if + * the reference count goes to 0. + */ +static void ppp_release_unit(struct ppp *ppp) +{ + struct list_head *list, *next; + int ref; + + spin_lock(&all_ppp_lock); + ref = --ppp->refcnt; + if (ref == 0) + list_del(&ppp->list); + spin_unlock(&all_ppp_lock); + if (ref != 0) + return; + + /* Last fd open to this ppp unit is being closed or detached: + mark the interface down, free the ppp unit */ + if (ppp->dev) { + rtnl_lock(); + dev_close(ppp->dev); + rtnl_unlock(); + } + for (list = ppp->channels.next; list != &ppp->channels; list = next) { + /* forcibly detach this channel */ + struct channel *chan; + chan = list_entry(list, struct channel, list); + chan->chan->ppp = 0; + next = list->next; + kfree(chan); + } + + /* Free up resources. */ + ppp_ccp_closed(ppp); + lock_xmit_path(ppp); + lock_recv_path(ppp); + if (ppp->vj) { + slhc_free(ppp->vj); + ppp->vj = 0; + } + free_skbs(&ppp->xq); + free_skbs(&ppp->rq); + free_skbs(&ppp->recv_pending); + if (ppp->dev) { + rtnl_lock(); + unregister_netdevice(ppp->dev); + ppp->dev = 0; + rtnl_unlock(); + } + kfree(ppp); +} + +/* + * Locate an existing ppp unit. + * The caller should have locked the all_ppp_lock. + */ +static struct ppp * +ppp_find_unit(int unit) +{ + struct ppp *ppp; + struct list_head *list; + + list = &all_ppp_units; + while ((list = list->next) != &all_ppp_units) { + ppp = list_entry(list, struct ppp, list); + if (ppp->index == unit) + return ppp; + } + return 0; +} + +/* + * Module stuff. + */ +#ifdef MODULE +int +init_module(void) +{ + ppp_init(0); + return 0; +} + +void +cleanup_module(void) +{ + /* should never happen */ + if (!list_empty(&all_ppp_units)) + printk(KERN_ERR "PPP: removing module but units remain!\n"); + if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) + printk(KERN_ERR "PPP: failed to unregister PPP device\n"); +} +#endif /* MODULE */ diff --git a/drivers/net/ptifddi.c b/drivers/net/ptifddi.c index 978ee37ef..17d86b44e 100644 --- a/drivers/net/ptifddi.c +++ b/drivers/net/ptifddi.c @@ -1,4 +1,4 @@ -/* $Id: ptifddi.c,v 1.7 1999/06/09 08:19:01 davem Exp $ +/* $Id: ptifddi.c,v 1.9 1999/08/20 00:31:07 davem Exp $ * ptifddi.c: Network driver for Performance Technologies single-attach * and dual-attach FDDI sbus cards. * @@ -108,48 +108,48 @@ static void pti_is_not_so_happy(struct ptifddi *pp) { } -static inline void pti_tx(struct ptifddi *pp, struct device *dev) +static inline void pti_tx(struct ptifddi *pp, struct net_device *dev) { } -static inline void myri_rx(struct ptifddi *pp, struct device *dev) +static inline void myri_rx(struct ptifddi *pp, struct net_device *dev) { } static void pti_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct ptifddi *pp = (struct ptifddi *) dev->priv; } -static int pti_open(struct device *dev) +static int pti_open(struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; return pti_init(pp, in_interrupt()); } -static int pti_close(struct device *dev) +static int pti_close(struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; return 0; } -static int pti_start_xmit(struct sk_buff *skb, struct device *dev) +static int pti_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; } -static struct enet_statistics *pti_get_stats(struct device *dev) +static struct enet_statistics *pti_get_stats(struct net_device *dev) { return &(((struct ptifddi *)dev->priv)->enet_stats); } -static void pti_set_multicast(struct device *dev) +static void pti_set_multicast(struct net_device *dev) { } -static inline int pti_fddi_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int pti_fddi_init(struct net_device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct ptifddi *pp; @@ -213,7 +213,7 @@ static inline int pti_fddi_init(struct device *dev, struct linux_sbus_device *sd pti_load_main_firmware(pp); } -__initfunc(int ptifddi_sbus_probe(struct device *dev)) +int __init ptifddi_sbus_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff --git a/drivers/net/ptifddi.h b/drivers/net/ptifddi.h index dc59ca358..fc617bf26 100644 --- a/drivers/net/ptifddi.h +++ b/drivers/net/ptifddi.h @@ -1,4 +1,4 @@ -/* $Id: ptifddi.h,v 1.2 1996/12/16 06:15:15 davem Exp $ +/* $Id: ptifddi.h,v 1.3 1999/08/20 00:31:08 davem Exp $ * ptifddi.c: Defines for Performance Technologies FDDI sbus cards. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -70,7 +70,7 @@ struct ptifddi { struct dfddi_ram *dpram; unsigned char *reset; unsigned char *unreset; - struct device *dev; + struct net_device *dev; struct ptifddi *next_module; }; diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c index 0aa979bc1..1b7b2d618 100644 --- a/drivers/net/rcpci45.c +++ b/drivers/net/rcpci45.c @@ -63,7 +63,6 @@ static char *version = #include <linux/malloc.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/bios32.h> #include <linux/timer.h> #include <asm/irq.h> /* For NR_IRQS only. */ #include <asm/bitops.h> @@ -128,7 +127,7 @@ typedef struct * pointer to the device structure which is part * of the interface to the Linux kernel. */ - struct device *dev; + struct net_device *dev; char devname[8]; /* "ethN" string */ U8 id; /* the AdapterID */ @@ -137,7 +136,7 @@ typedef struct U32 function; struct timer_list timer; /* timer */ struct enet_statistics stats; /* the statistics structure */ - struct device *next; /* points to the next RC adapter */ + struct net_device *next; /* points to the next RC adapter */ unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/ unsigned char shutdown; unsigned char reboot; @@ -158,31 +157,31 @@ static PDPA PCIAdapters[MAX_ADAPTERS] = }; -static int RCinit(struct device *dev); -static int RCscan(struct device *dev); -static int RCfound_device(struct device *, int, int, int, int, int, int); +static int RCinit(struct net_device *dev); +static int RCscan(struct net_device *dev); +static int RCfound_device(struct net_device *, int, int, int, int, int, int); -static int RCopen(struct device *); -static int RC_xmit_packet(struct sk_buff *, struct device *); +static int RCopen(struct net_device *); +static int RC_xmit_packet(struct sk_buff *, struct net_device *); static void RCinterrupt(int, void *, struct pt_regs *); -static int RCclose(struct device *dev); -static struct enet_statistics *RCget_stats(struct device *); -static int RCioctl(struct device *, struct ifreq *, int); -static int RCconfig(struct device *, struct ifmap *); +static int RCclose(struct net_device *dev); +static struct enet_statistics *RCget_stats(struct net_device *); +static int RCioctl(struct net_device *, struct ifreq *, int); +static int RCconfig(struct net_device *, struct ifmap *); static void RCxmit_callback(U32, U16, PU32, U16); static void RCrecv_callback(U32, U8, U32, PU32, U16); static void RCreset_callback(U32, U32, U32, U16); static void RCreboot_callback(U32, U32, U32, U16); -static int RC_allocate_and_post_buffers(struct device *, int); +static int RC_allocate_and_post_buffers(struct net_device *, int); /* A list of all installed RC devices, for removing the driver module. */ -static struct device *root_RCdev = NULL; +static struct net_device *root_RCdev = NULL; #ifdef MODULE int init_module(void) #else -int rcpci_probe(struct device *dev) +int rcpci_probe(struct net_device *dev) #endif { int cards_found; @@ -197,7 +196,7 @@ int rcpci_probe(struct device *dev) return cards_found ? 0 : -ENODEV; } -static int RCscan(struct device *dev) +static int RCscan(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; @@ -211,9 +210,8 @@ static int RCscan(struct device *dev) int scan_status; int board_index = 0; unsigned char pci_irq_line; - unsigned short pci_command, vendor, device, class; unsigned int pci_ioaddr; - + struct pci_dev *pdev; scan_status = (pcibios_find_device (RC_PCI45_VENDOR_ID, @@ -224,75 +222,21 @@ static int RCscan(struct device *dev) #ifdef RCDEBUG printk("rc scan_status = 0x%X\n", scan_status); #endif - if (scan_status != PCIBIOS_SUCCESSFUL) + if (scan_status != PCIBIOS_SUCCESSFUL || + !((pdev = pci_find_slot(pci_bus, pci_device_fn)))) break; - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_DEVICE_ID, &device); - pcibios_read_config_byte(pci_bus, - pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, - pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_CLASS_DEVICE, &class); - - pci_ioaddr &= ~0xf; + pci_irq_line = pdev->irq; + pci_ioaddr = pdev->resource[0].start; #ifdef RCDEBUG printk("rc: Found RedCreek PCI adapter\n"); - printk("rc: pci class = 0x%x 0x%x \n", class, class>>8); printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn); printk("rc: pci_irq_line = 0x%x \n", pci_irq_line); printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr); #endif - if (check_region(pci_ioaddr, 2*32768)) - { - printk("rc: check_region failed\n"); - continue; - } -#ifdef RCDEBUG - else - { - printk("rc: check_region passed\n"); - } -#endif - - /* - * Get and check the bus-master and latency values. - * Some PCI BIOSes fail to set the master-enable bit. - */ + pci_set_master(pdev); - pcibios_read_config_word(pci_bus, - pci_device_fn, - PCI_COMMAND, - &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk("rc: PCI Master Bit has not been set!\n"); - - pci_command |= PCI_COMMAND_MASTER; - pcibios_write_config_word(pci_bus, - pci_device_fn, - PCI_COMMAND, - pci_command); - } - if ( ! (pci_command & PCI_COMMAND_MEMORY)) { - /* - * If the BIOS did not set the memory enable bit, what else - * did it not initialize? Skip this adapter. - */ - printk("rc: Adapter %d, PCI Memory Bit has not been set!\n", - cards_found); - printk("rc: Bios problem? \n"); - continue; - } - if (!RCfound_device(dev, pci_ioaddr, pci_irq_line, pci_bus, pci_device_fn, board_index++, cards_found)) @@ -307,7 +251,7 @@ static int RCscan(struct device *dev) return cards_found; } -static int RCinit(struct device *dev) +static int RCinit(struct net_device *dev) { dev->open = &RCopen; dev->hard_start_xmit = &RC_xmit_packet; @@ -319,7 +263,7 @@ static int RCinit(struct device *dev) } static int -RCfound_device(struct device *dev, int memaddr, int irq, +RCfound_device(struct net_device *dev, int memaddr, int irq, int bus, int function, int product_index, int card_idx) { int dev_size = 32768; @@ -329,15 +273,15 @@ RCfound_device(struct device *dev, int memaddr, int irq, /* * Allocate and fill new device structure. - * We need enough for struct device plus DPA plus the LAN API private + * We need enough for struct net_device plus DPA plus the LAN API private * area, which requires a minimum of 16KB. The top of the allocated - * area will be assigned to struct device; the next chunk will be + * area will be assigned to struct net_device; the next chunk will be * assigned to DPA; and finally, the rest will be assigned to the * the LAN API layer. */ #ifdef MODULE - dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + dev = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); if (!dev) { printk("rc: unable to kmalloc dev\n"); @@ -347,10 +291,10 @@ RCfound_device(struct device *dev, int memaddr, int irq, /* * dev->priv will point to the start of DPA. */ - dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15); + dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15); #else dev->priv = 0; - dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + dev->priv = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); if (!dev->priv) { printk("rc: unable to kmalloc private area\n"); @@ -461,7 +405,7 @@ RCfound_device(struct device *dev, int memaddr, int irq, } static int -RCopen(struct device *dev) +RCopen(struct net_device *dev) { int post_buffers = MAX_NMBR_RCV_BUFFERS; PDPA pDpa = (PDPA) dev->priv; @@ -526,7 +470,7 @@ RCopen(struct device *dev) } static int -RC_xmit_packet(struct sk_buff *skb, struct device *dev) +RC_xmit_packet(struct sk_buff *skb, struct net_device *dev) { PDPA pDpa = (PDPA) dev->priv; @@ -607,7 +551,7 @@ RCxmit_callback(U32 Status, { struct sk_buff *skb; PDPA pDpa; - struct device *dev; + struct net_device *dev; pDpa = PCIAdapters[AdapterID]; if (!pDpa) @@ -652,7 +596,7 @@ static void RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID) { PDPA pDpa; - struct device *dev; + struct net_device *dev; pDpa = PCIAdapters[AdapterID]; dev = pDpa->dev; @@ -752,7 +696,7 @@ RCrecv_callback(U32 Status, U32 len, count; PDPA pDpa; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; singleTCB tcb; psingleTCB ptcb = &tcb; @@ -908,7 +852,7 @@ RCinterrupt(int irq, void *dev_id, struct pt_regs *regs) { PDPA pDpa; - struct device *dev = (struct device *)(dev_id); + struct net_device *dev = (struct net_device *)(dev_id); pDpa = (PDPA) (dev->priv); @@ -934,7 +878,7 @@ RCinterrupt(int irq, void *dev_id, struct pt_regs *regs) #define REBOOT_REINIT_RETRY_LIMIT 4 static void rc_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; PDPA pDpa = (PDPA) (dev->priv); int init_status; static int retry = 0; @@ -1017,7 +961,7 @@ static void rc_timer(unsigned long data) } static int -RCclose(struct device *dev) +RCclose(struct net_device *dev) { PDPA pDpa = (PDPA) dev->priv; @@ -1056,7 +1000,7 @@ RCclose(struct device *dev) } static struct enet_statistics * -RCget_stats(struct device *dev) +RCget_stats(struct net_device *dev) { RCLINKSTATS RCstats; @@ -1143,7 +1087,7 @@ RCget_stats(struct device *dev) return 0; } -static int RCioctl(struct device *dev, struct ifreq *rq, int cmd) +static int RCioctl(struct net_device *dev, struct ifreq *rq, int cmd) { RCuser_struct RCuser; PDPA pDpa = dev->priv; @@ -1300,7 +1244,7 @@ static int RCioctl(struct device *dev, struct ifreq *rq, int cmd) return 0; } -static int RCconfig(struct device *dev, struct ifmap *map) +static int RCconfig(struct net_device *dev, struct ifmap *map) { /* * To be completed ... @@ -1324,7 +1268,7 @@ void cleanup_module(void) { PDPA pDpa; - struct device *next; + struct net_device *next; #ifdef RCDEBUG @@ -1353,7 +1297,7 @@ cleanup_module(void) static int -RC_allocate_and_post_buffers(struct device *dev, int numBuffers) +RC_allocate_and_post_buffers(struct net_device *dev, int numBuffers) { int i; diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 4016cf60f..1353e23e9 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -72,7 +72,7 @@ extern __u32 sysctl_rmem_max; static int probed __initdata = 0; -__initfunc(int rr_hippi_probe (struct device *dev)) +int __init rr_hippi_probe (struct net_device *dev) { int boards_found = 0; int version_disp; /* was version info already displayed? */ @@ -152,14 +152,14 @@ __initfunc(int rr_hippi_probe (struct device *dev)) printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI " "at 0x%08lx, irq %i, PCI latency %i\n", dev->name, - pdev->base_address[0], dev->irq, pci_latency); + pdev->resource[0].start, dev->irq, pci_latency); /* * Remap the regs into kernel space. */ rrpriv->regs = (struct rr_regs *) - ioremap(pdev->base_address[0], 0x1000); + ioremap(pdev->resource[0].start, 0x1000); if (!rrpriv->regs){ printk(KERN_ERR "%s: Unable to map I/O register, " @@ -202,7 +202,7 @@ __initfunc(int rr_hippi_probe (struct device *dev)) #endif } -static struct device *root_dev = NULL; +static struct net_device *root_dev = NULL; #ifdef MODULE #if LINUX_VERSION_CODE > 0x20118 @@ -224,7 +224,7 @@ int init_module(void) void cleanup_module(void) { struct rr_private *rr; - struct device *next; + struct net_device *next; while (root_dev) { next = ((struct rr_private *)root_dev->priv)->next; @@ -286,7 +286,7 @@ static void rr_issue_cmd(struct rr_private *rrpriv, struct cmd *cmd) * Reset the board in a sensible manner. The NIC is already halted * when we get here and a spin-lock is held. */ -static int rr_reset(struct device *dev) +static int rr_reset(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -502,7 +502,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv, } -__initfunc(static int rr_init(struct device *dev)) +static int __init rr_init(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -552,7 +552,7 @@ __initfunc(static int rr_init(struct device *dev)) } -static int rr_init1(struct device *dev) +static int rr_init1(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -703,7 +703,7 @@ static int rr_init1(struct device *dev) * events) and are handled here, outside the main interrupt handler, * to reduce the size of the handler. */ -static u32 rr_handle_event(struct device *dev, u32 prodidx, u32 eidx) +static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -795,7 +795,7 @@ static u32 rr_handle_event(struct device *dev, u32 prodidx, u32 eidx) } -static void rx_int(struct device *dev, u32 rxlimit, u32 index) +static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; u32 pkt_len; @@ -866,7 +866,7 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct rr_private *rrpriv; struct rr_regs *regs; - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon; unsigned long flags; @@ -930,7 +930,7 @@ static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) } -static int rr_open(struct device *dev) +static int rr_open(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -995,7 +995,7 @@ static int rr_open(struct device *dev) } -static void rr_dump(struct device *dev) +static void rr_dump(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1059,7 +1059,7 @@ static void rr_dump(struct device *dev) } -static int rr_close(struct device *dev) +static int rr_close(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1131,7 +1131,7 @@ static int rr_close(struct device *dev) } -static int rr_start_xmit(struct sk_buff *skb, struct device *dev) +static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; struct rr_regs *regs = rrpriv->regs; @@ -1197,7 +1197,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct device *dev) } -static struct net_device_stats *rr_get_stats(struct device *dev) +static struct net_device_stats *rr_get_stats(struct net_device *dev) { struct rr_private *rrpriv; @@ -1214,7 +1214,7 @@ static struct net_device_stats *rr_get_stats(struct device *dev) * This operation requires the NIC to be halted and is performed with * interrupts disabled and with the spinlock hold. */ -static int rr_load_firmware(struct device *dev) +static int rr_load_firmware(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1319,7 +1319,7 @@ out: } -static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct rr_private *rrpriv; unsigned char *image, *oldimage; diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h index e274efa39..81acdf88b 100644 --- a/drivers/net/rrunner.h +++ b/drivers/net/rrunner.h @@ -805,7 +805,7 @@ struct rr_private struct rr_regs *regs; /* Register base */ struct ring_ctrl *rx_ctrl; /* Receive ring control */ struct rr_info *info; /* Shared info page */ - struct device *next; + struct net_device *next; spinlock_t lock; struct timer_list timer; u32 cur_rx, cur_cmd, cur_evt; @@ -821,20 +821,20 @@ struct rr_private /* * Prototypes */ -static int rr_init(struct device *dev); -static int rr_init1(struct device *dev); +static int rr_init(struct net_device *dev); +static int rr_init1(struct net_device *dev); static void rr_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int rr_open(struct device *dev); -static int rr_start_xmit(struct sk_buff *skb, struct device *dev); -static int rr_close(struct device *dev); -static struct net_device_stats *rr_get_stats(struct device *dev); -static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int rr_open(struct net_device *dev); +static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int rr_close(struct net_device *dev); +static struct net_device_stats *rr_get_stats(struct net_device *dev); +static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static unsigned int rr_read_eeprom(struct rr_private *rrpriv, unsigned long offset, unsigned char *buf, unsigned long length); static u32 rr_read_eeprom_word(struct rr_private *rrpriv, void * offset); -static int rr_load_firmware(struct device *dev); +static int rr_load_firmware(struct net_device *dev); #endif /* _RRUNNER_H_ */ diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index d8a5b63b7..5d0b9c659 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -165,12 +165,12 @@ struct pci_id_info { const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct device * rtl8129_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device * rtl8129_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = @@ -254,7 +254,7 @@ unsigned long param[4][4]={ struct rtl8129_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; int chip_id; int chip_revision; unsigned char pci_bus, pci_devfn; @@ -294,32 +294,32 @@ MODULE_PARM(debug, "i"); #endif #endif -static int rtl8129_open(struct device *dev); +static int rtl8129_open(struct net_device *dev); static int read_eeprom(long ioaddr, int location); -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int val); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int val); static void rtl8129_timer(unsigned long data); -static void rtl8129_tx_timeout(struct device *dev); -static void rtl8129_init_ring(struct device *dev); -static int rtl8129_start_xmit(struct sk_buff *skb, struct device *dev); -static int rtl8129_rx(struct device *dev); +static void rtl8129_tx_timeout(struct net_device *dev); +static void rtl8129_init_ring(struct net_device *dev); +static int rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int rtl8129_rx(struct net_device *dev); static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int rtl8129_close(struct device *dev); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static struct enet_statistics *rtl8129_get_stats(struct device *dev); +static int rtl8129_close(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct enet_statistics *rtl8129_get_stats(struct net_device *dev); static inline u32 ether_crc(int length, unsigned char *data); -static void set_rx_mode(struct device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed RTL8129 devices, for removing the driver module. */ -static struct device *root_rtl8129_dev = NULL; +static struct net_device *root_rtl8129_dev = NULL; /* Ideally we would detect all network cards in slot order. That would be best done a central PCI probe dispatch, which wouldn't work well when dynamically adding drivers. So instead we detect just the Rtl81*9 cards in slot order. */ -int rtl8139_probe(struct device *dev) +int rtl8139_probe(struct net_device *dev) { int cards_found = 0; int pci_index = 0; @@ -353,7 +353,7 @@ int rtl8139_probe(struct device *dev) { #if defined(PCI_SUPPORT_VER2) struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[0] & ~3; + ioaddr = pdev->resource[0].start; irq = pdev->irq; #else u32 pci_ioaddr; @@ -405,8 +405,8 @@ int rtl8139_probe(struct device *dev) return cards_found ? 0 : -ENODEV; } -static struct device *rtl8129_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *rtl8129_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int found_cnt) { static int did_version = 0; /* Already printed version info. */ @@ -424,13 +424,15 @@ static struct device *rtl8129_probe1(int pci_bus, int pci_devfn, /* Bring the chip out of low-power mode. */ outb(0x00, ioaddr + Config1); - if (read_eeprom(ioaddr, 0) != 0xffff) - for (i = 0; i < 3; i++) - ((u16 *)(dev->dev_addr))[i] = read_eeprom(ioaddr, i + 7); - else + if (read_eeprom(ioaddr, 0) != 0xffff) { + for (i = 0; i < 3; i++) { + ((u16 *)(dev->dev_addr))[i] = + le16_to_cpu(read_eeprom(ioaddr, i + 7)); + } + } else { for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + MAC0 + i); - + } for (i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x.\n", dev->dev_addr[i]); @@ -596,7 +598,7 @@ static void mdio_sync(long mdio_addr) } return; } -static int mdio_read(struct device *dev, int phy_id, int location) +static int mdio_read(struct net_device *dev, int phy_id, int location) { long mdio_addr = dev->base_addr + MII_SMI; int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; @@ -629,7 +631,7 @@ static int mdio_read(struct device *dev, int phy_id, int location) return (retval>>1) & 0xffff; } -static void mdio_write(struct device *dev, int phy_id, int location, int value) +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { long mdio_addr = dev->base_addr + MII_SMI; int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; @@ -662,7 +664,7 @@ static void mdio_write(struct device *dev, int phy_id, int location, int value) static int -rtl8129_open(struct device *dev) +rtl8129_open(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -680,6 +682,7 @@ rtl8129_open(struct device *dev) tp->tx_bufs = kmalloc(TX_BUF_SIZE * NUM_TX_DESC, GFP_KERNEL); tp->rx_ring = kmalloc(RX_BUF_LEN + 16, GFP_KERNEL); if (tp->tx_bufs == NULL || tp->rx_ring == NULL) { + free_irq(dev->irq, dev); if (tp->tx_bufs) kfree(tp->tx_bufs); if (rtl8129_debug > 0) @@ -759,7 +762,7 @@ rtl8129_open(struct device *dev) static void rtl8129_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -855,7 +858,7 @@ static void rtl8129_timer(unsigned long data) add_timer(&tp->timer); } -static void rtl8129_tx_timeout(struct device *dev) +static void rtl8129_tx_timeout(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -938,7 +941,7 @@ static void rtl8129_tx_timeout(struct device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -rtl8129_init_ring(struct device *dev) +rtl8129_init_ring(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; int i; @@ -954,7 +957,7 @@ rtl8129_init_ring(struct device *dev) } static int -rtl8129_start_xmit(struct sk_buff *skb, struct device *dev) +rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -999,7 +1002,7 @@ rtl8129_start_xmit(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; int boguscnt = max_interrupt_work; int status, link_changed = 0; @@ -1172,7 +1175,7 @@ static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs) /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the field alignments and semantics. */ -static int rtl8129_rx(struct device *dev) +static int rtl8129_rx(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1187,7 +1190,7 @@ static int rtl8129_rx(struct device *dev) while ((inb(ioaddr + ChipCmd) & 1) == 0) { int ring_offset = cur_rx % RX_BUF_LEN; - u32 rx_status = *(u32*)(rx_ring + ring_offset); + u32 rx_status = le32_to_cpu(*(u32*)(rx_ring + ring_offset)); int rx_size = rx_status >> 16; if (rtl8129_debug > 4) { @@ -1196,7 +1199,7 @@ static int rtl8129_rx(struct device *dev) dev->name, rx_status, rx_size, cur_rx); printk(KERN_DEBUG"%s: Frame contents ", dev->name); for (i = 0; i < 70; i++) - printk(" %2.2x", rx_ring[ring_offset + i]); + printk(" %2.2x", le32_to_cpu(rx_ring[ring_offset + i])); printk(".\n"); } if (rx_status & RxTooLong) { @@ -1247,7 +1250,7 @@ static int rtl8129_rx(struct device *dev) printk(KERN_DEBUG"%s: Frame wrap @%d", dev->name, semi_count); for (i = 0; i < 16; i++) - printk(" %2.2x", rx_ring[i]); + printk(" %2.2x", le32_to_cpu(rx_ring[i])); printk(".\n"); memset(rx_ring, 0xcc, 16); } @@ -1282,7 +1285,7 @@ static int rtl8129_rx(struct device *dev) } static int -rtl8129_close(struct device *dev) +rtl8129_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; @@ -1327,7 +1330,7 @@ rtl8129_close(struct device *dev) return 0; } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; u16 *data = (u16 *)&rq->ifr_data; @@ -1350,7 +1353,7 @@ static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) } static struct enet_statistics * -rtl8129_get_stats(struct device *dev) +rtl8129_get_stats(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1387,7 +1390,7 @@ enum rx_mode_bits { AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01, }; -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; u32 mc_filter[2]; /* Multicast hash filter */ @@ -1432,7 +1435,7 @@ int init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_rtl8129_dev) { diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c new file mode 100644 index 000000000..b0d8a9ad4 --- /dev/null +++ b/drivers/net/sb1000.c @@ -0,0 +1,1294 @@ +/* sb1000.c: A General Instruments SB1000 driver for linux. */ +/* + Written 1998 by Franco Venturi. + + Copyright 1998 by Franco Venturi. + Copyright 1994,1995 by Donald Becker. + Copyright 1993 United States Government as represented by the + Director, National Security Agency. + + This driver is for the General Instruments SB1000 (internal SURFboard) + + The author may be reached as fventuri@mediaone.net + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU General + Public License as published by the Free Software + Foundation; either version 2 of the License, or (at + your option) any later version. + + Changes: + + 981115 Steven Hirsch <shirsch@adelphia.net> + + Linus changed the timer interface. Should work on all recent + development kernels. + + 980608 Steven Hirsch <shirsch@adelphia.net> + + Small changes to make it work with 2.1.x kernels. Hopefully, + nothing major will change before official release of Linux 2.2. + + Merged with 2.2 - Alan Cox +*/ + +static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n"; + +#include <linux/module.h> + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/in.h> +#include <linux/malloc.h> +#include <linux/ioport.h> +#include <linux/netdevice.h> +#include <linux/if_arp.h> +#include <linux/skbuff.h> +#include <linux/delay.h> /* for udelay() */ +#include <asm/processor.h> + +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <linux/etherdevice.h> + +/* for SIOGCM/SIOSCM stuff */ +#include <linux/if_cablemodem.h> + +#ifdef SB1000_DEBUG +int sb1000_debug = SB1000_DEBUG; +#else +int sb1000_debug = 1; +#endif + +static const int SB1000_IO_EXTENT = 8; +/* SB1000 Maximum Receive Unit */ +static const int SB1000_MRU = 1500; /* octects */ + +#define NPIDS 4 +struct sb1000_private { + struct sk_buff *rx_skb[NPIDS]; + short rx_dlen[NPIDS]; + unsigned int rx_bytes; + unsigned int rx_frames; + short rx_error_count; + short rx_error_dpc_count; + unsigned char rx_session_id[NPIDS]; + unsigned char rx_frame_id[NPIDS]; + unsigned char rx_pkt_type[NPIDS]; + struct net_device_stats stats; +}; + +/* prototypes for Linux interface */ +extern int sb1000_probe(struct net_device *dev); +static int sb1000_open(struct net_device *dev); +static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); +static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static struct enet_statistics *sb1000_stats(struct net_device *dev); +static int sb1000_close(struct net_device *dev); + +/* Plug-n-Play routine */ +static inline unsigned char read_resource_data(void); + +/* SB1000 hardware routines to be used during open/configuration phases */ +static inline void nicedelay(unsigned long usecs); +static inline int card_wait_for_busy_clear(const int ioaddr[], + const char* name); +static inline int card_wait_for_ready(const int ioaddr[], const char* name, + unsigned char in[]); +static inline int card_send_command(const int ioaddr[], const char* name, + const unsigned char out[], unsigned char in[]); + +/* SB1000 hardware routines to be used during frame rx interrupt */ +static inline int sb1000_wait_for_ready(const int ioaddr[], const char* name); +static inline int sb1000_wait_for_ready_clear(const int ioaddr[], + const char* name); +static inline void sb1000_send_command(const int ioaddr[], const char* name, + const unsigned char out[]); +static inline void sb1000_read_status(const int ioaddr[], unsigned char in[]); +static inline void sb1000_issue_read_command(const int ioaddr[], + const char* name); + +/* SB1000 commands for open/configuration */ +static inline int sb1000_reset(const int ioaddr[], const char* name); +static inline int sb1000_check_CRC(const int ioaddr[], const char* name); +static inline int sb1000_start_get_set_command(const int ioaddr[], + const char* name); +static inline int sb1000_end_get_set_command(const int ioaddr[], + const char* name); +static inline int sb1000_activate(const int ioaddr[], const char* name); +static inline int sb1000_get_firmware_version(const int ioaddr[], + const char* name, unsigned char version[], int do_end); +static inline int sb1000_get_frequency(const int ioaddr[], const char* name, + int* frequency); +static inline int sb1000_set_frequency(const int ioaddr[], const char* name, + int frequency); +static inline int sb1000_get_PIDs(const int ioaddr[], const char* name, + short PID[]); +static inline int sb1000_set_PIDs(const int ioaddr[], const char* name, + const short PID[]); + +/* SB1000 commands for frame rx interrupt */ +static inline int sb1000_rx(struct net_device *dev); +static inline void sb1000_error_dpc(struct net_device *dev); + + +/* Plug-n-Play constants */ +static const int READ_DATA_PORT = 0x203; /* This port number may change!!! */ +static const int ADDRESS_PORT = 0x279; +static const int WRITE_DATA_PORT = 0xa79; + +/* Plug-n-Play read resource mechanism */ +static inline unsigned char +read_resource_data(void) { + /* poll */ + outb(0x05, ADDRESS_PORT); /* Select PnP status register. */ + while (!(inb(READ_DATA_PORT) & 0x1)) ; + /* read resource data */ + outb(0x04, ADDRESS_PORT); /* Select PnP resource data register. */ + return inb(READ_DATA_PORT); +} + +/* probe for SB1000 using Plug-n-Play mechanism */ +int +sb1000_probe(struct net_device *dev) +{ + + unsigned short ioaddr[2], irq; + short i, csn; + unsigned int serial_number; + + const unsigned char initiation_key[] = { 0x00, 0x00, 0x6a, 0xb5, 0xda, + 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 0x0d, + 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, + 0xd1, 0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }; + const unsigned char sb1000_vendor_ID[] = { + 0x1d, 0x23, 0x10, 0x00 }; /* "GIC1000" */ + + /* Reset the ISA PnP mechanism */ + outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */ + outb(0x02, WRITE_DATA_PORT); /* Return to WaitForKey state. */ + + /* send initiation key */ + for (i = 0; i < sizeof(initiation_key) / sizeof(initiation_key[0]); i++) { + outb(initiation_key[i], ADDRESS_PORT); + } + + /* set card CSN into configuration mode */ + for (csn = 1; csn <= 255; csn++) { + outb(0x03, ADDRESS_PORT); /* Select PnP wake[CSN] register. */ + outb(csn, WRITE_DATA_PORT); /* Wake[CSN] */ + /* check card ID */ + for (i = 0; i < 4; i++) { + if (read_resource_data() != sb1000_vendor_ID[i]) break; + } + if (i == 4) break; + } + + /* SB1000 not found */ + if (csn > 255) { + /* return to WaitForKey state */ + outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */ + outb(0x02, WRITE_DATA_PORT);/* Return to WaitForKey state. */ + return -ENODEV; + } + + /* found: get serial number and skip checksum */ + serial_number = 0; + for (i = 0; i < 4; i++) { + serial_number |= read_resource_data() << (8 * i); + } + read_resource_data(); + + /* get I/O port base address */ + outb(0x60, ADDRESS_PORT); /* Select PnP I/O port base address 0. */ + ioaddr[0] = inb(READ_DATA_PORT) << 8; + outb(0x61, ADDRESS_PORT); + ioaddr[0] |= inb(READ_DATA_PORT); + outb(0x62, ADDRESS_PORT); /* Select PnP I/O port base address 1. */ + ioaddr[1] = inb(READ_DATA_PORT) << 8; + outb(0x63, ADDRESS_PORT); + ioaddr[1] |= inb(READ_DATA_PORT); + + /* get IRQ */ + outb(0x70, ADDRESS_PORT); /* Select PnP IRQ level select 0. */ + irq = inb(READ_DATA_PORT); + + /* return to WaitForKey state */ + outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */ + outb(0x02, WRITE_DATA_PORT); /* Return to WaitForKey state. */ + + /* check I/O base and IRQ */ + if (dev->base_addr != 0 && dev->base_addr != ioaddr[0]) { + return -ENODEV; + } + if (dev->rmem_end != 0 && dev->rmem_end != ioaddr[1]) { + return -ENODEV; + } + if (dev->irq != 0 && dev->irq != irq) { + return -ENODEV; + } + + dev->base_addr = ioaddr[0]; + /* rmem_end holds the second I/O address - fv */ + dev->rmem_end = ioaddr[1]; + dev->irq = irq; + + if (sb1000_debug > 0) + printk(KERN_NOTICE "%s: sb1000 at (%#3.3lx,%#3.3lx), csn %d, " + "S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr, + dev->rmem_end, csn, serial_number, dev->irq); + + dev = init_etherdev(dev, 0); + + /* Make up a SB1000-specific-data structure. */ + dev->priv = kmalloc(sizeof(struct sb1000_private), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct sb1000_private)); + + if (sb1000_debug > 0) + printk(KERN_NOTICE "%s", version); + + /* The SB1000-specific entries in the device structure. */ + dev->open = sb1000_open; + dev->do_ioctl = sb1000_dev_ioctl; + dev->hard_start_xmit = sb1000_start_xmit; + dev->stop = sb1000_close; + dev->get_stats = sb1000_stats; + + /* Fill in the generic fields of the device structure. */ + dev->change_mtu = NULL; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + dev->set_mac_address = NULL; + dev->header_cache_update= NULL; + + dev->type = ARPHRD_ETHER; + dev->hard_header_len = 0; + dev->mtu = 1500; + dev->addr_len = ETH_ALEN; + /* hardware address is 0:0:serial_number */ + dev->dev_addr[0] = 0; + dev->dev_addr[1] = 0; + dev->dev_addr[2] = serial_number >> 24 & 0xff; + dev->dev_addr[3] = serial_number >> 16 & 0xff; + dev->dev_addr[4] = serial_number >> 8 & 0xff; + dev->dev_addr[5] = serial_number >> 0 & 0xff; + dev->tx_queue_len = 0; + + /* New-style flags. */ + dev->flags = IFF_POINTOPOINT|IFF_NOARP; + return 0; +} + + +/* + * SB1000 hardware routines to be used during open/configuration phases + */ +const int TimeOutJiffies = (int)(8.75 * HZ); + +static inline void nicedelay(unsigned long usecs) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ); + return; +} + +/* Card Wait For Busy Clear (cannot be used during an interrupt) */ +static inline int +card_wait_for_busy_clear(const int ioaddr[], const char* name) +{ + unsigned char a; + unsigned long timeout; + + a = inb(ioaddr[0] + 7); + timeout = jiffies + TimeOutJiffies; + while (a & 0x80 || a & 0x40) { + /* a little sleep */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(0); + a = inb(ioaddr[0] + 7); + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: card_wait_for_busy_clear timeout\n", + name); + return -ETIME; + } + } + + return 0; +} + +/* Card Wait For Ready (cannot be used during an interrupt) */ +static inline int +card_wait_for_ready(const int ioaddr[], const char* name, unsigned char in[]) +{ + unsigned char a; + unsigned long timeout; + + a = inb(ioaddr[1] + 6); + timeout = jiffies + TimeOutJiffies; + while (a & 0x80 || !(a & 0x40)) { + /* a little sleep */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(0); + a = inb(ioaddr[1] + 6); + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: card_wait_for_ready timeout\n", + name); + return -ETIME; + } + } + + in[1] = inb(ioaddr[0] + 1); + in[2] = inb(ioaddr[0] + 2); + in[3] = inb(ioaddr[0] + 3); + in[4] = inb(ioaddr[0] + 4); + in[0] = inb(ioaddr[0] + 5); + in[6] = inb(ioaddr[0] + 6); + in[5] = inb(ioaddr[1] + 6); + return 0; +} + +/* Card Send Command (cannot be used during an interrupt) */ +static inline int +card_send_command(const int ioaddr[], const char* name, + const unsigned char out[], unsigned char in[]) +{ + int status, x; + + if ((status = card_wait_for_busy_clear(ioaddr, name))) + return status; + outb(0xa0, ioaddr[0] + 6); + outb(out[2], ioaddr[0] + 1); + outb(out[3], ioaddr[0] + 2); + outb(out[4], ioaddr[0] + 3); + outb(out[5], ioaddr[0] + 4); + outb(out[1], ioaddr[0] + 5); + outb(0xa0, ioaddr[0] + 6); + outb(out[0], ioaddr[0] + 7); + if (out[0] != 0x20 && out[0] != 0x30) { + if ((status = card_wait_for_ready(ioaddr, name, in))) + return status; + inb(ioaddr[0] + 7); + if (sb1000_debug > 3) + printk(KERN_DEBUG "%s: card_send_command " + "out: %02x%02x%02x%02x%02x%02x " + "in: %02x%02x%02x%02x%02x%02x%02x\n", name, + out[0], out[1], out[2], out[3], out[4], out[5], + in[0], in[1], in[2], in[3], in[4], in[5], in[6]); + } else { + if (sb1000_debug > 3) + printk(KERN_DEBUG "%s: card_send_command " + "out: %02x%02x%02x%02x%02x%02x\n", name, + out[0], out[1], out[2], out[3], out[4], out[5]); + } + + if (out[1] == 0x1b) { + x = (out[2] == 0x02); + } else { + if (out[0] >= 0x80 && in[0] != (out[1] | 0x80)) + return -EIO; + } + return 0; +} + + +/* + * SB1000 hardware routines to be used during frame rx interrupt + */ +const int Sb1000TimeOutJiffies = 7 * HZ; + +/* Card Wait For Ready (to be used during frame rx) */ +static inline int +sb1000_wait_for_ready(const int ioaddr[], const char* name) +{ + unsigned long timeout; + + timeout = jiffies + Sb1000TimeOutJiffies; + while (inb(ioaddr[1] + 6) & 0x80) { + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n", + name); + return -ETIME; + } + } + timeout = jiffies + Sb1000TimeOutJiffies; + while (!(inb(ioaddr[1] + 6) & 0x40)) { + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n", + name); + return -ETIME; + } + } + inb(ioaddr[0] + 7); + return 0; +} + +/* Card Wait For Ready Clear (to be used during frame rx) */ +static inline int +sb1000_wait_for_ready_clear(const int ioaddr[], const char* name) +{ + unsigned long timeout; + + timeout = jiffies + Sb1000TimeOutJiffies; + while (inb(ioaddr[1] + 6) & 0x80) { + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n", + name); + return -ETIME; + } + } + timeout = jiffies + Sb1000TimeOutJiffies; + while (inb(ioaddr[1] + 6) & 0x40) { + if (jiffies >= timeout) { + printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n", + name); + return -ETIME; + } + } + return 0; +} + +/* Card Send Command (to be used during frame rx) */ +static inline void +sb1000_send_command(const int ioaddr[], const char* name, + const unsigned char out[]) +{ + outb(out[2], ioaddr[0] + 1); + outb(out[3], ioaddr[0] + 2); + outb(out[4], ioaddr[0] + 3); + outb(out[5], ioaddr[0] + 4); + outb(out[1], ioaddr[0] + 5); + outb(out[0], ioaddr[0] + 7); + if (sb1000_debug > 3) + printk(KERN_DEBUG "%s: sb1000_send_command out: %02x%02x%02x%02x" + "%02x%02x\n", name, out[0], out[1], out[2], out[3], out[4], out[5]); + return; +} + +/* Card Read Status (to be used during frame rx) */ +static inline void +sb1000_read_status(const int ioaddr[], unsigned char in[]) +{ + in[1] = inb(ioaddr[0] + 1); + in[2] = inb(ioaddr[0] + 2); + in[3] = inb(ioaddr[0] + 3); + in[4] = inb(ioaddr[0] + 4); + in[0] = inb(ioaddr[0] + 5); + return; +} + +/* Issue Read Command (to be used during frame rx) */ +static inline void +sb1000_issue_read_command(const int ioaddr[], const char* name) +{ + const unsigned char Command0[6] = {0x20, 0x00, 0x00, 0x01, 0x00, 0x00}; + + sb1000_wait_for_ready_clear(ioaddr, name); + outb(0xa0, ioaddr[0] + 6); + sb1000_send_command(ioaddr, name, Command0); + return; +} + + +/* + * SB1000 commands for open/configuration + */ +/* reset SB1000 card */ +static inline int +sb1000_reset(const int ioaddr[], const char* name) +{ + unsigned char st[7]; + int port, status; + const unsigned char Command0[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00}; + + port = ioaddr[1] + 6; + outb(0x4, port); + inb(port); + udelay(1000); + outb(0x0, port); + inb(port); + nicedelay(60000); + outb(0x4, port); + inb(port); + udelay(1000); + outb(0x0, port); + inb(port); + udelay(0); + + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + if (st[3] != 0xf0) + return -EIO; + return 0; +} + +/* check SB1000 firmware CRC */ +static inline int +sb1000_check_CRC(const int ioaddr[], const char* name) +{ + unsigned char st[7]; + int crc, status; + const unsigned char Command0[6] = {0x80, 0x1f, 0x00, 0x00, 0x00, 0x00}; + + /* check CRC */ + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + if (st[1] != st[3] || st[2] != st[4]) + return -EIO; + crc = st[1] << 8 | st[2]; + return 0; +} + +static inline int +sb1000_start_get_set_command(const int ioaddr[], const char* name) +{ + unsigned char st[7]; + const unsigned char Command0[6] = {0x80, 0x1b, 0x00, 0x00, 0x00, 0x00}; + + return card_send_command(ioaddr, name, Command0, st); +} + +static inline int +sb1000_end_get_set_command(const int ioaddr[], const char* name) +{ + unsigned char st[7]; + int status; + const unsigned char Command0[6] = {0x80, 0x1b, 0x02, 0x00, 0x00, 0x00}; + const unsigned char Command1[6] = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + return card_send_command(ioaddr, name, Command1, st); +} + +static inline int +sb1000_activate(const int ioaddr[], const char* name) +{ + unsigned char st[7]; + int status; + const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00}; + + nicedelay(50000); + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + if ((status = card_send_command(ioaddr, name, Command1, st))) + return status; + if (st[3] != 0xf1) { + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + return -EIO; + } + udelay(1000); + return sb1000_start_get_set_command(ioaddr, name); +} + +/* get SB1000 firmware version */ +static inline int +sb1000_get_firmware_version(const int ioaddr[], const char* name, + unsigned char version[], int do_end) +{ + unsigned char st[7]; + int status; + const unsigned char Command0[6] = {0x80, 0x23, 0x00, 0x00, 0x00, 0x00}; + + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + if (st[0] != 0xa3) + return -EIO; + version[0] = st[1]; + version[1] = st[2]; + if (do_end) + return sb1000_end_get_set_command(ioaddr, name); + else + return 0; +} + +/* get SB1000 frequency */ +static inline int +sb1000_get_frequency(const int ioaddr[], const char* name, int* frequency) +{ + unsigned char st[7]; + int status; + const unsigned char Command0[6] = {0x80, 0x44, 0x00, 0x00, 0x00, 0x00}; + + udelay(1000); + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + *frequency = ((st[1] << 8 | st[2]) << 8 | st[3]) << 8 | st[4]; + return sb1000_end_get_set_command(ioaddr, name); +} + +/* set SB1000 frequency */ +static inline int +sb1000_set_frequency(const int ioaddr[], const char* name, int frequency) +{ + unsigned char st[7]; + int status; + unsigned char Command0[6] = {0x80, 0x29, 0x00, 0x00, 0x00, 0x00}; + + const int FrequencyLowerLimit = 57000; + const int FrequencyUpperLimit = 804000; + + if (frequency < FrequencyLowerLimit || frequency > FrequencyUpperLimit) { + printk(KERN_ERR "%s: frequency chosen (%d kHz) is not in the range " + "[%d,%d] kHz\n", name, frequency, FrequencyLowerLimit, + FrequencyUpperLimit); + return -EINVAL; + } + udelay(1000); + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + Command0[5] = frequency & 0xff; + frequency >>= 8; + Command0[4] = frequency & 0xff; + frequency >>= 8; + Command0[3] = frequency & 0xff; + frequency >>= 8; + Command0[2] = frequency & 0xff; + return card_send_command(ioaddr, name, Command0, st); +} + +/* get SB1000 PIDs */ +static inline int +sb1000_get_PIDs(const int ioaddr[], const char* name, short PID[]) +{ + unsigned char st[7]; + int status; + const unsigned char Command0[6] = {0x80, 0x40, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command1[6] = {0x80, 0x41, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command2[6] = {0x80, 0x42, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command3[6] = {0x80, 0x43, 0x00, 0x00, 0x00, 0x00}; + + udelay(1000); + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + PID[0] = st[1] << 8 | st[2]; + + if ((status = card_send_command(ioaddr, name, Command1, st))) + return status; + PID[1] = st[1] << 8 | st[2]; + + if ((status = card_send_command(ioaddr, name, Command2, st))) + return status; + PID[2] = st[1] << 8 | st[2]; + + if ((status = card_send_command(ioaddr, name, Command3, st))) + return status; + PID[3] = st[1] << 8 | st[2]; + + return sb1000_end_get_set_command(ioaddr, name); +} + +/* set SB1000 PIDs */ +static inline int +sb1000_set_PIDs(const int ioaddr[], const char* name, const short PID[]) +{ + unsigned char st[7]; + short p; + int status; + unsigned char Command0[6] = {0x80, 0x31, 0x00, 0x00, 0x00, 0x00}; + unsigned char Command1[6] = {0x80, 0x32, 0x00, 0x00, 0x00, 0x00}; + unsigned char Command2[6] = {0x80, 0x33, 0x00, 0x00, 0x00, 0x00}; + unsigned char Command3[6] = {0x80, 0x34, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command4[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00}; + + udelay(1000); + if ((status = sb1000_start_get_set_command(ioaddr, name))) + return status; + + p = PID[0]; + Command0[3] = p & 0xff; + p >>= 8; + Command0[2] = p & 0xff; + if ((status = card_send_command(ioaddr, name, Command0, st))) + return status; + + p = PID[1]; + Command1[3] = p & 0xff; + p >>= 8; + Command1[2] = p & 0xff; + if ((status = card_send_command(ioaddr, name, Command1, st))) + return status; + + p = PID[2]; + Command2[3] = p & 0xff; + p >>= 8; + Command2[2] = p & 0xff; + if ((status = card_send_command(ioaddr, name, Command2, st))) + return status; + + p = PID[3]; + Command3[3] = p & 0xff; + p >>= 8; + Command3[2] = p & 0xff; + if ((status = card_send_command(ioaddr, name, Command3, st))) + return status; + + if ((status = card_send_command(ioaddr, name, Command4, st))) + return status; + return sb1000_end_get_set_command(ioaddr, name); +} + + +static inline void +sb1000_print_status_buffer(const char* name, unsigned char st[], + unsigned char buffer[], int size) +{ + int i, j, k; + + printk(KERN_DEBUG "%s: status: %02x %02x\n", name, st[0], st[1]); + if (buffer[24] == 0x08 && buffer[25] == 0x00 && buffer[26] == 0x45) { + printk(KERN_DEBUG "%s: length: %d protocol: %d from: %d.%d.%d.%d:%d " + "to %d.%d.%d.%d:%d\n", name, buffer[28] << 8 | buffer[29], + buffer[35], buffer[38], buffer[39], buffer[40], buffer[41], + buffer[46] << 8 | buffer[47], + buffer[42], buffer[43], buffer[44], buffer[45], + buffer[48] << 8 | buffer[49]); + } else { + for (i = 0, k = 0; i < (size + 7) / 8; i++) { + printk(KERN_DEBUG "%s: %s", name, i ? " " : "buffer:"); + for (j = 0; j < 8 && k < size; j++, k++) + printk(" %02x", buffer[k]); + printk("\n"); + } + } + return; +} + +/* + * SB1000 commands for frame rx interrupt + */ +/* receive a single frame and assemble datagram + * (this is the heart of the interrupt routine) + */ +static inline int +sb1000_rx(struct net_device *dev) +{ + +#define FRAMESIZE 184 + unsigned char st[2], buffer[FRAMESIZE], session_id, frame_id; + short dlen; + int ioaddr, ns; + unsigned int skbsize; + struct sk_buff *skb; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + struct enet_statistics *stats = &lp->stats; + + /* SB1000 frame constants */ + const int FrameSize = FRAMESIZE; + const int NewDatagramHeaderSkip = 8; + const int NewDatagramHeaderSize = NewDatagramHeaderSkip + 18; + const int NewDatagramDataSize = FrameSize - NewDatagramHeaderSize; + const int ContDatagramHeaderSkip = 7; + const int ContDatagramHeaderSize = ContDatagramHeaderSkip + 1; + const int ContDatagramDataSize = FrameSize - ContDatagramHeaderSize; + const int TrailerSize = 4; + + ioaddr = dev->base_addr; + + insw(ioaddr, (unsigned short*) st, 1); +#ifdef XXXDEBUG +printk("cm0: received: %02x %02x\n", st[0], st[1]); +#endif /* XXXDEBUG */ + lp->rx_frames++; + + /* decide if it is a good or bad frame */ + for (ns = 0; ns < NPIDS; ns++) { + session_id = lp->rx_session_id[ns]; + frame_id = lp->rx_frame_id[ns]; + if (st[0] == session_id) { + if (st[1] == frame_id || (!frame_id && (st[1] & 0xf0) == 0x30)) { + goto good_frame; + } else if ((st[1] & 0xf0) == 0x30 && (st[0] & 0x40)) { + goto skipped_frame; + } else { + goto bad_frame; + } + } else if (st[0] == (session_id | 0x40)) { + if ((st[1] & 0xf0) == 0x30) { + goto skipped_frame; + } else { + goto bad_frame; + } + } + } + goto bad_frame; + +skipped_frame: + stats->rx_frame_errors++; + skb = lp->rx_skb[ns]; + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: missing frame(s): got %02x %02x " + "expecting %02x %02x\n", dev->name, st[0], st[1], + skb ? session_id : session_id | 0x40, frame_id); + if (skb) { + dev_kfree_skb(skb); + skb = 0; + } + +good_frame: + lp->rx_frame_id[ns] = 0x30 | ((st[1] + 1) & 0x0f); + /* new datagram */ + if (st[0] & 0x40) { + /* get data length */ + insw(ioaddr, buffer, NewDatagramHeaderSize / 2); +#ifdef XXXDEBUG +printk("cm0: IP identification: %02x%02x fragment offset: %02x%02x\n", buffer[30], buffer[31], buffer[32], buffer[33]); +#endif /* XXXDEBUG */ + if (buffer[0] != NewDatagramHeaderSkip) { + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: new datagram header skip error: " + "got %02x expecting %02x\n", dev->name, buffer[0], + NewDatagramHeaderSkip); + stats->rx_length_errors++; + insw(ioaddr, buffer, NewDatagramDataSize / 2); + goto bad_frame_next; + } + dlen = ((buffer[NewDatagramHeaderSkip + 3] & 0x0f) << 8 | + buffer[NewDatagramHeaderSkip + 4]) - 17; + if (dlen > SB1000_MRU) { + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: datagram length (%d) greater " + "than MRU (%d)\n", dev->name, dlen, SB1000_MRU); + stats->rx_length_errors++; + insw(ioaddr, buffer, NewDatagramDataSize / 2); + goto bad_frame_next; + } + lp->rx_dlen[ns] = dlen; + /* compute size to allocate for datagram */ + skbsize = dlen + FrameSize; + if ((skb = alloc_skb(skbsize, GFP_ATOMIC)) == NULL) { + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: can't allocate %d bytes long " + "skbuff\n", dev->name, skbsize); + stats->rx_dropped++; + insw(ioaddr, buffer, NewDatagramDataSize / 2); + goto dropped_frame; + } + skb->dev = dev; + skb->mac.raw = skb->data; + skb->protocol = (unsigned short) buffer[NewDatagramHeaderSkip + 16]; + insw(ioaddr, skb_put(skb, NewDatagramDataSize), + NewDatagramDataSize / 2); + lp->rx_skb[ns] = skb; + } else { + /* continuation of previous datagram */ + insw(ioaddr, buffer, ContDatagramHeaderSize / 2); + if (buffer[0] != ContDatagramHeaderSkip) { + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: cont datagram header skip error: " + "got %02x expecting %02x\n", dev->name, buffer[0], + ContDatagramHeaderSkip); + stats->rx_length_errors++; + insw(ioaddr, buffer, ContDatagramDataSize / 2); + goto bad_frame_next; + } + skb = lp->rx_skb[ns]; + insw(ioaddr, skb_put(skb, ContDatagramDataSize), + ContDatagramDataSize / 2); + dlen = lp->rx_dlen[ns]; + } + if (skb->len < dlen + TrailerSize) { + lp->rx_session_id[ns] &= ~0x40; + return 0; + } + + /* datagram completed: send to upper level */ + skb_trim(skb, dlen); + netif_rx(skb); + stats->rx_bytes+=dlen; + stats->rx_packets++; + lp->rx_bytes += dlen; + lp->rx_skb[ns] = 0; + lp->rx_session_id[ns] |= 0x40; + return 0; + +bad_frame: + insw(ioaddr, buffer, FrameSize / 2); + if (sb1000_debug > 1) + printk(KERN_WARNING "%s: frame error: got %02x %02x\n", + dev->name, st[0], st[1]); + stats->rx_frame_errors++; +bad_frame_next: + if (sb1000_debug > 2) + sb1000_print_status_buffer(dev->name, st, buffer, FrameSize); +dropped_frame: + stats->rx_errors++; + if (ns < NPIDS) { + if ((skb = lp->rx_skb[ns])) { + dev_kfree_skb(skb); + lp->rx_skb[ns] = 0; + } + lp->rx_session_id[ns] |= 0x40; + } + return -1; +} + +static inline void +sb1000_error_dpc(struct net_device *dev) +{ + char *name; + unsigned char st[5]; + int ioaddr[2]; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + const unsigned char Command0[6] = {0x80, 0x26, 0x00, 0x00, 0x00, 0x00}; + const int ErrorDpcCounterInitialize = 200; + + ioaddr[0] = dev->base_addr; + /* rmem_end holds the second I/O address - fv */ + ioaddr[1] = dev->rmem_end; + name = dev->name; + + sb1000_wait_for_ready_clear(ioaddr, name); + sb1000_send_command(ioaddr, name, Command0); + sb1000_wait_for_ready(ioaddr, name); + sb1000_read_status(ioaddr, st); + if (st[1] & 0x10) + lp->rx_error_dpc_count = ErrorDpcCounterInitialize; + return; +} + + +/* + * Linux interface functions + */ +static int +sb1000_open(struct net_device *dev) +{ + char *name; + int ioaddr[2], status; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + const unsigned short FirmwareVersion[] = {0x01, 0x01}; + + ioaddr[0] = dev->base_addr; + /* rmem_end holds the second I/O address - fv */ + ioaddr[1] = dev->rmem_end; + name = dev->name; + request_region(ioaddr[0], SB1000_IO_EXTENT, "sb1000"); + request_region(ioaddr[1], SB1000_IO_EXTENT, "sb1000"); + + /* initialize sb1000 */ + if ((status = sb1000_reset(ioaddr, name))) + return status; + nicedelay(200000); + if ((status = sb1000_check_CRC(ioaddr, name))) + return status; + + /* initialize private data before board can catch interrupts */ + lp->rx_skb[0] = NULL; + lp->rx_skb[1] = NULL; + lp->rx_skb[2] = NULL; + lp->rx_skb[3] = NULL; + lp->rx_dlen[0] = 0; + lp->rx_dlen[1] = 0; + lp->rx_dlen[2] = 0; + lp->rx_dlen[3] = 0; + lp->rx_bytes = 0; + lp->rx_frames = 0; + lp->rx_error_count = 0; + lp->rx_error_dpc_count = 0; + lp->rx_session_id[0] = 0x50; + lp->rx_session_id[0] = 0x48; + lp->rx_session_id[0] = 0x44; + lp->rx_session_id[0] = 0x42; + lp->rx_frame_id[0] = 0; + lp->rx_frame_id[1] = 0; + lp->rx_frame_id[2] = 0; + lp->rx_frame_id[3] = 0; + if (request_irq(dev->irq, &sb1000_interrupt, 0, "sb1000", dev)) { + return -EAGAIN; + } + + if (sb1000_debug > 2) + printk(KERN_DEBUG "%s: Opening, IRQ %d\n", name, dev->irq); + + /* Activate board and check firmware version */ + udelay(1000); + if ((status = sb1000_activate(ioaddr, name))) + return status; + udelay(0); + if ((status = sb1000_get_firmware_version(ioaddr, name, version, 0))) + return status; + if (version[0] != FirmwareVersion[0] || version[1] != FirmwareVersion[1]) + printk(KERN_WARNING "%s: found firmware version %x.%02x " + "(should be %x.%02x)\n", name, version[0], version[1], + FirmwareVersion[0], FirmwareVersion[1]); + + dev->interrupt = 0; + dev->tbusy = 0; + dev->start = 1; + + MOD_INC_USE_COUNT; + return 0; /* Always succeed */ +} + +static int sb1000_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + char* name; + unsigned char version[2]; + short PID[4]; + int ioaddr[2], status, frequency; + unsigned int stats[5]; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + + if (!(dev && dev->flags & IFF_UP)) + return -ENODEV; + + ioaddr[0] = dev->base_addr; + /* rmem_end holds the second I/O address - fv */ + ioaddr[1] = dev->rmem_end; + name = dev->name; + + switch (cmd) { + case SIOCGCMSTATS: /* get statistics */ + stats[0] = lp->rx_bytes; + stats[1] = lp->rx_frames; + stats[2] = lp->stats.rx_packets; + stats[3] = lp->stats.rx_errors; + stats[4] = lp->stats.rx_dropped; + if(copy_to_user(ifr->ifr_data, stats, sizeof(stats))) + return -EFAULT; + status = 0; + break; + + case SIOCGCMFIRMWARE: /* get firmware version */ + if ((status = sb1000_get_firmware_version(ioaddr, name, version, 1))) + return status; + if(copy_to_user(ifr->ifr_data, version, sizeof(version))) + return -EFAULT; + break; + + case SIOCGCMFREQUENCY: /* get frequency */ + if ((status = sb1000_get_frequency(ioaddr, name, &frequency))) + return status; + if(put_user(frequency, (int*) ifr->ifr_data)) + return -EFAULT; + break; + + case SIOCSCMFREQUENCY: /* set frequency */ + if (!suser()) + return -EPERM; + if(get_user(frequency, (int*) ifr->ifr_data)) + return -EFAULT; + if ((status = sb1000_set_frequency(ioaddr, name, frequency))) + return status; + break; + + case SIOCGCMPIDS: /* get PIDs */ + if ((status = sb1000_get_PIDs(ioaddr, name, PID))) + return status; + if(copy_to_user(ifr->ifr_data, PID, sizeof(PID))) + return -EFAULT; + break; + + case SIOCSCMPIDS: /* set PIDs */ + if (!suser()) + return -EPERM; + if(copy_from_user(PID, ifr->ifr_data, sizeof(PID))) + return -EFAULT; + if ((status = sb1000_set_PIDs(ioaddr, name, PID))) + return status; + /* set session_id, frame_id and pkt_type too */ + lp->rx_session_id[0] = 0x50 | (PID[0] & 0x0f); + lp->rx_session_id[1] = 0x48; + lp->rx_session_id[2] = 0x44; + lp->rx_session_id[3] = 0x42; + lp->rx_frame_id[0] = 0; + lp->rx_frame_id[1] = 0; + lp->rx_frame_id[2] = 0; + lp->rx_frame_id[3] = 0; + break; + + default: + status = -EINVAL; + break; + } + return status; +} + +/* transmit function: do nothing since SB1000 can't send anything out */ +static int +sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + printk(KERN_WARNING "%s: trying to transmit!!!\n", dev->name); + /* sb1000 can't xmit datagrams */ + dev_kfree_skb(skb); + return 0; +} + +/* SB1000 interrupt handler. */ +static void sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + char *name; + unsigned char st; + int ioaddr[2]; + struct net_device *dev = (struct net_device *) dev_id; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + + const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00}; + const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00}; + const int MaxRxErrorCount = 6; + + if (dev == NULL) { + printk(KERN_ERR "sb1000_interrupt(): irq %d for unknown device.\n", + irq); + return; + } + if (dev->interrupt) + printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", + dev->name); + dev->interrupt = 1; + + ioaddr[0] = dev->base_addr; + /* rmem_end holds the second I/O address - fv */ + ioaddr[1] = dev->rmem_end; + name = dev->name; + + /* is it a good interrupt? */ + st = inb(ioaddr[1] + 6); + if (!(st & 0x08 && st & 0x20)) { + dev->interrupt = 0; + return; + } + + if (sb1000_debug > 3) + printk(KERN_DEBUG "%s: entering interrupt\n", dev->name); + + st = inb(ioaddr[0] + 7); + if (sb1000_rx(dev)) + lp->rx_error_count++; +#ifdef SB1000_DELAY + udelay(SB1000_DELAY); +#endif /* SB1000_DELAY */ + sb1000_issue_read_command(ioaddr, name); + if (st & 0x01) { + sb1000_error_dpc(dev); + sb1000_issue_read_command(ioaddr, name); + } + if (lp->rx_error_dpc_count && !(--lp->rx_error_dpc_count)) { + sb1000_wait_for_ready_clear(ioaddr, name); + sb1000_send_command(ioaddr, name, Command0); + sb1000_wait_for_ready(ioaddr, name); + sb1000_issue_read_command(ioaddr, name); + } + if (lp->rx_error_count >= MaxRxErrorCount) { + sb1000_wait_for_ready_clear(ioaddr, name); + sb1000_send_command(ioaddr, name, Command1); + sb1000_wait_for_ready(ioaddr, name); + sb1000_issue_read_command(ioaddr, name); + lp->rx_error_count = 0; + } + + dev->interrupt = 0; + return; +} + +static struct net_device_stats *sb1000_stats(struct net_device *dev) +{ + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + return &lp->stats; +} + +static int sb1000_close(struct net_device *dev) +{ + int i; + int ioaddr[2]; + struct sb1000_private *lp = (struct sb1000_private *)dev->priv; + + if (sb1000_debug > 2) + printk(KERN_DEBUG "%s: Shutting down sb1000.\n", dev->name); + + dev->tbusy = 1; + dev->start = 0; + + ioaddr[0] = dev->base_addr; + /* rmem_end holds the second I/O address - fv */ + ioaddr[1] = dev->rmem_end; + + free_irq(dev->irq, dev); + /* If we don't do this, we can't re-insmod it later. */ + release_region(ioaddr[1], SB1000_IO_EXTENT); + release_region(ioaddr[0], SB1000_IO_EXTENT); + + /* free rx_skb's if needed */ + for (i=0; i<4; i++) { + if (lp->rx_skb[i]) { + dev_kfree_skb(lp->rx_skb[i]); + } + } + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MODULE +MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>"); +MODULE_DESCRIPTION("General Instruments SB1000 driver"); +MODULE_PARM(io, "1-2i"); +MODULE_PARM(irq, "i"); + +static char devname[8] = {0, }; +static struct net_device dev_sb1000 = { + devname, + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, sb1000_probe }; + +static int io[2] = {0, 0}; +static int irq = 0; + +int +init_module(void) +{ + int i; + for (i = 0; i < 100; i++) { + sprintf(devname, "cm%d", i); + if (dev_get(devname) == 0) break; + } + if (i == 100) { + printk(KERN_ERR "sb1000: can't register any device cm<n>\n"); + return -ENFILE; + } + dev_sb1000.base_addr = io[0]; + /* rmem_end holds the second I/O address - fv */ + dev_sb1000.rmem_end = io[1]; + dev_sb1000.irq = irq; + if (register_netdev(&dev_sb1000) != 0) { + printk(KERN_ERR "sb1000: failed to register device (io: %03x,%03x " + "irq: %d)\n", io[0], io[1], irq); + return -EIO; + } + return 0; +} + +void cleanup_module(void) +{ + unregister_netdev(&dev_sb1000); + kfree_s(dev_sb1000.priv, sizeof(struct sb1000_private)); + dev_sb1000.priv = NULL; +} +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O -m486 -c sb1000.c" + * version-control: t + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/drivers/net/sdla.c b/drivers/net/sdla.c index 32f22e14d..9b5152366 100644 --- a/drivers/net/sdla.c +++ b/drivers/net/sdla.c @@ -83,7 +83,7 @@ static unsigned int valid_mem[] __initdata = { #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) -static void sdla_read(struct device *dev, int addr, void *buf, short len) +static void sdla_read(struct net_device *dev, int addr, void *buf, short len) { unsigned long flags; char *temp, *base; @@ -108,7 +108,7 @@ static void sdla_read(struct device *dev, int addr, void *buf, short len) } } -static void sdla_write(struct device *dev, int addr, void *buf, short len) +static void sdla_write(struct net_device *dev, int addr, void *buf, short len) { unsigned long flags; char *temp, *base; @@ -131,7 +131,7 @@ static void sdla_write(struct device *dev, int addr, void *buf, short len) } } -static void sdla_clear(struct device *dev) +static void sdla_clear(struct net_device *dev) { unsigned long flags; char *base; @@ -155,7 +155,7 @@ static void sdla_clear(struct device *dev) restore_flags(flags); } -static char sdla_byte(struct device *dev, int addr) +static char sdla_byte(struct net_device *dev, int addr) { unsigned long flags; char byte, *temp; @@ -171,7 +171,7 @@ static char sdla_byte(struct device *dev, int addr) return(byte); } -void sdla_stop(struct device *dev) +void sdla_stop(struct net_device *dev) { struct frad_local *flp; @@ -198,7 +198,7 @@ void sdla_stop(struct device *dev) } } -void sdla_start(struct device *dev) +void sdla_start(struct net_device *dev) { struct frad_local *flp; @@ -236,7 +236,7 @@ void sdla_start(struct device *dev) * ***************************************************/ -int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2) +int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2) { unsigned long start, done, now; char resp, *temp; @@ -266,7 +266,7 @@ int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char #define Z80_SCC_OK '3' /* SCC is on board */ #define Z80_SCC_BAD '4' /* SCC was not found */ -static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr) +static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) { int jiffs; char data; @@ -328,7 +328,7 @@ struct _frad_stat struct _dlci_stat dlcis[SDLA_MAX_DLCI]; }; -static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) +static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data) { struct _dlci_stat *pstatus; short *pdlci; @@ -411,7 +411,7 @@ static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, } } -static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, +static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, void *inbuf, short inlen, void *outbuf, short *outlen) { static struct _frad_stat status; @@ -492,9 +492,9 @@ static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, * ***********************************************/ -static int sdla_reconfig(struct device *dev); +static int sdla_reconfig(struct net_device *dev); -int sdla_activate(struct device *slave, struct device *master) +int sdla_activate(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -516,7 +516,7 @@ int sdla_activate(struct device *slave, struct device *master) return(0); } -int sdla_deactivate(struct device *slave, struct device *master) +int sdla_deactivate(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -538,7 +538,7 @@ int sdla_deactivate(struct device *slave, struct device *master) return(0); } -int sdla_assoc(struct device *slave, struct device *master) +int sdla_assoc(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -575,7 +575,7 @@ int sdla_assoc(struct device *slave, struct device *master) return(0); } -int sdla_deassoc(struct device *slave, struct device *master) +int sdla_deassoc(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -604,7 +604,7 @@ int sdla_deassoc(struct device *slave, struct device *master) return(0); } -int sdla_dlci_conf(struct device *slave, struct device *master, int get) +int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) { struct frad_local *flp; struct dlci_local *dlp; @@ -643,7 +643,7 @@ int sdla_dlci_conf(struct device *slave, struct device *master, int get) **************************/ /* NOTE: the DLCI driver deals with freeing the SKB!! */ -static int sdla_transmit(struct sk_buff *skb, struct device *dev) +static int sdla_transmit(struct sk_buff *skb, struct net_device *dev) { struct frad_local *flp; int ret, addr, accept; @@ -742,9 +742,9 @@ static int sdla_transmit(struct sk_buff *skb, struct device *dev) return(ret); } -static void sdla_receive(struct device *dev) +static void sdla_receive(struct net_device *dev) { - struct device *master; + struct net_device *master; struct frad_local *flp; struct dlci_local *dlp; struct sk_buff *skb; @@ -872,7 +872,7 @@ static void sdla_receive(struct device *dev) static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev; + struct net_device *dev; struct frad_local *flp; char byte; @@ -930,10 +930,10 @@ static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) static void sdla_poll(unsigned long device) { - struct device *dev; + struct net_device *dev; struct frad_local *flp; - dev = (struct device *) device; + dev = (struct net_device *) device; flp = dev->priv; if (sdla_byte(dev, SDLA_502_RCV_BUF)) @@ -943,7 +943,7 @@ static void sdla_poll(unsigned long device) add_timer(&flp->timer); } -static int sdla_close(struct device *dev) +static int sdla_close(struct net_device *dev) { struct frad_local *flp; struct intr_info intr; @@ -1005,7 +1005,7 @@ struct conf_data { short dlci[CONFIG_DLCI_MAX]; }; -static int sdla_open(struct device *dev) +static int sdla_open(struct net_device *dev) { struct frad_local *flp; struct dlci_local *dlp; @@ -1105,7 +1105,7 @@ static int sdla_open(struct device *dev) return(0); } -static int sdla_config(struct device *dev, struct frad_conf *conf, int get) +static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get) { struct frad_local *flp; struct conf_data data; @@ -1203,7 +1203,7 @@ static int sdla_config(struct device *dev, struct frad_conf *conf, int get) return(0); } -static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read) +static int sdla_xfer(struct net_device *dev, struct sdla_mem *info, int read) { struct sdla_mem mem; char *temp; @@ -1234,7 +1234,7 @@ static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read) return(0); } -static int sdla_reconfig(struct device *dev) +static int sdla_reconfig(struct net_device *dev) { struct frad_local *flp; struct conf_data data; @@ -1258,7 +1258,7 @@ static int sdla_reconfig(struct device *dev) return(0); } -static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct frad_local *flp; @@ -1325,7 +1325,7 @@ NOTE: This is rather a useless action right now, as the return(0); } -int sdla_change_mtu(struct device *dev, int new_mtu) +int sdla_change_mtu(struct net_device *dev, int new_mtu) { struct frad_local *flp; @@ -1338,7 +1338,7 @@ int sdla_change_mtu(struct device *dev, int new_mtu) return(-EOPNOTSUPP); } -int sdla_set_config(struct device *dev, struct ifmap *map) +int sdla_set_config(struct net_device *dev, struct ifmap *map) { struct frad_local *flp; int i; @@ -1616,7 +1616,7 @@ int sdla_set_config(struct device *dev, struct ifmap *map) return(0); } -static struct net_device_stats *sdla_stats(struct device *dev) +static struct net_device_stats *sdla_stats(struct net_device *dev) { struct frad_local *flp; flp = dev->priv; @@ -1624,7 +1624,7 @@ static struct net_device_stats *sdla_stats(struct device *dev) return(&flp->stats); } -__initfunc(int sdla_init(struct device *dev)) +int __init sdla_init(struct net_device *dev) { struct frad_local *flp; @@ -1666,14 +1666,14 @@ __initfunc(int sdla_init(struct device *dev)) return(0); } -__initfunc(void sdla_setup(void)) +void __init sdla_setup(void) { printk("%s.\n", version); register_frad(devname); } #ifdef MODULE -static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init}; +static struct net_device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init}; int init_module(void) { diff --git a/drivers/net/sdla_fr.c b/drivers/net/sdla_fr.c index ecf784758..6b2201a81 100644 --- a/drivers/net/sdla_fr.c +++ b/drivers/net/sdla_fr.c @@ -136,7 +136,7 @@ /****** Data Structures *****************************************************/ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network * interface to keep the rest of channel-specific data. */ typedef struct fr_channel { @@ -239,20 +239,20 @@ static int Intr_test_counter; /* WAN link driver entry points. These are called by the WAN router module. */ static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct device *dev, +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct device *dev); +static int del_if(wan_device_t * wandev, struct net_device *dev); /* WANPIPE-specific entry points */ static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data); /* Network device interface */ -static int if_init(struct device *dev); -static int if_open(struct device *dev); -static int if_close(struct device *dev); -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); -static int if_send(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *if_stats(struct device *dev); +static int if_send(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *if_stats(struct net_device *dev); /* Interrupt handlers */ static void fr502_isr(sdla_t * card); static void fr508_isr(sdla_t * card); @@ -281,9 +281,9 @@ static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox); static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox); static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox); /* Miscellaneous functions */ -static int update_chan_state(struct device *dev); -static void set_chan_state(struct device *dev, int state); -static struct device *find_channel(sdla_t * card, unsigned dlci); +static int update_chan_state(struct net_device *dev); +static void set_chan_state(struct net_device *dev, int state); +static struct net_device *find_channel(sdla_t * card, unsigned dlci); static int is_tx_ready(sdla_t * card, fr_channel_t * chan); static unsigned int dec_to_uint(unsigned char *str, int len); static int reply_udp(unsigned char *data, unsigned int mbox_len); @@ -292,8 +292,8 @@ static void init_chan_statistics(fr_channel_t * chan); static void init_global_statistics(sdla_t * card); static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan); /* Udp management functions */ -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan); +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); /* IPX functions */ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming); @@ -499,7 +499,7 @@ static int update(wan_device_t * wandev) * < 0 failure (channel will not be created) */ -static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf) +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) { sdla_t *card = wandev->private; fr_channel_t *chan; @@ -570,7 +570,7 @@ static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf /*============================================================================ * Delete logical channel. */ -static int del_if(wan_device_t * wandev, struct device *dev) +static int del_if(wan_device_t * wandev, struct net_device *dev) { if (dev->priv) { @@ -627,7 +627,7 @@ static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data) * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init(struct device *dev) +static int if_init(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -668,11 +668,11 @@ static int if_init(struct device *dev) * Return 0 if O.k. or errno. */ -static int if_open(struct device *dev) +static int if_open(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; - struct device *dev2; + struct net_device *dev2; int err = 0; fr508_flags_t *flags = card->flags; struct timeval tv; @@ -797,7 +797,7 @@ static int if_open(struct device *dev) * o reset flags. */ -static int if_close(struct device *dev) +static int if_close(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -826,7 +826,7 @@ static int if_close(struct device *dev) * Return: media header length. */ -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { int hdr_len = 0; @@ -852,7 +852,7 @@ static int if_header(struct sk_buff *skb, struct device *dev, static int if_rebuild_hdr(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", @@ -879,13 +879,13 @@ static int if_rebuild_hdr(struct sk_buff *skb) * protocol stack and can be used for flow control with protocol layer. */ -static int if_send(struct sk_buff *skb, struct device *dev) +static int if_send(struct sk_buff *skb, struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; int retry = 0, err; unsigned char *sendpacket; - struct device *dev2; + struct net_device *dev2; unsigned long check_braddr, check_mcaddr; fr508_flags_t *adptr_flags = card->flags; int udp_type, send_data; @@ -1230,7 +1230,7 @@ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_ * Return a pointer to struct net_device_stats. */ -static struct net_device_stats *if_stats(struct device *dev) +static struct net_device_stats *if_stats(struct net_device *dev) { fr_channel_t *chan = dev->priv; if(chan==NULL) @@ -1270,8 +1270,8 @@ static void fr508_isr(sdla_t * card) fr508_flags_t *flags = card->flags; fr_buf_ctl_t *bctl; char *ptr = &flags->iflag; - struct device *dev = card->wandev.dev; - struct device *dev2; + struct net_device *dev = card->wandev.dev; + struct net_device *dev2; int i; unsigned long host_cpu_flags; unsigned disable_tx_intr = 1; @@ -1429,7 +1429,7 @@ static void fr502_rx_intr(sdla_t * card) { fr_mbox_t *mbox = card->rxmb; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; fr_channel_t *chan; unsigned dlci, len; void *buf; @@ -1517,7 +1517,7 @@ static void fr508_rx_intr(sdla_t * card) { fr_buf_ctl_t *frbuf = card->rxmb; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; fr_channel_t *chan; unsigned dlci, len, offs; void *buf; @@ -1653,7 +1653,7 @@ static void fr508_rx_intr(sdla_t * card) */ static void tx_intr(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (card->intr_mode == BUFFER_INTR_MODE) { for (; dev; dev = dev->slave) @@ -1801,7 +1801,7 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char static void wpf_poll(sdla_t * card) { -/* struct device* dev = card->wandev.dev; */ +/* struct net_device* dev = card->wandev.dev; */ fr508_flags_t *flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; @@ -2246,11 +2246,11 @@ static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox) int cnt = mbox->cmd.length / sizeof(dlci_status_t); fr_dlc_conf_t cfg; fr_channel_t *chan; - struct device *dev2; + struct net_device *dev2; for (; cnt; --cnt, ++status) { unsigned short dlci = status->dlci; - struct device *dev = find_channel(card, dlci); + struct net_device *dev = find_channel(card, dlci); if (dev == NULL) { printk(KERN_INFO @@ -2325,7 +2325,7 @@ static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox) /*============================================================================ * Update channel state. */ -static int update_chan_state(struct device *dev) +static int update_chan_state(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -2365,7 +2365,7 @@ static int update_chan_state(struct device *dev) /*============================================================================ * Set channel state. */ -static void set_chan_state(struct device *dev, int state) +static void set_chan_state(struct net_device *dev, int state) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -2402,9 +2402,9 @@ static void set_chan_state(struct device *dev, int state) /*============================================================================ * Find network device by its channel number. */ -static struct device *find_channel(sdla_t * card, unsigned dlci) +static struct net_device *find_channel(sdla_t * card, unsigned dlci) { - struct device *dev; + struct net_device *dev; for (dev = card->wandev.dev; dev; dev = dev->slave) if (((fr_channel_t *) dev->priv)->dlci == dlci) break; @@ -2454,7 +2454,7 @@ static unsigned int dec_to_uint(unsigned char *str, int len) * Process UDP call of type FPIPE8ND */ -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan) +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) { int c_retry = MAX_CMD_RETRY; unsigned char *data; @@ -2818,7 +2818,7 @@ static int intr_test(sdla_t * card) /*============================================================================ * Process UDP call of type DRVSTATS. */ -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan) +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) { int c_retry = MAX_CMD_RETRY; unsigned char *sendpacket; diff --git a/drivers/net/sdla_ppp.c b/drivers/net/sdla_ppp.c index ec9b71b85..d35ac7c18 100644 --- a/drivers/net/sdla_ppp.c +++ b/drivers/net/sdla_ppp.c @@ -147,20 +147,20 @@ extern void enable_irq(unsigned int); /* WAN link driver entry points. These are called by the WAN router module. */ static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct device *dev, +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct device *dev); +static int del_if(wan_device_t * wandev, struct net_device *dev); /* WANPIPE-specific entry points */ static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data); /* Network device interface */ -static int if_init(struct device *dev); -static int if_open(struct device *dev); -static int if_close(struct device *dev); -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); -static int if_send(struct sk_buff *skb, struct device *dev); -static struct enet_statistics *if_stats(struct device *dev); +static int if_send(struct sk_buff *skb, struct net_device *dev); +static struct enet_statistics *if_stats(struct net_device *dev); /* PPP firmware interface functions */ static int ppp_read_version(sdla_t * card, char *str); static int ppp_configure(sdla_t * card, void *data); @@ -185,8 +185,8 @@ static int config508(sdla_t * card); static void show_disc_cause(sdla_t * card, unsigned cause); static unsigned char bps_to_speed_code(unsigned long bps); static int reply_udp(unsigned char *data, unsigned int mbox_len); -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area); +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); static void init_ppp_tx_rx_buff(sdla_t * card); static int intr_test(sdla_t * card); static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); @@ -310,7 +310,7 @@ static int update(wan_device_t * wandev) * < 0 failure (channel will not be created) */ -static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf) +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) { sdla_t *card = wandev->private; ppp_private_area_t *ppp_priv_area; @@ -343,7 +343,7 @@ static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf * Delete logical channel. */ -static int del_if(wan_device_t * wandev, struct device *dev) +static int del_if(wan_device_t * wandev, struct net_device *dev) { if (dev->priv) { kfree(dev->priv); @@ -391,7 +391,7 @@ static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data) * registration. */ -static int if_init(struct device *dev) +static int if_init(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -429,7 +429,7 @@ static int if_init(struct device *dev) * Return 0 if O.k. or errno. */ -static int if_open(struct device *dev) +static int if_open(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -487,7 +487,7 @@ static int if_open(struct device *dev) * o reset flags. */ -static int if_close(struct device *dev) +static int if_close(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -512,7 +512,7 @@ static int if_close(struct device *dev) * Return: media header length. */ -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { switch (type) @@ -536,7 +536,7 @@ static int if_header(struct sk_buff *skb, struct device *dev, static int if_rebuild_hdr(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", @@ -562,7 +562,7 @@ static int if_rebuild_hdr(struct sk_buff *skb) * protocol stack and can be used for flow control with protocol layer. */ -static int if_send(struct sk_buff *skb, struct device *dev) +static int if_send(struct sk_buff *skb, struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -846,7 +846,7 @@ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_ * Return a pointer to struct enet_statistics. */ -static struct enet_statistics *if_stats(struct device *dev) +static struct enet_statistics *if_stats(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card; @@ -1052,7 +1052,7 @@ STATIC void wpp_isr(sdla_t * card) ppp_flags_t *flags = card->flags; char *ptr = &flags->iflag; unsigned long host_cpu_flags; - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; int i; card->in_isr = 1; ++card->statistics.isr_entry; @@ -1123,7 +1123,7 @@ STATIC void wpp_isr(sdla_t * card) static void rx_intr(sdla_t * card) { ppp_buf_ctl_t *rxbuf = card->rxmb; - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; ppp_private_area_t *ppp_priv_area; struct sk_buff *skb; unsigned len; @@ -1227,7 +1227,7 @@ static void rx_intr(sdla_t * card) static void tx_intr(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (!dev || !dev->start) { ++card->statistics.tx_intr_dev_not_started; return; @@ -1332,7 +1332,7 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char static void wpp_poll(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; ppp_flags_t *adptr_flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; @@ -1430,7 +1430,7 @@ static void poll_connecting(sdla_t * card) static void poll_disconnected(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (dev && dev->start && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); @@ -1591,7 +1591,7 @@ static unsigned char bps_to_speed_code(unsigned long bps) * Process UDP call of type DRVSTATS. */ -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area) +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area) { unsigned char *sendpacket; unsigned char buf2[5]; @@ -1776,7 +1776,7 @@ static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_bu */ static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, - struct sk_buff *skb, struct device *dev, + struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area) { unsigned char *sendpacket; diff --git a/drivers/net/sdla_x25.c b/drivers/net/sdla_x25.c index 0ef2771d8..270c5a59f 100644 --- a/drivers/net/sdla_x25.c +++ b/drivers/net/sdla_x25.c @@ -70,7 +70,7 @@ /****** Data Structures *****************************************************/ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network * interface to keep the rest of X.25 channel-specific data. */ typedef struct x25_channel @@ -114,22 +114,22 @@ typedef struct x25_call_info /* WAN link driver entry points. These are called by the WAN router module. */ static int update (wan_device_t* wandev); -static int new_if (wan_device_t* wandev, struct device* dev, +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf); -static int del_if (wan_device_t* wandev, struct device* dev); +static int del_if (wan_device_t* wandev, struct net_device* dev); /* WANPIPE-specific entry points */ static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data); /* Network device interface */ -static int if_init (struct device* dev); -static int if_open (struct device* dev); -static int if_close (struct device* dev); -static int if_header (struct sk_buff* skb, struct device* dev, +static int if_init (struct net_device* dev); +static int if_open (struct net_device* dev); +static int if_close (struct net_device* dev); +static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len); static int if_rebuild_hdr (struct sk_buff* skb); -static int if_send (struct sk_buff* skb, struct device* dev); -static struct net_device_stats * if_stats (struct device* dev); +static int if_send (struct sk_buff* skb, struct net_device* dev); +static struct net_device_stats * if_stats (struct net_device* dev); /* Interrupt handlers */ static void wpx_isr (sdla_t* card); @@ -173,11 +173,11 @@ static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb); /* Miscellaneous functions */ static int connect (sdla_t* card); static int disconnect (sdla_t* card); -static struct device* get_dev_by_lcn(wan_device_t* wandev, unsigned lcn); -static int chan_connect (struct device* dev); -static int chan_disc (struct device* dev); -static void set_chan_state (struct device* dev, int state); -static int chan_send (struct device* dev, struct sk_buff* skb); +static struct net_device* get_dev_by_lcn(wan_device_t* wandev, unsigned lcn); +static int chan_connect (struct net_device* dev); +static int chan_disc (struct net_device* dev); +static void set_chan_state (struct net_device* dev, int state); +static int chan_send (struct net_device* dev, struct sk_buff* skb); static unsigned char bps_to_speed_code (unsigned long bps); static unsigned int dec_to_uint (unsigned char* str, int len); static unsigned int hex_to_uint (unsigned char* str, int len); @@ -394,7 +394,7 @@ static int update (wan_device_t* wandev) * Return: 0 o.k. * < 0 failure (channel will not be created) */ -static int new_if (wan_device_t* wandev, struct device* dev, wanif_conf_t* conf) +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) { sdla_t* card = wandev->private; x25_channel_t* chan; @@ -470,7 +470,7 @@ static int new_if (wan_device_t* wandev, struct device* dev, wanif_conf_t* conf) /*============================================================================ * Delete logical channel. */ -static int del_if (wan_device_t* wandev, struct device* dev) +static int del_if (wan_device_t* wandev, struct net_device* dev) { if (dev->priv) { @@ -531,7 +531,7 @@ static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data) * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init (struct device* dev) +static int if_init (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -577,7 +577,7 @@ static int if_init (struct device* dev) * * Return 0 if O.k. or errno. */ -static int if_open (struct device* dev) +static int if_open (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -605,7 +605,7 @@ static int if_open (struct device* dev) * o reset flags. * o if there's no more open channels then disconnect physical link. */ -static int if_close (struct device* dev) +static int if_close (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -637,7 +637,7 @@ static int if_close (struct device* dev) * * Return: media header length. */ -static int if_header (struct sk_buff* skb, struct device* dev, +static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len) { x25_channel_t* chan = dev->priv; @@ -665,7 +665,7 @@ static int if_header (struct sk_buff* skb, struct device* dev, static int if_rebuild_hdr (struct sk_buff* skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -692,11 +692,11 @@ static int if_rebuild_hdr (struct sk_buff* skb) * protocol stack and can be used for flow control with protocol layer. */ -static int if_send (struct sk_buff* skb, struct device* dev) +static int if_send (struct sk_buff* skb, struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; - struct device *dev2; + struct net_device *dev2; TX25Status* status = card->flags; unsigned long host_cpu_flags; @@ -823,7 +823,7 @@ tx_done: * Return a pointer to struct net_device_stats */ -static struct net_device_stats* if_stats (struct device* dev) +static struct net_device_stats* if_stats (struct net_device* dev) { x25_channel_t* chan = dev->priv; if(chan==NULL) @@ -840,7 +840,7 @@ static struct net_device_stats* if_stats (struct device* dev) static void wpx_isr (sdla_t* card) { TX25Status* status = card->flags; - struct device *dev; + struct net_device *dev; unsigned long host_cpu_flags; card->in_isr = 1; @@ -933,7 +933,7 @@ static void rx_intr (sdla_t* card) unsigned len = rxmb->cmd.length; /* packet length */ unsigned qdm = rxmb->cmd.qdm; /* Q,D and M bits */ wan_device_t* wandev = &card->wandev; - struct device* dev = get_dev_by_lcn(wandev, lcn); + struct net_device* dev = get_dev_by_lcn(wandev, lcn); x25_channel_t* chan; struct sk_buff* skb; void* bufptr; @@ -1041,7 +1041,7 @@ static void rx_intr (sdla_t* card) static void tx_intr (sdla_t* card) { - struct device *dev; + struct net_device *dev; /* unbusy all devices and then dev_tint(); */ for(dev = card->wandev.dev; dev; dev = dev->slave) @@ -1165,7 +1165,7 @@ static void poll_disconnected (sdla_t* card) */ static void poll_active (sdla_t* card) { - struct device* dev; + struct net_device* dev; /* Fetch X.25 asynchronous events */ x25_fetch_events(card); @@ -1745,7 +1745,7 @@ static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { wan_device_t* wandev = &card->wandev; int new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(wandev, new_lcn); x25_channel_t* chan = NULL; int accept = 0; /* set to '1' if o.k. to accept call */ x25_call_info_t* info; @@ -1855,7 +1855,7 @@ static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { unsigned new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); x25_channel_t* chan; printk(KERN_INFO "%s: X.25 call accepted on LCN %d!\n", @@ -1887,7 +1887,7 @@ static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { unsigned new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); printk(KERN_INFO "%s: X.25 clear request on LCN %d! Cause:0x%02X " "Diagn:0x%02X\n", @@ -1905,7 +1905,7 @@ static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { wan_device_t* wandev = &card->wandev; - struct device* dev; + struct net_device* dev; printk(KERN_INFO "%s: X.25 restart request! Cause:0x%02X Diagn:0x%02X\n", @@ -1926,7 +1926,7 @@ static int timeout_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) if (mb->cmd.pktType == 0x05) /* call request time out */ { - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); printk(KERN_INFO "%s: X.25 call timed timeout on LCN %d!\n", card->devname, new_lcn); @@ -1976,9 +1976,9 @@ static int disconnect (sdla_t* card) /*============================================================================ * Find network device by its channel number. */ -static struct device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) +static struct net_device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) { - struct device* dev; + struct net_device* dev; for (dev = wandev->dev; dev; dev = dev->slave) if (((x25_channel_t*)dev->priv)->lcn == lcn) @@ -1995,7 +1995,7 @@ static struct device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) * >0 connection in progress * <0 failure */ -static int chan_connect (struct device* dev) +static int chan_connect (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -2024,7 +2024,7 @@ static int chan_connect (struct device* dev) * Disconnect logical channel. * o if SVC then clear X.25 call */ -static int chan_disc (struct device* dev) +static int chan_disc (struct net_device* dev) { x25_channel_t* chan = dev->priv; @@ -2037,7 +2037,7 @@ static int chan_disc (struct device* dev) /*============================================================================ * Set logical channel state. */ -static void set_chan_state (struct device* dev, int state) +static void set_chan_state (struct net_device* dev, int state) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -2092,7 +2092,7 @@ static void set_chan_state (struct device* dev, int state) * 2. When transmission is complete, an event notification should be issued * to the router. */ -static int chan_send (struct device* dev, struct sk_buff* skb) +static int chan_send (struct net_device* dev, struct sk_buff* skb) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; diff --git a/drivers/net/sdlamain.c b/drivers/net/sdlamain.c index d0aa8fd68..ca98eeff9 100644 --- a/drivers/net/sdlamain.c +++ b/drivers/net/sdlamain.c @@ -11,7 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ -* May 19, 1999 Arnaldo Melo __initfunc for wanpipe_init +* May 19, 1999 Arnaldo Melo __init for wanpipe_init * Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1 * Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags(); * Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0 @@ -43,7 +43,7 @@ #include <linux/wanpipe.h> /* WANPIPE common user API definitions */ #include <asm/uaccess.h> /* kernel <-> user copy */ #include <asm/io.h> /* phys_to_virt() */ -#include <linux/init.h> /* __initfunc (when not using as a module) */ +#include <linux/init.h> /* __init (when not using as a module) */ /****** Defines & Macros ****************************************************/ @@ -124,7 +124,7 @@ static struct tq_struct sdla_tq = #ifdef MODULE int init_module (void) #else -__initfunc(int wanpipe_init(void)) +int __init wanpipe_init(void) #endif { int cnt, err = 0; diff --git a/drivers/net/sealevel.c b/drivers/net/sealevel.c index 03e90828e..1dc146711 100644 --- a/drivers/net/sealevel.c +++ b/drivers/net/sealevel.c @@ -73,7 +73,7 @@ static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb) * We've been placed in the UP state */ -static int sealevel_open(struct device *d) +static int sealevel_open(struct net_device *d) { struct slvl_device *slvl=d->priv; int err = -1; @@ -123,7 +123,7 @@ static int sealevel_open(struct device *d) return 0; } -static int sealevel_close(struct device *d) +static int sealevel_close(struct net_device *d) { struct slvl_device *slvl=d->priv; int unit = slvl->channel; @@ -156,14 +156,14 @@ static int sealevel_close(struct device *d) return 0; } -static int sealevel_ioctl(struct device *d, struct ifreq *ifr, int cmd) +static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) { /* struct slvl_device *slvl=d->priv; z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *sealevel_get_stats(struct device *d) +static struct enet_statistics *sealevel_get_stats(struct net_device *d) { struct slvl_device *slvl=d->priv; if(slvl) @@ -176,7 +176,7 @@ static struct enet_statistics *sealevel_get_stats(struct device *d) * Passed PPP frames, fire them downwind. */ -static int sealevel_queue_xmit(struct sk_buff *skb, struct device *d) +static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d) { struct slvl_device *slvl=d->priv; return z8530_queue_xmit(slvl->chan, skb); @@ -192,7 +192,7 @@ static int sealevel_neigh_setup(struct neighbour *n) return 0; } -static int sealevel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = sealevel_neigh_setup; @@ -204,7 +204,7 @@ static int sealevel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) #else -static int return_0(struct device *d) +static int return_0(struct net_device *d) { return 0; } @@ -342,7 +342,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i sprintf(sv->name,"hdlc%d", i); if(dev_get(sv->name)==NULL) { - struct device *d=sv->chan->netdevice; + struct net_device *d=sv->chan->netdevice; /* * Initialise the PPP components diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index ee8104b6e..9d9b9d633 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -78,22 +78,22 @@ struct net_local { /* Index to functions, as function prototypes. */ -extern int seeq8005_probe(struct device *dev); +extern int seeq8005_probe(struct net_device *dev); -static int seeq8005_probe1(struct device *dev, int ioaddr); -static int seeq8005_open(struct device *dev); -static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev); +static int seeq8005_probe1(struct net_device *dev, int ioaddr); +static int seeq8005_open(struct net_device *dev); +static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev); static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void seeq8005_rx(struct device *dev); -static int seeq8005_close(struct device *dev); -static struct net_device_stats *seeq8005_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void seeq8005_rx(struct net_device *dev); +static int seeq8005_close(struct net_device *dev); +static struct net_device_stats *seeq8005_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Example routines you must write ;->. */ #define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON) -static void hardware_send_packet(struct device *dev, char *buf, int length); -extern void seeq8005_init(struct device *dev, int startp); -static inline void wait_for_buffer(struct device *dev); +static void hardware_send_packet(struct net_device *dev, char *buf, int length); +extern void seeq8005_init(struct net_device *dev, int startp); +static inline void wait_for_buffer(struct net_device *dev); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -109,7 +109,7 @@ struct netdev_entry seeq8005_drv = {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; #else int __init -seeq8005_probe(struct device *dev) +seeq8005_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -135,7 +135,7 @@ seeq8005_probe(struct device *dev) probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int __init seeq8005_probe1(struct device *dev, int ioaddr) +static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i,j; @@ -344,7 +344,7 @@ static int __init seeq8005_probe1(struct device *dev, int ioaddr) there is non-reboot way to recover if something goes wrong. */ static int -seeq8005_open(struct device *dev) +seeq8005_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -369,7 +369,7 @@ seeq8005_open(struct device *dev) } static int -seeq8005_send_packet(struct sk_buff *skb, struct device *dev) +seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -412,7 +412,7 @@ seeq8005_send_packet(struct sk_buff *skb, struct device *dev) static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; @@ -462,7 +462,7 @@ seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* We have a good packet(s), get it/them out of the buffers. */ static void -seeq8005_rx(struct device *dev) +seeq8005_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount = 10; @@ -561,7 +561,7 @@ seeq8005_rx(struct device *dev) /* The inverse routine to net_open(). */ static int -seeq8005_close(struct device *dev) +seeq8005_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -584,7 +584,7 @@ seeq8005_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *seeq8005_get_stats(struct device *dev) +static struct net_device_stats *seeq8005_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -598,7 +598,7 @@ static struct net_device_stats *seeq8005_get_stats(struct device *dev) best-effort filtering. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { /* * I _could_ do up to 6 addresses here, but won't (yet?) @@ -620,7 +620,7 @@ set_multicast_list(struct device *dev) #endif } -void seeq8005_init(struct device *dev, int startp) +void seeq8005_init(struct net_device *dev, int startp) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -677,7 +677,7 @@ void seeq8005_init(struct device *dev, int startp) } -static void hardware_send_packet(struct device * dev, char *buf, int length) +static void hardware_send_packet(struct net_device * dev, char *buf, int length) { int ioaddr = dev->base_addr; int status = inw(SEEQ_STATUS); @@ -722,7 +722,7 @@ static void hardware_send_packet(struct device * dev, char *buf, int length) * This routine waits for the SEEQ chip to assert that the FIFO is ready * by checking for a window interrupt, and then clearing it */ -inline void wait_for_buffer(struct device * dev) +inline void wait_for_buffer(struct net_device * dev) { int ioaddr = dev->base_addr; int tmp; @@ -740,7 +740,7 @@ inline void wait_for_buffer(struct device * dev) static char devicename[9] = { 0, }; -static struct device dev_seeq = +static struct net_device dev_seeq = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index c04922287..c6a453b61 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.c,v 1.9 1998/10/14 23:40:46 ralf Exp $ +/* $Id: sgiseeq.c,v 1.10 1999/08/11 20:26:50 andrewb Exp $ * * sgiseeq.c: Seeq8003 ethernet driver for SGI machines. * @@ -135,7 +135,7 @@ static inline void seeq_go(struct sgiseeq_private *sp, hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; } -static inline void seeq_load_eaddr(struct device *dev, +static inline void seeq_load_eaddr(struct net_device *dev, volatile struct sgiseeq_regs *sregs) { int i; @@ -149,7 +149,7 @@ static inline void seeq_load_eaddr(struct device *dev, #define RCNTCFG_INIT (HPCDMA_OWN | HPCDMA_EORP | HPCDMA_XIE) #define RCNTINFO_INIT (RCNTCFG_INIT | (PKT_BUF_SZ & HPCDMA_BCNT)) -static void seeq_init_ring(struct device *dev) +static void seeq_init_ring(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_init_block *ib = &sp->srings; @@ -197,7 +197,7 @@ static void seeq_init_ring(struct device *dev) #ifdef DEBUG static struct sgiseeq_private *gpriv; -static struct device *gdev; +static struct net_device *gdev; void sgiseeq_dump_rings(void) { @@ -242,7 +242,7 @@ void sgiseeq_dump_rings(void) #define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2) #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) -static void init_seeq(struct device *dev, struct sgiseeq_private *sp, +static void init_seeq(struct net_device *dev, struct sgiseeq_private *sp, volatile struct sgiseeq_regs *sregs) { volatile struct hpc3_ethregs *hregs = sp->hregs; @@ -295,7 +295,7 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp, !((rd)->rdma.cntinfo & HPCDMA_OWN); \ (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) -static inline void sgiseeq_rx(struct device *dev, struct sgiseeq_private *sp, +static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, volatile struct hpc3_ethregs *hregs, volatile struct sgiseeq_regs *sregs) { @@ -372,7 +372,7 @@ static inline void kick_tx(struct sgiseeq_tx_desc *td, } } -static inline void sgiseeq_tx(struct device *dev, struct sgiseeq_private *sp, +static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, volatile struct hpc3_ethregs *hregs, volatile struct sgiseeq_regs *sregs) { @@ -413,7 +413,7 @@ static inline void sgiseeq_tx(struct device *dev, struct sgiseeq_private *sp, } static inline void tx_maybe_unbusy(struct sgiseeq_private *sp, - struct device *dev) + struct net_device *dev) { if((TX_BUFFS_AVAIL(sp) >= 0) && dev->tbusy) { dev->tbusy = 0; @@ -423,7 +423,7 @@ static inline void tx_maybe_unbusy(struct sgiseeq_private *sp, static void sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct hpc3_ethregs *hregs = sp->hregs; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -443,7 +443,7 @@ static void sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) dev->interrupt = 0; } -static int sgiseeq_open(struct device *dev) +static int sgiseeq_open(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -465,7 +465,7 @@ static int sgiseeq_open(struct device *dev) return 0; } -static int sgiseeq_close(struct device *dev) +static int sgiseeq_close(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -481,7 +481,7 @@ static int sgiseeq_close(struct device *dev) return 0; } -static inline int sgiseeq_reset(struct device *dev) +static inline int sgiseeq_reset(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -503,7 +503,7 @@ void sgiseeq_my_reset(void) } static inline int verify_tx(struct sgiseeq_private *sp, - struct device *dev, + struct net_device *dev, struct sk_buff *skb) { /* Are we bolixed? */ @@ -530,7 +530,7 @@ static inline int verify_tx(struct sgiseeq_private *sp, return 0; } -static int sgiseeq_start_xmit(struct sk_buff *skb, struct device *dev) +static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct hpc3_ethregs *hregs = sp->hregs; @@ -586,14 +586,14 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct device *dev) return 0; } -static struct enet_statistics *sgiseeq_get_stats(struct device *dev) +static struct enet_statistics *sgiseeq_get_stats(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; return &sp->stats; } -static void sgiseeq_set_multicast(struct device *dev) +static void sgiseeq_set_multicast(struct net_device *dev) { } @@ -626,7 +626,7 @@ static char onboard_eth_addr[6]; #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct device *dev, struct sgiseeq_regs *sregs, +int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, struct hpc3_ethregs *hregs, int irq) { static unsigned version_printed = 0; @@ -722,7 +722,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) } } -int sgiseeq_probe(struct device *dev) +int sgiseeq_probe(struct net_device *dev) { static int initialized; char *ep; diff --git a/drivers/net/sgiseeq.h b/drivers/net/sgiseeq.h index 023c2c065..4f684f5a1 100644 --- a/drivers/net/sgiseeq.h +++ b/drivers/net/sgiseeq.h @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.h,v 1.2 1996/06/15 03:42:50 dm Exp $ +/* $Id: sgiseeq.h,v 1.1 1997/06/09 08:34:32 ralf Exp $ * sgiseeq.h: Defines for the Seeq8003 ethernet controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 318f4c19a..3c6589a06 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -51,14 +51,19 @@ * will render your machine defunct. Don't for now shape over * PPP or SLIP therefore! * This will be fixed in BETA4 - */ - -/* - * bh_atomic() SMP races fixes and rewritten the locking code to be SMP safe - * and irq-mask friendly. NOTE: we can't use start_bh_atomic() in kick_shaper() - * because it's going to be recalled from an irq handler, and synchronize_bh() - * is a nono if called from irq context. + * + * Update History : + * + * bh_atomic() SMP races fixes and rewritten the locking code to + * be SMP safe and irq-mask friendly. + * NOTE: we can't use start_bh_atomic() in kick_shaper() + * because it's going to be recalled from an irq handler, + * and synchronize_bh() is a nono if called from irq context. * 1999 Andrea Arcangeli + * + * Device statistics (tx_pakets, tx_bytes, + * tx_drops: queue_over_time and collisions: max_queue_exceded) + * 1999/06/18 Jordi Murgo <savage@apostols.org> */ #include <linux/module.h> @@ -228,18 +233,20 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) /* * Queue over time. Spill packet. */ - if(skb->shapeclock-jiffies > SHAPER_LATENCY) + if(skb->shapeclock-jiffies > SHAPER_LATENCY) { dev_kfree_skb(skb); - else + shaper->stats.tx_dropped++; + } else skb_queue_tail(&shaper->sendq, skb); } #endif - if(sh_debug) + if(sh_debug) printk("Frame queued.\n"); if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN) { ptr=skb_dequeue(&shaper->sendq); - dev_kfree_skb(ptr); + dev_kfree_skb(ptr); + shaper->stats.collisions++; } shaper_unlock(shaper); return 0; @@ -262,7 +269,11 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) printk("Kick new frame to %s, %d\n", shaper->dev->name,newskb->priority); dev_queue_xmit(newskb); - if(sh_debug) + + shaper->stats.tx_bytes+=newskb->len; + shaper->stats.tx_packets++; + + if(sh_debug) printk("Kicked new frame out.\n"); dev_kfree_skb(skb); } @@ -367,7 +378,7 @@ static void shaper_flush(struct shaper *shaper) * bind. */ -static int shaper_open(struct device *dev) +static int shaper_open(struct net_device *dev) { struct shaper *shaper=dev->priv; @@ -389,7 +400,7 @@ static int shaper_open(struct device *dev) * Closing a shaper flushes the queues. */ -static int shaper_close(struct device *dev) +static int shaper_close(struct net_device *dev) { struct shaper *shaper=dev->priv; shaper_flush(shaper); @@ -407,18 +418,19 @@ static int shaper_close(struct device *dev) */ -static int shaper_start_xmit(struct sk_buff *skb, struct device *dev) +static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct shaper *sh=dev->priv; return shaper_qframe(sh, skb); } -static struct net_device_stats *shaper_get_stats(struct device *dev) +static struct net_device_stats *shaper_get_stats(struct net_device *dev) { - return NULL; + struct shaper *sh=dev->priv; + return &sh->stats; } -static int shaper_header(struct sk_buff *skb, struct device *dev, +static int shaper_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct shaper *sh=dev->priv; @@ -434,7 +446,7 @@ static int shaper_header(struct sk_buff *skb, struct device *dev, static int shaper_rebuild_header(struct sk_buff *skb) { struct shaper *sh=skb->dev->priv; - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; int v; if(sh_debug) printk("Shaper rebuild header\n"); @@ -448,7 +460,7 @@ static int shaper_rebuild_header(struct sk_buff *skb) static int shaper_cache(struct neighbour *neigh, struct hh_cache *hh) { struct shaper *sh=neigh->dev->priv; - struct device *tmp; + struct net_device *tmp; int ret; if(sh_debug) printk("Shaper header cache bind\n"); @@ -459,7 +471,7 @@ static int shaper_cache(struct neighbour *neigh, struct hh_cache *hh) return ret; } -static void shaper_cache_update(struct hh_cache *hh, struct device *dev, +static void shaper_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char *haddr) { struct shaper *sh=dev->priv; @@ -478,7 +490,7 @@ static int shaper_neigh_setup(struct neighbour *n) return 0; } -static int shaper_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = shaper_neigh_setup; @@ -488,7 +500,7 @@ static int shaper_neigh_setup_dev(struct device *dev, struct neigh_parms *p) return 0; } -static int shaper_attach(struct device *shdev, struct shaper *sh, struct device *dev) +static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net_device *dev) { sh->dev = dev; sh->hard_start_xmit=dev->hard_start_xmit; @@ -541,7 +553,7 @@ static int shaper_attach(struct device *shdev, struct shaper *sh, struct device return 0; } -static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int shaper_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data; struct shaper *sh=dev->priv; @@ -549,7 +561,7 @@ static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd) { case SHAPER_SET_DEV: { - struct device *them=dev_get(ss->ss_name); + struct net_device *them=__dev_get_by_name(ss->ss_name); if(them==NULL) return -ENODEV; if(sh->dev) @@ -572,7 +584,7 @@ static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd) } } -static struct shaper *shaper_alloc(struct device *dev) +static struct shaper *shaper_alloc(struct net_device *dev) { struct shaper *sh=kmalloc(sizeof(struct shaper), GFP_KERNEL); if(sh==NULL) @@ -590,7 +602,7 @@ static struct shaper *shaper_alloc(struct device *dev) * Add a shaper device to the system */ -__initfunc(int shaper_probe(struct device *dev)) +int __init shaper_probe(struct net_device *dev) { /* * Set up the shaper. @@ -643,7 +655,7 @@ __initfunc(int shaper_probe(struct device *dev)) static char devicename[9]; -static struct device dev_shape = +static struct net_device dev_shape = { devicename, 0, 0, 0, 0, @@ -665,7 +677,9 @@ int init_module(void) void cleanup_module(void) { - /* + struct shaper *sh=dev_shape.priv; + + /* * No need to check MOD_IN_USE, as sys_delete_module() checks. * To be unloadable we must be closed and detached so we don't * need to flush things. @@ -674,16 +688,15 @@ void cleanup_module(void) unregister_netdev(&dev_shape); /* - * Free up the private structure, or leak memory :-) + * Free up the private structure, or leak memory :-) */ - - kfree(dev_shape.priv); + kfree(sh); dev_shape.priv = NULL; } #else -static struct device dev_sh0 = +static struct net_device dev_sh0 = { "shaper0", 0, 0, 0, 0, @@ -692,7 +705,7 @@ static struct device dev_sh0 = }; -static struct device dev_sh1 = +static struct net_device dev_sh1 = { "shaper1", 0, 0, 0, 0, @@ -701,7 +714,7 @@ static struct device dev_sh1 = }; -static struct device dev_sh2 = +static struct net_device dev_sh2 = { "shaper2", 0, 0, 0, 0, @@ -709,7 +722,7 @@ static struct device dev_sh2 = 0, 0, 0, NULL, shaper_probe }; -static struct device dev_sh3 = +static struct net_device dev_sh3 = { "shaper3", 0, 0, 0, 0, diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c new file mode 100644 index 000000000..d356e39af --- /dev/null +++ b/drivers/net/sis900.c @@ -0,0 +1,1909 @@ +/*****************************************************************************/ +/* sis900.c: A SiS 900 PCI Fast Ethernet driver for Linux. */ +/* */ +/* Silicon Integrated System Corporation */ +/* Revision: 1.05 Aug 7 1999 */ +/* */ +/*****************************************************************************/ + +/* + Modified from the driver which is originally written by Donald Becker. + + This software may be used and distributed according to the terms + of the GNU Public License (GPL), incorporated herein by reference. + Drivers based on this skeleton fall under the GPL and must retain + the authorship (implicit copyright) notice. + + The author may be reached as becker@tidalwave.net, or + Donald Becker + 312 Severn Ave. #W302 + Annapolis MD 21403 + + Support and updates [to the original skeleton] available at + http://www.tidalwave.net/~becker/pci-skeleton.html +*/ + +static const char *version = +"sis900.c:v1.05 8/07/99\n"; + +static int max_interrupt_work = 20; +#define sis900_debug debug +static int sis900_debug = 0; + +static int multicast_filter_limit = 128; + +#define MAX_UNITS 8 /* More are supported, limit only on options */ +static int speeds[MAX_UNITS] = {100, 100, 100, 100, 100, 100, 100, 100}; +static int full_duplex[MAX_UNITS] = {1, 1, 1, 1, 1, 1, 1, 1}; + +#define TX_BUF_SIZE 1536 +#define RX_BUF_SIZE 1536 + +#define TX_DMA_BURST 0 +#define RX_DMA_BURST 0 +#define TX_FIFO_THRESH 16 +#define TxDRNT_100 (1536>>5) +#define TxDRNT_10 16 +#define RxDRNT_100 8 +#define RxDRNT_10 8 +#define TRUE 1 +#define FALSE 0 + +/* Operational parameters that usually are not changed. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (4*HZ) + +#include <linux/module.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/malloc.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <asm/processor.h> /* Processor type for cache alignment. */ +#include <asm/bitops.h> +#include <asm/io.h> + +#define RUN_AT(x) (jiffies + (x)) + +#include <linux/delay.h> + +#if LINUX_VERSION_CODE < 0x20123 +#define test_and_set_bit(val, addr) set_bit(val, addr) +#endif +#if LINUX_VERSION_CODE <= 0x20139 +#define net_device_stats enet_statistics +#else +#define NETSTATS_VER2 +#endif +#if LINUX_VERSION_CODE < 0x20155 || defined(CARDBUS) +/* Grrrr, the PCI code changed, but did not consider CardBus... */ +#include <linux/bios32.h> +#define PCI_SUPPORT_VER1 +#else +#define PCI_SUPPORT_VER2 +#endif +#if LINUX_VERSION_CODE < 0x20159 +#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE); +#else +#define dev_free_skb(skb) dev_kfree_skb(skb); +#endif + +/* The I/O extent. */ +#define SIS900_TOTAL_SIZE 0x100 + +/* This table drives the PCI probe routines. It's mostly boilerplate in all + of the drivers, and will likely be provided by some future kernel. + Note the matching code -- the first table entry matchs all 56** cards but + second only the 1234 card. +*/ + +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, +}; + +struct pci_id_info { + const char *name; + u16 vendor_id, device_id, device_id_mask, flags; + int io_size; + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); +}; + +static struct net_device * sis900_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, + int irq, int chp_idx, int fnd_cnt); + +static struct pci_id_info pci_tbl[] = +{{ "SiS 900 PCI Fast Ethernet", + 0x1039, 0x0900, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x100, sis900_probe1}, + { "SiS 7016 PCI Fast Ethernet", + 0x1039, 0x7016, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x100, sis900_probe1}, + {0,}, /* 0 terminated list. */ +}; + +/* The capability table matches the chip table above. */ +enum {HAS_MII_XCVR=0x01, HAS_CHIP_XCVR=0x02, HAS_LNK_CHNG=0x04}; +static int sis_cap_tbl[] = { + HAS_MII_XCVR|HAS_CHIP_XCVR|HAS_LNK_CHNG, + HAS_MII_XCVR|HAS_CHIP_XCVR|HAS_LNK_CHNG, +}; + +/* The rest of these values should never change. */ +#define NUM_TX_DESC 16 /* Number of Tx descriptor registers. */ +#define NUM_RX_DESC 8 /* Number of Rx descriptor registers. */ + +/* Symbolic offsets to registers. */ +enum SIS900_registers { + cr=0x0, //Command Register + cfg=0x4, //Configuration Register + mear=0x8, //EEPROM Access Register + ptscr=0xc, //PCI Test Control Register + isr=0x10, //Interrupt Status Register + imr=0x14, //Interrupt Mask Register + ier=0x18, //Interrupt Enable Register + epar=0x18, //Enhanced PHY Access Register + txdp=0x20, //Transmit Descriptor Pointer Register + txcfg=0x24, //Transmit Configuration Register + rxdp=0x30, //Receive Descriptor Pointer Register + rxcfg=0x34, //Receive Configuration Register + flctrl=0x38, //Flow Control Register + rxlen=0x3c, //Receive Packet Length Register + rfcr=0x48, //Receive Filter Control Register + rfdr=0x4C, //Receive Filter Data Register + pmctrl=0xB0, //Power Management Control Register + pmer=0xB4 //Power Management Wake-up Event Register +}; + +#define RESET 0x00000100 +#define SWI 0x00000080 +#define RxRESET 0x00000020 +#define TxRESET 0x00000010 +#define RxDIS 0x00000008 +#define RxENA 0x00000004 +#define TxDIS 0x00000002 +#define TxENA 0x00000001 + +#define BISE 0x80000000 +#define EUPHCOM 0x00000100 +#define REQALG 0x00000080 +#define SB 0x00000040 +#define POW 0x00000020 +#define EXD 0x00000010 +#define PESEL 0x00000008 +#define LPM 0x00000004 +#define BEM 0x00000001 + +/* Interrupt register bits, using my own meaningful names. */ +#define WKEVT 0x10000000 +#define TxPAUSEEND 0x08000000 +#define TxPAUSE 0x04000000 +#define TxRCMP 0x02000000 +#define RxRCMP 0x01000000 +#define DPERR 0x00800000 +#define SSERR 0x00400000 +#define RMABT 0x00200000 +#define RTABT 0x00100000 +#define RxSOVR 0x00010000 +#define HIBERR 0x00008000 +#define SWINT 0x00001000 +#define MIBINT 0x00000800 +#define TxURN 0x00000400 +#define TxIDLE 0x00000200 +#define TxERR 0x00000100 +#define TxDESC 0x00000080 +#define TxOK 0x00000040 +#define RxORN 0x00000020 +#define RxIDLE 0x00000010 +#define RxEARLY 0x00000008 +#define RxERR 0x00000004 +#define RxDESC 0x00000002 +#define RxOK 0x00000001 + +#define IE 0x00000001 + +#define TxCSI 0x80000000 +#define TxHBI 0x40000000 +#define TxMLB 0x20000000 +#define TxATP 0x10000000 +#define TxIFG 0x0C000000 +#define TxMXF 0x03800000 +#define TxMXF_shift 0x23 +#define TxMXDMA 0x00700000 +#define TxMXDMA_shift 20 +#define TxRTCNT 0x000F0000 +#define TxRTCNT_shift 16 +#define TxFILLT 0x00007F00 +#define TxFILLT_shift 8 +#define TxDRNT 0x0000007F + +#define RxAEP 0x80000000 +#define RxARP 0x40000000 +#define RxATP 0x10000000 +#define RxAJAB 0x08000000 +#define RxMXF 0x03800000 +#define RxMXF_shift 23 +#define RxMXDMA 0x00700000 +#define RxMXDMA_shift 20 +#define RxDRNT 0x0000007F + +#define RFEN 0x80000000 +#define RFAAB 0x40000000 +#define RFAAM 0x20000000 +#define RFAAP 0x10000000 +#define RFPromiscuous (RFAAB|RFAAM|RFAAP) +#define RFAA_shift 28 +#define RFEP 0x00070000 +#define RFEP_shift 16 + +#define RFDAT 0x0000FFFF + +#define OWN 0x80000000 +#define MORE 0x40000000 +#define INTR 0x20000000 +#define OK 0x08000000 +#define DSIZE 0x00000FFF + +#define SUPCRC 0x10000000 +#define ABORT 0x04000000 +#define UNDERRUN 0x02000000 +#define NOCARRIER 0x01000000 +#define DEFERD 0x00800000 +#define EXCDEFER 0x00400000 +#define OWCOLL 0x00200000 +#define EXCCOLL 0x00100000 +#define COLCNT 0x000F0000 + +#define INCCRC 0x10000000 +// ABORT 0x04000000 +#define OVERRUN 0x02000000 +#define DEST 0x01800000 +#define BCAST 0x01800000 +#define MCAST 0x01000000 +#define UNIMATCH 0x00800000 +#define TOOLONG 0x00400000 +#define RUNT 0x00200000 +#define RXISERR 0x00100000 +#define CRCERR 0x00080000 +#define FAERR 0x00040000 +#define LOOPBK 0x00020000 +#define RXCOL 0x00010000 + +#define EuphLiteEEMACAddr 0x08 +#define EuphLiteEEVendorID 0x02 +#define EuphLiteEEDeviceID 0x03 +#define EuphLiteEECardTypeRev 0x0b +#define EuphLiteEEPlexusRev 0x0c +#define EuphLiteEEChecksum 0x0f + +#define RXSTS_shift 18 +#define OWN 0x80000000 +#define MORE 0x40000000 +#define INTR 0x20000000 +#define OK 0x08000000 +#define DSIZE 0x00000FFF +/* MII register offsets */ +#define MII_CONTROL 0x0000 +#define MII_STATUS 0x0001 +#define MII_PHY_ID0 0x0002 +#define MII_PHY_ID1 0x0003 +#define MII_ANAR 0x0004 +#define MII_ANLPAR 0x0005 +#define MII_ANER 0x0006 +/* MII Control register bit definitions. */ +#define MIICNTL_FDX 0x0100 +#define MIICNTL_RST_AUTO 0x0200 +#define MIICNTL_ISOLATE 0x0400 +#define MIICNTL_PWRDWN 0x0800 +#define MIICNTL_AUTO 0x1000 +#define MIICNTL_SPEED 0x2000 +#define MIICNTL_LPBK 0x4000 +#define MIICNTL_RESET 0x8000 +/* MII Status register bit significance. */ +#define MIISTAT_EXT 0x0001 +#define MIISTAT_JAB 0x0002 +#define MIISTAT_LINK 0x0004 +#define MIISTAT_CAN_AUTO 0x0008 +#define MIISTAT_FAULT 0x0010 +#define MIISTAT_AUTO_DONE 0x0020 +#define MIISTAT_CAN_T 0x0800 +#define MIISTAT_CAN_T_FDX 0x1000 +#define MIISTAT_CAN_TX 0x2000 +#define MIISTAT_CAN_TX_FDX 0x4000 +#define MIISTAT_CAN_T4 0x8000 +/* MII NWAY Register Bits ... +** valid for the ANAR (Auto-Negotiation Advertisement) and +** ANLPAR (Auto-Negotiation Link Partner) registers */ +#define MII_NWAY_NODE_SEL 0x001f +#define MII_NWAY_CSMA_CD 0x0001 +#define MII_NWAY_T 0x0020 +#define MII_NWAY_T_FDX 0x0040 +#define MII_NWAY_TX 0x0080 +#define MII_NWAY_TX_FDX 0x0100 +#define MII_NWAY_T4 0x0200 +#define MII_NWAY_RF 0x2000 +#define MII_NWAY_ACK 0x4000 +#define MII_NWAY_NP 0x8000 + +/* MII Auto-Negotiation Expansion Register Bits */ +#define MII_ANER_PDF 0x0010 +#define MII_ANER_LP_NP_ABLE 0x0008 +#define MII_ANER_NP_ABLE 0x0004 +#define MII_ANER_RX_PAGE 0x0002 +#define MII_ANER_LP_AN_ABLE 0x0001 +#define HALF_DUPLEX 1 +#define FDX_CAPABLE_DUPLEX_UNKNOWN 2 +#define FDX_CAPABLE_HALF_SELECTED 3 +#define FDX_CAPABLE_FULL_SELECTED 4 +#define HW_SPEED_UNCONFIG 0 +#define HW_SPEED_10_MBPS 10 +#define HW_SPEED_100_MBPS 100 +#define HW_SPEED_DEFAULT (HW_SPEED_10_MBPS) + +#define ACCEPT_ALL_PHYS 0x01 +#define ACCEPT_ALL_MCASTS 0x02 +#define ACCEPT_ALL_BCASTS 0x04 +#define ACCEPT_ALL_ERRORS 0x08 +#define ACCEPT_CAM_QUALIFIED 0x10 +#define MAC_LOOPBACK 0x20 +//#define FDX_CAPABLE_FULL_SELECTED 4 +#define CRC_SIZE 4 +#define MAC_HEADER_SIZE 14 + +typedef struct _EuphLiteDesc { + u32 llink; + unsigned char* buf; + u32 physAddr; + /* Hardware sees the physical address of descriptor */ + u32 plink; + u32 cmdsts; + u32 bufPhys; +} EuphLiteDesc; + +struct sis900_private { + char devname[8]; /* Used only for kernel debugging. */ + const char *product_name; + struct net_device *next_module; + int chip_id; + int chip_revision; + unsigned char pci_bus, pci_devfn; +#if LINUX_VERSION_CODE > 0x20139 + struct net_device_stats stats; +#else + struct enet_statistics stats; +#endif + struct timer_list timer; /* Media selection timer. */ + unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ + unsigned int cur_tx, dirty_tx, tx_flag; + + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct sk_buff* tx_skbuff[NUM_TX_DESC]; + EuphLiteDesc tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */ + EuphLiteDesc rx_buf[NUM_RX_DESC]; + unsigned char *rx_bufs; + unsigned char *tx_bufs; /* Tx bounce buffer region. */ + char phys[4]; /* MII device addresses. */ + int phy_idx; /* Support Max 4 PHY */ + u16 pmd_status; + unsigned int tx_full; /* The Tx queue is full. */ + int MediaSpeed; /* user force speed */ + int MediaDuplex; /* user force duplex */ + int full_duplex; /* Full/Half-duplex. */ + int speeds; /* 100/10 Mbps. */ + u16 LinkOn; + u16 LinkChange; +}; + +#ifdef MODULE +#if LINUX_VERSION_CODE > 0x20115 +MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>"); +MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver"); +MODULE_PARM(speeds, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(multicast_filter_limit, "i"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(debug, "i"); +#endif +#endif + +static int sis900_open(struct net_device *dev); +static u16 read_eeprom(long ioaddr, int location); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int val); +static void sis900_timer(unsigned long data); +static void sis900_tx_timeout(struct net_device *dev); +static void sis900_init_ring(struct net_device *dev); +static int sis900_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int sis900_rx(struct net_device *dev); +static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static int sis900_close(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct enet_statistics *sis900_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); +static void sis900_reset(struct net_device *dev); +static u16 elAutoNegotiate(struct net_device *dev, int phy_id, int *duplex, int *speed); +static void elSetCapability(struct net_device *dev, int phy_id, int duplex, int speed); +static u16 elPMDreadMode(struct net_device *dev, int phy_id, int *speed, int *duplex); +static u16 elMIIpollBit(struct net_device *dev, int phy_id, int location, u16 mask, u16 polarity, u16 *value); +static void elSetMediaType(struct net_device *dev, int speed, int duplex); + +/* A list of all installed SiS900 devices, for removing the driver module. */ +static struct net_device *root_sis900_dev = NULL; + +/* Ideally we would detect all network cards in slot order. That would + be best done a central PCI probe dispatch, which wouldn't work + well when dynamically adding drivers. So instead we detect just the + SiS 900 cards in slot order. */ + +int sis900_probe(struct net_device *dev) +{ + int cards_found = 0; + int pci_index = 0; + unsigned char pci_bus, pci_device_fn; + + if ( ! pcibios_present()) + return -ENODEV; + + for (;pci_index < 0xff; pci_index++) { + u16 vendor, device, pci_command, new_command; + int chip_idx, irq; + long ioaddr; + + if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, + pci_index, + &pci_bus, &pci_device_fn) + != PCIBIOS_SUCCESSFUL) { + break; + } + pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, + &vendor); + pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, + &device); + + for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) + if (vendor == pci_tbl[chip_idx].vendor_id && + (device & pci_tbl[chip_idx].device_id_mask) == + pci_tbl[chip_idx].device_id) + break; + if (pci_tbl[chip_idx].vendor_id == 0) /* Compiled out! */ + continue; + + { + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->resource[0].start; + irq = pdev->irq; + } + + if ((pci_tbl[chip_idx].flags & PCI_USES_IO) && + check_region(ioaddr, pci_tbl[chip_idx].io_size)) + continue; + + /* Activate the card: fix for brain-damaged Win98 BIOSes. */ + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + new_command = pci_command | (pci_tbl[chip_idx].flags & 7); + if (pci_command != new_command) { + printk(KERN_INFO " The PCI BIOS has not enabled the" + " device at %d/%d!" + "Updating PCI command %4.4x->%4.4x.\n", + pci_bus, pci_device_fn, + pci_command, new_command); + + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, new_command); + } + + dev = pci_tbl[chip_idx].probe1(pci_bus, + pci_device_fn, + dev, + ioaddr, + irq, + chip_idx, + cards_found); + + if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) { + u8 pci_latency; + + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, &pci_latency); + + if (pci_latency < 32) { + printk(KERN_NOTICE " PCI latency timer (CFLT) is " + "unreasonably low at %d. Setting to 64 clocks.\n", + pci_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, 64); + } + } + dev = 0; + cards_found++; + } + return cards_found ? 0 : -ENODEV; +} + +static struct net_device * sis900_probe1( int pci_bus, + int pci_devfn, + struct net_device *dev, + long ioaddr, + int irq, + int chip_idx, + int found_cnt) +{ + static int did_version = 0; /* Already printed version info. */ + struct sis900_private *tp; + u16 status; + int duplex = found_cnt < MAX_UNITS ? full_duplex[found_cnt] : 0 ; + int speed = found_cnt < MAX_UNITS ? speeds[found_cnt] : 0 ; + int phy=0, phy_idx=0, i; + + if (did_version++ == 0) + printk(KERN_INFO "%s", version); + + dev = init_etherdev(dev, 0); + + if(dev==NULL) + return NULL; + + printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", + dev->name, pci_tbl[chip_idx].name, ioaddr, irq); + + if ((u16)read_eeprom(ioaddr, EuphLiteEEVendorID) != 0xffff) { + for (i = 0; i < 3; i++) + ((u16 *)(dev->dev_addr))[i] = + read_eeprom(ioaddr,i+EuphLiteEEMACAddr); + for (i = 0; i < 5; i++) + printk("%2.2x:", (u8)dev->dev_addr[i]); + printk("%2.2x.\n", dev->dev_addr[i]); + } else + printk(KERN_INFO "Error EEPROM read\n"); + + /* We do a request_region() to register /proc/ioports info. */ + request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name); + + dev->base_addr = ioaddr; + dev->irq = irq; + + /* Some data structures must be quadword aligned. */ + tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA); + if(tp==NULL) + { + release_region(ioaddr, pci_tbl[chip_idx].io_size); + return NULL; + } + memset(tp, 0, sizeof(*tp)); + dev->priv = tp; + + tp->next_module = root_sis900_dev; + root_sis900_dev = dev; + + tp->chip_id = chip_idx; + tp->pci_bus = pci_bus; + tp->pci_devfn = pci_devfn; + + /* Find the connected MII xcvrs. + Doing this in open() would allow detecting external xcvrs later, but + takes too much time. */ + if (sis_cap_tbl[chip_idx] & HAS_MII_XCVR) { + for (phy = 0, phy_idx = 0; + phy < 32 && phy_idx < sizeof(tp->phys); phy++) + { + int mii_status ; + mii_status = mdio_read(dev, phy, MII_STATUS); + + if (mii_status != 0xffff && mii_status != 0x0000) { + tp->phy_idx = phy_idx; + tp->phys[phy_idx++] = phy; + tp->pmd_status=mdio_read(dev, phy, MII_STATUS); + printk(KERN_INFO "%s: MII transceiver found " + "at address %d.\n", + dev->name, phy); + break; + } + } + + if (phy_idx == 0) { + printk(KERN_INFO "%s: No MII transceivers found!\n", + dev->name); + tp->phys[0] = -1; + tp->pmd_status = 0; + } + } else { + tp->phys[0] = -1; + tp->pmd_status = 0; + } + + if ((tp->pmd_status > 0) && (phy_idx > 0)) { + if (sis900_debug > 1) { + printk(KERN_INFO "duplex=%d, speed=%d\n", + duplex, speed); + } + if (!duplex && !speed) { + // auto-config media type + // Set full capability + if (sis900_debug > 1) { + printk(KERN_INFO "Auto Config ...\n"); + } + elSetCapability(dev, tp->phys[tp->phy_idx], 1, 100); + tp->pmd_status=elAutoNegotiate(dev, + tp->phys[tp->phy_idx], + &tp->full_duplex, + &tp->speeds); + } else { + tp->MediaSpeed = speed; + tp->MediaDuplex = duplex; + elSetCapability(dev, tp->phys[tp->phy_idx], + duplex, speed); + elAutoNegotiate(dev, tp->phys[tp->phy_idx], + &tp->full_duplex, + &tp->speeds); + status = mdio_read(dev, phy, MII_ANLPAR); + if ( !(status & (MII_NWAY_T | MII_NWAY_T_FDX | + MII_NWAY_TX | MII_NWAY_TX_FDX ))) + { + u16 cmd=0; + cmd |= ( speed == 100 ? + MIICNTL_SPEED : 0 ); + cmd |= ( duplex ? MIICNTL_FDX : 0 ); + mdio_write(dev, phy, MII_CONTROL, cmd); + elSetMediaType(dev, speed==100 ? + HW_SPEED_100_MBPS : + HW_SPEED_10_MBPS, + duplex ? + FDX_CAPABLE_FULL_SELECTED: + FDX_CAPABLE_HALF_SELECTED); + elMIIpollBit(dev, phy, MII_STATUS, + MIISTAT_LINK, TRUE, &status); + } else { + status = mdio_read(dev, phy, MII_STATUS); + } + } + + if (tp->pmd_status & MIISTAT_LINK) + tp->LinkOn = TRUE; + else + tp->LinkOn = FALSE; + + tp->LinkChange = FALSE; + + } + + if (sis900_debug > 1) { + if (tp->full_duplex == FDX_CAPABLE_FULL_SELECTED) { + printk(KERN_INFO "%s: Media type is Full Duplex.\n", + dev->name); + } else { + printk(KERN_INFO "%s: Media type is Half Duplex.\n", + dev->name); + } + if (tp->speeds == HW_SPEED_100_MBPS) { + printk(KERN_INFO "%s: Speed is 100mbps.\n", dev->name); + } else { + printk(KERN_INFO "%s: Speed is 10mbps.\n", dev->name); + } + } + + /* The SiS900-specific entries in the device structure. */ + dev->open = &sis900_open; + dev->hard_start_xmit = &sis900_start_xmit; + dev->stop = &sis900_close; + dev->get_stats = &sis900_get_stats; + dev->set_multicast_list = &set_rx_mode; + dev->do_ioctl = &mii_ioctl; + + return dev; +} + +/* Serial EEPROM section. */ + +/* EEPROM_Ctrl bits. */ +#define EECLK 0x00000004 /* EEPROM shift clock. */ +#define EECS 0x00000008 /* EEPROM chip select. */ +#define EEDO 0x00000002 /* EEPROM chip data out. */ +#define EEDI 0x00000001 /* EEPROM chip data in. */ + +/* Delay between EEPROM clock transitions. + No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. + */ + +#define eeprom_delay() inl(ee_addr) + +/* The EEPROM commands include the alway-set leading bit. */ +#define EEread 0x0180 +#define EEwrite 0x0140 +#define EEerase 0x01C0 +#define EEwriteEnable 0x0130 +#define EEwriteDisable 0x0100 +#define EEeraseAll 0x0120 +#define EEwriteAll 0x0110 +#define EEaddrMask 0x013F +#define EEcmdShift 16 + +static u16 read_eeprom(long ioaddr, int location) +{ + int i; + u16 retval = 0; + long ee_addr = ioaddr + mear; + u32 read_cmd = location | EEread; + + outl(0, ee_addr); + eeprom_delay(); + outl(EECLK, ee_addr); + eeprom_delay(); + + /* Shift the read command bits out. */ + for (i = 8; i >= 0; i--) { + u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS; + outl(dataval, ee_addr); + eeprom_delay(); + outl(dataval | EECLK, ee_addr); + eeprom_delay(); + } + outb(EECS, ee_addr); + eeprom_delay(); + + for (i = 16; i > 0; i--) { + outl(EECS, ee_addr); + eeprom_delay(); + outl(EECS | EECLK, ee_addr); + eeprom_delay(); + retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0); + eeprom_delay(); + } + + /* Terminate the EEPROM access. */ + outl(0, ee_addr); + eeprom_delay(); + outl(EECLK, ee_addr); + return (retval); +} + +/* MII serial management: mostly bogus for now. */ +/* Read and write the MII management registers using software-generated + serial MDIO protocol. + The maximum data clock rate is 2.5 Mhz. The minimum timing is usually + met by back-to-back PCI I/O cycles, but we insert a delay to avoid + "overclocking" issues. */ + +#define mdio_delay() inl(mdio_addr) + +#define MIIread 0x6000 +#define MIIwrite 0x6002 +#define MIIpmdMask 0x0F80 +#define MIIpmdShift 7 +#define MIIregMask 0x007C +#define MIIregShift 2 +#define MIIturnaroundBits 2 +#define MIIcmdLen 16 +#define MIIcmdShift 16 +#define MIIreset 0xFFFFFFFF +#define MIIwrLen 32 + +#define MDC 0x00000040 +#define MDDIR 0x00000020 +#define MDIO 0x00000010 + +static void mdio_idle(long mdio_addr) +{ + outl(MDIO | MDDIR, mdio_addr); + mdio_delay(); + outl(MDIO | MDDIR | MDC, mdio_addr); +} + +/* Syncronize the MII management interface by shifting 32 one bits out. */ +static void mdio_reset(long mdio_addr) +{ + int i; + + for (i = 31; i >= 0; i--) { + outl(MDDIR | MDIO, mdio_addr); + mdio_delay(); + outl(MDDIR | MDIO | MDC, mdio_addr); + mdio_delay(); + } + return; +} + +static int mdio_read(struct net_device *dev, int phy_id, int location) +{ + long mdio_addr = dev->base_addr + mear; + int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift); + int retval = 0; + int i; + + mdio_reset(mdio_addr); + mdio_idle(mdio_addr); + + for (i = 15; i >= 0; i--) { + int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; + outl(dataval, mdio_addr); + outl(dataval | MDC, mdio_addr); + } + + /* Read the two transition, 16 data, and wire-idle bits. */ + for (i = 16; i > 0; i--) { + outl(0, mdio_addr); + //mdio_delay(); + retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0); + outl(MDC, mdio_addr); + mdio_delay(); + } + return retval; +} + +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) +{ + long mdio_addr = dev->base_addr + mear; + int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift); + int i; + + mdio_reset(mdio_addr); + mdio_idle(mdio_addr); + + /* Shift the command bits out. */ + for (i = 31; i >= 0; i--) { + int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; + outb(dataval, mdio_addr); + mdio_delay(); + outb(dataval | MDC, mdio_addr); + mdio_delay(); + } + mdio_delay(); + /* Clear out extra bits. */ + for (i = 2; i > 0; i--) { + outb(0, mdio_addr); + mdio_delay(); + outb(MDC, mdio_addr); + mdio_delay(); + } + return; +} + +static int +sis900_open(struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + long ioaddr = dev->base_addr; + + if (sis900_debug > 0) + printk(KERN_INFO "%s sis900_open, IO Addr=%x, Irq=%x\n", + dev->name, (unsigned int)ioaddr, dev->irq); + + /* Soft reset the chip. */ + outl(0, ioaddr + imr); + outl(0, ioaddr + ier); + outl(0, ioaddr + rfcr); + outl(RESET | RxRESET | TxRESET, ioaddr + cr); + + if (request_irq(dev->irq, &sis900_interrupt, SA_SHIRQ, dev->name, dev)) + { + return -EAGAIN; + } + + MOD_INC_USE_COUNT; + + tp->tx_bufs = kmalloc(TX_BUF_SIZE * NUM_TX_DESC, GFP_KERNEL); + tp->rx_bufs = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL); + if (tp->tx_bufs == NULL || tp->rx_bufs == NULL) { + if (tp->tx_bufs) + kfree(tp->tx_bufs); + if (tp->rx_bufs) + kfree(tp->rx_bufs); + if (!tp->tx_bufs) { + printk(KERN_ERR "%s: Can't allocate a %d byte TX Bufs.\n", + dev->name, TX_BUF_SIZE * NUM_TX_DESC); + } + if (!tp->rx_bufs) { + printk(KERN_ERR "%s: Can't allocate a %d byte RX Bufs.\n", + dev->name, RX_BUF_SIZE * NUM_RX_DESC); + } + return -ENOMEM; + } + + { + u32 rfcrSave; + u32 w; + u32 i; + + rfcrSave = inl(rfcr); + outl(rfcrSave & ~RFEN, rfcr); + for (i=0 ; i<3 ; i++) { + w = (u16)*((u16*)(dev->dev_addr)+i); + outl((((u32) i) << RFEP_shift), ioaddr + rfcr); + outl((u32)w, ioaddr + rfdr); + if (sis900_debug > 4) { + printk(KERN_INFO "Filter Addr[%d]=%x\n", + i, inl(ioaddr + rfdr)); + } + } + outl(rfcrSave, rfcr); + } + + sis900_init_ring(dev); + outl((u32)tp->tx_buf[0].physAddr, ioaddr + txdp); + outl((u32)tp->rx_buf[0].physAddr, ioaddr + rxdp); + + if (sis900_debug > 4) + printk(KERN_INFO "txdp:%8.8x\n", inl(ioaddr + txdp)); + + /* Check that the chip has finished the reset. */ + { + u32 status; + int j=0; + status = TxRCMP | RxRCMP; + while (status && (j++ < 30000)) { + status ^= (inl(isr) & status); + } + } + + outl(PESEL, ioaddr + cfg); + + /* Must enable Tx/Rx before setting transfer thresholds! */ + /* + * #define TX_DMA_BURST 0 + * #define RX_DMA_BURST 0 + * #define TX_FIFO_THRESH 16 + * #define TxDRNT_100 (1536>>5) + * #define TxDRNT_10 (1536>>5) + * #define RxDRNT_100 (1536>>5) + * #define RxDRNT_10 (1536>>5) + */ + outl((RX_DMA_BURST<<20) | (RxDRNT_10 << 1), ioaddr+rxcfg); + outl(TxATP | (TX_DMA_BURST << 20) | (TX_FIFO_THRESH<<8) | TxDRNT_10, + ioaddr + txcfg); + if (sis900_debug > 1) + { + if (tp->LinkOn) { + printk(KERN_INFO"%s: Media Type %s%s-duplex.\n", + dev->name, + tp->speeds==HW_SPEED_100_MBPS ? + "100mbps " : "10mbps ", + tp->full_duplex== FDX_CAPABLE_FULL_SELECTED ? + "full" : "half"); + } + else printk(KERN_INFO"%s: Media Link Off\n", dev->name); + } + set_rx_mode(dev); + + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + /* Enable all known interrupts by setting the interrupt mask. */ + outl((RxOK|RxERR|RxORN|RxSOVR|TxOK|TxERR|TxURN), ioaddr + imr); + outl(RxENA, ioaddr + cr); + outl(IE, ioaddr + ier); + + if (sis900_debug > 3) + printk(KERN_INFO "%s: sis900_open() ioaddr %#lx IRQ %d \n", + dev->name, ioaddr, dev->irq); + + /* Set the timer to switch to check for link beat and perhaps switch + to an alternate media type. */ + init_timer(&tp->timer); + tp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */ + tp->timer.data = (unsigned long)dev; + tp->timer.function = &sis900_timer; /* timer handler */ + add_timer(&tp->timer); + + return 0; +} + +static void sis900_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct sis900_private *tp = (struct sis900_private *)dev->priv; + int next_tick = 0; + u16 status; + + if (!tp->LinkOn) { + status = mdio_read(dev, tp->phys[tp->phy_idx], MII_STATUS); + if (status & MIISTAT_LINK) { + elPMDreadMode(dev, tp->phys[tp->phy_idx], + &tp->speeds, &tp->full_duplex); + tp->LinkOn = TRUE; + printk(KERN_INFO "%s: Media Link On %s%s-duplex ", + dev->name, + tp->speeds == HW_SPEED_100_MBPS ? + "100mbps " : "10mbps ", + tp->full_duplex==FDX_CAPABLE_FULL_SELECTED ? + "full" : "half"); + } + } else { // previous link on + status = mdio_read(dev, tp->phys[tp->phy_idx], MII_STATUS); + if (!(status & MIISTAT_LINK)) { + tp->LinkOn = FALSE; + printk(KERN_INFO "%s: Media Link Off\n", dev->name); + } + } + next_tick = 2*HZ; + + if (next_tick) { + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); + } +} + +static void sis900_tx_timeout(struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + long ioaddr = dev->base_addr; + int i; + + if (sis900_debug > 0) + printk(KERN_INFO "%s: Transmit timeout, status %2.2x %4.4x \n", + dev->name, inl(ioaddr + cr), inl(ioaddr + isr)); + + /* Disable interrupts by clearing the interrupt mask. */ + outl(0x0000, ioaddr + imr); + + /* Emit info to figure out what went wrong. */ + if (sis900_debug > 1) { + printk(KERN_INFO "%s:Tx queue start entry %d dirty entry %d.\n", + dev->name, tp->cur_tx, tp->dirty_tx); + for (i = 0; i < NUM_TX_DESC; i++) + printk(KERN_INFO "%s: Tx descriptor %d is %8.8x.%s\n", + dev->name, i, (unsigned int)&tp->tx_buf[i], + i == tp->dirty_tx % NUM_TX_DESC ? + " (queue head)" : ""); + } + + /* Soft reset the chip. */ + //outb(RESET, ioaddr + cr); + /* Check that the chip has finished the reset. */ + /* + for (i = 1000; i > 0; i--) + if ((inb(ioaddr + cr) & RESET) == 0) + break; + */ + + tp->cur_rx = 0; + /* Must enable Tx/Rx before setting transfer thresholds! */ + /* + set_rx_mode(dev); + */ + { /* Save the unsent Tx packets. */ + struct sk_buff *saved_skb[NUM_TX_DESC], *skb; + int j; + for (j = 0; tp->cur_tx - tp->dirty_tx > 0 ; j++, tp->dirty_tx++) + saved_skb[j]=tp->tx_skbuff[tp->dirty_tx % NUM_TX_DESC]; + tp->dirty_tx = tp->cur_tx = 0; + + for (i = 0; i < j; i++) { + skb = tp->tx_skbuff[i] = saved_skb[i]; + /* Always alignment */ + memcpy((unsigned char*)(tp->tx_buf[i].buf), + skb->data, skb->len); + tp->tx_buf[i].cmdsts = OWN | skb->len; + /* Note: the chip doesn't have auto-pad! */ + /* + outl(tp->tx_flag|(skb->len>=ETH_ZLEN?skb->len:ETH_ZLEN), + ioaddr + TxStatus0 + i*4); + */ + } + outl(TxENA, ioaddr + cr); + tp->cur_tx = i; + while (i < NUM_TX_DESC) + tp->tx_skbuff[i++] = 0; + if (tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */ + dev->tbusy = 0; + tp->tx_full = 0; + } else { + tp->tx_full = 1; + } + } + + dev->trans_start = jiffies; + tp->stats.tx_errors++; + /* Enable all known interrupts by setting the interrupt mask. */ + outl((RxOK|RxERR|RxORN|RxSOVR|TxOK|TxERR|TxURN), ioaddr + imr); + return; +} + + +/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ +static void +sis900_init_ring(struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + int i; + + tp->tx_full = 0; + tp->cur_rx = 0; + tp->dirty_tx = tp->cur_tx = 0; + + /* Tx Buffer */ + for (i = 0; i < NUM_TX_DESC; i++) { + tp->tx_skbuff[i] = 0; + tp->tx_buf[i].buf = &tp->tx_bufs[i*TX_BUF_SIZE]; + tp->tx_buf[i].bufPhys = + virt_to_bus(&tp->tx_bufs[i*TX_BUF_SIZE]); + } + + /* Tx Descriptor */ + for (i = 0; i< NUM_TX_DESC; i++) { + tp->tx_buf[i].llink = (u32) + &(tp->tx_buf[((i+1) < NUM_TX_DESC) ? (i+1) : 0]); + tp->tx_buf[i].plink = (u32) + virt_to_bus(&(tp->tx_buf[((i+1) < NUM_TX_DESC) ? + (i+1) : 0].plink)); + tp->tx_buf[i].physAddr= + virt_to_bus(&(tp->tx_buf[i].plink)); + tp->tx_buf[i].cmdsts=0; + } + + /* Rx Buffer */ + for (i = 0; i < NUM_RX_DESC; i++) { + tp->rx_buf[i].buf = &tp->rx_bufs[i*RX_BUF_SIZE]; + tp->rx_buf[i].bufPhys = + virt_to_bus(&tp->rx_bufs[i*RX_BUF_SIZE]); + } + + /* Rx Descriptor */ + for (i = 0; i< NUM_RX_DESC; i++) { + tp->rx_buf[i].llink = (u32) + &(tp->rx_buf[((i+1) < NUM_RX_DESC) ? (i+1) : 0]); + tp->rx_buf[i].plink = (u32) + virt_to_bus(&(tp->rx_buf[((i+1) < NUM_RX_DESC) ? + (i+1) : 0].plink)); + tp->rx_buf[i].physAddr= + virt_to_bus(&(tp->rx_buf[i].plink)); + tp->rx_buf[i].cmdsts=RX_BUF_SIZE; + } +} + +static int +sis900_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + long ioaddr = dev->base_addr; + int entry; + + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + if (jiffies - dev->trans_start < TX_TIMEOUT) + return 1; + sis900_tx_timeout(dev); + return 1; + } + + /* Calculate the next Tx descriptor entry. ????? */ + entry = tp->cur_tx % NUM_TX_DESC; + + tp->tx_skbuff[entry] = skb; + + if (sis900_debug > 5) { + int i; + printk(KERN_INFO "%s: SKB Tx Frame contents:(len=%d)", + dev->name,skb->len); + + for (i = 0; i < skb->len; i++) { + printk("%2.2x ", + (u8)skb->data[i]); + } + printk(".\n"); + } + + memcpy(tp->tx_buf[entry].buf, + skb->data, skb->len); + + tp->tx_buf[entry].cmdsts=(OWN | skb->len); + + //tp->tx_buf[entry].plink = 0; + outl(TxENA, ioaddr + cr); + if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */ + clear_bit(0, (void*)&dev->tbusy); + } else { + tp->tx_full = 1; + } + + /* Note: the chip doesn't have auto-pad! */ + + dev->trans_start = jiffies; + if (sis900_debug > 4) + printk(KERN_INFO "%s: Queued Tx packet at " + "%p size %d to slot %d.\n", + dev->name, skb->data, (int)skb->len, entry); + + return 0; +} + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *)dev_instance; + struct sis900_private *tp = (struct sis900_private *)dev->priv; + int boguscnt = max_interrupt_work; + int status; + long ioaddr = dev->base_addr; + +#if defined(__i386__) + /* A lock to prevent simultaneous entry bug on Intel SMP machines. */ + if (test_and_set_bit(0, (void*)&dev->interrupt)) { + printk(KERN_INFO "%s: SMP simultaneous entry of " + "an interrupt handler.\n", dev->name); + dev->interrupt = 0; /* Avoid halting machine. */ + return; + } +#else + if (dev->interrupt) { + printk(KERN_INFO "%s: Re-entering the " + "interrupt handler.\n", dev->name); + return; + } + dev->interrupt = 1; +#endif + + do { + status = inl(ioaddr + isr); + /* Acknowledge all of the current interrupt sources ASAP. */ + outl(status, ioaddr + isr); // ????? + + if (sis900_debug > 4) + printk(KERN_INFO "%s: interrupt status=%#4.4x " + "new intstat=%#4.4x.\n", + dev->name, status, inl(ioaddr + isr)); + + if ((status & (TxURN|TxERR|TxOK | RxORN|RxERR|RxOK)) == 0) { + break; + } + + if (status & (RxOK|RxORN|RxERR)) /* Rx interrupt */ + sis900_rx(dev); + + if (status & (TxOK | TxERR)) { + unsigned int dirty_tx; + + if (sis900_debug > 5) { + printk(KERN_INFO "TxOK:tp->cur_tx:%d," + "tp->dirty_tx:%x\n", + tp->cur_tx, tp->dirty_tx); + } + for (dirty_tx = tp->dirty_tx; dirty_tx < tp->cur_tx; + dirty_tx++) + { + int i; + int entry = dirty_tx % NUM_TX_DESC; + int txstatus = tp->tx_buf[entry].cmdsts; + + if (sis900_debug > 4) { + printk(KERN_INFO "%s: Tx Frame contents:" + "(len=%d)", + dev->name, (txstatus & DSIZE)); + + for (i = 0; i < (txstatus & DSIZE) ; + i++) { + printk("%2.2x ", + (u8)(tp->tx_buf[entry].buf[i])); + } + printk(".\n"); + } + if ( ! (txstatus & (OK | UNDERRUN))) + { + if (sis900_debug > 1) + printk(KERN_INFO "Tx NOT (OK," + "UnderRun)\n"); + break; /* It still hasn't been Txed */ + } + + /* Note: TxCarrierLost is always asserted + at 100mbps. */ + if (txstatus & (OWCOLL | ABORT)) { + /* There was an major error, log it. */ + if (sis900_debug > 1) + printk(KERN_INFO "Tx Out of " + " Window,Abort\n"); +#ifndef final_version + if (sis900_debug > 1) + printk(KERN_INFO "%s: Transmit " + "error, Tx status %8.8x.\n", + dev->name, txstatus); +#endif + tp->stats.tx_errors++; + if (txstatus & ABORT) { + tp->stats.tx_aborted_errors++; + } + if (txstatus & NOCARRIER) + tp->stats.tx_carrier_errors++; + if (txstatus & OWCOLL) + tp->stats.tx_window_errors++; +#ifdef ETHER_STATS + if ((txstatus & COLCNT)==COLCNT) + tp->stats.collisions16++; +#endif + } else { +#ifdef ETHER_STATS + /* No count for tp->stats.tx_deferred */ +#endif + if (txstatus & UNDERRUN) { + if (sis900_debug > 2) + printk(KERN_INFO "Tx UnderRun\n"); + } + tp->stats.collisions += + (txstatus >> 16) & 0xF; +#if LINUX_VERSION_CODE > 0x20119 + tp->stats.tx_bytes += txstatus & DSIZE; +#endif + if (sis900_debug > 2) + printk(KERN_INFO "Tx Transmit OK\n"); + tp->stats.tx_packets++; + } + + /* Free the original skb. */ + if (sis900_debug > 2) + printk(KERN_INFO "Free original skb\n"); + dev_free_skb(tp->tx_skbuff[entry]); + tp->tx_skbuff[entry] = 0; + } // for dirty + +#ifndef final_version + if (tp->cur_tx - dirty_tx > NUM_TX_DESC) { + printk(KERN_INFO"%s: Out-of-sync dirty pointer," + " %d vs. %d, full=%d.\n", + dev->name, dirty_tx, + tp->cur_tx, tp->tx_full); + dirty_tx += NUM_TX_DESC; + } +#endif + + if (tp->tx_full && dirty_tx > tp->cur_tx-NUM_TX_DESC) { + /* The ring is no longer full, clear tbusy. */ + if (sis900_debug > 3) + printk(KERN_INFO "Tx Ring NO LONGER Full\n"); + tp->tx_full = 0; + dev->tbusy = 0; + mark_bh(NET_BH); + } + + tp->dirty_tx = dirty_tx; + if (sis900_debug > 2) + printk(KERN_INFO "TxOK,tp->cur_tx:%d,tp->dirty:%d\n", + tp->cur_tx, tp->dirty_tx); + } // if (TxOK | TxERR) + + /* Check uncommon events with one test. */ + if (status & (RxORN | TxERR | RxERR)) { + if (sis900_debug > 2) + printk(KERN_INFO "%s: Abnormal interrupt," + "status %8.8x.\n", dev->name, status); + + if (status == 0xffffffff) + break; + if (status & (RxORN | RxERR)) + tp->stats.rx_errors++; + + + if (status & RxORN) { + tp->stats.rx_over_errors++; + } + } + if (--boguscnt < 0) { + printk(KERN_INFO "%s: Too much work at interrupt, " + "IntrStatus=0x%4.4x.\n", + dev->name, status); + break; + } + } while (1); + + if (sis900_debug > 3) + printk(KERN_INFO "%s: exiting interrupt, intr_status=%#4.4x.\n", + dev->name, inl(ioaddr + isr)); + +#if defined(__i386__) + clear_bit(0, (void*)&dev->interrupt); +#else + dev->interrupt = 0; +#endif + return; +} + +/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the + field alignments and semantics. */ +static int sis900_rx(struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + long ioaddr = dev->base_addr; + u16 cur_rx = tp->cur_rx % NUM_RX_DESC; + int rx_status=tp->rx_buf[cur_rx].cmdsts; + + if (sis900_debug > 4) + printk(KERN_INFO "%s: sis900_rx, current %4.4x," + " rx status=%8.8x\n", + dev->name, cur_rx, + rx_status); + + while (rx_status & OWN) { + int rx_size = rx_status & DSIZE; + rx_size -= CRC_SIZE; + + if (sis900_debug > 4) { + int i; + printk(KERN_INFO "%s: sis900_rx, rx status %8.8x," + " size %4.4x, cur %4.4x.\n", + dev->name, rx_status, rx_size, cur_rx); + printk(KERN_INFO "%s: Rx Frame contents:", dev->name); + + for (i = 0; i < rx_size; i++) { + printk("%2.2x ", + (u8)(tp->rx_buf[cur_rx].buf[i])); + } + + printk(".\n"); + } + if (rx_status & TOOLONG) { + if (sis900_debug > 1) + printk(KERN_INFO "%s: Oversized Ethernet frame," + " status %4.4x!\n", + dev->name, rx_status); + tp->stats.rx_length_errors++; + } else if (rx_status & (RXISERR | RUNT | CRCERR | FAERR)) { + if (sis900_debug > 1) + printk(KERN_INFO"%s: Ethernet frame had errors," + " status %4.4x.\n", + dev->name, rx_status); + tp->stats.rx_errors++; + if (rx_status & (RXISERR | FAERR)) + tp->stats.rx_frame_errors++; + if (rx_status & (RUNT | TOOLONG)) + tp->stats.rx_length_errors++; + if (rx_status & CRCERR) tp->stats.rx_crc_errors++; + } else { + /* Malloc up new buffer, compatible with net-2e. */ + /* Omit the four octet CRC from the length. */ + struct sk_buff *skb; + + skb = dev_alloc_skb(rx_size + 2); + if (skb == NULL) { + printk(KERN_INFO "%s: Memory squeeze," + "deferring packet.\n", + dev->name); + /* We should check that some rx space is free. + If not, + free one and mark stats->rx_dropped++. */ + tp->stats.rx_dropped++; + tp->rx_buf[cur_rx].cmdsts = RX_BUF_SIZE; + break; + } + skb->dev = dev; + skb_reserve(skb, 2); /* 16 byte align the IP fields. */ + if (rx_size+CRC_SIZE > RX_BUF_SIZE) { + /* + int semi_count = RX_BUF_LEN - ring_offset - 4; + memcpy(skb_put(skb, semi_count), + &rx_bufs[ring_offset + 4], semi_count); + memcpy(skb_put(skb, rx_size-semi_count), + rx_bufs, rx_size - semi_count); + if (sis900_debug > 4) { + int i; + printk(KERN_DEBUG"%s: Frame wrap @%d", + dev->name, semi_count); + for (i = 0; i < 16; i++) + printk(" %2.2x", rx_bufs[i]); + printk(".\n"); + memset(rx_bufs, 0xcc, 16); + } + */ + } else { +#if 0 /* USE_IP_COPYSUM */ + eth_copy_and_sum(skb, + tp->rx_buf[cur_rx].buf, rx_size, 0); + skb_put(skb, rx_size); +#else + memcpy(skb_put(skb, rx_size), + tp->rx_buf[cur_rx].buf, rx_size); +#endif + } + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); +#if LINUX_VERSION_CODE > 0x20119 + tp->stats.rx_bytes += rx_size; +#endif + tp->stats.rx_packets++; + } + tp->rx_buf[cur_rx].cmdsts = RX_BUF_SIZE; + + cur_rx = ((cur_rx+1) % NUM_RX_DESC); + rx_status = tp->rx_buf[cur_rx].cmdsts; + } // while + if (sis900_debug > 4) + printk(KERN_INFO "%s: Done sis900_rx(), current %4.4x " + "Cmd %2.2x.\n", + dev->name, cur_rx, + inb(ioaddr + cr)); + tp->cur_rx = cur_rx; + return 0; +} + +static int +sis900_close(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct sis900_private *tp = (struct sis900_private *)dev->priv; + int i; + + dev->start = 0; + dev->tbusy = 1; + + if (sis900_debug > 1) + printk(KERN_DEBUG"%s: Shutting down ethercard, status was 0x%4.4x.\n", + dev->name, inl(ioaddr + isr)); + + /* Disable interrupts by clearing the interrupt mask. */ + outl(0x0000, ioaddr + imr); + + /* Stop the chip's Tx and Rx DMA processes. */ + outl(0x00, ioaddr + cr); + + del_timer(&tp->timer); + + free_irq(dev->irq, dev); + + for (i = 0; i < NUM_TX_DESC; i++) { + if (tp->tx_skbuff[i]) + dev_free_skb(tp->tx_skbuff[i]); + tp->tx_skbuff[i] = 0; + } + kfree(tp->rx_bufs); + kfree(tp->tx_bufs); + + /* Green! Put the chip in low-power mode. */ + + MOD_DEC_USE_COUNT; + + return 0; +} + +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + u16 *data = (u16 *)&rq->ifr_data; + + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + data[0] = tp->phys[tp->phy_idx]; + /* Fall Through */ + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f); + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + if (!suser()) + return -EPERM; + mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static struct enet_statistics * +sis900_get_stats(struct net_device *dev) +{ + struct sis900_private *tp = (struct sis900_private *)dev->priv; + + return &tp->stats; +} + +/* Set or clear the multicast filter for this adaptor. + This routine is not state sensitive and need not be SMP locked. */ + +static u16 elComputeHashTableIndex(u8 *addr) +{ +#define POLYNOMIAL 0x04C11DB6L + u32 crc = 0xffffffff, msb; + int i, j; + u8 byte; + + for( i=0; i<6; i++ ) { + byte = *addr++; + for( j=0; j<8; j++ ) { + msb = crc >> 31; + crc <<= 1; + if( msb ^ ( byte & 1 )) { + crc ^= POLYNOMIAL; + crc |= 1; + } + byte >>= 1; + } + } + // 7 bit crc for 128 bit hash table + return( (int)(crc >> 25) ); +} + +static u16 elMIIpollBit(struct net_device *dev, + int phy_id, + int location, + u16 mask, + u16 polarity, + u16 *value) +{ + u32 i; + i=0; + while (1) { + *value = mdio_read(dev, phy_id, location); + if (polarity) { + if (mask & *value) return(TRUE); + } else { + if (mask & ~(*value)) return(TRUE); + } + if (++i == 1200) break; + } + return(FALSE); +} + +static u16 elPMDreadMode(struct net_device *dev, + int phy_id, + int *speed, + int *duplex) +{ + u16 status, OurCap; + + *speed = HW_SPEED_10_MBPS; + *duplex = FDX_CAPABLE_HALF_SELECTED; + + status = mdio_read(dev, phy_id, MII_ANLPAR); + OurCap = mdio_read(dev, phy_id, MII_ANAR); + if (sis900_debug > 1) { + printk(KERN_INFO "Link Part Status %4X\n", status); + printk(KERN_INFO "Our Status %4X\n", OurCap); + printk(KERN_INFO "Status Reg %4X\n", + mdio_read(dev, phy_id, MII_STATUS)); + } + status &= OurCap; + + if ( !( status & + (MII_NWAY_T|MII_NWAY_T_FDX | MII_NWAY_TX | MII_NWAY_TX_FDX ))) { + if (sis900_debug > 1) { + printk(KERN_INFO "The other end NOT support NWAY...\n"); + } + while (( status = mdio_read(dev, phy_id, 18)) & 0x4000) ; + while (( status = mdio_read(dev, phy_id, 18)) & 0x0020) ; + if (status & 0x80) + *speed = HW_SPEED_100_MBPS; + if (status & 0x40) + *duplex = FDX_CAPABLE_FULL_SELECTED; + if (sis900_debug > 3) { + printk(KERN_INFO"%s: Setting %s%s-duplex.\n", + dev->name, + *speed == HW_SPEED_100_MBPS ? + "100mbps " : "10mbps ", + *duplex == FDX_CAPABLE_FULL_SELECTED ? + "full" : "half"); + } + } else { + if (sis900_debug > 1) { + printk(KERN_INFO "The other end support NWAY...\n"); + } + + if (status & (MII_NWAY_TX_FDX | MII_NWAY_T_FDX)) { + *duplex = FDX_CAPABLE_FULL_SELECTED; + } + if (status & (MII_NWAY_TX_FDX | MII_NWAY_TX)) { + *speed = HW_SPEED_100_MBPS; + } + if (sis900_debug > 3) { + printk(KERN_INFO"%s: Setting %s%s-duplex based on" + " auto-negotiated partner ability.\n", + dev->name, + *speed == HW_SPEED_100_MBPS ? + "100mbps " : "10mbps ", + *duplex == FDX_CAPABLE_FULL_SELECTED ? + "full" : "half"); + } + } + return (status); +} + +static u16 elAutoNegotiate(struct net_device *dev, int phy_id, int *duplex, int *speed) +{ + u16 status, retnVal; + + if (sis900_debug > 1) { + printk(KERN_INFO "AutoNegotiate...\n"); + } + mdio_write(dev, phy_id, MII_CONTROL, 0); + mdio_write(dev, phy_id, MII_CONTROL, MIICNTL_AUTO | MIICNTL_RST_AUTO); + retnVal = elMIIpollBit(dev, phy_id, MII_CONTROL, MIICNTL_RST_AUTO, + FALSE,&status); + if (!retnVal) { + printk(KERN_INFO "Not wait for Reset Complete\n"); + } + retnVal = elMIIpollBit(dev, phy_id, MII_STATUS, MIISTAT_AUTO_DONE, + TRUE, &status); + if (!retnVal) { + printk(KERN_INFO "Not wait for AutoNego Complete\n"); + } + retnVal = elMIIpollBit(dev, phy_id, MII_STATUS, MIISTAT_LINK, + TRUE, &status); + if (!retnVal) { + printk(KERN_INFO "Not wait for Link Complete\n"); + } + if (status & MIISTAT_LINK) { + elPMDreadMode(dev, phy_id, speed, duplex); + elSetMediaType(dev, *speed, *duplex); + } + return(status); +} + +static void elSetCapability(struct net_device *dev, int phy_id, + int duplex, int speed) +{ + u16 cap = ( MII_NWAY_T | MII_NWAY_T_FDX | + MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_CSMA_CD ); + + if (speed != 100) { + cap &= ~( MII_NWAY_TX | MII_NWAY_TX_FDX ); + if (sis900_debug > 1) { + printk(KERN_INFO "UNSET 100Mbps\n"); + } + } + + if (!duplex) { + cap &= ~( MII_NWAY_T_FDX | MII_NWAY_TX_FDX ); + if (sis900_debug > 1) { + printk(KERN_INFO "UNSET full-duplex\n"); + } + } + + mdio_write(dev, phy_id, MII_ANAR, cap); +} + +static void elSetMediaType(struct net_device *dev, int speed, int duplex) +{ + long ioaddr = dev->base_addr; + u32 txCfgOn = 0, txCfgOff = TxDRNT; + u32 rxCfgOn = 0, rxCfgOff = 0; + + if (speed == HW_SPEED_100_MBPS) { + txCfgOn |= (TxDRNT_100 | TxHBI); + } else { + txCfgOn |= TxDRNT_10; + } + + if (duplex == FDX_CAPABLE_FULL_SELECTED) { + txCfgOn |= (TxCSI | TxHBI); + rxCfgOn |= RxATP; + } else { + txCfgOff |= (TxCSI | TxHBI); + rxCfgOff |= RxATP; + } + outl( (inl(ioaddr + txcfg) & ~txCfgOff) | txCfgOn, ioaddr + txcfg); + outl( (inl(ioaddr + rxcfg) & ~rxCfgOff) | rxCfgOn, ioaddr + rxcfg); +} + +static void set_rx_mode(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + u16 mc_filter[8]; + int i; + int rx_mode; + u32 rxCfgOn = 0, rxCfgOff = 0; + u32 txCfgOn = 0, txCfgOff = 0; + + if (sis900_debug > 3) + printk(KERN_INFO "%s: set_rx_mode (%4.4x) done--" + "RxCfg %8.8x.\n", + dev->name, dev->flags, inl(ioaddr + rxcfg)); + + /* Note: do not reorder, GCC is clever about common statements. */ + if (dev->flags & IFF_PROMISC) { + printk(KERN_NOTICE"%s: Promiscuous mode enabled.\n", dev->name); + rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS | + ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_PHYS; + for (i=0 ; i<8 ; i++) + mc_filter[i]=0xffff; + } else if ((dev->mc_count > multicast_filter_limit) + || (dev->flags & IFF_ALLMULTI)) { + rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS | + ACCEPT_CAM_QUALIFIED; + for (i=0 ; i<8 ; i++) + mc_filter[i]=0xffff; + } else { + struct dev_mc_list *mclist; + rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS | + ACCEPT_CAM_QUALIFIED; + for (i=0 ; i<8 ; i++) + mc_filter[i]=0; + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) + set_bit(elComputeHashTableIndex(mclist->dmi_addr), + mc_filter); + } + + for (i=0 ; i<8 ; i++) { + outl((u32)(0x00000004+i) << 16, ioaddr + rfcr); + outl(mc_filter[i], ioaddr + rfdr); + } + /* We can safely update without stopping the chip. */ + //rx_mode = ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_BCASTS | ACCEPT_ALL_PHYS; + //rx_mode = ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_BCASTS; + outl(RFEN | ((rx_mode & (ACCEPT_ALL_MCASTS | ACCEPT_ALL_BCASTS | + ACCEPT_ALL_PHYS)) << RFAA_shift), ioaddr + rfcr); + + if (rx_mode & ACCEPT_ALL_ERRORS) { + rxCfgOn = RxAEP | RxARP | RxAJAB; + } else { + rxCfgOff = RxAEP | RxARP | RxAJAB; + } + if (rx_mode & MAC_LOOPBACK) { + rxCfgOn |= RxATP; + txCfgOn |= TxMLB; + } else { + if (!(( (struct sis900_private *)(dev->priv) )->full_duplex)) + rxCfgOff |= RxATP; + txCfgOff |= TxMLB; + } + + if (sis900_debug > 2) { + printk(KERN_INFO "Before Set TxCfg=%8.8x\n",inl(ioaddr+txcfg)); + printk(KERN_INFO "Before Set RxCfg=%8.8x\n",inl(ioaddr+rxcfg)); + } + + outl((inl(ioaddr + rxcfg) | rxCfgOn) & ~rxCfgOff, ioaddr + rxcfg); + outl((inl(ioaddr + txcfg) | txCfgOn) & ~txCfgOff, ioaddr + txcfg); + + if (sis900_debug > 2) { + printk(KERN_INFO "After Set TxCfg=%8.8x\n",inl(ioaddr+txcfg)); + printk(KERN_INFO "After Set RxCfg=%8.8x\n",inl(ioaddr+rxcfg)); + printk(KERN_INFO "Receive Filter Register:%8.8x\n", + inl(ioaddr + rfcr)); + } + return; +} + +static void sis900_reset(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + + outl(0, ioaddr + ier); + outl(0, ioaddr + imr); + outl(0, ioaddr + rfcr); + + outl(RxRESET | TxRESET | RESET, ioaddr + cr); + outl(PESEL, ioaddr + cfg); + + set_rx_mode(dev); +} + +#ifdef MODULE +int init_module(void) +{ + return sis900_probe(0); +} + +void +cleanup_module(void) +{ + struct net_device *next_dev; + + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ + while (root_sis900_dev) { + struct sis900_private *tp = + (struct sis900_private *)root_sis900_dev->priv; + next_dev = tp->next_module; + unregister_netdev(root_sis900_dev); + release_region(root_sis900_dev->base_addr, + pci_tbl[tp->chip_id].io_size); + kfree(tp); + kfree(root_sis900_dev); + root_sis900_dev = next_dev; + } +} + +#endif /* MODULE */ +/* + * Local variables: + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c sis900.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c sis900.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c index 244df7544..9c57cb269 100644 --- a/drivers/net/sk_g16.c +++ b/drivers/net/sk_g16.c @@ -466,28 +466,28 @@ static SK_RAM *board; /* pointer to our memory mapped board components */ * See for short explanation of each function its definitions header. */ -int SK_init(struct device *dev); -static int SK_probe(struct device *dev, short ioaddr); +int SK_init(struct net_device *dev); +static int SK_probe(struct net_device *dev, short ioaddr); -static int SK_open(struct device *dev); -static int SK_send_packet(struct sk_buff *skb, struct device *dev); +static int SK_open(struct net_device *dev); +static int SK_send_packet(struct sk_buff *skb, struct net_device *dev); static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs); -static void SK_rxintr(struct device *dev); -static void SK_txintr(struct device *dev); -static int SK_close(struct device *dev); +static void SK_rxintr(struct net_device *dev); +static void SK_txintr(struct net_device *dev); +static int SK_close(struct net_device *dev); -static struct net_device_stats *SK_get_stats(struct device *dev); +static struct net_device_stats *SK_get_stats(struct net_device *dev); unsigned int SK_rom_addr(void); -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); /* * LANCE Functions * --------------- */ -static int SK_lance_init(struct device *dev, unsigned short mode); +static int SK_lance_init(struct net_device *dev, unsigned short mode); void SK_reset_board(void); void SK_set_RAP(int reg_number); int SK_read_reg(int reg_number); @@ -499,9 +499,9 @@ void SK_write_reg(int reg_number, int value); * ------------------- */ -void SK_print_pos(struct device *dev, char *text); -void SK_print_dev(struct device *dev, char *text); -void SK_print_ram(struct device *dev); +void SK_print_pos(struct net_device *dev, char *text); +void SK_print_dev(struct net_device *dev, char *text); +void SK_print_ram(struct net_device *dev); /*- @@ -513,7 +513,7 @@ void SK_print_ram(struct device *dev); * This function gets called by dev_init which initializes * all Network devices. * - * Parameters : I : struct device *dev - structure preconfigured + * Parameters : I : struct net_device *dev - structure preconfigured * from Space.c * Return Value : 0 = Driver Found and initialized * Errors : ENODEV - no device found @@ -531,7 +531,7 @@ void SK_print_ram(struct device *dev); * (detachable devices only). */ -__initfunc(int SK_init(struct device *dev)) +int __init SK_init(struct net_device *dev) { int ioaddr = 0; /* I/O port address used for POS regs */ int *port, ports[] = SK_IO_PORTS; /* SK_G16 supported ports */ @@ -603,7 +603,7 @@ __initfunc(int SK_init(struct device *dev)) * Description : This function is called by SK_init and * does the main part of initialization. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : short ioaddr - I/O Port address where POS is. * Return Value : 0 = Initialization done * Errors : ENODEV - No SK_G16 found @@ -614,7 +614,7 @@ __initfunc(int SK_init(struct device *dev)) * 94/06/30 pwe SK_ADDR now checked and at the correct place -*/ -__initfunc(int SK_probe(struct device *dev, short ioaddr)) +int __init SK_probe(struct net_device *dev, short ioaddr) { int i,j; /* Counters */ int sk_addr_flag = 0; /* SK ADDR correct? 1 - no, 0 - yes */ @@ -832,7 +832,7 @@ __initfunc(int SK_probe(struct device *dev, short ioaddr)) * * (Called by dev_open() /net/inet/dev.c) * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : 0 - Device opened * Errors : -EAGAIN - Open failed * Side Effects : None @@ -840,7 +840,7 @@ __initfunc(int SK_probe(struct device *dev, short ioaddr)) * YY/MM/DD uid Description -*/ -static int SK_open(struct device *dev) +static int SK_open(struct net_device *dev) { int i = 0; int irqval = 0; @@ -994,7 +994,7 @@ static int SK_open(struct device *dev) * Description : Reset LANCE chip, fill RMD, TMD structures with * start values and Start LANCE. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : int mode - put LANCE into "mode" see data-sheet for * more info. * Return Value : 0 - Init done @@ -1003,7 +1003,7 @@ static int SK_open(struct device *dev) * YY/MM/DD uid Description -*/ -static int SK_lance_init(struct device *dev, unsigned short mode) +static int SK_lance_init(struct net_device *dev, unsigned short mode) { int i; unsigned long flags; @@ -1161,7 +1161,7 @@ static int SK_lance_init(struct device *dev, unsigned short mode) * and starts transmission. * * Parameters : I : struct sk_buff *skb - packet to transfer - * I : struct device *dev - SK_G16 device structure + * I : struct net_device *dev - SK_G16 device structure * Return Value : 0 - OK * 1 - Could not transmit (dev_queue_xmit will queue it) * and try to sent it later @@ -1171,7 +1171,7 @@ static int SK_lance_init(struct device *dev, unsigned short mode) * YY/MM/DD uid Description -*/ -static int SK_send_packet(struct sk_buff *skb, struct device *dev) +static int SK_send_packet(struct sk_buff *skb, struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; struct tmd *tmdp; @@ -1278,7 +1278,7 @@ static int SK_send_packet(struct sk_buff *skb, struct device *dev) static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int csr0; - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct priv *p = (struct priv *) dev->priv; @@ -1342,7 +1342,7 @@ static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs) * statistics and relinquish ownership of transmit * descriptor ring. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : None * Errors : None * Globals : None @@ -1350,7 +1350,7 @@ static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs) * YY/MM/DD uid Description -*/ -static void SK_txintr(struct device *dev) +static void SK_txintr(struct net_device *dev) { int tmdstat; struct tmd *tmdp; @@ -1470,7 +1470,7 @@ static void SK_txintr(struct device *dev) * YY/MM/DD uid Description -*/ -static void SK_rxintr(struct device *dev) +static void SK_rxintr(struct net_device *dev) { struct rmd *rmdp; @@ -1607,7 +1607,7 @@ static void SK_rxintr(struct device *dev) * Description : close gets called from dev_close() and should * deinstall the card (free_irq, mem etc). * - * Parameters : I : struct device *dev - our device structure + * Parameters : I : struct net_device *dev - our device structure * Return Value : 0 - closed device driver * Errors : None * Globals : None @@ -1619,7 +1619,7 @@ static void SK_rxintr(struct device *dev) * down' the system stops. So I don't shut set card to init state. */ -static int SK_close(struct device *dev) +static int SK_close(struct net_device *dev) { PRINTK(("## %s: SK_close(). CSR0: %#06x\n", @@ -1648,7 +1648,7 @@ static int SK_close(struct device *dev) * Description : Return current status structure to upper layers. * It is called by sprintf_stats (dev.c). * - * Parameters : I : struct device *dev - our device structure + * Parameters : I : struct net_device *dev - our device structure * Return Value : struct net_device_stats * - our current statistics * Errors : None * Side Effects : None @@ -1656,7 +1656,7 @@ static int SK_close(struct device *dev) * YY/MM/DD uid Description -*/ -static struct net_device_stats *SK_get_stats(struct device *dev) +static struct net_device_stats *SK_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1684,7 +1684,7 @@ static struct net_device_stats *SK_get_stats(struct device *dev) * but it is also a security problem. You have to remember * that all information on the net is not encrypted. * - * Parameters : I : struct device *dev - SK_G16 device Structure + * Parameters : I : struct net_device *dev - SK_G16 device Structure * Return Value : None * Errors : None * Globals : None @@ -1697,7 +1697,7 @@ static struct net_device_stats *SK_get_stats(struct device *dev) /* Set or clear the multicast filter for SK_G16. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if (dev->flags&IFF_PROMISC) @@ -1737,7 +1737,7 @@ static void set_multicast_list(struct device *dev) * YY/MM/DD uid Description -*/ -__initfunc(unsigned int SK_rom_addr(void)) +unsigned int __init SK_rom_addr(void) { int i,j; int rom_found = 0; @@ -1949,7 +1949,7 @@ void SK_write_reg(int reg_number, int value) * Description : This function prints out the 4 POS (Programmable * Option Select) Registers. Used mainly to debug operation. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : char * - Text which will be printed as title * Return Value : None * Errors : None @@ -1957,7 +1957,7 @@ void SK_write_reg(int reg_number, int value) * YY/MM/DD uid Description -*/ -void SK_print_pos(struct device *dev, char *text) +void SK_print_pos(struct net_device *dev, char *text) { int ioaddr = dev->base_addr; @@ -1984,7 +1984,7 @@ void SK_print_pos(struct device *dev, char *text) * Description : This function simply prints out the important fields * of the device structure. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : char *text - Title for printing * Return Value : None * Errors : None @@ -1992,7 +1992,7 @@ void SK_print_pos(struct device *dev, char *text) * YY/MM/DD uid Description -*/ -void SK_print_dev(struct device *dev, char *text) +void SK_print_dev(struct net_device *dev, char *text) { if (dev == NULL) { @@ -2027,7 +2027,7 @@ void SK_print_dev(struct device *dev, char *text) * It contains a minor bug in printing, but has no effect to the values * only newlines are not correct. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : None * Errors : None * Globals : None @@ -2035,7 +2035,7 @@ void SK_print_dev(struct device *dev, char *text) * YY/MM/DD uid Description -*/ -void SK_print_ram(struct device *dev) +void SK_print_ram(struct net_device *dev) { int i; diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index 720b50beb..c11248958 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -62,9 +62,14 @@ History: implemented LANCE multicast filter Jun 6th, 1999 additions for Linux 2.2 + Aug 2nd, 1999 + small fixes (David Weinehall) *************************************************************************/ +#include <linux/module.h> +#include <linux/version.h> + #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> @@ -79,11 +84,6 @@ History: #include <asm/bitops.h> #include <asm/io.h> -#ifdef MODULE -#include <linux/module.h> -#include <linux/version.h> -#endif - #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> @@ -110,7 +110,7 @@ static unsigned char poly[] = /* dump parts of shared memory - only needed during debugging */ #ifdef DEBUG -static void dumpmem(struct device *dev, u32 start, u32 len) +static void dumpmem(struct net_device *dev, u32 start, u32 len) { int z; @@ -199,7 +199,7 @@ static int dofind(int *junior, int firstslot) /* reset the whole board */ -static void ResetBoard(struct device *dev) +static void ResetBoard(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; @@ -210,7 +210,7 @@ static void ResetBoard(struct device *dev) /* set LANCE register - must be atomic */ -static void SetLANCE(struct device *dev, u16 addr, u16 value) +static void SetLANCE(struct net_device *dev, u16 addr, u16 value) { skmca_priv *priv = (skmca_priv*) dev->priv; unsigned long flags; @@ -247,7 +247,7 @@ static void SetLANCE(struct device *dev, u16 addr, u16 value) /* get LANCE register */ -static u16 GetLANCE(struct device *dev, u16 addr) +static u16 GetLANCE(struct net_device *dev, u16 addr) { skmca_priv *priv = (skmca_priv*) dev->priv; unsigned long flags; @@ -287,7 +287,7 @@ static u16 GetLANCE(struct device *dev, u16 addr) /* build up descriptors in shared RAM */ -static void InitDscrs(struct device *dev) +static void InitDscrs(struct net_device *dev) { u32 bufaddr; @@ -381,7 +381,7 @@ static unsigned int GetHash(char *address) /* feed ready-built initialization block into LANCE */ -static void InitLANCE(struct device *dev) +static void InitLANCE(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; @@ -420,7 +420,7 @@ static void InitLANCE(struct device *dev) /* stop the LANCE so we can reinitialize it */ -static void StopLANCE(struct device *dev) +static void StopLANCE(struct net_device *dev) { /* can't take frames any more */ @@ -433,7 +433,7 @@ static void StopLANCE(struct device *dev) /* initialize card and LANCE for proper operation */ -static void InitBoard(struct device *dev) +static void InitBoard(struct net_device *dev) { LANCE_InitBlock block; @@ -458,7 +458,7 @@ static void InitBoard(struct device *dev) /* deinitialize card and LANCE */ -static void DeinitBoard(struct device *dev) +static void DeinitBoard(struct net_device *dev) { /* stop LANCE */ @@ -475,7 +475,7 @@ static void DeinitBoard(struct device *dev) /* LANCE has read initializazion block -> start it */ -static u16 irqstart_handler(struct device *dev, u16 oldcsr0) +static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0) { /* now we're ready to transmit */ @@ -489,7 +489,7 @@ static u16 irqstart_handler(struct device *dev, u16 oldcsr0) /* receive interrupt */ -static u16 irqrx_handler(struct device *dev, u16 oldcsr0) +static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_RxDescr descr; @@ -575,7 +575,7 @@ static u16 irqrx_handler(struct device *dev, u16 oldcsr0) /* transmit interrupt */ -static u16 irqtx_handler(struct device *dev, u16 oldcsr0) +static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_TxDescr descr; @@ -653,7 +653,7 @@ static u16 irqtx_handler(struct device *dev, u16 oldcsr0) static void irq_handler(int irq, void *device, struct pt_regs *regs) { - struct device *dev = (struct device*) device; + struct net_device *dev = (struct net_device*) device; u16 csr0val; /* read CSR0 to get interrupt cause */ @@ -692,7 +692,7 @@ static void irq_handler(int irq, void *device, struct pt_regs *regs) static int skmca_getinfo(char *buf, int slot, void *d) { int len = 0, i; - struct device *dev = (struct device*) d; + struct net_device *dev = (struct net_device*) d; skmca_priv *priv; /* can't say anything about an uninitialized device... */ @@ -721,7 +721,7 @@ static int skmca_getinfo(char *buf, int slot, void *d) /* open driver. Means also initialization and start of LANCE */ -static int skmca_open(struct device *dev) +static int skmca_open(struct net_device *dev) { int result; skmca_priv *priv = (skmca_priv*) dev->priv; @@ -748,7 +748,7 @@ static int skmca_open(struct device *dev) /* close driver. Shut down board and free allocated resources */ -static int skmca_close(struct device *dev) +static int skmca_close(struct net_device *dev) { /* turn off board */ DeinitBoard(dev); @@ -767,7 +767,7 @@ static int skmca_close(struct device *dev) /* transmit a block. */ -static int skmca_tx(struct sk_buff *skb, struct device *dev) +static int skmca_tx(struct sk_buff *skb, struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_TxDescr descr; @@ -864,17 +864,17 @@ tx_done: /* return pointer to Ethernet statistics */ -static struct enet_statistics *skmca_stats(struct device *dev) +static struct enet_statistics *skmca_stats(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; return &(priv->stat); } -/* we don't support runtime reconfiguration, since am MCA card can +/* we don't support runtime reconfiguration, since an MCA card can be unambigously identified by its POS registers. */ -static int skmca_config(struct device *dev, struct ifmap *map) +static int skmca_config(struct net_device *dev, struct ifmap *map) { return 0; } @@ -882,7 +882,7 @@ static int skmca_config(struct device *dev, struct ifmap *map) /* switch receiver mode. We use the LANCE's multicast filter to prefilter multicast addresses. */ -static void skmca_set_multicast_list(struct device *dev) +static void skmca_set_multicast_list(struct net_device *dev) { LANCE_InitBlock block; @@ -929,7 +929,7 @@ static int startslot; /* counts through slots when probing multiple devices */ #define startslot 0 /* otherwise a dummy, since there is only eth0 in-kern*/ #endif -int skmca_probe(struct device *dev) +int skmca_probe(struct net_device *dev) { int force_detect = 0; int junior, slot, i; @@ -962,9 +962,6 @@ int skmca_probe(struct device *dev) getaddrs(slot, junior, &base, &irq, &medium); -#if 0 - /* this should work, but it doesn't with 2.2.9 :-( - somehow 'mca_is_adapter_used()' is missing in kernel syms... */ #if LINUX_VERSION_CODE >= 0x020200 /* slot already in use ? */ @@ -974,7 +971,6 @@ int skmca_probe(struct device *dev) continue; } #endif -#endif /* were we looking for something different ? */ @@ -1082,7 +1078,7 @@ int skmca_probe(struct device *dev) #define DEVMAX 5 static char NameSpace[8 * DEVMAX]; -static struct device moddevs[DEVMAX] = +static struct net_device moddevs[DEVMAX] = {{NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, {NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, {NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, @@ -1110,7 +1106,7 @@ int init_module(void) void cleanup_module(void) { - struct device *dev; + struct net_device *dev; skmca_priv *priv; int z; diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h index f45aadf61..089f11ade 100644 --- a/drivers/net/sk_mca.h +++ b/drivers/net/sk_mca.h @@ -168,7 +168,7 @@ typedef struct /* LANCE Rx descriptor */ #endif /* _SK_MCA_DRIVER_ */ -extern int skmca_probe(struct device *); +extern int skmca_probe(struct net_device *); #endif /* _SK_MCA_INCLUDE_ */
\ No newline at end of file diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index 1ba460691..5b3cfabab 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -96,21 +96,21 @@ struct net_local { /* Index to functions, as function prototypes. */ -extern int netcard_probe(struct device *dev); +extern int netcard_probe(struct net_device *dev); -static int netcard_probe1(struct device *dev, int ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int netcard_probe1(struct net_device *dev, int ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Example routines you must write ;->. */ #define tx_done(dev) 1 extern void hardware_send_packet(short ioaddr, char *buf, int length); -extern void chipset_init(struct device *dev, int startp); +extern void chipset_init(struct net_device *dev, int startp); /* * Check for a network adaptor of this type, and return '0' iff one exists. @@ -127,8 +127,8 @@ extern void chipset_init(struct device *dev, int startp); struct netdev_entry netcard_drv = {cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -__initfunc(int -netcard_probe(struct device *dev)) +int __init +netcard_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -155,7 +155,7 @@ netcard_probe(struct device *dev)) * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -__initfunc(static int netcard_probe1(struct device *dev, int ioaddr)) +static int __init netcard_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i; @@ -306,7 +306,7 @@ __initfunc(static int netcard_probe1(struct device *dev, int ioaddr)) * there is non-reboot way to recover if something goes wrong. */ static int -net_open(struct device *dev) +net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -340,7 +340,7 @@ net_open(struct device *dev) return 0; } -static int net_send_packet(struct sk_buff *skb, struct device *dev) +static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -389,7 +389,7 @@ static int net_send_packet(struct sk_buff *skb, struct device *dev) */ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; @@ -425,7 +425,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -480,7 +480,7 @@ net_rx(struct device *dev) /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -512,7 +512,7 @@ net_close(struct device *dev) * Get the current statistics. * This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -533,7 +533,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) * and do best-effort filtering. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; if (dev->flags&IFF_PROMISC) @@ -562,7 +562,7 @@ set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device this_device = { +static struct net_device this_device = { devicename, /* will be inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff --git a/drivers/net/sktr.c b/drivers/net/sktr.c index a5e64eae9..f9b877f66 100644 --- a/drivers/net/sktr.c +++ b/drivers/net/sktr.c @@ -116,63 +116,63 @@ static unsigned int sktr_debug = SKTR_DEBUG; */ /* "B" */ -static int sktr_bringup_diags(struct device *dev); +static int sktr_bringup_diags(struct net_device *dev); /* "C" */ static void sktr_cancel_tx_queue(struct net_local* tp); -static int sktr_chipset_init(struct device *dev); -static void sktr_chk_irq(struct device *dev); -static unsigned char sktr_chk_frame(struct device *dev, unsigned char *Addr); -static void sktr_chk_outstanding_cmds(struct device *dev); +static int sktr_chipset_init(struct net_device *dev); +static void sktr_chk_irq(struct net_device *dev); +static unsigned char sktr_chk_frame(struct net_device *dev, unsigned char *Addr); +static void sktr_chk_outstanding_cmds(struct net_device *dev); static void sktr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr); static unsigned char sktr_chk_ssb(struct net_local *tp, unsigned short IrqType); -static int sktr_close(struct device *dev); -static void sktr_cmd_status_irq(struct device *dev); +static int sktr_close(struct net_device *dev); +static void sktr_cmd_status_irq(struct net_device *dev); /* "D" */ -static void sktr_disable_interrupts(struct device *dev); +static void sktr_disable_interrupts(struct net_device *dev); static void sktr_dump(unsigned char *Data, int length); /* "E" */ -static void sktr_enable_interrupts(struct device *dev); -static void sktr_exec_cmd(struct device *dev, unsigned short Command); -static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue); +static void sktr_enable_interrupts(struct net_device *dev); +static void sktr_exec_cmd(struct net_device *dev, unsigned short Command); +static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); /* "F" */ static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen); /* "G" */ -static struct enet_statistics *sktr_get_stats(struct device *dev); +static struct enet_statistics *sktr_get_stats(struct net_device *dev); /* "H" */ -static void sktr_hardware_send_packet(struct device *dev, +static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp); /* "I" */ -static int sktr_init_adapter(struct device *dev); -static int sktr_init_card(struct device *dev); +static int sktr_init_adapter(struct net_device *dev); +static int sktr_init_card(struct net_device *dev); static void sktr_init_ipb(struct net_local *tp); -static void sktr_init_net_local(struct device *dev); +static void sktr_init_net_local(struct net_device *dev); static void sktr_init_opb(struct net_local *tp); static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int sktr_isa_chk_card(struct device *dev, int ioaddr); +static int sktr_isa_chk_card(struct net_device *dev, int ioaddr); static int sktr_isa_chk_ioaddr(int ioaddr); /* "O" */ -static int sktr_open(struct device *dev); -static void sktr_open_adapter(struct device *dev); +static int sktr_open(struct net_device *dev); +static void sktr_open_adapter(struct net_device *dev); /* "P" */ -static int sktr_pci_chk_card(struct device *dev); -int sktr_probe(struct device *dev); -static int sktr_probe1(struct device *dev, int ioaddr); +static int sktr_pci_chk_card(struct net_device *dev); +int sktr_probe(struct net_device *dev); +static int sktr_probe1(struct net_device *dev, int ioaddr); /* "R" */ -static void sktr_rcv_status_irq(struct device *dev); -static void sktr_read_addr(struct device *dev, unsigned char *Address); -static void sktr_read_ptr(struct device *dev); -static void sktr_read_ram(struct device *dev, unsigned char *Data, +static void sktr_rcv_status_irq(struct net_device *dev); +static void sktr_read_addr(struct net_device *dev, unsigned char *Address); +static void sktr_read_ptr(struct net_device *dev); +static void sktr_read_ram(struct net_device *dev, unsigned char *Data, unsigned short Address, int Length); -static int sktr_reset_adapter(struct device *dev); -static void sktr_reset_interrupt(struct device *dev); -static void sktr_ring_status_irq(struct device *dev); +static int sktr_reset_adapter(struct net_device *dev); +static void sktr_reset_interrupt(struct net_device *dev); +static void sktr_ring_status_irq(struct net_device *dev); /* "S" */ -static int sktr_send_packet(struct sk_buff *skb, struct device *dev); -static void sktr_set_multicast_list(struct device *dev); +static int sktr_send_packet(struct sk_buff *skb, struct net_device *dev); +static void sktr_set_multicast_list(struct net_device *dev); /* "T" */ static void sktr_timer_chk(unsigned long data); static void sktr_timer_end_wait(unsigned long data); -static void sktr_tx_status_irq(struct device *dev); +static void sktr_tx_status_irq(struct net_device *dev); /* "U" */ static void sktr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], unsigned int Length); @@ -186,7 +186,7 @@ static void sktr_write_tpl_status(TPL *tpl, unsigned int Status); * If dev->base_addr == 0, probe all likely locations. * If dev->base_addr == 1, always return failure. */ -__initfunc(int sktr_probe(struct device *dev)) +int __init sktr_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -217,7 +217,7 @@ __initfunc(int sktr_probe(struct device *dev)) /* * Detect and setup the PCI SysKonnect TR cards in slot order. */ -__initfunc(static int sktr_pci_chk_card(struct device *dev)) +static int __init sktr_pci_chk_card(struct net_device *dev) { static int pci_index = 0; unsigned char pci_bus, pci_device_fn; @@ -246,7 +246,7 @@ __initfunc(static int sktr_pci_chk_card(struct device *dev)) pdev = pci_find_slot(pci_bus, pci_device_fn); pci_irq_line = pdev->irq; - pci_ioaddr = pdev->base_address[0]; + pci_ioaddr = pdev->resource[0].start; pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, &pci_command); @@ -295,7 +295,7 @@ __initfunc(static int sktr_pci_chk_card(struct device *dev)) /* * Detect and setup the ISA SysKonnect TR cards. */ -__initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr)) +static int __init sktr_isa_chk_card(struct net_device *dev, int ioaddr) { int i, err; unsigned long flags; @@ -386,7 +386,7 @@ __initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr)) return (0); } -__initfunc(static int sktr_probe1(struct device *dev, int ioaddr)) +static int __init sktr_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; struct net_local *tp; @@ -428,7 +428,7 @@ __initfunc(static int sktr_probe1(struct device *dev, int ioaddr)) } /* Dummy function */ -__initfunc(static int sktr_init_card(struct device *dev)) +static int __init sktr_init_card(struct net_device *dev) { if(sktr_debug > 3) printk("%s: sktr_init_card\n", dev->name); @@ -440,7 +440,7 @@ __initfunc(static int sktr_init_card(struct device *dev)) * This function tests if an adapter is really installed at the * given I/O address. Return negative if no adapter at IO addr. */ -__initfunc(static int sktr_isa_chk_ioaddr(int ioaddr)) +static int __init sktr_isa_chk_ioaddr(int ioaddr) { unsigned char old, chk1, chk2; @@ -480,7 +480,7 @@ __initfunc(static int sktr_isa_chk_ioaddr(int ioaddr)) * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ -static int sktr_open(struct device *dev) +static int sktr_open(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int err; @@ -549,7 +549,7 @@ static int sktr_open(struct device *dev) */ static void sktr_timer_end_wait(unsigned long data) { - struct device *dev = (struct device*)data; + struct net_device *dev = (struct net_device*)data; struct net_local *tp = (struct net_local *)dev->priv; if(tp->Sleeping) @@ -564,7 +564,7 @@ static void sktr_timer_end_wait(unsigned long data) /* * Initialize the chipset */ -static int sktr_chipset_init(struct device *dev) +static int sktr_chipset_init(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char PosReg, Tmp; @@ -621,7 +621,7 @@ static int sktr_chipset_init(struct device *dev) /* * Initializes the net_local structure. */ -static void sktr_init_net_local(struct device *dev) +static void sktr_init_net_local(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int i; @@ -778,7 +778,7 @@ static void sktr_init_opb(struct net_local *tp) /* * Send OPEN command to adapter */ -static void sktr_open_adapter(struct device *dev) +static void sktr_open_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -795,7 +795,7 @@ static void sktr_open_adapter(struct device *dev) * Clear the adapter's interrupt flag. Clear system interrupt enable * (SINTEN): disable adapter to system interrupts. */ -static void sktr_disable_interrupts(struct device *dev) +static void sktr_disable_interrupts(struct net_device *dev) { outb(0, dev->base_addr + SIFACL); @@ -806,7 +806,7 @@ static void sktr_disable_interrupts(struct device *dev) * Set the adapter's interrupt flag. Set system interrupt enable * (SINTEN): enable adapter to system interrupts. */ -static void sktr_enable_interrupts(struct device *dev) +static void sktr_enable_interrupts(struct net_device *dev) { outb(ACL_SINTEN, dev->base_addr + SIFACL); @@ -816,7 +816,7 @@ static void sktr_enable_interrupts(struct device *dev) /* * Put command in command queue, try to execute it. */ -static void sktr_exec_cmd(struct device *dev, unsigned short Command) +static void sktr_exec_cmd(struct net_device *dev, unsigned short Command) { struct net_local *tp = (struct net_local *)dev->priv; @@ -855,7 +855,7 @@ static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen) /* * Gets skb from system, queues it and checks if it can be sent */ -static int sktr_send_packet(struct sk_buff *skb, struct device *dev) +static int sktr_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -906,7 +906,7 @@ static int sktr_send_packet(struct sk_buff *skb, struct device *dev) /* * Move frames from internal skb queue into adapter tx queue */ -static void sktr_hardware_send_packet(struct device *dev, struct net_local* tp) +static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp) { TPL *tpl; short length; @@ -1014,7 +1014,7 @@ static void sktr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr) */ static void sktr_timer_chk(unsigned long data) { - struct device *dev = (struct device*)data; + struct net_device *dev = (struct net_device*)data; struct net_local *tp = (struct net_local*)dev->priv; if(tp->HaltInProgress) @@ -1045,7 +1045,7 @@ static void sktr_timer_chk(unsigned long data) */ static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *tp; int ioaddr; unsigned short irq_type; @@ -1139,7 +1139,7 @@ static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* * Reset the INTERRUPT SYSTEM bit and issue SSB CLEAR command. */ -static void sktr_reset_interrupt(struct device *dev) +static void sktr_reset_interrupt(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; SSB *ssb = &tp->ssb; @@ -1225,7 +1225,7 @@ static unsigned char sktr_chk_ssb(struct net_local *tp, unsigned short IrqType) /* * Evaluates the command results status in the SSB status field. */ -static void sktr_cmd_status_irq(struct device *dev) +static void sktr_cmd_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short ssb_cmd, ssb_parm_0; @@ -1422,7 +1422,7 @@ static void sktr_cmd_status_irq(struct device *dev) /* * The inverse routine to sktr_open(). */ -static int sktr_close(struct device *dev) +static int sktr_close(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1473,7 +1473,7 @@ static int sktr_close(struct device *dev) * Get the current statistics. This may be called with the card open * or closed. */ -static struct enet_statistics *sktr_get_stats(struct device *dev) +static struct enet_statistics *sktr_get_stats(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1483,7 +1483,7 @@ static struct enet_statistics *sktr_get_stats(struct device *dev) /* * Set or clear the multicast filter for this adapter. */ -static void sktr_set_multicast_list(struct device *dev) +static void sktr_set_multicast_list(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned int OpenOptions; @@ -1539,7 +1539,7 @@ static void sktr_wait(unsigned long time) /* * Write a command value to the SIFCMD register */ -static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue) +static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue) { int ioaddr = dev->base_addr; unsigned short cmd; @@ -1561,7 +1561,7 @@ static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue) * Processes adapter hardware reset, halts adapter and downloads firmware, * clears the halt bit. */ -static int sktr_reset_adapter(struct device *dev) +static int sktr_reset_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short *fw_ptr = (unsigned short *)&sktr_code; @@ -1630,7 +1630,7 @@ static int sktr_reset_adapter(struct device *dev) * Starts bring up diagnostics of token ring adapter and evaluates * diagnostic results. */ -static int sktr_bringup_diags(struct device *dev) +static int sktr_bringup_diags(struct net_device *dev) { int loop_cnt, retry_cnt; unsigned short Status; @@ -1685,7 +1685,7 @@ static int sktr_bringup_diags(struct device *dev) * Copy initialisation data to adapter memory, beginning at address * 1:0A00; Starting DMA test and evaluating result bits. */ -static int sktr_init_adapter(struct device *dev) +static int sktr_init_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1787,7 +1787,7 @@ static int sktr_init_adapter(struct device *dev) * Check for outstanding commands in command queue and tries to execute * command immediately. Corresponding command flag in command queue is cleared. */ -static void sktr_chk_outstanding_cmds(struct device *dev) +static void sktr_chk_outstanding_cmds(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned long Addr = 0; @@ -1967,7 +1967,7 @@ static void sktr_chk_outstanding_cmds(struct device *dev) * error counter overflow (255); opened adapter is the only station in ring. * After some of the IRQs the adapter is closed! */ -static void sktr_ring_status_irq(struct device *dev) +static void sktr_ring_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -2037,7 +2037,7 @@ static void sktr_ring_status_irq(struct device *dev) * Issued if adapter has encountered an unrecoverable hardware * or software error. */ -static void sktr_chk_irq(struct device *dev) +static void sktr_chk_irq(struct net_device *dev) { int i; unsigned short AdapterCheckBlock[4]; @@ -2196,7 +2196,7 @@ static void sktr_chk_irq(struct device *dev) * Internal adapter pointer to RAM data are copied from adapter into * host system. */ -static void sktr_read_ptr(struct device *dev) +static void sktr_read_ptr(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short adapterram; @@ -2215,7 +2215,7 @@ static void sktr_read_ptr(struct device *dev) /* * Reads a number of bytes from adapter to system memory. */ -static void sktr_read_ram(struct device *dev, unsigned char *Data, +static void sktr_read_ram(struct net_device *dev, unsigned char *Data, unsigned short Address, int Length) { int i; @@ -2256,7 +2256,7 @@ static void sktr_read_ram(struct device *dev, unsigned char *Data, /* * Reads MAC address from adapter ROM. */ -static void sktr_read_addr(struct device *dev, unsigned char *Address) +static void sktr_read_addr(struct net_device *dev, unsigned char *Address) { int i, In; unsigned short ioaddr = dev->base_addr; @@ -2322,7 +2322,7 @@ static void sktr_cancel_tx_queue(struct net_local* tp) * adapter. For a command complete interrupt, it is checked if we have to * issue a new transmit command or not. */ -static void sktr_tx_status_irq(struct device *dev) +static void sktr_tx_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char HighByte, HighAc, LowAc; @@ -2396,7 +2396,7 @@ static void sktr_tx_status_irq(struct device *dev) * Called if a frame receive interrupt is generated by the adapter. * Check if the frame is valid and indicate it to system. */ -static void sktr_rcv_status_irq(struct device *dev) +static void sktr_rcv_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char *ReceiveDataPtr; @@ -2599,7 +2599,7 @@ static void sktr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], * Check if it is a frame of myself. Compare source address with my current * address in reverse direction, and mask out the TR_RII. */ -static unsigned char sktr_chk_frame(struct device *dev, unsigned char *Addr) +static unsigned char sktr_chk_frame(struct net_device *dev, unsigned char *Addr) { int i; @@ -2635,7 +2635,7 @@ static void sktr_dump(unsigned char *Data, int length) #ifdef MODULE -static struct device* dev_sktr[SKTR_MAX_ADAPTERS]; +static struct net_device* dev_sktr[SKTR_MAX_ADAPTERS]; static int io[SKTR_MAX_ADAPTERS] = { 0, 0 }; static int irq[SKTR_MAX_ADAPTERS] = { 0, 0 }; static int mem[SKTR_MAX_ADAPTERS] = { 0, 0 }; @@ -2664,7 +2664,7 @@ int init_module(void) if(register_trdev(dev_sktr[i]) != 0) { - kfree_s(dev_sktr[i], sizeof(struct device)); + kfree_s(dev_sktr[i], sizeof(struct net_device)); dev_sktr[i] = NULL; if(i == 0) { @@ -2695,7 +2695,7 @@ void cleanup_module(void) free_dma(dev_sktr[i]->dma); if(dev_sktr[i]->priv) kfree_s(dev_sktr[i]->priv, sizeof(struct net_local)); - kfree_s(dev_sktr[i], sizeof(struct device)); + kfree_s(dev_sktr[i], sizeof(struct net_device)); dev_sktr[i] = NULL; } } diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index 690c75e84..7dc3fbf39 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -752,8 +752,7 @@ void cleanup_module(void) } #else /* MODULE */ - -__initfunc(void slhc_install(void)) +void __init slhc_install(void) { } diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 7187a3d8f..4fa976736 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -89,9 +89,9 @@ typedef struct slip_ctrl { - char if_name[8]; /* "sl0\0" .. "sl99999\0" */ + char if_name[16]; /* "sl0\0" .. "sl99999\0" */ struct slip ctrl; /* SLIP things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } slip_ctrl_t; static slip_ctrl_t **slip_ctrls = NULL; @@ -109,7 +109,7 @@ static void slip_unesc6(struct slip *sl, unsigned char c); #ifdef CONFIG_SLIP_SMART static void sl_keepalive(unsigned long sls); static void sl_outfill(unsigned long sls); -static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd); +static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); #endif /******************************** @@ -233,7 +233,7 @@ sl_free_bufs(struct slip *sl) static int sl_realloc_bufs(struct slip *sl, int mtu) { int err = 0; - struct device *dev = sl->dev; + struct net_device *dev = sl->dev; unsigned char *xbuff, *rbuff; #ifdef SL_INCLUDE_CSLIP unsigned char *cbuff; @@ -473,7 +473,7 @@ static void slip_write_wakeup(struct tty_struct *tty) /* Encapsulate an IP datagram and kick it into a TTY queue. */ static int -sl_xmit(struct sk_buff *skb, struct device *dev) +sl_xmit(struct sk_buff *skb, struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -536,7 +536,7 @@ sl_xmit(struct sk_buff *skb, struct device *dev) /* Netdevice UP -> DOWN routine */ static int -sl_close(struct device *dev) +sl_close(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -557,7 +557,7 @@ sl_close(struct device *dev) /* Netdevice DOWN -> UP routine */ -static int sl_open(struct device *dev) +static int sl_open(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -573,7 +573,7 @@ static int sl_open(struct device *dev) /* Netdevice change MTU request */ -static int sl_change_mtu(struct device *dev, int new_mtu) +static int sl_change_mtu(struct net_device *dev, int new_mtu) { struct slip *sl = (struct slip*)(dev->priv); @@ -588,7 +588,7 @@ static int sl_change_mtu(struct device *dev, int new_mtu) /* Netdevice get statistics request */ static struct net_device_stats * -sl_get_stats(struct device *dev) +sl_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct slip *sl = (struct slip*)(dev->priv); @@ -624,7 +624,7 @@ sl_get_stats(struct device *dev) /* Netdevice register callback */ -static int sl_init(struct device *dev) +static int sl_init(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -831,6 +831,9 @@ slip_open(struct tty_struct *tty) struct slip *sl; int err; + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + MOD_INC_USE_COUNT; /* RTnetlink lock is misused here to serialize concurrent @@ -1243,7 +1246,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) to allow get/set outfill/keepalive parameter by ifconfig */ -static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd) +static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) { struct slip *sl = (struct slip*)(dev->priv); @@ -1318,7 +1321,7 @@ static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd) #ifdef MODULE static int slip_init_ctrl_dev(void) #else /* !MODULE */ -__initfunc(int slip_init_ctrl_dev(struct device *dummy)) +int __init slip_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; diff --git a/drivers/net/slip.h b/drivers/net/slip.h index a5043a7f4..6172f2a1f 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -52,7 +52,7 @@ struct slip { /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ #ifdef SL_INCLUDE_CSLIP struct slcompress *slcomp; /* for header compression */ unsigned char *cbuff; /* compression buffer */ @@ -118,6 +118,6 @@ struct slip { #define SLIP_MAGIC 0x5302 -extern int slip_init(struct device *dev); +extern int slip_init(struct net_device *dev); #endif /* _LINUX_SLIP.H */ diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index a588a1b9a..23644ef1d 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -1,4 +1,4 @@ -/* smc-ultra.c: A SMC Ultra ethernet driver for linux. */ +/* smc-mca.c: A SMC Ultra ethernet driver for linux. */ /* Most of this driver, except for ultramca_probe is nearly verbatim from smc-ultra.c by Donald Becker. The rest is @@ -8,7 +8,7 @@ This driver uses the cards in the 8390-compatible, shared memory mode. Most of the run-time complexity is handled by the generic code in - 8390.c. The code in this file is responsible for + 8390.c. This driver enables the shared memory only when doing the actual data transfers to avoid a bug in early version of the card that corrupted @@ -20,9 +20,20 @@ Changelog: - Paul Gortmaker : multiple card support for module users. - David Weis : Micro Channel-ized it. - + Paul Gortmaker : multiple card support for module users. + David Weis : Micro Channel-ized it. + Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A + Christopher Turcksin : Changed MCA-probe so that multiple adapters are + found correctly (Jul 16, 1997) + Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997) + Tom Sightler : Fixed minor detection bug caused by above merge + Tom Sightler : Added support for three more Western Digital + MCA-adapters + Tom Sightler : Added support for 2.2.x mca_find_unused_adapter + Hartmut Schmidt : - Modified parameter detection to handle each + card differently depending on a switch-list + - 'card_ver' removed from the adapter list + - Some minor bug fixes */ @@ -42,20 +53,20 @@ #include "smc-mca.h" #include <linux/mca.h> -int ultramca_probe(struct device *dev); +int ultramca_probe(struct net_device *dev); -static int ultramca_open(struct device *dev); -static void ultramca_reset_8390(struct device *dev); -static void ultramca_get_8390_hdr(struct device *dev, +static int ultramca_open(struct net_device *dev); +static void ultramca_reset_8390(struct net_device *dev); +static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultramca_block_input(struct device *dev, int count, +static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultramca_block_output(struct device *dev, int count, +static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultramca_close_card(struct device *dev); +static int ultramca_close_card(struct net_device *dev); #define START_PG 0x00 /* First page of TX buffer */ @@ -66,53 +77,176 @@ static int ultramca_close_card(struct device *dev); #define ULTRA_IO_EXTENT 32 #define EN0_ERWCNT 0x08 /* Early receive warning count. */ +#define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0 +#define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1 +#define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2 +#define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3 +#define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4 +#define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5 +#define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6 +#define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7 + +struct smc_mca_adapters_t { + unsigned int id; + char *name; +}; + +const struct smc_mca_adapters_t smc_mca_adapters[] = { + { 0x61c8, "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)" }, + { 0x61c9, "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)" }, + { 0x6fc0, "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)" }, + { 0x6fc1, "WD Starcard PLUS/A (WD8003ST/A)" }, + { 0x6fc2, "WD Ethercard PLUS 10T/A (WD8003W/A)" }, + { 0xefd4, "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)" }, + { 0xefd5, "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)" }, + { 0xefe5, "IBM PS/2 Adapter/A for Ethernet" }, + { 0x0000, NULL } +}; -__initfunc(int ultramca_probe(struct device *dev)) +int __init ultramca_probe(struct net_device *dev) { unsigned short ioaddr; unsigned char reg4, num_pages; - char slot; - unsigned char pos2, pos3, pos4, pos5; - int i; + char slot = -1; + unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; + int i, j; + int adapter_found = 0; + int adapter = 0; + int tbase = 0; + int tirq = 0; + int base_addr = dev ? dev->base_addr : 0; + int irq = dev ? dev->irq : 0; + + if (!MCA_bus) { + return ENODEV; + } + + if (base_addr || irq) { + printk(KERN_INFO "Probing for SMC MCA adapter"); + if (base_addr) { + printk(KERN_INFO " at I/O address 0x%04x%c", + base_addr, irq ? ' ' : '\n'); + } + if (irq) { + printk(KERN_INFO "using irq %d\n", irq); + } + } - /* Look for two flavors of SMC Elite/A (3013EP/A) -jeh- */ - if(( (slot=mca_find_adapter(0x61c8,0)) != MCA_NOTFOUND) || - ((slot=mca_find_adapter(0xefd5,0)) != MCA_NOTFOUND) ) + /* proper multicard detection by ZP Gu (zpg@castle.net) */ + + for (j = 0; (smc_mca_adapters[j].name != NULL) && !adapter_found; j++) { + slot = mca_find_unused_adapter(smc_mca_adapters[j].id, 0); + + while((slot != MCA_NOTFOUND) && !adapter_found) { + tirq = 0; + tbase = 0; + + /* If we're trying to match a specificied irq or + * io address, we'll reject the adapter + * found unless it's the one we're looking for + */ + + pos2 = mca_read_stored_pos(slot, 2); /* io_addr */ + pos3 = mca_read_stored_pos(slot, 3); /* shared mem */ + pos4 = mca_read_stored_pos(slot, 4); /* ROM bios addr + * range */ + pos5 = mca_read_stored_pos(slot, 5); /* irq, media + * and RIPL */ + + /* Test the following conditions: + * - If an irq parameter is supplied, compare it + * with the irq of the adapter we found + * - If a base_addr paramater is given, compare it + * with the base_addr of the adapter we found + * - Check that the irq and the base_addr of the + * adapter we found is not already in use by + * this driver + */ + + switch (j) { /* j = card-idx (card array above) [hs] */ + case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: + case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: + case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: + case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: + { + tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr; + tirq = irq_table[(pos5 & 0xc) >> 2].new_irq; + break; + } + case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: + case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: + case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: + case _efe5_IBM_PS2_Adapter_A_for_Ethernet: + { + tbase = ((pos2 & 0x0fe) * 0x10); + tirq = irq_table[(pos5 & 3)].old_irq; + break; + } + } - { -#ifndef MODULE - mca_set_adapter_name( slot, "SMC Elite/A (8013EP/A)" ); -#endif + if(!tirq || !tbase || (irq && irq != tirq) || (base_addr && tbase != base_addr)) { + slot = mca_find_unused_adapter(smc_mca_adapters[j].id, slot + 1); + } else { + adapter_found = 1; + adapter = j; + } + } } - else if( (slot=mca_find_adapter(0x61c9,0)) != MCA_NOTFOUND) - { -#ifndef MODULE - mca_set_adapter_name( slot, "SMC Elite10T/A (8013WP/A)" ); -#endif + + if(!adapter_found) { + return ((base_addr || irq) ? ENXIO : ENODEV); } - else - return -ENODEV; - pos2 = mca_read_stored_pos(slot, 2); /* IO range */ - pos3 = mca_read_stored_pos(slot, 3); /* shared mem */ - pos4 = mca_read_stored_pos(slot, 4); /* bios base */ - pos5 = mca_read_stored_pos(slot, 5); /* irq and media */ + /* Adapter found. */ - dev->base_addr = ioaddr = addr_table[pos2 >> 4].base_addr; - dev->irq = irq_table[(pos5 & ~IRQ_MASK) >> 2].irq; + printk(KERN_INFO "%s: %s found in slot %d\n", + dev->name, smc_mca_adapters[adapter].name, slot + 1); + mca_set_adapter_name(slot, smc_mca_adapters[adapter].name); + mca_mark_as_used(slot); + + + dev->base_addr = ioaddr = tbase; + dev->irq = tirq; dev->mem_start = 0; - num_pages = 40; - for (i = 0; i < 15; i++) - { - if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) + num_pages = 40; + + switch (j) { /* 'j' = card-# in const array above [hs] */ + case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: + case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: + { + for (i = 0; i < 16; i++) { /* taking 16 counts + * up to 15 [hs] */ + if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) { + dev->mem_start = mem_table[i].mem_start; + num_pages = mem_table[i].num_pages; + } + } + break; + } + case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: + case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: + case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: + case _efe5_IBM_PS2_Adapter_A_for_Ethernet: + { + dev->mem_start = ((pos3 & 0xfc) * 0x1000); + num_pages = 0x40; + break; + } + case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: + case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: { - dev->mem_start = mem_table[i].mem_start; - num_pages = mem_table[i].num_pages; + /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates + * the index of the 0x2000 step. + * beware different number of pages [hs] + */ + dev->mem_start = 0xc0000 + (0x2000 * (pos3 & 0xf)); + num_pages = 0x20 + (2 * (pos3 & 0x10)); + break; } } - if (dev->mem_start == 0) /* sanity check, shouldn't happen */ + if (dev->mem_start == 0) /* sanity check, shouldn't happen */ return -ENODEV; reg4 = inb(ioaddr + 4) & 0x7f; @@ -121,52 +255,45 @@ __initfunc(int ultramca_probe(struct device *dev)) if (load_8390_module("wd.c")) return -ENOSYS; - printk("%s: SMC Ultra MCA at %#3x,", dev->name, ioaddr); + printk(KERN_INFO "%s: Parameters: %#3x,", dev->name, ioaddr); for (i = 0; i < 6; i++) - printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); + printk(KERN_INFO " %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); - /* - * Switch from the station address to the alternate register set and - * read the useful registers there. + /* Switch from the station address to the alternate register set + * and read the useful registers there. */ outb(0x80 | reg4, ioaddr + 4); - /* - * Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. + /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); - /* - * Switch back to the station address register set so that the MS-DOS driver - * can find the card after a warm boot. + /* Switch back to the station address register set so that + * the MS-DOS driver can find the card after a warm boot. */ outb(reg4, ioaddr + 4); - /* - * Allocate dev->priv and fill in 8390 specific dev fields. + /* Allocate dev->priv and fill in 8390 specific dev fields. */ - if (ethdev_init(dev)) - { - printk (", no memory for dev->priv.\n"); + if (ethdev_init(dev)) { + printk (KERN_INFO ", no memory for dev->priv.\n"); return -ENOMEM; } - /* - * OK, we are certain this is going to work. Setup the device. + /* OK, we are certain this is going to work. Setup the device. */ request_region(ioaddr, ULTRA_IO_EXTENT, "smc-mca"); - /* - * The 8390 isn't at the base address, so fake the offset + /* The 8390 isn't at the base address, so fake the offset */ - dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; + dev->base_addr = ioaddr + ULTRA_NIC_OFFSET; ei_status.name = "SMC Ultra MCA"; ei_status.word16 = 1; @@ -174,16 +301,20 @@ __initfunc(int ultramca_probe(struct device *dev)) ei_status.rx_start_page = START_PG + TX_PAGES; ei_status.stop_page = num_pages; - dev->rmem_start = dev->mem_start + TX_PAGES*256; + dev->rmem_start = dev->mem_start + TX_PAGES * 256; dev->mem_end = dev->rmem_end = - dev->mem_start + (ei_status.stop_page - START_PG)*256; + dev->mem_start + (ei_status.stop_page - START_PG) * 256; - printk(", IRQ %d memory %#lx-%#lx.\n", dev->irq, dev->mem_start, dev->mem_end-1); + printk(KERN_INFO ", IRQ %d memory %#lx-%#lx.\n", + dev->irq, dev->mem_start, dev->mem_end - 1); ei_status.reset_8390 = &ultramca_reset_8390; ei_status.block_input = &ultramca_block_input; ei_status.block_output = &ultramca_block_output; ei_status.get_8390_hdr = &ultramca_get_8390_hdr; + + ei_status.priv = slot; + dev->open = &ultramca_open; dev->stop = &ultramca_close_card; NS8390_init(dev, 0); @@ -191,26 +322,24 @@ __initfunc(int ultramca_probe(struct device *dev)) return 0; } -static int ultramca_open(struct device *dev) +static int ultramca_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev)) - return -EAGAIN; + return -EAGAIN; outb(ULTRA_MEMENB, ioaddr); /* Enable memory */ outb(0x80, ioaddr + 5); /* ??? */ outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ outb(0x04, ioaddr + 5); /* ??? */ - /* - * Set the early receive warning level in window 0 high enough not - * to receive ERW interrupts. + /* Set the early receive warning level in window 0 high enough not + * to receive ERW interrupts. */ - /* - * outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); - * outb(0xff, dev->base_addr + EN0_ERWCNT); + /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr); + * outb(0xff, dev->base_addr + EN0_ERWCNT); */ ei_open(dev); @@ -218,12 +347,13 @@ static int ultramca_open(struct device *dev) return 0; } -static void ultramca_reset_8390(struct device *dev) +static void ultramca_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ outb(ULTRA_RESET, ioaddr); - if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies); + if (ei_debug > 1) + printk("resetting Ultra, t=%ld...", jiffies); ei_status.txing = 0; outb(0x80, ioaddr + 5); /* ??? */ @@ -235,12 +365,13 @@ static void ultramca_reset_8390(struct device *dev) } /* Grab the 8390 specific header. Similar to the block_input routine, but - we don't need to be concerned with ring wrap as the header will be at - the start of a page, so we optimize accordingly. */ + * we don't need to be concerned with ring wrap as the header will be at + * the start of a page, so we optimize accordingly. + */ -static void ultramca_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); + unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG) << 8); #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ @@ -251,37 +382,35 @@ static void ultramca_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, } /* Block input and output are easy on shared memory ethercards, the only - complication is when the ring buffer wraps. */ + * complication is when the ring buffer wraps. + */ -static void ultramca_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { - unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8); + unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG << 8); - if (xfer_start + count > dev->rmem_end) - { - /* We must wrap the input move. */ + if (xfer_start + count > dev->rmem_end) { + /* We must wrap the input move. */ int semi_count = dev->rmem_end - xfer_start; memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); - } - else - { + } else { /* Packet is in one chunk -- we can copy + cksum. */ eth_io_copy_and_sum(skb, xfer_start, count, 0); } } -static void ultramca_block_output(struct device *dev, int count, const unsigned char *buf, +static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { - unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8); + unsigned long shmem = dev->mem_start + ((start_page - START_PG) << 8); memcpy_toio(shmem, buf, count); } -static int ultramca_close_card(struct device *dev) +static int ultramca_close_card(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -296,7 +425,8 @@ static int ultramca_close_card(struct device *dev) NS8390_init(dev, 0); /* We should someday disable shared memory and change to 8-bit mode - "just in case"... */ + * "just in case"... + */ MOD_DEC_USE_COUNT; @@ -307,11 +437,12 @@ static int ultramca_close_card(struct device *dev) #ifdef MODULE #undef MODULE /* don't want to bother now! */ -#define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */ -#define NAMELEN 8 /* # of chars for storing dev->name */ +#define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */ +#define NAMELEN 8 /* # of chars for storing dev->name */ + static char namelist[NAMELEN * MAX_ULTRAMCA_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRAMCA_CARDS] = +static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ @@ -327,33 +458,23 @@ static int irq[MAX_ULTRAMCA_CARDS] = { 0, }; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i"); -/* This is set up so that only a single autoprobe takes place per call. -ISA device autoprobes on a running machine are not recommended. */ - int init_module(void) { int this_dev, found = 0; - for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) - { - struct device *dev = &dev_ultra[this_dev]; - dev->name = namelist+(NAMELEN*this_dev); + for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) { + struct net_device *dev = &dev_ultra[this_dev]; + dev->name = namelist + (NAMELEN * this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; dev->init = ultramca_probe; - if (io[this_dev] == 0) - { - if (this_dev != 0) - break; /* only autoprobe 1st one */ - printk(KERN_NOTICE "smc-mca.c: Presently autoprobing (not recommended) for a single card.\n"); - } - if (register_netdev(dev) != 0) - { - printk(KERN_WARNING "smc-mca.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); + + if (register_netdev(dev) != 0) { if (found != 0) { /* Got at least one. */ lock_8390_module(); return 0; } + printk(KERN_NOTICE "smc-mca.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); return -ENXIO; } found++; @@ -366,14 +487,13 @@ void cleanup_module(void) { int this_dev; - for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) - { - struct device *dev = &dev_ultra[this_dev]; - if (dev->priv != NULL) - { + for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) { + struct net_device *dev = &dev_ultra[this_dev]; + if (dev->priv != NULL) { void *priv = dev->priv; /* NB: ultra_close_card() does free_irq */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; + mca_mark_as_unused(ei_status.priv); release_region(ioaddr, ULTRA_IO_EXTENT); unregister_netdev(dev); kfree(priv); @@ -383,7 +503,6 @@ void cleanup_module(void) } #endif /* MODULE */ - /* * Local variables: * compile-command: "gcc -D__KERNEL__ -Wall -O6 -I/usr/src/linux/net/inet -c smc-mca.c" diff --git a/drivers/net/smc-mca.h b/drivers/net/smc-mca.h index dc6657d17..ac50117a7 100644 --- a/drivers/net/smc-mca.h +++ b/drivers/net/smc-mca.h @@ -1,7 +1,7 @@ -/* - djweis weisd3458@uni.edu - most of this file was taken from ps2esdi.h -*/ +/* + * djweis weisd3458@uni.edu + * most of this file was taken from ps2esdi.h + */ struct { unsigned int base_addr; @@ -25,6 +25,7 @@ struct { }; #define MEM_MASK 64 + struct { unsigned char mem_index; unsigned long mem_start; @@ -50,13 +51,11 @@ struct { #define IRQ_MASK 243 struct { - unsigned char irq; + unsigned char new_irq; + unsigned char old_irq; } irq_table[] = { - { 3 }, - { 4 }, - { 10 }, - { 14 } + { 3, 3 }, + { 4, 4 }, + { 10, 10 }, + { 14, 15 } }; - - - diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index ea3712c7e..938eaf389 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -66,24 +66,24 @@ static const char *version = static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; -int ultra_probe(struct device *dev); -int ultra_probe1(struct device *dev, int ioaddr); +int ultra_probe(struct net_device *dev); +int ultra_probe1(struct net_device *dev, int ioaddr); -static int ultra_open(struct device *dev); -static void ultra_reset_8390(struct device *dev); -static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int ultra_open(struct net_device *dev); +static void ultra_reset_8390(struct net_device *dev); +static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra_block_input(struct device *dev, int count, +static void ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra_block_output(struct device *dev, int count, +static void ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra_pio_input(struct device *dev, int count, +static void ultra_pio_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra_pio_output(struct device *dev, int count, +static void ultra_pio_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultra_close_card(struct device *dev); +static int ultra_close_card(struct net_device *dev); #define START_PG 0x00 /* First page of TX buffer */ @@ -106,7 +106,7 @@ struct netdev_entry ultra_drv = {"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -__initfunc(int ultra_probe(struct device *dev)) +int __init ultra_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -128,7 +128,7 @@ __initfunc(int ultra_probe(struct device *dev)) } #endif -__initfunc(int ultra_probe1(struct device *dev, int ioaddr)) +int __init ultra_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -250,7 +250,7 @@ __initfunc(int ultra_probe1(struct device *dev, int ioaddr)) } static int -ultra_open(struct device *dev) +ultra_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, @@ -281,7 +281,7 @@ ultra_open(struct device *dev) } static void -ultra_reset_8390(struct device *dev) +ultra_reset_8390(struct net_device *dev) { int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */ @@ -305,7 +305,7 @@ ultra_reset_8390(struct device *dev) the start of a page, so we optimize accordingly. */ static void -ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); @@ -323,7 +323,7 @@ ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) complication is when the ring buffer wraps. */ static void -ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8); @@ -345,7 +345,7 @@ ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_o } static void -ultra_block_output(struct device *dev, int count, const unsigned char *buf, +ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8); @@ -366,7 +366,7 @@ ultra_block_output(struct device *dev, int count, const unsigned char *buf, and must be always be rewritten between each read/write direction change. This is no problem for us, as the 8390 code ensures that we are single threaded. */ -static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -375,7 +375,7 @@ static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1); } -static void ultra_pio_input(struct device *dev, int count, +static void ultra_pio_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -388,7 +388,7 @@ static void ultra_pio_input(struct device *dev, int count, insw(ioaddr + IOPD, buf, (count+1)>>1); } -static void ultra_pio_output(struct device *dev, int count, +static void ultra_pio_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -399,7 +399,7 @@ static void ultra_pio_output(struct device *dev, int count, } static int -ultra_close_card(struct device *dev) +ultra_close_card(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */ @@ -427,7 +427,7 @@ ultra_close_card(struct device *dev) #define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRA_CARDS] = { +static struct net_device dev_ultra[MAX_ULTRA_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -452,7 +452,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -478,7 +478,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { /* NB: ultra_close_card() does free_irq + irq2dev */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index f78f02a6e..d941ef7be 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -60,18 +60,18 @@ static const char *version = "smc-ultra32.c: 06/97 v1.00\n"; #include <linux/etherdevice.h> #include "8390.h" -int ultra32_probe(struct device *dev); -int ultra32_probe1(struct device *dev, int ioaddr); -static int ultra32_open(struct device *dev); -static void ultra32_reset_8390(struct device *dev); -static void ultra32_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +int ultra32_probe(struct net_device *dev); +int ultra32_probe1(struct net_device *dev, int ioaddr); +static int ultra32_open(struct net_device *dev); +static void ultra32_reset_8390(struct net_device *dev); +static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra32_block_input(struct device *dev, int count, +static void ultra32_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra32_block_output(struct device *dev, int count, +static void ultra32_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultra32_close(struct device *dev); +static int ultra32_close(struct net_device *dev); #define ULTRA32_CMDREG 0 /* Offset to ASIC command register. */ #define ULTRA32_RESET 0x80 /* Board reset, in ULTRA32_CMDREG. */ @@ -103,7 +103,7 @@ static int ultra32_close(struct device *dev); following. */ -__initfunc(int ultra32_probe(struct device *dev)) +int __init ultra32_probe(struct net_device *dev) { const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; int ioaddr, edge, media; @@ -126,7 +126,7 @@ __initfunc(int ultra32_probe(struct device *dev)) return ENODEV; } -__initfunc(int ultra32_probe1(struct device *dev, int ioaddr)) +int __init ultra32_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -240,7 +240,7 @@ __initfunc(int ultra32_probe1(struct device *dev, int ioaddr)) return 0; } -static int ultra32_open(struct device *dev) +static int ultra32_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */ int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : SA_SHIRQ; @@ -261,7 +261,7 @@ static int ultra32_open(struct device *dev) return 0; } -static int ultra32_close(struct device *dev) +static int ultra32_close(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */ @@ -282,7 +282,7 @@ static int ultra32_close(struct device *dev) return 0; } -static void ultra32_reset_8390(struct device *dev) +static void ultra32_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */ @@ -302,7 +302,7 @@ static void ultra32_reset_8390(struct device *dev) we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ultra32_get_8390_hdr(struct device *dev, +static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { @@ -325,7 +325,7 @@ static void ultra32_get_8390_hdr(struct device *dev, packet spans an 8KB boundary. Note that the current 8KB segment is already set by the get_8390_hdr routine. */ -static void ultra32_block_input(struct device *dev, +static void ultra32_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) @@ -353,7 +353,7 @@ static void ultra32_block_input(struct device *dev, } } -static void ultra32_block_output(struct device *dev, +static void ultra32_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) @@ -371,7 +371,7 @@ static void ultra32_block_output(struct device *dev, #define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ULTRA32_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRA32_CARDS] = { +static struct net_device dev_ultra[MAX_ULTRA32_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -385,7 +385,7 @@ int init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->init = ultra32_probe; if (register_netdev(dev) != 0) { @@ -407,7 +407,7 @@ void cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; void *priv = dev->priv; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 7f7a99ab7..944ad87c3 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -208,43 +208,43 @@ struct smc_local { . . NB:This shouldn't be static since it is referred to externally. */ -int smc_init(struct device *dev); +int smc_init(struct net_device *dev); /* . The kernel calls this function when someone wants to use the device, . typically 'ifconfig ethX up'. */ -static int smc_open(struct device *dev); +static int smc_open(struct net_device *dev); /* . This is called by the kernel to send a packet out into the net. it's . responsible for doing a best-effort send, but if it's simply not possible . to send it, the packet gets dropped. */ -static int smc_send_packet(struct sk_buff *skb, struct device *dev); +static int smc_send_packet(struct sk_buff *skb, struct net_device *dev); /* . This is called by the kernel in response to 'ifconfig ethX down'. It . is responsible for cleaning up everything that the open routine . does, and maybe putting the card into a powerdown state. */ -static int smc_close(struct device *dev); +static int smc_close(struct net_device *dev); /* . This routine allows the proc file system to query the driver's . statistics. */ -static struct net_device_stats * smc_query_statistics( struct device *dev); +static struct net_device_stats * smc_query_statistics( struct net_device *dev); /* . Finally, a call to set promiscuous mode ( for TCPDUMP and related . programs ) and multicast modes. */ #ifdef SUPPORT_OLD_KERNEL -static void smc_set_multicast_list(struct device *dev, int num_addrs, +static void smc_set_multicast_list(struct net_device *dev, int num_addrs, void *addrs); #else -static void smc_set_multicast_list(struct device *dev); +static void smc_set_multicast_list(struct net_device *dev); #endif /*--------------------------------------------------------------- @@ -265,12 +265,12 @@ static void smc_interrupt(int irq, struct pt_regs *regs); . This is a separate procedure to handle the receipt of a packet, to . leave the interrupt code looking slightly cleaner */ -inline static void smc_rcv( struct device *dev ); +inline static void smc_rcv( struct net_device *dev ); /* . This handles a TX interrupt, which is only called when an error . relating to a packet is sent. */ -inline static void smc_tx( struct device * dev ); +inline static void smc_tx( struct net_device * dev ); /* ------------------------------------------------------------ @@ -292,7 +292,7 @@ static int smc_probe( int ioaddr ); . of a device parameter. . It will give an error if it can't initialize the card. */ -static int smc_initcard( struct device *, int ioaddr ); +static int smc_initcard( struct net_device *, int ioaddr ); /* . A rather simple routine to print out a packet for debugging purposes. @@ -304,13 +304,13 @@ static void print_packet( byte *, int ); #define tx_done(dev) 1 /* this is called to actually send the packet to the chip */ -static void smc_hardware_send_packet( struct device * dev ); +static void smc_hardware_send_packet( struct net_device * dev ); /* Since I am not sure if I will have enough room in the chip's ram . to store the packet, I call this routine, which either sends it . now, or generates an interrupt when the card is ready for the . packet */ -static int smc_wait_to_send_packet( struct sk_buff * skb, struct device *dev ); +static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev ); /* this does a soft reset on the device */ static void smc_reset( int ioaddr ); @@ -337,7 +337,7 @@ static int crc32( char *, int ); #endif #ifdef SUPPORT_OLD_KERNEL -extern struct device *init_etherdev(struct device *dev, int sizeof_private, +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private, unsigned long *mem_startp ); #endif @@ -529,7 +529,7 @@ static int crc32( char * s, int length ) { /* - . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * ) + . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * ) . Purpose: . Attempt to allocate memory for a packet, if chip-memory is not . available, then tell the card to generate an interrupt when it @@ -544,7 +544,7 @@ static int crc32( char * s, int length ) { . o (NO): Enable interrupts and let the interrupt handler deal with it. . o (YES):Send it now. */ -static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev ) +static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) { struct smc_local *lp = (struct smc_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -621,7 +621,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev ) } /* - . Function: smc_hardware_send_packet(struct device * ) + . Function: smc_hardware_send_packet(struct net_device * ) . Purpose: . This sends the actual packet to the SMC9xxx chip. . @@ -638,7 +638,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev ) . Enable the transmit interrupt, so I know if it failed . Free the kernel data if I actually sent it. */ -static void smc_hardware_send_packet( struct device * dev ) +static void smc_hardware_send_packet( struct net_device * dev ) { struct smc_local *lp = (struct smc_local *)dev->priv; byte packet_no; @@ -737,7 +737,7 @@ static void smc_hardware_send_packet( struct device * dev ) /*------------------------------------------------------------------------- | - | smc_init( struct device * dev ) + | smc_init( struct net_device * dev ) | Input parameters: | dev->base_addr == 0, try to find all possible locations | dev->base_addr == 1, return failure code @@ -750,7 +750,7 @@ static void smc_hardware_send_packet( struct device * dev ) | --------------------------------------------------------------------------- */ -__initfunc(int smc_init(struct device *dev)) +int __init smc_init(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -795,7 +795,7 @@ __initfunc(int smc_init(struct device *dev)) . interrupt, so an auto-detect routine can detect it, and find the IRQ, ------------------------------------------------------------------------ */ -__initfunc(int smc_findirq( int ioaddr )) +int __init smc_findirq( int ioaddr ) { int timeout = 20; @@ -877,7 +877,7 @@ __initfunc(int smc_findirq( int ioaddr )) .--------------------------------------------------------------------- */ -__initfunc(static int smc_probe( int ioaddr )) +static int __init smc_probe( int ioaddr ) { unsigned int bank; word revision_register; @@ -942,7 +942,7 @@ __initfunc(static int smc_probe( int ioaddr )) . o GRAB the region .----------------------------------------------------------------- */ -__initfunc(static int smc_initcard(struct device *dev, int ioaddr)) +static int __init smc_initcard(struct net_device *dev, int ioaddr) { int i; @@ -1165,7 +1165,7 @@ static void print_packet( byte * buf, int length ) * Set up everything, reset the card, etc .. * */ -static int smc_open(struct device *dev) +static int smc_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1220,7 +1220,7 @@ static int smc_open(struct device *dev) . skeleton.c, from Becker. .-------------------------------------------------------- */ -static int smc_send_packet(struct sk_buff *skb, struct device *dev) +static int smc_send_packet(struct sk_buff *skb, struct net_device *dev) { if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. @@ -1272,7 +1272,7 @@ static void smc_interrupt(int irq, void * dev_id, struct pt_regs * regs) static void smc_interrupt(int irq, struct pt_regs * regs) #endif { - struct device *dev = dev_id; + struct net_device *dev = dev_id; int ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; @@ -1414,7 +1414,7 @@ static void smc_interrupt(int irq, struct pt_regs * regs) . o otherwise, read in the packet -------------------------------------------------------------- */ -static void smc_rcv(struct device *dev) +static void smc_rcv(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1553,7 +1553,7 @@ static void smc_rcv(struct device *dev) . ( resend? Not really, since we don't want old packets around ) . Restore saved values ************************************************************************/ -static void smc_tx( struct device * dev ) +static void smc_tx( struct net_device * dev ) { int ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; @@ -1614,7 +1614,7 @@ static void smc_tx( struct device * dev ) . an 'ifconfig ethX down' . -----------------------------------------------------*/ -static int smc_close(struct device *dev) +static int smc_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -1634,7 +1634,7 @@ static int smc_close(struct device *dev) . Get the current statistics. . This may be called with the card open or closed. .-------------------------------------------------------------*/ -static struct net_device_stats* smc_query_statistics(struct device *dev) { +static struct net_device_stats* smc_query_statistics(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; return &lp->stats; @@ -1649,10 +1649,10 @@ static struct net_device_stats* smc_query_statistics(struct device *dev) { . a select set of multicast packets */ #ifdef SUPPORT_OLD_KERNEL -static void smc_set_multicast_list( struct device * dev, +static void smc_set_multicast_list( struct net_device * dev, int num_addrs, void * addrs ) #else -static void smc_set_multicast_list(struct device *dev) +static void smc_set_multicast_list(struct net_device *dev) #endif { short ioaddr = dev->base_addr; @@ -1725,7 +1725,7 @@ static void smc_set_multicast_list(struct device *dev) #ifdef MODULE static char devicename[9] = { 0, }; -static struct device devSMC9194 = { +static struct net_device devSMC9194 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index 633401b84..e6d180094 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c @@ -26,7 +26,7 @@ * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ -static int sonic_open(struct device *dev) +static int sonic_open(struct net_device *dev) { if (sonic_debug > 2) printk("sonic_open: initializing sonic driver.\n"); @@ -67,7 +67,7 @@ static int sonic_open(struct device *dev) * Close the SONIC device */ static int -sonic_close(struct device *dev) +sonic_close(struct net_device *dev) { unsigned int base_addr = dev->base_addr; @@ -93,7 +93,7 @@ sonic_close(struct device *dev) /* * transmit packet */ -static int sonic_send_packet(struct sk_buff *skb, struct device *dev) +static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -183,7 +183,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct device *dev) static void sonic_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; unsigned int base_addr = dev->base_addr; struct sonic_local *lp; int status; @@ -301,7 +301,7 @@ sonic_interrupt(int irq, void *dev_id, struct pt_regs * regs) * We have a good packet(s), get it/them out of the buffers. */ static void -sonic_rx(struct device *dev) +sonic_rx(struct net_device *dev) { unsigned int base_addr = dev->base_addr; struct sonic_local *lp = (struct sonic_local *)dev->priv; @@ -378,7 +378,7 @@ sonic_rx(struct device *dev) * This may be called with the device open or closed. */ static struct enet_statistics * -sonic_get_stats(struct device *dev) +sonic_get_stats(struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -399,7 +399,7 @@ sonic_get_stats(struct device *dev) * Set or clear the multicast filter for this adaptor. */ static void -sonic_multicast_list(struct device *dev) +sonic_multicast_list(struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -445,7 +445,7 @@ sonic_multicast_list(struct device *dev) /* * Initialize the SONIC ethernet controller. */ -static int sonic_init(struct device *dev) +static int sonic_init(struct net_device *dev) { unsigned int base_addr = dev->base_addr; unsigned int cmd; diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h index c4cf074b2..4c18dbe70 100644 --- a/drivers/net/sonic.h +++ b/drivers/net/sonic.h @@ -9,11 +9,16 @@ * and pad structure members must be exchanged. Also, the structures * need to be changed accordingly to the bus size. * + * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian), + * see CONFIG_MACSONIC branch below. + * */ #ifndef SONIC_H #define SONIC_H +#include <linux/config.h> + /* * SONIC register offsets */ @@ -213,6 +218,108 @@ #define SONIC_END_OF_LINKS 0x0001 +#ifdef CONFIG_MACSONIC +/* Big endian like structures on Mac + * (680x0) + */ + +typedef struct { + u32 rx_bufadr_l; /* receive buffer ptr */ + u32 rx_bufadr_h; + + u32 rx_bufsize_l; /* no. of words in the receive buffer */ + u32 rx_bufsize_h; +} sonic_rr_t; + +/* + * Sonic receive descriptor. Receive descriptors are + * kept in a linked list of these structures. + */ + +typedef struct { + SREGS_PAD(pad0); + u16 rx_status; /* status after reception of a packet */ + SREGS_PAD(pad1); + u16 rx_pktlen; /* length of the packet incl. CRC */ + + /* + * Pointers to the location in the receive buffer area (RBA) + * where the packet resides. A packet is always received into + * a contiguous piece of memory. + */ + SREGS_PAD(pad2); + u16 rx_pktptr_l; + SREGS_PAD(pad3); + u16 rx_pktptr_h; + + SREGS_PAD(pad4); + u16 rx_seqno; /* sequence no. */ + + SREGS_PAD(pad5); + u16 link; /* link to next RDD (end if EOL bit set) */ + + /* + * Owner of this descriptor, 0= driver, 1=sonic + */ + + SREGS_PAD(pad6); + u16 in_use; + + caddr_t rda_next; /* pointer to next RD */ +} sonic_rd_t; + + +/* + * Describes a Transmit Descriptor + */ +typedef struct { + SREGS_PAD(pad0); + u16 tx_status; /* status after transmission of a packet */ + SREGS_PAD(pad1); + u16 tx_config; /* transmit configuration for this packet */ + SREGS_PAD(pad2); + u16 tx_pktsize; /* size of the packet to be transmitted */ + SREGS_PAD(pad3); + u16 tx_frag_count; /* no. of fragments */ + + SREGS_PAD(pad4); + u16 tx_frag_ptr_l; + SREGS_PAD(pad5); + u16 tx_frag_ptr_h; + SREGS_PAD(pad6); + u16 tx_frag_size; + + SREGS_PAD(pad7); + u16 link; /* ptr to next descriptor */ +} sonic_td_t; + + +/* + * Describes an entry in the CAM Descriptor Area. + */ + +typedef struct { + SREGS_PAD(pad0); + u16 cam_entry_pointer; + SREGS_PAD(pad1); + u16 cam_cap0; + SREGS_PAD(pad2); + u16 cam_cap1; + SREGS_PAD(pad3); + u16 cam_cap2; +} sonic_cd_t; + +#define CAM_DESCRIPTORS 16 + + +typedef struct { + sonic_cd_t cam_desc[CAM_DESCRIPTORS]; + SREGS_PAD(pad); + u16 cam_enable; +} sonic_cda_t; + +#else /* original declarations, little endian 32 bit */ + /* * structure definitions */ @@ -311,14 +418,23 @@ typedef struct { u16 cam_enable; SREGS_PAD(pad); } sonic_cda_t; +#endif /* endianness */ /* * Some tunables for the buffer areas. Power of 2 is required * the current driver uses one receive buffer for each descriptor. + * + * MSch: use more buffer space for the slow m68k Macs! */ +#ifdef CONFIG_MACSONIC +#define SONIC_NUM_RRS 32 /* number of receive resources */ +#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ +#define SONIC_NUM_TDS 32 /* number of transmit descriptors */ +#else #define SONIC_NUM_RRS 16 /* number of receive resources */ #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ +#endif #define SONIC_RBSIZE 1520 /* size of one resource buffer */ #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) @@ -349,14 +465,14 @@ struct sonic_local { /* Index to functions, as function prototypes. */ -static int sonic_open(struct device *dev); -static int sonic_send_packet(struct sk_buff *skb, struct device *dev); +static int sonic_open(struct net_device *dev); +static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev); static void sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void sonic_rx(struct device *dev); -static int sonic_close(struct device *dev); -static struct enet_statistics *sonic_get_stats(struct device *dev); -static void sonic_multicast_list(struct device *dev); -static int sonic_init(struct device *dev); +static void sonic_rx(struct net_device *dev); +static int sonic_close(struct net_device *dev); +static struct enet_statistics *sonic_get_stats(struct net_device *dev); +static void sonic_multicast_list(struct net_device *dev); +static int sonic_init(struct net_device *dev); static const char *version = "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c new file mode 100644 index 000000000..09891202c --- /dev/null +++ b/drivers/net/starfire.c @@ -0,0 +1,1431 @@ +/* starfire.c: Linux device driver for the Adaptec Starfire network adapter. */ +/* + Written 1998-1999 by Donald Becker. + + This software may be used and distributed according to the terms + of the GNU Public License (GPL), incorporated herein by reference. + + The author may be reached as becker@usra.edu, or + Donald Becker + 312 Severn Ave. #W302 + Annapolis MD 21403 + + Support and updates available at + http://cesdis.gsfc.nasa.gov/linux/drivers/starfire.html +*/ + +static const char *versionA = +"starfire.c:v0.12 5/28/99 Written by Donald Becker\n", +*versionB =" Undates and info at http://www.beowulf.org/linux/drivers.html\n"; + +/* A few user-configurable values. These may be modified when a driver + module is loaded.*/ + +/* Used for tuning interrupt latency vs. overhead. */ +static int interrupt_mitigation = 0x0; + +static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int max_interrupt_work = 20; +static int min_pci_latency = 64; +static int mtu = 0; +/* Maximum number of multicast addresses to filter (vs. rx-all-multicast). + The Starfire has a 512 element hash table based on the Ethernet CRC. */ +static int multicast_filter_limit = 32; + +/* Set the copy breakpoint for the copy-only-tiny-frames scheme. + Setting to > 1518 effectively disables this feature. */ +static int rx_copybreak = 0; + +/* Used to pass the media type, etc. + Both 'options[]' and 'full_duplex[]' exist for driver interoperability. + The media type is usually passed in 'options[]'. +*/ +#define MAX_UNITS 8 /* More are supported, limit only on options */ +static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; +static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +/* Operational parameters that are set at compile time. */ + +/* The "native" ring sizes are either 256 or 2048. + However in some modes a descriptor may be marked to wrap the ring earlier. + The driver allocates a single page for each descriptor ring, constraining + the maximum size in an architecture-dependent way. +*/ +#define RX_RING_SIZE 256 +#define TX_RING_SIZE 32 +/* The completion queues are fixed at 1024 entries i.e. 4K or 8KB. */ +#define DONE_Q_SIZE 1024 + +/* Operational parameters that usually are not changed. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (2*HZ) + +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ + +#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) +#warning You must compile this file with the correct options! +#warning See the last lines of the source file. +#error You must compile this driver with "-O". +#endif + +/* Include files, designed to support most kernel versions 2.0.0 and later. */ +#include <linux/config.h> +#ifdef MODULE +#ifdef MODVERSIONS +#include <linux/modversions.h> +#endif +#include <linux/module.h> +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/malloc.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <asm/processor.h> /* Processor type for cache alignment. */ +#include <asm/bitops.h> +#include <asm/io.h> + +/* Kernel compatibility defines, some common to David Hind's PCMCIA package. + This is only in the support-all-kernels source code. */ + +#define RUN_AT(x) (jiffies + (x)) + +#ifdef MODULE +MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>"); +MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(min_pci_latency, "i"); +MODULE_PARM(mtu, "i"); +MODULE_PARM(debug, "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); +#endif + +/* + Theory of Operation + +I. Board Compatibility + +State the chips and boards this driver is known to work with. +Note any similar chips or boards that will not work. + +This driver skeleton demonstrates the driver for an idealized +descriptor-based bus-master PCI chip. + +II. Board-specific settings + +No jumpers exist on most PCI boards, so this section is usually empty. + +III. Driver operation + +IIIa. Ring buffers + +The Starfire hardware uses multiple fixed-size descriptor queues/rings. The +ring sizes are set fixed by the hardware, but may optionally be wrapped +earlier by the END bit in the descriptor. +This driver uses that hardware queue size for the Rx ring, where a large +number of entries has no ill effect beyond increases the potential backlog. +The Tx ring is wrapped with the END bit, since a large hardware Tx queue +disables the queue layer priority ordering and we have no mechanism to +utilize the hardware two-level priority queue. When modifying the +RX/TX_RING_SIZE pay close attention to page sizes and the ring-empty warning +levels. + +IIIb/c. Transmit/Receive Structure + +See the Adaptec manual for the many possible structures, and options for +each structure. There are far too many to document here. + +For transmit this driver uses type 1 transmit descriptors, and relies on +automatic minimum-length padding. It does not use the completion queue +consumer index, but instead checks for non-zero status entries. + +For receive this driver uses type 0 receive descriptors. The driver +allocates full frame size skbuffs for the Rx ring buffers, so all frames +should fit in a single descriptor. The driver does not use the completion +queue consumer index, but instead checks for non-zero status entries. + +When an incoming frame is less than RX_COPYBREAK bytes long, a fresh skbuff +is allocated and the frame is copied to the new skbuff. When the incoming +frame is larger, the skbuff is passed directly up the protocol stack. +Buffers consumed this way are replaced by newly allocated skbuffs in a later +phase of receive. + +A notable aspect of operation is that unaligned buffers are not permitted by +the Starfire hardware. The IP header at offset 14 in an ethernet frame thus +isn't longword aligned, which may cause problems on some machine +e.g. Alphas. Copied frames are put into the skbuff at an offset of "+2", +16-byte aligning the IP header. + +IIId. Synchronization + +The driver runs as two independent, single-threaded flows of control. One +is the send-packet routine, which enforces single-threaded use by the +dev->tbusy flag. The other thread is the interrupt handler, which is single +threaded by the hardware and interrupt handling software. + +The send packet thread has partial control over the Tx ring and 'dev->tbusy' +flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next +queue slot is empty, it clears the tbusy flag when finished otherwise it sets +the 'lp->tx_full' flag. + +The interrupt handler has exclusive control over the Rx ring and records stats +from the Tx ring. After reaping the stats, it marks the Tx queue entry as +empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it +clears both the tx_full and tbusy flags. + +IV. Notes + +IVb. References + +The Adaptec Starfire manuals. +http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html +http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html + + +IVc. Errata + +*/ + + + +/* This table drives the PCI probe routines. It's mostly boilerplate in all + PCI drivers, and will likely be provided by some future kernel. +*/ +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +}; +struct pci_id_info { + const char *name; + u16 vendor_id, device_id, device_id_mask, flags; + int io_size; + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); +}; + +static struct net_device *starfire_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, + int irq, int chp_idx, int fnd_cnt); + +#if 0 +#define ADDR_64BITS 1 /* This chip uses 64 bit addresses. */ +#endif +#define MEM_ADDR_SZ 0x80000 /* And maps in 0.5MB(!). */ + +static struct pci_id_info pci_tbl[] = { + { "Adaptec Starfire 6915", + 0x9004, 0x6915, 0xffff, PCI_USES_MASTER, 128, starfire_probe1}, + {0,}, /* 0 terminated list. */ +}; + + +/* A chip capabilities table, matching the entries in pci_tbl[] above. */ +enum chip_capability_flags {CanHaveMII=1, }; +struct chip_info { + char *chip_name; + int io_size; + int flags; + void (*media_timer)(unsigned long data); +} static skel_netdrv_tbl[] = { + {"Adaptec Starfire 6915", 128, CanHaveMII, 0, }, +}; + + +/* Offsets to the device registers. + Unlike software-only systems, device drivers interact with complex hardware. + It's not useful to define symbolic names for every register bit in the + device. The name can only partially document the semantics and make + the driver longer and more difficult to read. + In general, only the important configuration values or bits changed + multiple times should be defined symbolically. +*/ +enum register_offsets { + PCIDeviceConfig=0x50040, GenCtrl=0x50070, IntrTimerCtrl=0x50074, + IntrClear=0x50080, IntrStatus=0x50084, IntrEnable=0x50088, + MIICtrl=0x52000, StationAddr=0x50120, EEPROMCtrl=0x51000, + TxDescCtrl=0x50090, + TxRingPtr=0x50098, HiPriTxRingPtr=0x50094, /* Low and High priority. */ + TxRingHiAddr=0x5009C, /* 64 bit address extension. */ + TxProducerIdx=0x500A0, TxConsumerIdx=0x500A4, + TxThreshold=0x500B0, + CompletionHiAddr=0x500B4, TxCompletionAddr=0x500B8, + RxCompletionAddr=0x500BC, RxCompletionQ2Addr=0x500C0, + CompletionQConsumerIdx=0x500C4, + RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0, + RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4, + TxMode=0x55000, +}; + +/* Bits in the interrupt status/mask registers. */ +enum intr_status_bits { + IntrNormalSummary=0x8000, IntrAbnormalSummary=0x02000000, + IntrRxDone=0x0300, IntrRxEmpty=0x10040, IntrRxPCIErr=0x80000, + IntrTxDone=0x4000, IntrTxEmpty=0x1000, IntrTxPCIErr=0x80000, + StatsMax=0x08000000, LinkChange=0xf0000000, + IntrTxDataLow=0x00040000, +}; + +/* Bits in the RxFilterMode register. */ +enum rx_mode_bits { + AcceptBroadcast=0x04, AcceptAllMulticast=0x02, AcceptAll=0x01, + AcceptMulticast=0x10, AcceptMyPhys=0xE040, +}; + +/* The Rx and Tx buffer descriptors. */ +struct starfire_rx_desc { + u32 rxaddr; /* Optionally 64 bits. */ +}; +enum rx_desc_bits { + RxDescValid=1, RxDescEndRing=2, +}; + +/* Completion queue entry. + You must update the page allocation, init_ring and the shift count in rx() + if using a larger format. */ +struct rx_done_desc { + u32 status; /* Low 16 bits is length. */ +#ifdef full_rx_status + u32 status2; + u16 vlanid; + u16 csum; /* partial checksum */ + u32 timestamp; +#endif +}; +enum rx_done_bits { + RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000, +}; + +/* Type 1 Tx descriptor. */ +struct starfire_tx_desc { + u32 status; /* Upper bits are status, lower 16 length. */ + u32 addr; +}; +enum tx_desc_bits { + TxDescID=0xB1010000, /* Also marks single fragment, add CRC. */ + TxDescIntr=0x08000000, TxRingWrap=0x04000000, +}; +struct tx_done_report { + u32 status; /* timestamp, index. */ +#if 0 + u32 intrstatus; /* interrupt status */ +#endif +}; + +struct netdev_private { + /* Descriptor rings first for alignment. */ + struct starfire_rx_desc *rx_ring; + struct starfire_tx_desc *tx_ring; + struct net_device *next_module; /* Link for devices of this type. */ + const char *product_name; + /* The addresses of rx/tx-in-place skbuffs. */ + struct sk_buff* rx_skbuff[RX_RING_SIZE]; + struct sk_buff* tx_skbuff[TX_RING_SIZE]; + /* Pointers to completion queues (full pages). I should cache line pad..*/ + u8 pad0[100]; + struct rx_done_desc *rx_done_q; + unsigned int rx_done; + struct tx_done_report *tx_done_q; + unsigned int tx_done; + struct net_device_stats stats; + struct timer_list timer; /* Media monitoring timer. */ + /* Frequently used values: keep some adjacent for cache effect. */ + int chip_id; + unsigned char pci_bus, pci_devfn; + unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ + unsigned int cur_tx, dirty_tx; + unsigned int rx_buf_sz; /* Based on MTU+slack. */ + unsigned int tx_full:1; /* The Tx queue is full. */ + /* These values are keep track of the transceiver/media in use. */ + unsigned int duplex_lock:1; + unsigned int full_duplex:1, /* Full-duplex operation requested. */ + rx_flowctrl:1, + tx_flowctrl:1; /* Use 802.3x flow control. */ + unsigned int medialock:1; /* Do not sense media. */ + unsigned int default_port:4; /* Last dev->if_port value. */ + u32 tx_mode; + u8 tx_threshold; + /* MII transceiver section. */ + int mii_cnt; /* MII device addresses. */ + u16 advertising; /* NWay media advertisement */ + unsigned char phys[2]; /* MII device addresses. */ + u32 pad[4]; /* Used for 32-byte alignment */ +}; + +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static int netdev_open(struct net_device *dev); +static void check_duplex(struct net_device *dev, int startup); +static void netdev_timer(unsigned long data); +static void tx_timeout(struct net_device *dev); +static void init_ring(struct net_device *dev); +static int start_tx(struct sk_buff *skb, struct net_device *dev); +static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static void netdev_error(struct net_device *dev, int intr_status); +static int netdev_rx(struct net_device *dev); +static void netdev_error(struct net_device *dev, int intr_status); +static void set_rx_mode(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int netdev_close(struct net_device *dev); + + + +/* A list of our installed devices, for removing the driver module. */ +static struct net_device *root_net_dev = NULL; + +/* Ideally we would detect all network cards in slot order. That would + be best done a central PCI probe dispatch, which wouldn't work + well when dynamically adding drivers. So instead we detect just the + cards we know about in slot order. */ + +static int pci_etherdev_probe(struct net_device *dev, struct pci_id_info pci_tbl[]) +{ + int cards_found = 0; + int pci_index = 0; + unsigned char pci_bus, pci_device_fn; + + if ( ! pcibios_present()) + return -ENODEV; + + for (;pci_index < 0xff; pci_index++) { + u16 vendor, device, pci_command, new_command; + int chip_idx, irq; + long pciaddr; + long ioaddr; + + if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index, + &pci_bus, &pci_device_fn) + != PCIBIOS_SUCCESSFUL) + break; + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_DEVICE_ID, &device); + + for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) + if (vendor == pci_tbl[chip_idx].vendor_id + && (device & pci_tbl[chip_idx].device_id_mask) == + pci_tbl[chip_idx].device_id) + break; + if (pci_tbl[chip_idx].vendor_id == 0) /* Compiled out! */ + continue; + + { + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + + pciaddr = pdev->resource[0].start; +#if defined(ADDR_64BITS) && defined(__alpha__) + pciaddr |= ((long)pdev->base_address[1]) << 32; +#endif + irq = pdev->irq; + } + + if (debug > 2) + printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n", + pci_tbl[chip_idx].name, pciaddr, irq); + + if ((pci_tbl[chip_idx].flags & PCI_USES_IO)) { + if (check_region(pciaddr, pci_tbl[chip_idx].io_size)) + continue; + ioaddr = pciaddr; + } else if ((ioaddr = (long)ioremap(pciaddr&~0xf, MEM_ADDR_SZ)) == 0) { + printk(KERN_INFO "Failed to map PCI address %#lx.\n", + pciaddr); + continue; + } + + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + new_command = pci_command | (pci_tbl[chip_idx].flags & 7); + if (pci_command != new_command) { + printk(KERN_INFO " The PCI BIOS has not enabled the" + " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n", + pci_bus, pci_device_fn, pci_command, new_command); + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, new_command); + } + + dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, + irq, chip_idx, cards_found); + + if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) { + u8 pci_latency; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < min_pci_latency) { + printk(KERN_INFO " PCI latency timer (CFLT) is " + "unreasonably low at %d. Setting to %d clocks.\n", + pci_latency, min_pci_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, min_pci_latency); + } + } + dev = 0; + cards_found++; + } + + return cards_found ? 0 : -ENODEV; +} + +int starfire_probe(struct net_device *dev) +{ + if (pci_etherdev_probe(dev, pci_tbl) < 0) + return -ENODEV; + printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); + return 0; +} + + +static struct net_device * +starfire_probe1(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_id, int card_idx) +{ + struct netdev_private *np; + int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0; + + dev = init_etherdev(dev, sizeof(struct netdev_private)); + + printk(KERN_INFO "%s: %s at 0x%lx, ", + dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr); + + /* Serial EEPROM reads are hidden by the hardware. */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i); + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + +#if ! defined(final_version) /* Dump the EEPROM contents during development. */ + if (debug > 4) + for (i = 0; i < 0x20; i++) + printk("%2.2x%s", readb(ioaddr + EEPROMCtrl + i), + i % 16 != 15 ? " " : "\n"); +#endif + + /* Reset the chip to erase previous misconfiguration. */ + writel(1, ioaddr + PCIDeviceConfig); + + dev->base_addr = ioaddr; + dev->irq = irq; + + /* Make certain the descriptor lists are aligned. */ + np = (void *)(((long)kmalloc(sizeof(*np), GFP_KERNEL) + 15) & ~15); + memset(np, 0, sizeof(*np)); + dev->priv = np; + + np->next_module = root_net_dev; + root_net_dev = dev; + + np->pci_bus = pci_bus; + np->pci_devfn = pci_devfn; + np->chip_id = chip_id; + + if (dev->mem_start) + option = dev->mem_start; + + /* The lower four bits are the media type. */ + if (option > 0) { + if (option & 0x200) + np->full_duplex = 1; + np->default_port = option & 15; + if (np->default_port) + np->medialock = 1; + } + if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) + np->full_duplex = 1; + + if (np->full_duplex) + np->duplex_lock = 1; + + /* The chip-specific entries in the device structure. */ + dev->open = &netdev_open; + dev->hard_start_xmit = &start_tx; + dev->stop = &netdev_close; + dev->get_stats = &get_stats; + dev->set_multicast_list = &set_rx_mode; + dev->do_ioctl = &mii_ioctl; + + if (mtu) + dev->mtu = mtu; + + if (skel_netdrv_tbl[np->chip_id].flags & CanHaveMII) { + int phy, phy_idx = 0; + for (phy = 0; phy < 32 && phy_idx < 4; phy++) { + int mii_status = mdio_read(dev, phy, 1); + if (mii_status != 0xffff && mii_status != 0x0000) { + np->phys[phy_idx++] = phy; + np->advertising = mdio_read(dev, phy, 4); + printk(KERN_INFO "%s: MII PHY found at address %d, status " + "0x%4.4x advertising %4.4x.\n", + dev->name, phy, mii_status, np->advertising); + } + } + np->mii_cnt = phy_idx; + } + + return dev; +} + + +/* Read the MII Management Data I/O (MDIO) interfaces. */ + +static int mdio_read(struct net_device *dev, int phy_id, int location) +{ + long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2); + int result, boguscnt=1000; + /* ??? Must add a busy-wait here. */ + do + result = readl(mdio_addr); + while ((result & 0xC0000000) != 0x80000000 && --boguscnt >= 0); + return result & 0xffff; +} + +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) +{ + long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2); + writel(value, mdio_addr); + /* The busy-wait will occur before a read. */ + return; +} + + +static int netdev_open(struct net_device *dev) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + long ioaddr = dev->base_addr; + int i; + + /* Do we need to reset the chip??? */ + + if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) + return -EAGAIN; + + /* Disable the Rx and Tx, and reset the chip. */ + writel(0, ioaddr + GenCtrl); + writel(1, ioaddr + PCIDeviceConfig); + if (debug > 1) + printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", + dev->name, dev->irq); + /* Allocate the various queues, failing gracefully. */ + if (np->tx_done_q == 0) + np->tx_done_q = (struct tx_done_report *)get_free_page(GFP_KERNEL); + if (np->rx_done_q == 0) + np->rx_done_q = (struct rx_done_desc *)get_free_page(GFP_KERNEL); + if (np->tx_ring == 0) + np->tx_ring = (struct starfire_tx_desc *)get_free_page(GFP_KERNEL); + if (np->rx_ring == 0) + np->rx_ring = (struct starfire_rx_desc *)get_free_page(GFP_KERNEL); + if (np->tx_done_q == 0 || np->rx_done_q == 0 + || np->rx_ring == 0 || np->tx_ring == 0) + return -ENOMEM; + + MOD_INC_USE_COUNT; + + init_ring(dev); + /* Set the size of the Rx buffers. */ + writel((np->rx_buf_sz<<16) | 0xA000, ioaddr + RxDescQCtrl); + + /* Set Tx descriptor to type 1 and padding to 0 bytes. */ + writel(0x02000401, ioaddr + TxDescCtrl); + +#if defined(ADDR_64BITS) && defined(__alpha__) + writel(virt_to_bus(np->rx_ring) >> 32, ioaddr + RxDescQHiAddr); + writel(virt_to_bus(np->tx_ring) >> 32, ioaddr + TxRingHiAddr); +#else + writel(0, ioaddr + RxDescQHiAddr); + writel(0, ioaddr + TxRingHiAddr); + writel(0, ioaddr + CompletionHiAddr); +#endif + writel(virt_to_bus(np->rx_ring), ioaddr + RxDescQAddr); + writel(virt_to_bus(np->tx_ring), ioaddr + TxRingPtr); + + writel(virt_to_bus(np->tx_done_q), ioaddr + TxCompletionAddr); + writel(virt_to_bus(np->rx_done_q), ioaddr + RxCompletionAddr); + + if (debug > 1) + printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name); + + /* Fill both the unused Tx SA register and the Rx perfect filter. */ + for (i = 0; i < 6; i++) + writeb(dev->dev_addr[i], ioaddr + StationAddr + 6-i); + for (i = 0; i < 16; i++) { + u16 *eaddrs = (u16 *)dev->dev_addr; + long setup_frm = ioaddr + 0x56000 + i*16; + writew(eaddrs[0], setup_frm); setup_frm += 4; + writew(eaddrs[1], setup_frm); setup_frm += 4; + writew(eaddrs[2], setup_frm); setup_frm += 4; + } + + /* Initialize other registers. */ + /* Configure the PCI bus bursts and FIFO thresholds. */ + np->tx_threshold = 4; + writel(np->tx_threshold, ioaddr + TxThreshold); + writel(interrupt_mitigation, ioaddr + IntrTimerCtrl); + + if (dev->if_port == 0) + dev->if_port = np->default_port; + + dev->tbusy = 0; + dev->interrupt = 0; + + if (debug > 1) + printk(KERN_DEBUG "%s: Setting the Rx and Tx modes.\n", dev->name); + set_rx_mode(dev); + + check_duplex(dev, 1); + + dev->start = 1; + + /* Set the interrupt mask and enable PCI interrupts. */ + writel(IntrRxDone | IntrRxEmpty | IntrRxPCIErr | + IntrTxDone | IntrTxEmpty | IntrTxPCIErr | + StatsMax | LinkChange | IntrNormalSummary | IntrAbnormalSummary + | 0x0010 , ioaddr + IntrEnable); + writel(0x00800000 | readl(ioaddr + PCIDeviceConfig), + ioaddr + PCIDeviceConfig); + + /* Enable the Rx and Tx units. */ + writel(0x000F, ioaddr + GenCtrl); + + if (debug > 2) + printk(KERN_DEBUG "%s: Done netdev_open().\n", + dev->name); + + /* Set the timer to check for link beat. */ + init_timer(&np->timer); + np->timer.expires = RUN_AT(3*HZ); + np->timer.data = (unsigned long)dev; + np->timer.function = &netdev_timer; /* timer handler */ + add_timer(&np->timer); + + return 0; +} + +static void check_duplex(struct net_device *dev, int startup) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + long ioaddr = dev->base_addr; + int mii_reg5 = mdio_read(dev, np->phys[0], 5); + int duplex, new_tx_mode ; + + new_tx_mode = 0x0C04 | (np->tx_flowctrl ? 0x0800:0) | (np->rx_flowctrl ? 0x0400:0); + if (np->duplex_lock) + duplex = 1; + else + duplex = (mii_reg5 & 0x0100) || (mii_reg5 & 0x01C0) == 0x0040; + if (duplex) + new_tx_mode |= 2; + if (np->full_duplex != duplex) { + np->full_duplex = duplex; + if (debug) + printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link" + " partner capability of %4.4x.\n", dev->name, + duplex ? "full" : "half", np->phys[0], mii_reg5); + } + if (new_tx_mode != np->tx_mode) { + np->tx_mode = new_tx_mode; + writel(np->tx_mode | 0x8000, ioaddr + TxMode); + writel(np->tx_mode, ioaddr + TxMode); + } +} + +static void netdev_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct netdev_private *np = (struct netdev_private *)dev->priv; + long ioaddr = dev->base_addr; + int next_tick = 60*HZ; /* Check before driver release. */ + + if (debug > 3) { + printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x.\n", + dev->name, readl(ioaddr + IntrStatus)); + } + check_duplex(dev, 0); +#if ! defined(final_version) + /* This is often falsely triggered. */ + if (readl(ioaddr + IntrStatus) & 1) { + int new_status = readl(ioaddr + IntrStatus); + /* Bogus hardware IRQ: Fake an interrupt handler call. */ + if (new_status & 1) { + printk(KERN_ERR "%s: Interrupt blocked, status %8.8x/%8.8x.\n", + dev->name, new_status, readl(ioaddr + IntrStatus)); + intr_handler(dev->irq, dev, 0); + } + } +#endif + + np->timer.expires = RUN_AT(next_tick); + add_timer(&np->timer); +} + +static void tx_timeout(struct net_device *dev) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + long ioaddr = dev->base_addr; + + printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," + " resetting...\n", dev->name, readl(ioaddr + IntrStatus)); + +#ifndef __alpha__ + { + int i; + printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); + for (i = 0; i < RX_RING_SIZE; i++) + printk(" %8.8x", (unsigned int)le32_to_cpu(np->rx_ring[i].rxaddr)); + printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring); + for (i = 0; i < TX_RING_SIZE; i++) + printk(" %4.4x", le32_to_cpu(np->tx_ring[i].status)); + printk("\n"); + } +#endif + + /* Perhaps we should reinitialize the hardware here. */ + dev->if_port = 0; + /* Stop and restart the chip's Tx processes . */ + + /* Trigger an immediate transmit demand. */ + + dev->trans_start = jiffies; + np->stats.tx_errors++; + return; +} + + +/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ +static void init_ring(struct net_device *dev) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + int i; + + np->tx_full = 0; + np->cur_rx = np->cur_tx = 0; + np->dirty_rx = np->rx_done = np->dirty_tx = np->tx_done = 0; + + np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); + + /* Fill in the Rx buffers. Handle allocation failure gracefully. */ + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + np->rx_skbuff[i] = skb; + if (skb == NULL) + break; + skb->dev = dev; /* Mark as being used by this device. */ + /* Grrr, we cannot offset to correctly align the IP header. */ + np->rx_ring[i].rxaddr = cpu_to_le32(virt_to_bus(skb->tail) | RxDescValid); + } + writew(i-1, dev->base_addr + RxDescQIdx); + np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); + + /* Clear the remainder of the Rx buffer ring. */ + for ( ; i < RX_RING_SIZE; i++) { + np->rx_ring[i].rxaddr = 0; + np->rx_skbuff[i] = 0; + } + /* Mark the last entry as wrapping the ring. */ + np->rx_ring[i-1].rxaddr |= cpu_to_le32(RxDescEndRing); + + /* Clear the completion rings. */ + for (i = 0; i < DONE_Q_SIZE; i++) { + np->rx_done_q[i].status = 0; + np->tx_done_q[i].status = 0; + } + + for (i = 0; i < TX_RING_SIZE; i++) { + np->tx_skbuff[i] = 0; + np->tx_ring[i].status = 0; + } + return; +} + +static int start_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + unsigned entry; + + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + if (jiffies - dev->trans_start < TX_TIMEOUT) + return 1; + tx_timeout(dev); + return 1; + } + + /* Caution: the write order is important here, set the field + with the "ownership" bits last. */ + + /* Calculate the next Tx descriptor entry. */ + entry = np->cur_tx % TX_RING_SIZE; + + np->tx_skbuff[entry] = skb; + + np->tx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->data)); + /* Add |TxDescIntr to generate Tx-done interrupts. */ + np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID); + if (debug > 5) { + printk(KERN_DEBUG "%s: Tx #%d slot %d %8.8x %8.8x.\n", + dev->name, np->cur_tx, entry, + le32_to_cpu(np->tx_ring[entry].status), + le32_to_cpu(np->tx_ring[entry].addr)); + } + np->cur_tx++; +#if 1 + if (entry >= TX_RING_SIZE-1) { /* Wrap ring */ + np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); + entry = -1; + } +#endif + + /* Non-x86: explicitly flush descriptor cache lines here. */ + + /* Update the producer index. */ + writel(++entry, dev->base_addr + TxProducerIdx); + + if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) + np->tx_full = 1; + if (! np->tx_full) + clear_bit(0, (void*)&dev->tbusy); + dev->trans_start = jiffies; + + if (debug > 4) { + printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n", + dev->name, np->cur_tx, entry); + } + return 0; +} + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +{ + struct net_device *dev = (struct net_device *)dev_instance; + struct netdev_private *np; + long ioaddr, boguscnt = max_interrupt_work; + +#ifndef final_version /* Can never occur. */ + if (dev == NULL) { + printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown " + "device.\n", irq); + return; + } +#endif + + ioaddr = dev->base_addr; + np = (struct netdev_private *)dev->priv; +#if defined(__i386__) + /* A lock to prevent simultaneous entry bug on Intel SMP machines. */ + if (test_and_set_bit(0, (void*)&dev->interrupt)) { + printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n", + dev->name); + dev->interrupt = 0; /* Avoid halting machine. */ + return; + } +#else + if (dev->interrupt) { + printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); + return; + } + dev->interrupt = 1; +#endif + + do { + u32 intr_status = readl(ioaddr + IntrClear); + + if (debug > 4) + printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n", + dev->name, intr_status); + + if (intr_status == 0) + break; + + if (intr_status & IntrRxDone) + netdev_rx(dev); + + /* Scavenge the skbuff list based on the Tx-done queue. + There are redundant checks here that may be cleaned up when + after the driver has proven reliable. */ + { + int consumer = readl(ioaddr + TxConsumerIdx); + int tx_status; + if (debug > 4) + printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n", + dev->name, consumer); +#if 0 + if (np->tx_done >= 250 || np->tx_done == 0) + printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, " + "%d is %8.8x.\n", dev->name, + np->tx_done, le32_to_cpu(np->tx_done_q[np->tx_done].status), + (np->tx_done+1) & (DONE_Q_SIZE-1), + le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status)); +#endif + while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) { + if (debug > 4) + printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n", + dev->name, np->tx_done, tx_status); + if ((tx_status & 0xe0000000) == 0xa0000000) { + np->stats.tx_packets++; + } else if ((tx_status & 0xe0000000) == 0x80000000) { + u16 entry = tx_status; /* Implicit truncate */ + entry >>= 3; + /* Scavenge the descriptor. */ + dev_kfree_skb(np->tx_skbuff[entry]); + np->tx_skbuff[entry] = 0; + np->dirty_tx++; + } + np->tx_done_q[np->tx_done].status = 0; + np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1); + } + writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2); + } + if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) { + /* The ring is no longer full, clear tbusy. */ + np->tx_full = 0; + clear_bit(0, (void*)&dev->tbusy); + mark_bh(NET_BH); + } + + /* Abnormal error summary/uncommon events handlers. */ + if (intr_status & IntrAbnormalSummary) + netdev_error(dev, intr_status); + + if (--boguscnt < 0) { + printk(KERN_WARNING "%s: Too much work at interrupt, " + "status=0x%4.4x.\n", + dev->name, intr_status); + break; + } + } while (1); + + if (debug > 4) + printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", + dev->name, readl(ioaddr + IntrStatus)); + +#ifndef final_version + /* Code that should never be run! Remove after testing.. */ + { + static int stopit = 10; + if (dev->start == 0 && --stopit < 0) { + printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n", + dev->name); + free_irq(irq, dev); + } + } +#endif + +#if defined(__i386__) + clear_bit(0, (void*)&dev->interrupt); +#else + dev->interrupt = 0; +#endif + return; +} + +/* This routine is logically part of the interrupt handler, but seperated + for clarity and better register allocation. */ +static int netdev_rx(struct net_device *dev) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; + u32 desc_status; + if (np->rx_done_q == 0) { + printk(KERN_ERR "%s: rx_done_q is NULL! rx_done is %d. %p.\n", + dev->name, np->rx_done, np->tx_done_q); + return 0; + } + + /* If EOP is set on the next entry, it's a new packet. Send it up. */ + while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) { + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() status of %d was %8.8x.\n", + np->rx_done, desc_status); + if (--boguscnt < 0) + break; + if (! (desc_status & RxOK)) { + /* There was a error. */ + if (debug > 2) + printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n", + desc_status); + np->stats.rx_errors++; + if (desc_status & RxFIFOErr) + np->stats.rx_fifo_errors++; + } else { + struct sk_buff *skb; + u16 pkt_len = desc_status; /* Implicitly Truncate */ + int entry = (desc_status >> 16) & 0x7ff; + +#ifndef final_version + if (debug > 4) + printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d" + ", bogus_cnt %d.\n", + pkt_len, boguscnt); +#endif + /* Check if the packet is long enough to accept without copying + to a minimally-sized skbuff. */ + if (pkt_len < rx_copybreak + && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + skb->dev = dev; + skb_reserve(skb, 2); /* 16 byte align the IP header */ +#if HAS_IP_COPYSUM /* Call copy + cksum if available. */ + eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + skb_put(skb, pkt_len); +#else + memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail, + pkt_len); +#endif + } else { + char *temp = skb_put(skb = np->rx_skbuff[entry], pkt_len); + np->rx_skbuff[entry] = NULL; +#ifndef final_version /* Remove after testing. */ + if (bus_to_virt(le32_to_cpu(np->rx_ring[entry].rxaddr) & ~3) != temp) + printk(KERN_ERR "%s: Internal fault: The skbuff addresses " + "do not match in netdev_rx: %p vs. %p / %p.\n", + dev->name, bus_to_virt(le32_to_cpu(np->rx_ring[entry].rxaddr)), + skb->head, temp); +#endif + } +#ifndef final_version /* Remove after testing. */ + /* You will want this info for the initial debug. */ + if (debug > 5) + printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:" + "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x " + "%d.%d.%d.%d.\n", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5], skb->data[6], skb->data[7], + skb->data[8], skb->data[9], skb->data[10], + skb->data[11], skb->data[12], skb->data[13], + skb->data[14], skb->data[15], skb->data[16], + skb->data[17]); +#endif + skb->protocol = eth_type_trans(skb, dev); +#ifdef full_rx_status + if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) + skb->ip_summed = CHECKSUM_UNNECESSARY; +#endif + netif_rx(skb); + dev->last_rx = jiffies; + np->stats.rx_packets++; + } + np->cur_rx++; + np->rx_done_q[np->rx_done].status = 0; + np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1); + } + writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx); + + /* Refill the Rx ring buffers. */ + for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) { + struct sk_buff *skb; + int entry = np->dirty_rx % RX_RING_SIZE; + if (np->rx_skbuff[entry] == NULL) { + skb = dev_alloc_skb(np->rx_buf_sz); + np->rx_skbuff[entry] = skb; + if (skb == NULL) + break; /* Better luck next round. */ + skb->dev = dev; /* Mark as being used by this device. */ + np->rx_ring[entry].rxaddr = cpu_to_le32(virt_to_bus(skb->tail) | RxDescValid); + } + if (entry == RX_RING_SIZE - 1) + np->rx_ring[entry].rxaddr |= cpu_to_le32(RxDescEndRing); + /* We could defer this until later... */ + writew(entry, dev->base_addr + RxDescQIdx); + } + + if (debug > 5 + || memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1)) + printk(KERN_DEBUG " exiting netdev_rx() status of %d was %8.8x %d.\n", + np->rx_done, desc_status, + memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1)); + + /* Restart Rx engine if stopped. */ + return 0; +} + +static void netdev_error(struct net_device *dev, int intr_status) +{ + struct netdev_private *np = (struct netdev_private *)dev->priv; + + if (intr_status & LinkChange) { + printk(KERN_ERR "%s: Link changed: Autonegotiation advertising" + " %4.4x partner %4.4x.\n", dev->name, + mdio_read(dev, np->phys[0], 4), + mdio_read(dev, np->phys[0], 5)); + check_duplex(dev, 0); + } + if (intr_status & StatsMax) { + get_stats(dev); + } + /* Came close to underrunning the Tx FIFO, increase threshold. */ + if (intr_status & IntrTxDataLow) + writel(++np->tx_threshold, dev->base_addr + TxThreshold); + if ((intr_status & + ~(IntrAbnormalSummary|LinkChange|StatsMax|IntrTxDataLow|1)) && debug) + printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", + dev->name, intr_status); + /* Hmmmmm, it's not clear how to recover from PCI faults. */ + if (intr_status & IntrTxPCIErr) + np->stats.tx_fifo_errors++; + if (intr_status & IntrRxPCIErr) + np->stats.rx_fifo_errors++; +} + +static struct enet_statistics *get_stats(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct netdev_private *np = (struct netdev_private *)dev->priv; + + /* We should lock this segment of code for SMP eventually, although + the vulnerability window is very small and statistics are + non-critical. */ +#if LINUX_VERSION_CODE > 0x20119 + np->stats.tx_bytes = readl(ioaddr + 0x57010); + np->stats.rx_bytes = readl(ioaddr + 0x57044); +#endif + np->stats.tx_packets = readl(ioaddr + 0x57000); + np->stats.tx_aborted_errors = + readl(ioaddr + 0x57024) + readl(ioaddr + 0x57028); + np->stats.tx_window_errors = readl(ioaddr + 0x57018); + np->stats.collisions = readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008); + + /* The chip only need report frame silently dropped. */ + np->stats.rx_dropped += readw(ioaddr + RxDMAStatus); + writew(0, ioaddr + RxDMAStatus); + np->stats.rx_crc_errors = readl(ioaddr + 0x5703C); + np->stats.rx_frame_errors = readl(ioaddr + 0x57040); + np->stats.rx_length_errors = readl(ioaddr + 0x57058); + np->stats.rx_missed_errors = readl(ioaddr + 0x5707C); + + return &np->stats; +} + +/* The little-endian AUTODIN II ethernet CRC calculations. + A big-endian version is also available. + This is slow but compact code. Do not use this routine for bulk data, + use a table-based routine instead. + This is common code and should be moved to net/core/crc.c. + Chips may use the upper or lower CRC bits, and may reverse and/or invert + them. Select the endian-ness that results in minimal calculations. +*/ +static unsigned const ethernet_polynomial_le = 0xedb88320U; +static inline unsigned ether_crc_le(int length, unsigned char *data) +{ + unsigned int crc = 0xffffffff; /* Initial value. */ + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 8; --bit >= 0; current_octet >>= 1) { + if ((crc ^ current_octet) & 1) { + crc >>= 1; + crc ^= ethernet_polynomial_le; + } else + crc >>= 1; + } + } + return crc; +} + +static void set_rx_mode(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + u32 rx_mode; + struct dev_mc_list *mclist; + int i; + + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + /* Unconditionally log net taps. */ + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys; + } else if ((dev->mc_count > multicast_filter_limit) + || (dev->flags & IFF_ALLMULTI)) { + /* Too many to match, or accept all multicasts. */ + rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys; + } else if (dev->mc_count <= 15) { + /* Use the 16 element perfect filter. */ + long filter_addr = ioaddr + 0x56000 + 1*16; + for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count; + i++, mclist = mclist->next) { + u16 *eaddrs = (u16 *)mclist->dmi_addr; + writew(*eaddrs++, filter_addr); filter_addr += 4; + writew(*eaddrs++, filter_addr); filter_addr += 4; + writew(*eaddrs++, filter_addr); filter_addr += 8; + } + while (i++ < 16) { + writew(0xffff, filter_addr); filter_addr += 4; + writew(0xffff, filter_addr); filter_addr += 4; + writew(0xffff, filter_addr); filter_addr += 8; + } + rx_mode = AcceptBroadcast | AcceptMyPhys; + } else { + /* Must use a multicast hash table. */ + long filter_addr; + u16 mc_filter[32] __attribute__ ((aligned(sizeof(long)))); /* Multicast hash filter */ + + memset(mc_filter, 0, sizeof(mc_filter)); + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23, mc_filter); + } + /* Clear the perfect filter list. */ + filter_addr = ioaddr + 0x56000 + 1*16; + for (i = 1; i < 16; i++) { + writew(0xffff, filter_addr); filter_addr += 4; + writew(0xffff, filter_addr); filter_addr += 4; + writew(0xffff, filter_addr); filter_addr += 8; + } + for (filter_addr=ioaddr + 0x56100, i=0; i < 32; filter_addr+= 16, i++) + writew(mc_filter[i], filter_addr); + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + } + writel(rx_mode|AcceptAll, ioaddr + RxFilterMode); +} + +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + u16 *data = (u16 *)&rq->ifr_data; + + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + data[0] = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; + /* Fall Through */ + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f); + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int netdev_close(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct netdev_private *np = (struct netdev_private *)dev->priv; + int i; + + dev->start = 0; + dev->tbusy = 1; + + if (debug > 1) { + printk(KERN_DEBUG "%s: Shutting down ethercard, status was Int %4.4x.\n", + dev->name, readl(ioaddr + IntrStatus)); + printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", + dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx); + } + + /* Disable interrupts by clearing the interrupt mask. */ + writel(0, ioaddr + IntrEnable); + + /* Stop the chip's Tx and Rx processes. */ + + del_timer(&np->timer); + +#ifdef __i386__ + if (debug > 2) { + printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", + (int)virt_to_bus(np->tx_ring)); + for (i = 0; i < 8 /* TX_RING_SIZE */; i++) + printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n", + i, le32_to_cpu(np->tx_ring[i].status), + le32_to_cpu(np->tx_ring[i].addr), + le32_to_cpu(np->tx_done_q[i].status)); + printk(KERN_DEBUG " Rx ring at %8.8x -> %p:\n", + (int)virt_to_bus(np->rx_ring), np->rx_done_q); + if (np->rx_done_q) + for (i = 0; i < 8 /* RX_RING_SIZE */; i++) { + printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n", + i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status)); + } + } +#endif /* __i386__ debugging only */ + + free_irq(dev->irq, dev); + + /* Free all the skbuffs in the Rx queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + np->rx_ring[i].rxaddr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ + if (np->rx_skbuff[i]) { +#if LINUX_VERSION_CODE < 0x20100 + np->rx_skbuff[i]->free = 1; +#endif + dev_kfree_skb(np->rx_skbuff[i]); + } + np->rx_skbuff[i] = 0; + } + for (i = 0; i < TX_RING_SIZE; i++) { + if (np->tx_skbuff[i]) + dev_kfree_skb(np->tx_skbuff[i]); + np->tx_skbuff[i] = 0; + } + + MOD_DEC_USE_COUNT; + + return 0; +} + + +#ifdef MODULE +int init_module(void) +{ + if (debug) /* Emit version even if no cards detected. */ + printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); +#ifdef CARDBUS + register_driver(ðerdev_ops); + return 0; +#else + if (pci_etherdev_probe(NULL, pci_tbl)) { + printk(KERN_INFO " No Starfire adapters detected, driver not loaded.\n"); + return -ENODEV; + } + return 0; +#endif +} + +void cleanup_module(void) +{ + struct net_device *next_dev; + +#ifdef CARDBUS + unregister_driver(ðerdev_ops); +#endif + + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ + while (root_net_dev) { + struct netdev_private *np = + (struct netdev_private *)root_net_dev->priv; + next_dev = np->next_module; + unregister_netdev(root_net_dev); + iounmap((char *)root_net_dev->base_addr); + if (np->tx_done_q) free_page((long)np->tx_done_q); + if (np->rx_done_q) free_page((long)np->rx_done_q); + kfree(root_net_dev); + root_net_dev = next_dev; + } +} + +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c starfire.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c starfire.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * simple-compile-command: "gcc -DMODULE -D__KERNEL__ -O6 -c starfire.c" + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/drivers/net/strip.c b/drivers/net/strip.c index 32c208a8f..9acb7f031 100644 --- a/drivers/net/strip.c +++ b/drivers/net/strip.c @@ -89,7 +89,6 @@ static const char StripVersion[] = "1.3-STUART.CHESHIRE"; #endif #include <asm/system.h> -#include <linux/types.h> #include <asm/uaccess.h> #include <asm/segment.h> #include <asm/bitops.h> @@ -312,7 +311,7 @@ struct strip struct tty_struct *tty; /* ptr to TTY structure */ char8 if_name; /* Dynamically generated name */ - struct device dev; /* Our device structure */ + struct net_device dev; /* Our device structure */ /* * Neighbour radio records @@ -506,7 +505,7 @@ extern __inline__ void RestoreInterrupts(InterruptStatus x) restore_flags(x); } -static int arp_query(unsigned char *haddr, u32 paddr, struct device * dev) +static int arp_query(unsigned char *haddr, u32 paddr, struct net_device * dev) { struct neighbour *neighbor_entry; @@ -933,7 +932,7 @@ static __u8 *radio_address_to_string(const MetricomAddress *addr, MetricomAddres static int allocate_buffers(struct strip *strip_info) { - struct device *dev = &strip_info->dev; + struct net_device *dev = &strip_info->dev; int sx_size = MAX(STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096); int tx_size = STRIP_ENCAP_SIZE(dev->mtu) + MaxCommandStringLength; __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC); @@ -964,7 +963,7 @@ static int allocate_buffers(struct strip *strip_info) static void strip_changedmtu(struct strip *strip_info) { int old_mtu = strip_info->mtu; - struct device *dev = &strip_info->dev; + struct net_device *dev = &strip_info->dev; unsigned char *orbuff = strip_info->rx_buff; unsigned char *osbuff = strip_info->sx_buff; unsigned char *otbuff = strip_info->tx_buff; @@ -1465,9 +1464,18 @@ static unsigned char *strip_make_packet(unsigned char *buffer, struct strip *str */ if (haddr.c[0] == 0xFF) { - struct in_device *in_dev = strip_info->dev.ip_ptr; + u32 brd = 0; + struct in_device *in_dev = in_dev_get(&strip_info->dev); + if (in_dev == NULL) + return NULL; + read_lock(&in_dev->lock); + if (in_dev->ifa_list) + brd = in_dev->ifa_list->ifa_broadcast; + read_unlock(&in_dev->lock); + in_dev_put(in_dev); + /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */ - if (!arp_query(haddr.c, in_dev->ifa_list->ifa_broadcast, &strip_info->dev)) + if (!arp_query(haddr.c, brd, &strip_info->dev)) { printk(KERN_ERR "%s: Unable to send packet (no broadcast hub configured)\n", strip_info->dev.name); @@ -1511,7 +1519,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) unsigned char *ptr = strip_info->tx_buff; int doreset = (long)jiffies - strip_info->watchdog_doreset >= 0; int doprobe = (long)jiffies - strip_info->watchdog_doprobe >= 0 && !doreset; - struct in_device *in_dev = strip_info->dev.ip_ptr; + u32 addr, brd; /* * 1. If we have a packet, encapsulate it and put it in the buffer @@ -1595,6 +1603,21 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) */ if (doreset) { ResetRadio(strip_info); return; } + if (1) { + struct in_device *in_dev = in_dev_get(&strip_info->dev); + brd = addr = 0; + if (in_dev) { + read_lock(&in_dev->lock); + if (in_dev->ifa_list) { + brd = in_dev->ifa_list->ifa_broadcast; + addr = in_dev->ifa_list->ifa_local; + } + read_unlock(&in_dev->lock); + in_dev_put(in_dev); + } + } + + /* * 6. If it is time for a periodic ARP, queue one up to be sent. * We only do this if: @@ -1611,7 +1634,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) */ if (strip_info->working && (long)jiffies - strip_info->gratuitous_arp >= 0 && memcmp(strip_info->dev.dev_addr, zero_address.c, sizeof(zero_address)) && - arp_query(haddr.c, in_dev->ifa_list->ifa_broadcast, &strip_info->dev)) + arp_query(haddr.c, brd, &strip_info->dev)) { /*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n", strip_info->dev.name, strip_info->arp_interval / HZ);*/ @@ -1619,12 +1642,12 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) strip_info->arp_interval *= 2; if (strip_info->arp_interval > MaxARPInterval) strip_info->arp_interval = MaxARPInterval; - if (in_dev && in_dev->ifa_list) + if (addr) arp_send( ARPOP_REPLY, ETH_P_ARP, - in_dev->ifa_list->ifa_address, /* Target address of ARP packet is our address */ + addr, /* Target address of ARP packet is our address */ &strip_info->dev, /* Device to send packet on */ - in_dev->ifa_list->ifa_address, /* Source IP address this ARP packet comes from */ + addr, /* Source IP address this ARP packet comes from */ NULL, /* Destination HW address is NULL (broadcast it) */ strip_info->dev.dev_addr, /* Source HW address is our HW address */ strip_info->dev.dev_addr); /* Target HW address is our HW address (redundant) */ @@ -1637,7 +1660,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) } /* Encapsulate a datagram and kick it into a TTY queue. */ -static int strip_xmit(struct sk_buff *skb, struct device *dev) +static int strip_xmit(struct sk_buff *skb, struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -1694,7 +1717,7 @@ static int strip_xmit(struct sk_buff *skb, struct device *dev) static void strip_IdleTask(unsigned long parameter) { - strip_xmit(NULL, (struct device *)parameter); + strip_xmit(NULL, (struct net_device *)parameter); } /* @@ -1708,7 +1731,7 @@ static void strip_IdleTask(unsigned long parameter) * rebuild_header later to fill in the address) */ -static int strip_header(struct sk_buff *skb, struct device *dev, +static int strip_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -2019,7 +2042,7 @@ static void process_Info(struct strip *strip_info, __u8 *ptr, __u8 *end) if (ptr+16 > end) RecvErr("Bad Info Msg:", strip_info); } -static struct device *get_strip_dev(struct strip *strip_info) +static struct net_device *get_strip_dev(struct strip *strip_info) { /* If our hardware address is *manually set* to zero, and we know our */ /* real radio hardware address, try to find another strip device that has been */ @@ -2028,7 +2051,7 @@ static struct device *get_strip_dev(struct strip *strip_info) !memcmp(strip_info->dev.dev_addr, zero_address.c, sizeof(zero_address)) && memcmp(&strip_info->true_dev_addr, zero_address.c, sizeof(zero_address))) { - struct device *dev; + struct net_device *dev; read_lock_bh(&dev_base_lock); dev = dev_base; while (dev) @@ -2415,7 +2438,7 @@ static int set_mac_address(struct strip *strip_info, MetricomAddress *addr) return 0; } -static int dev_set_mac_address(struct device *dev, void *addr) +static int dev_set_mac_address(struct net_device *dev, void *addr) { struct strip *strip_info = (struct strip *)(dev->priv); struct sockaddr *sa = addr; @@ -2424,7 +2447,7 @@ static int dev_set_mac_address(struct device *dev, void *addr) return 0; } -static struct enet_statistics *strip_get_stats(struct device *dev) +static struct enet_statistics *strip_get_stats(struct net_device *dev) { static struct enet_statistics stats; struct strip *strip_info = (struct strip *)(dev->priv); @@ -2469,10 +2492,12 @@ static struct enet_statistics *strip_get_stats(struct device *dev) /* Open the low-level part of the STRIP channel. Easy! */ -static int strip_open_low(struct device *dev) +static int strip_open_low(struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); +#if 0 struct in_device *in_dev = dev->ip_ptr; +#endif if (strip_info->tty == NULL) return(-ENODEV); @@ -2489,12 +2514,17 @@ static int strip_open_low(struct device *dev) strip_info->next_command = CompatibilityCommand; strip_info->user_baud = get_baud(strip_info->tty); +#if 0 /* * Needed because address '0' is special + * + * --ANK Needed it or not needed, it does not matter at all. + * Make it at user level, guys. */ if (in_dev->ifa_list->ifa_address == 0) in_dev->ifa_list->ifa_address = ntohl(0xC0A80001); +#endif dev->tbusy = 0; dev->start = 1; @@ -2510,7 +2540,7 @@ static int strip_open_low(struct device *dev) * Close the low-level part of the STRIP channel. Easy! */ -static int strip_close_low(struct device *dev) +static int strip_close_low(struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -2547,7 +2577,7 @@ static int strip_close_low(struct device *dev) * (dynamically assigned) device is registered */ -static int strip_dev_init(struct device *dev) +static int strip_dev_init(struct net_device *dev) { /* * Finish setting up the DEVICE info. @@ -2822,7 +2852,7 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file, #ifdef MODULE static #endif -int strip_init_ctrl_dev(struct device *dummy) +int strip_init_ctrl_dev(struct net_device *dummy) { static struct tty_ldisc strip_ldisc; int status; diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c new file mode 100644 index 000000000..4fff08b7f --- /dev/null +++ b/drivers/net/sun3lance.c @@ -0,0 +1,885 @@ +/* sun3lance.c: Ethernet driver for SUN3 Lance chip */ +/* + + Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net). + This driver is a part of the linux kernel, and is thus distributed + under the GNU Public License. + + The values used in LANCE_OBIO and LANCE_IRQ seem to be empirically + true for the correct IRQ and address of the lance registers. They + have not been widely tested, however. What we probably need is a + "proper" way to search for a device in the sun3's prom, but, alas, + linux has no such thing. + + This driver is largely based on atarilance.c, by Roman Hodek. Other + sources of inspiration were the NetBSD sun3 am7990 driver, and the + linux sparc lance driver (sunlance.c). + + There are more assumptions made throughout this driver, it almost + certainly still needs work, but it does work at least for RARP/BOOTP and + mounting the root NFS filesystem. + +*/ + +static char *version = "sun3lance.c: v1.0 12/12/96 Sam Creasey (sammy@users.qual.net)\n"; + +#include <linux/module.h> + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/malloc.h> +#include <linux/interrupt.h> +#include <linux/init.h> + +#include <asm/setup.h> +#include <asm/irq.h> + +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/idprom.h> +#include <asm/pgtable.h> +#include <asm/sun3mmu.h> +#include <asm/dvma.h> + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> + +/* sun3/60 addr/irq for the lance chip. If your sun is different, + change this. */ +#define LANCE_OBIO 0x120000 +#define LANCE_IRQ IRQ3 + +/* Debug level: + * 0 = silent, print only serious errors + * 1 = normal, print error messages + * 2 = debug, print debug infos + * 3 = debug, print even more debug infos (packet data) + */ + +#define LANCE_DEBUG 1 + +#ifdef LANCE_DEBUG +static int lance_debug = LANCE_DEBUG; +#else +static int lance_debug = 1; +#endif +MODULE_PARM(lance_debug, "i"); + +#define DPRINTK(n,a) \ + do { \ + if (lance_debug >= n) \ + printk a; \ + } while( 0 ) + + +/* we're only using 32k of memory, so we use 4 TX + buffers and 16 RX buffers. These values are expressed as log2. */ + +#define TX_LOG_RING_SIZE 3 +#define RX_LOG_RING_SIZE 5 + +/* These are the derived values */ + +#define TX_RING_SIZE (1 << TX_LOG_RING_SIZE) +#define TX_RING_LEN_BITS (TX_LOG_RING_SIZE << 5) +#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) + +#define RX_RING_SIZE (1 << RX_LOG_RING_SIZE) +#define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5) +#define RX_RING_MOD_MASK (RX_RING_SIZE - 1) + +/* Definitions for packet buffer access: */ +#define PKT_BUF_SZ 1544 + +/* Get the address of a packet buffer corresponding to a given buffer head */ +#define PKTBUF_ADDR(head) (void *)((unsigned long)(MEM) | (head)->base) + + +/* The LANCE Rx and Tx ring descriptors. */ +struct lance_rx_head { + unsigned short base; /* Low word of base addr */ + volatile unsigned char flag; + unsigned char base_hi; /* High word of base addr (unused) */ + short buf_length; /* This length is 2s complement! */ + volatile short msg_length; /* This length is "normal". */ +}; + +struct lance_tx_head { + unsigned short base; /* Low word of base addr */ + volatile unsigned char flag; + unsigned char base_hi; /* High word of base addr (unused) */ + short length; /* Length is 2s complement! */ + volatile short misc; +}; + +/* The LANCE initialization block, described in databook. */ +struct lance_init_block { + unsigned short mode; /* Pre-set mode */ + unsigned char hwaddr[6]; /* Physical ethernet address */ + unsigned int filter[2]; /* Multicast filter (unused). */ + /* Receive and transmit ring base, along with length bits. */ + unsigned short rdra; + unsigned short rlen; + unsigned short tdra; + unsigned short tlen; + unsigned short pad[4]; /* is thie needed? */ +}; + +/* The whole layout of the Lance shared memory */ +struct lance_memory { + struct lance_init_block init; + struct lance_tx_head tx_head[TX_RING_SIZE]; + struct lance_rx_head rx_head[RX_RING_SIZE]; + char rx_data[RX_RING_SIZE][PKT_BUF_SZ]; + char tx_data[RX_RING_SIZE][PKT_BUF_SZ]; +}; + +/* The driver's private device structure */ + +struct lance_private { + volatile unsigned short *iobase; + struct lance_memory *mem; + int new_rx, new_tx; /* The next free ring entry */ + int old_tx, old_rx; /* ring entry to be processed */ + struct net_device_stats stats; +/* These two must be ints for set_bit() */ + int tx_full; + int lock; +}; + +/* I/O register access macros */ + +#define MEM lp->mem +#define DREG lp->iobase[0] +#define AREG lp->iobase[1] +#define REGA(a) ( AREG = (a), DREG ) + +/* Definitions for the Lance */ + +/* tx_head flags */ +#define TMD1_ENP 0x01 /* end of packet */ +#define TMD1_STP 0x02 /* start of packet */ +#define TMD1_DEF 0x04 /* deferred */ +#define TMD1_ONE 0x08 /* one retry needed */ +#define TMD1_MORE 0x10 /* more than one retry needed */ +#define TMD1_ERR 0x40 /* error summary */ +#define TMD1_OWN 0x80 /* ownership (set: chip owns) */ + +#define TMD1_OWN_CHIP TMD1_OWN +#define TMD1_OWN_HOST 0 + +/* tx_head misc field */ +#define TMD3_TDR 0x03FF /* Time Domain Reflectometry counter */ +#define TMD3_RTRY 0x0400 /* failed after 16 retries */ +#define TMD3_LCAR 0x0800 /* carrier lost */ +#define TMD3_LCOL 0x1000 /* late collision */ +#define TMD3_UFLO 0x4000 /* underflow (late memory) */ +#define TMD3_BUFF 0x8000 /* buffering error (no ENP) */ + +/* rx_head flags */ +#define RMD1_ENP 0x01 /* end of packet */ +#define RMD1_STP 0x02 /* start of packet */ +#define RMD1_BUFF 0x04 /* buffer error */ +#define RMD1_CRC 0x08 /* CRC error */ +#define RMD1_OFLO 0x10 /* overflow */ +#define RMD1_FRAM 0x20 /* framing error */ +#define RMD1_ERR 0x40 /* error summary */ +#define RMD1_OWN 0x80 /* ownership (set: ship owns) */ + +#define RMD1_OWN_CHIP RMD1_OWN +#define RMD1_OWN_HOST 0 + +/* register names */ +#define CSR0 0 /* mode/status */ +#define CSR1 1 /* init block addr (low) */ +#define CSR2 2 /* init block addr (high) */ +#define CSR3 3 /* misc */ +#define CSR8 8 /* address filter */ +#define CSR15 15 /* promiscuous mode */ + +/* CSR0 */ +/* (R=readable, W=writeable, S=set on write, C=clear on write) */ +#define CSR0_INIT 0x0001 /* initialize (RS) */ +#define CSR0_STRT 0x0002 /* start (RS) */ +#define CSR0_STOP 0x0004 /* stop (RS) */ +#define CSR0_TDMD 0x0008 /* transmit demand (RS) */ +#define CSR0_TXON 0x0010 /* transmitter on (R) */ +#define CSR0_RXON 0x0020 /* receiver on (R) */ +#define CSR0_INEA 0x0040 /* interrupt enable (RW) */ +#define CSR0_INTR 0x0080 /* interrupt active (R) */ +#define CSR0_IDON 0x0100 /* initialization done (RC) */ +#define CSR0_TINT 0x0200 /* transmitter interrupt (RC) */ +#define CSR0_RINT 0x0400 /* receiver interrupt (RC) */ +#define CSR0_MERR 0x0800 /* memory error (RC) */ +#define CSR0_MISS 0x1000 /* missed frame (RC) */ +#define CSR0_CERR 0x2000 /* carrier error (no heartbeat :-) (RC) */ +#define CSR0_BABL 0x4000 /* babble: tx-ed too many bits (RC) */ +#define CSR0_ERR 0x8000 /* error (RC) */ + +/* CSR3 */ +#define CSR3_BCON 0x0001 /* byte control */ +#define CSR3_ACON 0x0002 /* ALE control */ +#define CSR3_BSWP 0x0004 /* byte swap (1=big endian) */ + +/***************************** Prototypes *****************************/ + +static int lance_probe( struct net_device *dev); +static int lance_open( struct net_device *dev ); +static void lance_init_ring( struct net_device *dev ); +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); +static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); +static int lance_rx( struct net_device *dev ); +static int lance_close( struct net_device *dev ); +static struct net_device_stats *lance_get_stats( struct net_device *dev ); +static void set_multicast_list( struct net_device *dev ); + +/************************* End of Prototypes **************************/ + +int __init sun3lance_probe( struct net_device *dev ) +{ + static int found = 0; + + if(found) + return(ENODEV); + + if (lance_probe(dev)) { + found = 1; + return( 0 ); + } + + return( ENODEV ); +} + +static int __init lance_probe( struct net_device *dev) +{ + unsigned long ioaddr, iopte; + + struct lance_private *lp; + int i; + static int did_version = 0; + int found = 0; + + /* LANCE_OBIO can be found within the IO pmeg with some effort */ + for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 + + SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) { + + iopte = sun3_get_pte(ioaddr); + if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */ + continue; + + if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) == + LANCE_OBIO) { + found = 1; + break; + } + } + + if(!found) + return 0; + + init_etherdev( dev, sizeof(struct lance_private) ); + if (!dev->priv) + dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL ); + lp = (struct lance_private *)dev->priv; + MEM = (struct lance_memory *)sun3_dvma_malloc(sizeof(struct + lance_memory)); + lp->iobase = (volatile unsigned short *)ioaddr; + dev->base_addr = (unsigned long)ioaddr; /* informational only */ + + REGA(CSR0) = CSR0_STOP; + + request_irq(LANCE_IRQ, lance_interrupt, 0, "SUN3 Lance", dev); + dev->irq = (unsigned short)LANCE_IRQ; + + + printk("%s: SUN3 Lance at io %#lx, mem %#lx, irq %d, hwaddr ", + dev->name, + (unsigned long)ioaddr, + (unsigned long)MEM, + dev->irq); + + /* copy in the ethernet address from the prom */ + for(i = 0; i < 6 ; i++) + dev->dev_addr[i] = idprom->id_ethaddr[i]; + + /* tell the card it's ether address, bytes swapped */ + MEM->init.hwaddr[0] = dev->dev_addr[1]; + MEM->init.hwaddr[1] = dev->dev_addr[0]; + MEM->init.hwaddr[2] = dev->dev_addr[3]; + MEM->init.hwaddr[3] = dev->dev_addr[2]; + MEM->init.hwaddr[4] = dev->dev_addr[5]; + MEM->init.hwaddr[5] = dev->dev_addr[4]; + + for( i = 0; i < 6; ++i ) + printk( "%02x%s", dev->dev_addr[i], (i < 5) ? ":" : "\n" ); + + MEM->init.mode = 0x0000; + MEM->init.filter[0] = 0x00000000; + MEM->init.filter[1] = 0x00000000; + MEM->init.rdra = sun3_dvma_vtop(MEM->rx_head); + MEM->init.rlen = (RX_LOG_RING_SIZE << 13) | + (sun3_dvma_vtop(MEM->rx_head) >> 16); + MEM->init.tdra = sun3_dvma_vtop(MEM->tx_head); + MEM->init.tlen = (TX_LOG_RING_SIZE << 13) | + (sun3_dvma_vtop(MEM->tx_head) >> 16); + + DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n", + sun3_dvma_vtop(&(MEM->init)), sun3_dvma_vtop(MEM->rx_head), + (sun3_dvma_vtop(MEM->tx_head)))); + + + if (did_version++ == 0) + DPRINTK( 1, ( version )); + + /* The LANCE-specific entries in the device structure. */ + dev->open = &lance_open; + dev->hard_start_xmit = &lance_start_xmit; + dev->stop = &lance_close; + dev->get_stats = &lance_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->set_mac_address = 0; + dev->start = 0; + + memset( &lp->stats, 0, sizeof(lp->stats) ); + + return 1; +} + +static int lance_open( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + int i; + + DPRINTK( 2, ( "%s: lance_open()\n", dev->name )); + + REGA(CSR0) = CSR0_STOP; + + /* tell the lance the address of its init block */ + REGA(CSR1) = sun3_dvma_vtop(&(MEM->init)); + REGA(CSR2) = sun3_dvma_vtop(&(MEM->init)) >> 16; + + lance_init_ring(dev); + + /* Re-initialize the LANCE, and start it when done. */ + + REGA(CSR3) = CSR3_BSWP; + + /* From now on, AREG is kept to point to CSR0 */ + REGA(CSR0) = CSR0_INIT; + + i = 1000000; + while (--i > 0) + if (DREG & CSR0_IDON) + break; + if (i < 0 || (DREG & CSR0_ERR)) { + DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", + dev->name, i, DREG )); + DREG = CSR0_STOP; + return( -EIO ); + } + + DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA; + + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); + MOD_INC_USE_COUNT; + + return( 0 ); +} + + +/* Initialize the LANCE Rx and Tx rings. */ + +static void lance_init_ring( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + int i; + + lp->lock = 0; + lp->tx_full = 0; + lp->new_rx = lp->new_tx = 0; + lp->old_rx = lp->old_tx = 0; + + for( i = 0; i < TX_RING_SIZE; i++ ) { + MEM->tx_head[i].base = sun3_dvma_vtop(MEM->tx_data[i]); + MEM->tx_head[i].flag = 0; + MEM->tx_head[i].base_hi = + (sun3_dvma_vtop(MEM->tx_data[i])) >>16; + MEM->tx_head[i].length = 0; + MEM->tx_head[i].misc = 0; + } + + for( i = 0; i < RX_RING_SIZE; i++ ) { + MEM->rx_head[i].base = sun3_dvma_vtop(MEM->rx_data[i]); + MEM->rx_head[i].flag = TMD1_OWN_CHIP; + MEM->rx_head[i].base_hi = + (sun3_dvma_vtop(MEM->rx_data[i])) >> 16; + MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000; + MEM->rx_head[i].msg_length = 0; + } + +} + + +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + int entry, len; + struct lance_tx_head *head; + unsigned long flags; + + /* Transmitter timeout, serious problems. */ + if (dev->tbusy) { + int tickssofar = jiffies - dev->trans_start; + if (tickssofar < 20) + return( 1 ); + + DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n", + dev->name, DREG )); + DREG = CSR0_STOP; + /* + * Always set BSWP after a STOP as STOP puts it back into + * little endian mode. + */ + REGA(CSR3) = CSR3_BSWP; + lp->stats.tx_errors++; + + if(lance_debug >= 2) { + int i; + printk("Ring data: old_tx %d new_tx %d%s new_rx %d\n", + lp->old_tx, lp->new_tx, + lp->tx_full ? " (full)" : "", + lp->new_rx ); + for( i = 0 ; i < RX_RING_SIZE; i++ ) + printk( "rx #%d: base=%04x blen=%04x mlen=%04x\n", + i, MEM->rx_head[i].base, + -MEM->rx_head[i].buf_length, + MEM->rx_head[i].msg_length); + for( i = 0 ; i < TX_RING_SIZE; i++ ) + printk("tx #%d: base=%04x len=%04x misc=%04x\n", + i, MEM->tx_head[i].base, + -MEM->tx_head[i].length, + MEM->tx_head[i].misc ); + } + + lance_init_ring(dev); + REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT; + + dev->tbusy = 0; + dev->trans_start = jiffies; + + return 0; + } + + AREG = CSR0; +// DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", +// dev->name, DREG )); + + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit( 0, (void*)&dev->tbusy ) != 0) { + printk("%s: Transmitter access conflict.\n", dev->name); + return 1; + } + + if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) { + printk( "%s: tx queue lock!.\n", dev->name); + /* don't clear dev->tbusy flag. */ + return 1; + } + + /* Fill in a Tx ring entry */ +#if 0 + if (lance_debug >= 3) { + u_char *p; + int i; + printk( "%s: TX pkt %d type 0x%04x from ", dev->name, + lp->new_tx, ((u_short *)skb->data)[6]); + for( p = &((u_char *)skb->data)[6], i = 0; i < 6; i++ ) + printk("%02x%s", *p++, i != 5 ? ":" : "" ); + printk(" to "); + for( p = (u_char *)skb->data, i = 0; i < 6; i++ ) + printk("%02x%s", *p++, i != 5 ? ":" : "" ); + printk(" data at 0x%08x len %d\n", (int)skb->data, + (int)skb->len ); + } +#endif + /* We're not prepared for the int until the last flags are set/reset. + * And the int may happen already after setting the OWN_CHIP... */ + save_and_cli(flags); + + /* Mask to ring buffer boundary. */ + entry = lp->new_tx; + head = &(MEM->tx_head[entry]); + + /* Caution: the write order is important here, set the "ownership" bits + * last. + */ + + /* the sun3's lance needs it's buffer padded to the minimum + size */ + len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + +// head->length = -len; + head->length = (-len) | 0xf000; + head->misc = 0; + + memcpy( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); + head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; + lp->new_tx = (lp->new_tx + 1) & TX_RING_MOD_MASK; + lp->stats.tx_bytes += skb->len; + + /* Trigger an immediate send poll. */ + REGA(CSR0) = CSR0_INEA | CSR0_TDMD; + dev->trans_start = jiffies; + dev_kfree_skb( skb ); + + lp->lock = 0; + if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) == + TMD1_OWN_HOST) + dev->tbusy = 0; + + restore_flags(flags); + + return 0; +} + +/* The LANCE interrupt handler. */ + +static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) +{ + struct net_device *dev = dev_id; + struct lance_private *lp = dev->priv; + int csr0; + + if (dev == NULL) { + DPRINTK( 1, ( "lance_interrupt(): invalid dev_id\n" )); + return; + } + + if (dev->interrupt) + DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name )); + dev->interrupt = 1; + + still_more: + + AREG = CSR0; + csr0 = DREG; + + /* ack interrupts */ + DREG = csr0 & (CSR0_TINT | CSR0_RINT); + + /* clear errors */ + if(csr0 & CSR0_ERR) + DREG = CSR0_BABL | CSR0_MERR | CSR0_CERR | CSR0_MISS; + + + DPRINTK( 2, ( "%s: interrupt csr0=%04x new csr=%04x.\n", + dev->name, csr0, DREG )); + + if (csr0 & CSR0_TINT) { /* Tx-done interrupt */ + int old_tx = lp->old_tx; + +// if(lance_debug >= 3) { +// int i; +// +// printk("%s: tx int\n", dev->name); +// +// for(i = 0; i < TX_RING_SIZE; i++) +// printk("ring %d flag=%04x\n", i, +// MEM->tx_head[i].flag); +// } + + while( old_tx != lp->new_tx) { + struct lance_tx_head *head = &(MEM->tx_head[old_tx]); + + DPRINTK(3, ("on tx_ring %d\n", old_tx)); + + if (head->flag & TMD1_OWN_CHIP) + break; /* It still hasn't been Txed */ + + if (head->flag & TMD1_ERR) { + int status = head->misc; + lp->stats.tx_errors++; + if (status & TMD3_RTRY) lp->stats.tx_aborted_errors++; + if (status & TMD3_LCAR) lp->stats.tx_carrier_errors++; + if (status & TMD3_LCOL) lp->stats.tx_window_errors++; + if (status & (TMD3_UFLO | TMD3_BUFF)) { + lp->stats.tx_fifo_errors++; + printk("%s: Tx FIFO error\n", + dev->name); + REGA(CSR0) = CSR0_STOP; + REGA(CSR3) = CSR3_BSWP; + lance_init_ring(dev); + REGA(CSR0) = CSR0_STRT | CSR0_INEA; + return; + } + } else if(head->flag & (TMD1_ENP | TMD1_STP)) { + + head->flag &= ~(TMD1_ENP | TMD1_STP); + if(head->flag & (TMD1_ONE | TMD1_MORE)) + lp->stats.collisions++; + + lp->stats.tx_packets++; + DPRINTK(3, ("cleared tx ring %d\n", old_tx)); + } + old_tx = (old_tx +1) & TX_RING_MOD_MASK; + } + + lp->old_tx = old_tx; + } + + + if (dev->tbusy) { + /* The ring is no longer full, clear tbusy. */ + dev->tbusy = 0; + mark_bh( NET_BH ); + } + + if (csr0 & CSR0_RINT) /* Rx interrupt */ + lance_rx( dev ); + + /* Log misc errors. */ + if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */ + if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */ + if (csr0 & CSR0_MERR) { + DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), " + "status %04x.\n", dev->name, csr0 )); + /* Restart the chip. */ + REGA(CSR0) = CSR0_STOP; + REGA(CSR3) = CSR3_BSWP; + lance_init_ring(dev); + REGA(CSR0) = CSR0_STRT | CSR0_INEA; + } + + + /* Clear any other interrupt, and set interrupt enable. */ +// DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR | +// CSR0_IDON | CSR0_INEA; + + REGA(CSR0) = CSR0_INEA; + + if(DREG & (CSR0_RINT | CSR0_TINT)) { + DPRINTK(2, ("restarting interrupt, csr0=%#04x\n", DREG)); + goto still_more; + } + + DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n", + dev->name, DREG )); + dev->interrupt = 0; + return; +} + +/* get packet, toss into skbuff */ +static int lance_rx( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + int entry = lp->new_rx; + + /* If we own the next entry, it's a new packet. Send it up. */ + while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) { + struct lance_rx_head *head = &(MEM->rx_head[entry]); + int status = head->flag; + + if (status != (RMD1_ENP|RMD1_STP)) { /* There was an error. */ + /* There is a tricky error noted by John Murphy, + <murf@perftech.com> to Russ Nelson: Even with + full-sized buffers it's possible for a jabber packet to use two + buffers, with only the last correctly noting the error. */ + if (status & RMD1_ENP) /* Only count a general error at the */ + lp->stats.rx_errors++; /* end of a packet.*/ + if (status & RMD1_FRAM) lp->stats.rx_frame_errors++; + if (status & RMD1_OFLO) lp->stats.rx_over_errors++; + if (status & RMD1_CRC) lp->stats.rx_crc_errors++; + if (status & RMD1_BUFF) lp->stats.rx_fifo_errors++; + head->flag &= (RMD1_ENP|RMD1_STP); + } else { + /* Malloc up new buffer, compatible with net-3. */ +// short pkt_len = head->msg_length;// & 0xfff; + short pkt_len = (head->msg_length & 0xfff) - 4; + struct sk_buff *skb; + + if (pkt_len < 60) { + printk( "%s: Runt packet!\n", dev->name ); + lp->stats.rx_errors++; + } + else { + skb = dev_alloc_skb( pkt_len+2 ); + if (skb == NULL) { + DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", + dev->name )); + + lp->stats.rx_dropped++; + head->msg_length = 0; + head->flag |= RMD1_OWN_CHIP; + lp->new_rx = (lp->new_rx+1) & + RX_RING_MOD_MASK; + } + +#if 0 + if (lance_debug >= 3) { + u_char *data = PKTBUF_ADDR(head), *p; + printk( "%s: RX pkt %d type 0x%04x from ", dev->name, entry, ((u_short *)data)[6]); + for( p = &data[6], i = 0; i < 6; i++ ) + printk("%02x%s", *p++, i != 5 ? ":" : "" ); + printk(" to "); + for( p = data, i = 0; i < 6; i++ ) + printk("%02x%s", *p++, i != 5 ? ":" : "" ); + printk(" data %02x %02x %02x %02x %02x %02x %02x %02x " + "len %d at %08x\n", + data[15], data[16], data[17], data[18], + data[19], data[20], data[21], data[22], + pkt_len, data); + } +#endif + if (lance_debug >= 3) { + u_char *data = PKTBUF_ADDR(head); + printk( "%s: RX pkt %d type 0x%04x len %d\n ", dev->name, entry, ((u_short *)data)[6], pkt_len); + } + + + skb->dev = dev; + skb_reserve( skb, 2 ); /* 16 byte align */ + skb_put( skb, pkt_len ); /* Make room */ +// memcpy( skb->data, PKTBUF_ADDR(head), pkt_len ); + eth_copy_and_sum(skb, + PKTBUF_ADDR(head), + pkt_len, 0); + + skb->protocol = eth_type_trans( skb, dev ); + netif_rx( skb ); + lp->stats.rx_packets++; + lp->stats.rx_bytes += skb->len; + } + } + +// head->buf_length = -PKT_BUF_SZ | 0xf000; + head->msg_length = 0; + head->flag = RMD1_OWN_CHIP; + + entry = lp->new_rx = (lp->new_rx +1) & RX_RING_MOD_MASK; + } + + /* From lance.c (Donald Becker): */ + /* We should check that at least two ring entries are free. + If not, we should free one and mark stats->rx_dropped++. */ + + return 0; +} + + +static int lance_close( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + + dev->start = 0; + dev->tbusy = 1; + + AREG = CSR0; + + DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n", + dev->name, DREG )); + + /* We stop the LANCE here -- it occasionally polls + memory if we don't. */ + DREG = CSR0_STOP; + + MOD_DEC_USE_COUNT; + return 0; +} + + +static struct net_device_stats *lance_get_stats( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + + return &lp->stats; +} + + +/* Set or clear the multicast filter for this adaptor. + num_addrs == -1 Promiscuous mode, receive all packets + num_addrs == 0 Normal mode, clear multicast list + num_addrs > 0 Multicast mode, receive normal and MC packets, and do + best-effort filtering. + */ + +/* completely untested on a sun3 */ +static void set_multicast_list( struct net_device *dev ) +{ + struct lance_private *lp = (struct lance_private *)dev->priv; + + if (!dev->start) + /* Only possible if board is already started */ + return; + + /* We take the simple way out and always enable promiscuous mode. */ + DREG = CSR0_STOP; /* Temporarily stop the lance. */ + + if (dev->flags & IFF_PROMISC) { + /* Log any net taps. */ + DPRINTK( 1, ( "%s: Promiscuous mode enabled.\n", dev->name )); + REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */ + } else { + short multicast_table[4]; + int num_addrs = dev->mc_count; + int i; + /* We don't use the multicast table, but rely on upper-layer + * filtering. */ + memset( multicast_table, (num_addrs == 0) ? 0 : -1, + sizeof(multicast_table) ); + for( i = 0; i < 4; i++ ) + REGA( CSR8+i ) = multicast_table[i]; + REGA( CSR15 ) = 0; /* Unset promiscuous mode */ + } + + /* + * Always set BSWP after a STOP as STOP puts it back into + * little endian mode. + */ + REGA( CSR3 ) = CSR3_BSWP; + + /* Resume normal operation and reset AREG to CSR0 */ + REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT; +} + + +#ifdef MODULE +static char devicename[9] = { 0, }; + +static struct net_device sun3lance_dev = +{ + devicename, /* filled in by register_netdev() */ + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sun3lance_probe, +}; + +int init_module(void) +{ + int err; + + if ((err = register_netdev( &sun3lance_dev ))) { + if (err == -EIO) { + printk( "SUN3 Lance not detected. Module not loaded.\n"); + } + return( err ); + } + return( 0 ); +} + +void cleanup_module(void) +{ + unregister_netdev( &sun3lance_dev ); +} + +#endif /* MODULE */ + diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index b9f773e5d..f4a926dc9 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -199,7 +199,7 @@ static inline void bigmac_clean_rings(struct bigmac *bp) static void bigmac_init_rings(struct bigmac *bp, int from_irq) { struct bmac_init_block *bb = bp->bmac_block; - struct device *dev = bp->dev; + struct net_device *dev = bp->dev; int i, gfp_flags = GFP_KERNEL; if(from_irq || in_interrupt()) @@ -1014,7 +1014,7 @@ static void sun4c_bigmac_interrupt(int irq, void *dev_id, struct pt_regs *regs) } #endif -static int bigmac_open(struct device *dev) +static int bigmac_open(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; int res; @@ -1041,7 +1041,7 @@ static int bigmac_open(struct device *dev) return res; } -static int bigmac_close(struct device *dev) +static int bigmac_close(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; @@ -1057,7 +1057,7 @@ static int bigmac_close(struct device *dev) } /* Put a packet on the wire. */ -static int bigmac_start_xmit(struct sk_buff *skb, struct device *dev) +static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; int len, entry; @@ -1123,7 +1123,7 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct device *dev) } #ifndef __sparc_v9__ -static int sun4c_bigmac_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4c_bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; struct bigmac_buffers *bbufs = bp->sun4c_buffers; @@ -1182,7 +1182,7 @@ static int sun4c_bigmac_start_xmit(struct sk_buff *skb, struct device *dev) } #endif -static struct enet_statistics *bigmac_get_stats(struct device *dev) +static struct enet_statistics *bigmac_get_stats(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; @@ -1193,7 +1193,7 @@ static struct enet_statistics *bigmac_get_stats(struct device *dev) #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void bigmac_set_multicast(struct device *dev) +static void bigmac_set_multicast(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; struct BIG_MAC_regs *bregs = bp->bregs; @@ -1253,7 +1253,7 @@ static void bigmac_set_multicast(struct device *dev) bregs->rx_cfg |= BIGMAC_RXCFG_ENABLE; } -__initfunc(static int bigmac_ether_init(struct device *dev, struct linux_sbus_device *qec_sdev)) +static int __init bigmac_ether_init(struct net_device *dev, struct linux_sbus_device *qec_sdev) { static unsigned version_printed = 0; struct bigmac *bp = 0; @@ -1492,7 +1492,7 @@ fail_and_cleanup: return res; /* Return error code. */ } -__initfunc(int bigmac_probe(struct device *dev)) +int __init bigmac_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h index 9284654fc..15c691acd 100644 --- a/drivers/net/sunbmac.h +++ b/drivers/net/sunbmac.h @@ -356,7 +356,7 @@ struct bigmac { struct enet_statistics enet_stats; struct linux_sbus_device *qec_sbus_dev; struct linux_sbus_device *bigmac_sbus_dev; - struct device *dev; + struct net_device *dev; struct bigmac *next_module; }; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 86ce45951..77e04b9df 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1046,7 +1046,7 @@ static inline void happy_meal_clean_rings(struct happy_meal *hp) static void happy_meal_init_rings(struct happy_meal *hp, int from_irq) { struct hmeal_init_block *hb = hp->happy_block; - struct device *dev = hp->dev; + struct net_device *dev = hp->dev; int i, gfp_flags = GFP_KERNEL; if(from_irq || in_interrupt()) @@ -1841,7 +1841,7 @@ static inline void sun4c_happy_meal_tx(struct happy_meal *hp) * ring when we cannot get a new skb and give them all back to the happy meal, * maybe things will be "happier" now. */ -static inline void happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -1947,7 +1947,7 @@ static inline void happy_meal_rx(struct happy_meal *hp, struct device *dev, } #ifdef CONFIG_PCI -static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void pci_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2067,7 +2067,7 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev, #endif #ifndef __sparc_v9__ -static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2130,7 +2130,7 @@ static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev RXD((">")); } -static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2242,7 +2242,7 @@ static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct device *dev static void happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2287,7 +2287,7 @@ static void happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) #ifdef CONFIG_PCI static void pci_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2333,7 +2333,7 @@ static void pci_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs #ifndef __sparc_v9__ static void sun4c_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2377,7 +2377,7 @@ static void sun4c_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *re static void sun4d_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2426,20 +2426,49 @@ static void quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs *ptregs int i; for(i = 0; i < 4; i++) { - struct device *hdev = qp->happy_meals[i]; - struct happy_meal *hp = (struct happy_meal *) hdev->priv; - volatile u32 *sreg = qp->irq_status[i]; + struct net_device *dev = qp->happy_meals[i]; + struct happy_meal *hp = (struct happy_meal *) dev->priv; + struct hmeal_gregs *gregs = hp->gregs; + struct hmeal_tcvregs *tregs = hp->tcvregs; + unsigned int happy_status = hme_read32(hp, &gregs->stat); - if(sreg && - (hme_read32(hp, sreg) & (GREG_STAT_ERRORS | - GREG_STAT_MIFIRQ | - GREG_STAT_TXALL | - GREG_STAT_RXTOHOST)) != 0) - qp->handler(irq, hdev, ptregs); + HMD(("quattro_interrupt: status=%08x ",happy_status)); + + dev->interrupt=1; + + if(happy_status & GREG_STAT_ERRORS) { + HMD(("ERRORS ")); + if(happy_meal_is_not_so_happy(hp, gregs, happy_status)) { + dev->interrupt=0; + break; + } + } + + if(happy_status & GREG_STAT_MIFIRQ) { + HMD(("MIFIRQ ")); + happy_meal_mif_interrupt(hp, gregs, tregs); + } + + if(happy_status & GREG_STAT_TXALL) { + HMD(("TXALL ")); + happy_meal_tx(hp); + } + + if(happy_status & GREG_STAT_RXTOHOST) { + HMD(("RXTOHOST ")); + happy_meal_rx(hp, dev, gregs); + } + + if(dev->tbusy && (TX_BUFFS_AVAIL(hp) >= 0)) { + hp->dev->tbusy = 0; + mark_bh(NET_BH); + } + dev->interrupt=0; } + HMD(("done\n")); } -static int happy_meal_open(struct device *dev) +static int happy_meal_open(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int res; @@ -2499,7 +2528,7 @@ after_request_irq: return res; } -static int happy_meal_close(struct device *dev) +static int happy_meal_close(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -2530,7 +2559,7 @@ static int happy_meal_close(struct device *dev) #define SXD(x) #endif -static int happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2593,7 +2622,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) } #ifdef CONFIG_PCI -static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2647,7 +2676,7 @@ static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) #endif #ifndef __sparc_v9__ -static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_buffers *hbufs = hp->sun4c_buffers; @@ -2703,7 +2732,7 @@ static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) return 0; } -static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2756,7 +2785,7 @@ static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) } #endif -static struct net_device_stats *happy_meal_get_stats(struct device *dev) +static struct net_device_stats *happy_meal_get_stats(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -2764,7 +2793,7 @@ static struct net_device_stats *happy_meal_get_stats(struct device *dev) return &hp->net_stats; } -static void happy_meal_set_multicast(struct device *dev) +static void happy_meal_set_multicast(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_bigmacregs *bregs = hp->bigmacregs; @@ -2822,7 +2851,7 @@ static void happy_meal_set_multicast(struct device *dev) } /* Ethtool support... */ -static int happy_meal_ioctl(struct device *dev, +static int happy_meal_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -2947,8 +2976,11 @@ static struct quattro * __init quattro_sbus_find(struct linux_sbus_device *goal_ struct linux_sbus_device *sdev; struct quattro *qp; + if(qfe_sbus_list == NULL) + goto found; + for(qp = qfe_sbus_list; qp != NULL; qp = qp->next) { - for(sdev = qp->quattro_sbus_dev->child; + for(sdev = qp->quattro_sbus_dev; sdev != NULL; sdev = sdev->next) { if(sdev == goal_sdev) @@ -2980,7 +3012,7 @@ found: qp->happy_meals[i] = NULL; } qp->handler = NULL; - qp->quattro_sbus_dev = sdev; + qp->quattro_sbus_dev = goal_sdev; #ifdef CONFIG_PCI qp->quattro_pci_dev = NULL; #endif @@ -3037,7 +3069,7 @@ static void __init quattro_sbus_register_irqs(void) #ifndef __sparc_v9__ if(sparc_cpu_model == sun4c) qp->handler = sun4c_happy_meal_interrupt; - else if(sparc_cpu_model == sun4c) + else if(sparc_cpu_model == sun4d) qp->handler = sun4d_happy_meal_interrupt; else #endif @@ -3061,7 +3093,7 @@ static void __init quattro_sbus_register_irqs(void) static unsigned hme_version_printed = 0; -static int __init happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev, int is_qfe) +static int __init happy_meal_ether_init(struct net_device *dev, struct linux_sbus_device *sdev, int is_qfe) { struct quattro *qp = NULL; struct happy_meal *hp; @@ -3088,7 +3120,7 @@ static int __init happy_meal_ether_init(struct device *dev, struct linux_sbus_de printk(version); if(qfe_slot != -1) - printk("%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet", + printk("%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", dev->name, qfe_slot); else printk("%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ", @@ -3097,10 +3129,14 @@ static int __init happy_meal_ether_init(struct device *dev, struct linux_sbus_de dev->base_addr = (long) sdev; /* XXX Check for local-mac-address property on Quattro... -DaveM */ + /* Quattro local-mac-address... */ + if(qfe_slot != -1 && prom_getproplen(sdev->prom_node,"local-mac-address")==6) + prom_getproperty(sdev->prom_node,"local-mac-address",dev->dev_addr,6); + else + memcpy(dev->dev_addr,idprom->id_ethaddr,6); for(i = 0; i < 6; i++) printk("%2.2x%c", - dev->dev_addr[i] = idprom->id_ethaddr[i], - i == 5 ? ' ' : ':'); + dev->dev_addr[i], i == 5 ? ' ' : ':'); printk("\n"); hp = (struct happy_meal *) dev->priv; @@ -3250,7 +3286,7 @@ static int __init happy_meal_ether_init(struct device *dev, struct linux_sbus_de } #ifdef CONFIG_PCI -static int __init happy_meal_pci_init(struct device *dev, struct pci_dev *pdev) +static int __init happy_meal_pci_init(struct net_device *dev, struct pci_dev *pdev) { struct quattro *qp = NULL; struct pcidev_cookie *pcp; @@ -3324,12 +3360,11 @@ static int __init happy_meal_pci_init(struct device *dev, struct pci_dev *pdev) qp->happy_meals[qfe_slot] = dev; } - hpreg_base = pdev->base_address[0]; - if((hpreg_base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { + hpreg_base = pdev->resource[0].start; + if ((pdev->resource[0].flags & IORESOURCE_IO) != 0) { printk("happymeal(PCI): Cannot find proper PCI device base address.\n"); return ENODEV; } - hpreg_base &= PCI_BASE_ADDRESS_MEM_MASK; if (qfe_slot != -1 && prom_getproplen(node, "local-mac-address") == 6) prom_getproperty(node, "local-mac-address", dev->dev_addr, 6); @@ -3424,7 +3459,7 @@ static int __init happy_meal_pci_init(struct device *dev, struct pci_dev *pdev) } #endif -int __init happy_meal_probe(struct device *dev) +int __init happy_meal_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h index b6b1b8b63..4563300c9 100644 --- a/drivers/net/sunhme.h +++ b/drivers/net/sunhme.h @@ -560,7 +560,7 @@ struct happy_meal { #ifdef CONFIG_PCI struct pci_dev *happy_pci_dev; #endif - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct quattro *qfe_parent; /* For Quattro cards */ int qfe_ent; /* Which instance on quattro */ struct happy_meal *next_module; @@ -587,7 +587,7 @@ struct happy_meal { /* Support for QFE/Quattro cards. */ struct quattro { volatile u32 *irq_status[4]; - struct device *happy_meals[4]; + struct net_device *happy_meals[4]; void (*handler)(int, void *, struct pt_regs *); struct linux_sbus_device *quattro_sbus_dev; @@ -604,107 +604,75 @@ struct quattro { /* We use this to acquire receive skb's that we can DMA directly into. */ #define ALIGNED_RX_SKB_ADDR(addr) \ ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr)) -static inline struct sk_buff *happy_meal_alloc_skb(unsigned int length, int gfp_flags) -{ - struct sk_buff *skb; - - skb = alloc_skb(length + 64, gfp_flags); - if(skb) { - int offset = ALIGNED_RX_SKB_ADDR(skb->data); - - if(offset) - skb_reserve(skb, offset); - } - return skb; -} +#define happy_meal_alloc_skb(__length, __gfp_flags) \ +({ struct sk_buff *__skb; \ + __skb = alloc_skb((__length) + 64, (__gfp_flags)); \ + if(__skb) { \ + int __offset = ALIGNED_RX_SKB_ADDR(__skb->data); \ + if(__offset) \ + skb_reserve(__skb, __offset); \ + } \ + __skb; \ +}) /* Register/DMA access stuff, used to cope with differences between * PCI and SBUS happy meals. */ -extern inline u32 kva_to_hva(struct happy_meal *hp, char *addr) -{ -#ifdef CONFIG_PCI - if(hp->happy_flags & HFLAG_PCI) - return (u32) virt_to_bus((volatile void *)addr); - else -#endif - { -#ifdef __sparc_v9__ - if (((unsigned long) addr) >= MAX_DMA_ADDRESS) { - printk("sunhme: Bogus DMA buffer address " - "[%016lx]\n", ((unsigned long) addr)); - panic("DMA address too large, tell DaveM"); - } -#endif - return sbus_dvma_addr(addr); - } -} - -extern inline unsigned int hme_read32(struct happy_meal *hp, - volatile unsigned int *reg) -{ -#ifdef CONFIG_PCI - if(hp->happy_flags & HFLAG_PCI) - return readl((unsigned long)reg); - else -#endif - return *reg; -} - -extern inline void hme_write32(struct happy_meal *hp, - volatile unsigned int *reg, - unsigned int val) -{ -#ifdef CONFIG_PCI - if(hp->happy_flags & HFLAG_PCI) - writel(val, (unsigned long)reg); - else +#if defined(CONFIG_PCI) +#define kva_to_hva(__hp, __addr) \ +({ u32 __ret; \ + if ((__hp)->happy_flags & HFLAG_PCI) \ + (__ret) = (u32) virt_to_bus((volatile void *)(__addr)); \ + else \ + (__ret) = sbus_dvma_addr(__addr); \ + __ret; \ +}) +#define hme_read32(__hp, __reg) \ +({ unsigned int __ret; \ + if ((__hp)->happy_flags & HFLAG_PCI) \ + __ret = readl((unsigned long)(__reg)); \ + else \ + __ret = *(__reg); \ + __ret; \ +}) +#define hme_write32(__hp, __reg, __val) \ +do { if ((__hp)->happy_flags & HFLAG_PCI) \ + writel((__val), (unsigned long)(__reg)); \ + else \ + *(__reg) = (__val); \ +} while(0) +#else +#define kva_to_hva(__hp, __addr) ((u32)sbus_dvma_addr(__addr)) +#define hme_read32(__hp, __reg) (*(__reg)) +#define hme_write32(__hp, __reg, __val) ((*(__reg)) = (__val)) #endif - *reg = val; -} #ifdef CONFIG_PCI #ifdef __sparc_v9__ -extern inline void pcihme_write_rxd(struct happy_meal_rxd *rp, - unsigned int flags, - unsigned int addr) -{ - __asm__ __volatile__(" - stwa %3, [%0] %2 - stwa %4, [%1] %2 -" : /* no outputs */ - : "r" (&rp->rx_addr), "r" (&rp->rx_flags), - "i" (ASI_PL), "r" (addr), "r" (flags)); -} - -extern inline void pcihme_write_txd(struct happy_meal_txd *tp, - unsigned int flags, - unsigned int addr) -{ - __asm__ __volatile__(" - stwa %3, [%0] %2 - stwa %4, [%1] %2 -" : /* no outputs */ - : "r" (&tp->tx_addr), "r" (&tp->tx_flags), - "i" (ASI_PL), "r" (addr), "r" (flags)); -} +#define pcihme_write_rxd(__rp, __flags, __addr) \ + __asm__ __volatile__("stwa %3, [%0] %2\n\t" \ + "stwa %4, [%1] %2" \ + : /* no outputs */ \ + : "r" (&(__rp)->rx_addr), "r" (&(__rp)->rx_flags), \ + "i" (ASI_PL), "r" (__addr), "r" (__flags)) + +#define pcihme_write_txd(__tp, __flags, __addr) \ + __asm__ __volatile__("stwa %3, [%0] %2\n\t" \ + "stwa %4, [%1] %2" \ + : /* no outputs */ \ + : "r" (&(__tp)->tx_addr), "r" (&(__tp)->tx_flags), \ + "i" (ASI_PL), "r" (__addr), "r" (__flags)) #else -extern inline void pcihme_write_rxd(struct happy_meal_rxd *rp, - unsigned int flags, - unsigned int addr) -{ - rp->rx_addr = flip_dword(addr); - rp->rx_flags = flip_dword(flags); -} +#define pcihme_write_rxd(__rp, __flags, __addr) \ +do { (__rp)->rx_addr = flip_dword(__addr); \ + (__rp)->rx_flags = flip_dword(__flags); \ +} while(0) -extern inline void pcihme_write_txd(struct happy_meal_txd *tp, - unsigned int flags, - unsigned int addr) -{ - tp->tx_addr = flip_dword(addr); - tp->tx_flags = flip_dword(flags); -} +#define pcihme_write_txd(__tp, __flags, __addr) \ +do { (__tp)->tx_addr = flip_dword(__addr); \ + (__tp)->tx_flags = flip_dword(__flags); \ +} while(0) #endif /* def __sparc_v9__ */ #endif /* def CONFIG_PCI */ diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 0d5311080..ae9fb9a63 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.85 1999/03/21 05:22:05 davem Exp $ +/* $Id: sunlance.c,v 1.88 1999/08/20 00:31:45 davem Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -252,7 +252,7 @@ struct lance_private { unsigned short busmaster_regval; unsigned short pio_buffer; - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct lance_private *next_module; struct linux_sbus *sbus; struct timer_list multicast_timer; @@ -311,7 +311,7 @@ static void load_csrs (struct lance_private *lp) /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -444,7 +444,7 @@ static int init_restart_lance (struct lance_private *lp) return 0; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -518,7 +518,7 @@ static int lance_rx (struct device *dev) return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -599,7 +599,7 @@ static int lance_tx (struct device *dev) static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; int csr0; @@ -660,9 +660,9 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open (struct device *dev) +static int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -744,7 +744,7 @@ static int lance_open (struct device *dev) return status; } -static int lance_close (struct device *dev) +static int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -762,7 +762,7 @@ static int lance_close (struct device *dev) return 0; } -static inline int lance_reset (struct device *dev) +static inline int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -793,7 +793,7 @@ static inline int lance_reset (struct device *dev) return status; } -static int lance_start_xmit (struct sk_buff *skb, struct device *dev) +static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -861,7 +861,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev) return 0; } -static struct net_device_stats *lance_get_stats (struct device *dev) +static struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -869,7 +869,7 @@ static struct net_device_stats *lance_get_stats (struct device *dev) } /* taken from the depca driver */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -915,7 +915,7 @@ static void lance_load_multicast (struct device *dev) } } -static void lance_set_multicast (struct device *dev) +static void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -965,10 +965,10 @@ static void lance_set_multicast (struct device *dev) mark_bh(NET_BH); } -__initfunc(static int -sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, +static int __init +sparc_lance_init (struct net_device *dev, struct linux_sbus_device *sdev, struct Linux_SBus_DMA *ledma, - struct linux_sbus_device *lebuffer)) + struct linux_sbus_device *lebuffer) { static unsigned version_printed = 0; int i; @@ -1157,7 +1157,7 @@ find_ledma (struct linux_sbus_device *dev) #include <asm/sun4paddr.h> /* Find all the lance cards on the system and initialize them */ -__initfunc(int sparc_lance_probe (struct device *dev)) +int __init sparc_lance_probe (struct net_device *dev) { static struct linux_sbus_device sdev; static int called = 0; @@ -1179,7 +1179,7 @@ __initfunc(int sparc_lance_probe (struct device *dev)) #else /* !CONFIG_SUN4 */ /* Find all the lance cards on the system and initialize them */ -__initfunc(int sparc_lance_probe (struct device *dev)) +int __init sparc_lance_probe (struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 4b126e3c6..45140e386 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -3,11 +3,11 @@ * controller out there can be most efficiently programmed * if you make it look like a LANCE. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) */ static char *version = - "sunqe.c:v1.1 8/Nov/96 David S. Miller (davem@caipfs.rutgers.edu)\n"; + "sunqe.c:v2.0 9/9/99 David S. Miller (davem@redhat.com)\n"; #include <linux/module.h> @@ -49,6 +49,8 @@ static char *version = static struct sunqec *root_qec_dev = NULL; #endif +static void qe_set_multicast(struct net_device *dev); + #define QEC_RESET_TRIES 200 static inline int qec_global_reset(struct qe_globreg *gregs) @@ -109,82 +111,21 @@ static inline int qe_stop(struct sunqe *qep) return 0; } -static inline void qe_clean_rings(struct sunqe *qep) -{ - int i; - - for(i = 0; i < RX_RING_SIZE; i++) { - if(qep->rx_skbs[i] != NULL) { - dev_kfree_skb(qep->rx_skbs[i]); - qep->rx_skbs[i] = NULL; - } - } - - for(i = 0; i < TX_RING_SIZE; i++) { - if(qep->tx_skbs[i] != NULL) { - dev_kfree_skb(qep->tx_skbs[i]); - qep->tx_skbs[i] = NULL; - } - } -} - -static void qe_init_rings(struct sunqe *qep, int from_irq) -{ - struct qe_init_block *qb = qep->qe_block; - struct device *dev = qep->dev; - int i, gfp_flags = GFP_KERNEL; - - if(from_irq || in_interrupt()) - gfp_flags = GFP_ATOMIC; - - qep->rx_new = qep->rx_old = qep->tx_new = qep->tx_old = 0; - - qe_clean_rings(qep); - - for(i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb; - - skb = qe_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags | GFP_DMA); - if(!skb) - continue; - - qep->rx_skbs[i] = skb; - skb->dev = dev; - - skb_put(skb, ETH_FRAME_LEN); - skb_reserve(skb, 34); - - qb->qe_rxd[i].rx_addr = sbus_dvma_addr(skb->data); - qb->qe_rxd[i].rx_flags = - (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH)); - } - - for(i = 0; i < TX_RING_SIZE; i++) - qb->qe_txd[i].tx_flags = qb->qe_txd[i].tx_addr = 0; -} - -static void sun4c_qe_init_rings(struct sunqe *qep) +static void qe_init_rings(struct sunqe *qep) { struct qe_init_block *qb = qep->qe_block; - struct sunqe_buffers *qbufs = qep->sun4c_buffers; - __u32 qbufs_dvma = qep->s4c_buf_dvma; + struct sunqe_buffers *qbufs = qep->buffers; + __u32 qbufs_dvma = qep->buffers_dvma; int i; qep->rx_new = qep->rx_old = qep->tx_new = qep->tx_old = 0; - + memset(qb, 0, sizeof(struct qe_init_block)); memset(qbufs, 0, sizeof(struct sunqe_buffers)); - - for(i = 0; i < RX_RING_SIZE; i++) - qb->qe_rxd[i].rx_flags = qb->qe_rxd[i].rx_addr = 0; - - for(i = 0; i < SUN4C_RX_RING_SIZE; i++) { + for(i = 0; i < RX_RING_SIZE; i++) { qb->qe_rxd[i].rx_addr = qbufs_dvma + qebuf_offset(rx_buf, i); qb->qe_rxd[i].rx_flags = - (RXD_OWN | ((SUN4C_RX_BUFF_SIZE) & RXD_LENGTH)); + (RXD_OWN | ((RXD_PKT_SZ) & RXD_LENGTH)); } - - for(i = 0; i < TX_RING_SIZE; i++) - qb->qe_txd[i].tx_flags = qb->qe_txd[i].tx_addr = 0; } static int qe_init(struct sunqe *qep, int from_irq) @@ -205,9 +146,10 @@ static int qe_init(struct sunqe *qep, int from_irq) cregs->rxds = qep->qblock_dvma + qib_offset(qe_rxd, 0); cregs->txds = qep->qblock_dvma + qib_offset(qe_txd, 0); - /* Enable the various irq's. */ + /* Enable/mask the various irq's. */ cregs->rimask = 0; - cregs->timask = 0; + cregs->timask = 1; + cregs->qmask = 0; cregs->mmask = CREG_MMASK_RXCOLL; @@ -222,6 +164,7 @@ static int qe_init(struct sunqe *qep, int from_irq) cregs->pipg = 0; /* Now dork with the AMD MACE. */ + mregs->phyconfig = MREGS_PHYCONFIG_AUTO; mregs->txfcntl = MREGS_TXFCNTL_AUTOPAD; /* Save us some tx work. */ mregs->rxfcntl = 0; @@ -240,6 +183,8 @@ static int qe_init(struct sunqe *qep, int from_irq) /* Tell MACE we are changing the ether address. */ mregs->iaconfig = (MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_PARESET); + while ((mregs->iaconfig & MREGS_IACONFIG_ACHNGE) != 0) + barrier(); mregs->ethaddr = e[0]; mregs->ethaddr = e[1]; mregs->ethaddr = e[2]; @@ -249,28 +194,38 @@ static int qe_init(struct sunqe *qep, int from_irq) /* Clear out the address filter. */ mregs->iaconfig = (MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET); - for(i = 0; i < 8; i++) mregs->filter = 0; + while ((mregs->iaconfig & MREGS_IACONFIG_ACHNGE) != 0) + barrier(); + for(i = 0; i < 8; i++) + mregs->filter = 0; /* Address changes are now complete. */ mregs->iaconfig = 0; - if(sparc_cpu_model == sun4c) - sun4c_qe_init_rings(qep); - else - qe_init_rings(qep, from_irq); + qe_init_rings(qep); /* Wait a little bit for the link to come up... */ + mdelay(5); if(!(mregs->phyconfig & MREGS_PHYCONFIG_LTESTDIS)) { - mdelay(5); - if(!(mregs->phyconfig & MREGS_PHYCONFIG_LSTAT)) + int tries = 50; + + while (tries--) { + mdelay(5); + barrier(); + if((mregs->phyconfig & MREGS_PHYCONFIG_LSTAT) != 0) + break; + } + if (tries == 0) printk("%s: Warning, link state is down.\n", qep->dev->name); } /* Missed packet counter is cleared on a read. */ garbage = mregs->mpcnt; - /* Turn on the MACE receiver and transmitter. */ - mregs->mconfig = (MREGS_MCONFIG_TXENAB | MREGS_MCONFIG_RXENAB); + /* Reload multicast information, this will enable the receiver + * and transmitter. But set the base mconfig value right now. + */ + qe_set_multicast(qep->dev); /* QEC should now start to show interrupts. */ return 0; @@ -281,7 +236,7 @@ static int qe_init(struct sunqe *qep, int from_irq) */ static int qe_is_bolixed(struct sunqe *qep, unsigned int qe_status) { - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; int mace_hwbug_workaround = 0; if(qe_status & CREG_STAT_EDEFER) { @@ -429,159 +384,27 @@ static int qe_is_bolixed(struct sunqe *qep, unsigned int qe_status) return mace_hwbug_workaround; } -/* Per-QE transmit complete interrupt service routine. */ -static inline void qe_tx(struct sunqe *qep) -{ - struct qe_txd *txbase = &qep->qe_block->qe_txd[0]; - struct qe_txd *this; - int elem = qep->tx_old; - - while(elem != qep->tx_new) { - struct sk_buff *skb; - - this = &txbase[elem]; - if(this->tx_flags & TXD_OWN) - break; - skb = qep->tx_skbs[elem]; - qep->tx_skbs[elem] = NULL; - qep->net_stats.tx_bytes+=skb->len; - dev_kfree_skb(skb); - - qep->net_stats.tx_packets++; - elem = NEXT_TX(elem); - } - qep->tx_old = elem; -} - -static inline void sun4c_qe_tx(struct sunqe *qep) -{ - struct qe_txd *txbase = &qep->qe_block->qe_txd[0]; - struct qe_txd *this; - int elem = qep->tx_old; - - while(elem != qep->tx_new) { - this = &txbase[elem]; - if(this->tx_flags & TXD_OWN) - break; - qep->net_stats.tx_packets++; - elem = NEXT_TX(elem); - } - qep->tx_old = elem; -} - /* Per-QE receive interrupt service routine. Just like on the happy meal * we receive directly into skb's with a small packet copy water mark. */ -static inline void qe_rx(struct sunqe *qep) -{ - struct qe_rxd *rxbase = &qep->qe_block->qe_rxd[0]; - struct qe_rxd *this; - int elem = qep->rx_new, drops = 0; - - this = &rxbase[elem]; - while(!(this->rx_flags & RXD_OWN)) { - struct sk_buff *skb; - unsigned int flags = this->rx_flags; - int len = (flags & RXD_LENGTH) - 4; /* QE adds ether FCS size to len */ - - /* Check for errors. */ - if(len < ETH_ZLEN) { - qep->net_stats.rx_errors++; - qep->net_stats.rx_length_errors++; - - drop_it: - /* Return it to the QE. */ - qep->net_stats.rx_dropped++; - this->rx_addr = sbus_dvma_addr(qep->rx_skbs[elem]->data); - this->rx_flags = - (RXD_OWN | (RX_BUF_ALLOC_SIZE & RXD_LENGTH)); - goto next; - } - skb = qep->rx_skbs[elem]; -#ifdef NEED_DMA_SYNCHRONIZATION -#ifdef __sparc_v9__ - if ((unsigned long) (skb->data + skb->len) >= MAX_DMA_ADDRESS) { - printk("sunqe: Bogus DMA buffer address " - "[%016lx]\n", ((unsigned long) skb->data)); - panic("DMA address too large, tell DaveM"); - } -#endif - mmu_sync_dma(sbus_dvma_addr(skb->data), - skb->len, qep->qe_sbusdev->my_bus); -#endif - if(len > RX_COPY_THRESHOLD) { - struct sk_buff *new_skb; - - /* Now refill the entry, if we can. */ - new_skb = qe_alloc_skb(RX_BUF_ALLOC_SIZE, (GFP_DMA|GFP_ATOMIC)); - if(!new_skb) { - drops++; - goto drop_it; - } - - qep->rx_skbs[elem] = new_skb; - new_skb->dev = qep->dev; - skb_put(new_skb, ETH_FRAME_LEN); - skb_reserve(new_skb, 34); - - rxbase[elem].rx_addr = sbus_dvma_addr(new_skb->data); - rxbase[elem].rx_flags = - (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH)); - - /* Trim the original skb for the netif. */ - skb_trim(skb, len); - } else { - struct sk_buff *copy_skb = dev_alloc_skb(len + 2); - - if(!copy_skb) { - drops++; - goto drop_it; - } - - copy_skb->dev = qep->dev; - skb_reserve(copy_skb, 2); - skb_put(copy_skb, len); - eth_copy_and_sum(copy_skb, (unsigned char *)skb->data, len, 0); - - /* Reuse original ring buffer. */ - rxbase[elem].rx_addr = sbus_dvma_addr(skb->data); - rxbase[elem].rx_flags = - (RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH)); - - skb = copy_skb; - } - - /* No checksums are done by this card ;-( */ - skb->protocol = eth_type_trans(skb, qep->dev); - netif_rx(skb); - qep->net_stats.rx_packets++; - next: - elem = NEXT_RX(elem); - this = &rxbase[elem]; - } - qep->rx_new = elem; - if(drops) - printk("%s: Memory squeeze, deferring packet.\n", qep->dev->name); -} - -static inline void sun4c_qe_rx(struct sunqe *qep) +static void qe_rx(struct sunqe *qep) { struct qe_rxd *rxbase = &qep->qe_block->qe_rxd[0]; struct qe_rxd *this; - struct sunqe_buffers *qbufs = qep->sun4c_buffers; - __u32 qbufs_dvma = qep->s4c_buf_dvma; + struct sunqe_buffers *qbufs = qep->buffers; + __u32 qbufs_dvma = qep->buffers_dvma; int elem = qep->rx_new, drops = 0; + unsigned int flags; this = &rxbase[elem]; - while(!(this->rx_flags & RXD_OWN)) { + while(!((flags = this->rx_flags) & RXD_OWN)) { struct sk_buff *skb; unsigned char *this_qbuf = - qbufs->rx_buf[elem & (SUN4C_RX_RING_SIZE - 1)]; + &qbufs->rx_buf[elem & (RX_RING_SIZE - 1)][0]; __u32 this_qbuf_dvma = qbufs_dvma + - qebuf_offset(rx_buf, (elem & (SUN4C_RX_RING_SIZE - 1))); + qebuf_offset(rx_buf, (elem & (RX_RING_SIZE - 1))); struct qe_rxd *end_rxd = - &rxbase[(elem+SUN4C_RX_RING_SIZE)&(RX_RING_SIZE-1)]; - unsigned int flags = this->rx_flags; + &rxbase[(elem+RX_RING_SIZE)&(RX_RING_MAXSIZE-1)]; int len = (flags & RXD_LENGTH) - 4; /* QE adds ether FCS size to len */ /* Check for errors. */ @@ -603,10 +426,11 @@ static inline void sun4c_qe_rx(struct sunqe *qep) skb->protocol = eth_type_trans(skb, qep->dev); netif_rx(skb); qep->net_stats.rx_packets++; + qep->net_stats.rx_bytes+=len; } } end_rxd->rx_addr = this_qbuf_dvma; - end_rxd->rx_flags = (RXD_OWN | (SUN4C_RX_BUFF_SIZE & RXD_LENGTH)); + end_rxd->rx_flags = (RXD_OWN | ((RXD_PKT_SZ) & RXD_LENGTH)); elem = NEXT_RX(elem); this = &rxbase[elem]; @@ -631,7 +455,7 @@ static void qec_interrupt(int irq, void *dev_id, struct pt_regs *regs) while(channel < 4) { if(qec_status & 0xf) { struct sunqe *qep = qecp->qes[channel]; - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; unsigned int qe_status; dev->interrupt = 1; @@ -643,55 +467,6 @@ static void qec_interrupt(int irq, void *dev_id, struct pt_regs *regs) if(qe_status & CREG_STAT_RXIRQ) qe_rx(qep); - - if(qe_status & CREG_STAT_TXIRQ) - qe_tx(qep); - - if(dev->tbusy && (TX_BUFFS_AVAIL(qep) >= 0)) { - dev->tbusy = 0; - mark_bh(NET_BH); - } - - next: - dev->interrupt = 0; - } - qec_status >>= 4; - channel++; - } -} - -static void sun4c_qec_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct sunqec *qecp = (struct sunqec *) dev_id; - unsigned int qec_status; - int channel = 0; - - /* Latch the status now. */ - qec_status = qecp->gregs->stat; - while(channel < 4) { - if(qec_status & 0xf) { - struct sunqe *qep = qecp->qes[channel]; - struct device *dev = qep->dev; - unsigned int qe_status; - - dev->interrupt = 1; - - qe_status = qep->qcregs->stat; - if(qe_status & CREG_STAT_ERRORS) - if(qe_is_bolixed(qep, qe_status)) - goto next; - - if(qe_status & CREG_STAT_RXIRQ) - sun4c_qe_rx(qep); - - if(qe_status & CREG_STAT_TXIRQ) - sun4c_qe_tx(qep); - - if(dev->tbusy && (SUN4C_TX_BUFFS_AVAIL(qep) >= 0)) { - dev->tbusy = 0; - mark_bh(NET_BH); - } - next: dev->interrupt = 0; } @@ -700,105 +475,86 @@ static void sun4c_qec_interrupt(int irq, void *dev_id, struct pt_regs *regs) } } -static int qe_open(struct device *dev) +static int qe_open(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; int res; + qep->mconfig = (MREGS_MCONFIG_TXENAB | + MREGS_MCONFIG_RXENAB | + MREGS_MCONFIG_MBAENAB); res = qe_init(qep, 0); - if(!res) { + if(!res) MOD_INC_USE_COUNT; - } + return res; } -static int qe_close(struct device *dev) +static int qe_close(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; qe_stop(qep); - qe_clean_rings(qep); MOD_DEC_USE_COUNT; return 0; } -/* Get a packet queued to go onto the wire. */ -static int qe_start_xmit(struct sk_buff *skb, struct device *dev) +/* Reclaim TX'd frames from the ring. */ +static void qe_tx_reclaim(struct sunqe *qep) { - struct sunqe *qep = (struct sunqe *) dev->priv; - int len, entry; - - if(dev->tbusy) - return 1; - - if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) { - printk("%s: Transmitter access conflict.\n", dev->name); - return 1; - } + struct qe_txd *txbase = &qep->qe_block->qe_txd[0]; + struct net_device *dev = qep->dev; + int elem = qep->tx_old; - if(!TX_BUFFS_AVAIL(qep)) - return 1; + while(elem != qep->tx_new) { + unsigned int flags = txbase[elem].tx_flags; -#ifdef NEED_DMA_SYNCHRONIZATION -#ifdef __sparc_v9__ - if ((unsigned long) (skb->data + skb->len) >= MAX_DMA_ADDRESS) { - struct sk_buff *new_skb = skb_copy(skb, GFP_DMA | GFP_ATOMIC); - if(!new_skb) - return 1; - dev_kfree_skb(skb); - skb = new_skb; + if (flags & TXD_OWN) + break; + qep->net_stats.tx_packets++; + qep->net_stats.tx_bytes+=(flags & TXD_LENGTH); + elem = NEXT_TX(elem); } -#endif - mmu_sync_dma(sbus_dvma_addr(skb->data), - skb->len, qep->qe_sbusdev->my_bus); -#endif - len = skb->len; - entry = qep->tx_new; - - /* Avoid a race... */ - qep->qe_block->qe_txd[entry].tx_flags = TXD_UPDATE; - - qep->tx_skbs[entry] = skb; - - qep->qe_block->qe_txd[entry].tx_addr = sbus_dvma_addr(skb->data); - qep->qe_block->qe_txd[entry].tx_flags = - (TXD_OWN | TXD_SOP | TXD_EOP | (len & TXD_LENGTH)); - qep->tx_new = NEXT_TX(entry); - - /* Get it going. */ - qep->qcregs->ctrl = CREG_CTRL_TWAKEUP; + qep->tx_old = elem; - if(TX_BUFFS_AVAIL(qep)) + if(dev->tbusy && (TX_BUFFS_AVAIL(qep) > 0)) { dev->tbusy = 0; - - return 0; + mark_bh(NET_BH); + } } -static int sun4c_qe_start_xmit(struct sk_buff *skb, struct device *dev) +/* Get a packet queued to go onto the wire. */ +static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; - struct sunqe_buffers *qbufs = qep->sun4c_buffers; - __u32 txbuf_dvma, qbufs_dvma = qep->s4c_buf_dvma; + struct sunqe_buffers *qbufs = qep->buffers; + __u32 txbuf_dvma, qbufs_dvma = qep->buffers_dvma; unsigned char *txbuf; int len, entry; - if(dev->tbusy) - return 1; + qe_tx_reclaim(qep); if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) { - printk("%s: Transmitter access conflict.\n", dev->name); + long tickssofar = jiffies - dev->trans_start; + + if (tickssofar >= 40) { + printk("%s: transmit timed out, resetting\n", dev->name); + qe_init(qep, 1); + dev->tbusy = 0; + dev->trans_start = jiffies; + } return 1; } - if(!SUN4C_TX_BUFFS_AVAIL(qep)) + if(!TX_BUFFS_AVAIL(qep)) return 1; len = skb->len; entry = qep->tx_new; - txbuf = &qbufs->tx_buf[entry & (SUN4C_TX_RING_SIZE - 1)][0]; + txbuf = &qbufs->tx_buf[entry & (TX_RING_SIZE - 1)][0]; txbuf_dvma = qbufs_dvma + - qebuf_offset(tx_buf, (entry & (SUN4C_TX_RING_SIZE - 1))); + qebuf_offset(tx_buf, (entry & (TX_RING_SIZE - 1))); /* Avoid a race... */ qep->qe_block->qe_txd[entry].tx_flags = TXD_UPDATE; @@ -811,19 +567,18 @@ static int sun4c_qe_start_xmit(struct sk_buff *skb, struct device *dev) qep->tx_new = NEXT_TX(entry); /* Get it going. */ + dev->trans_start = jiffies; qep->qcregs->ctrl = CREG_CTRL_TWAKEUP; - qep->net_stats.tx_bytes+=skb->len; - dev_kfree_skb(skb); - if(SUN4C_TX_BUFFS_AVAIL(qep)) + if(TX_BUFFS_AVAIL(qep)) dev->tbusy = 0; return 0; } -static struct net_device_stats *qe_get_stats(struct device *dev) +static struct net_device_stats *qe_get_stats(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; @@ -833,11 +588,11 @@ static struct net_device_stats *qe_get_stats(struct device *dev) #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void qe_set_multicast(struct device *dev) +static void qe_set_multicast(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; - unsigned char new_mconfig = (MREGS_MCONFIG_TXENAB | MREGS_MCONFIG_RXENAB); + unsigned char new_mconfig = qep->mconfig; char *addrs; int i, j, bit, byte; u32 crc, poly = CRC_POLYNOMIAL_LE; @@ -847,6 +602,8 @@ static void qe_set_multicast(struct device *dev) if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) { qep->mregs->iaconfig = MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET; + while ((qep->mregs->iaconfig & MREGS_IACONFIG_ACHNGE) != 0) + barrier(); for(i = 0; i < 8; i++) qep->mregs->filter = 0xff; qep->mregs->iaconfig = 0; @@ -882,6 +639,8 @@ static void qe_set_multicast(struct device *dev) } /* Program the qe with the new filter value. */ qep->mregs->iaconfig = MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET; + while ((qep->mregs->iaconfig & MREGS_IACONFIG_ACHNGE) != 0) + barrier(); for(i = 0; i < 8; i++) qep->mregs->filter = *hbytes++; qep->mregs->iaconfig = 0; @@ -893,7 +652,8 @@ static void qe_set_multicast(struct device *dev) * refuses to listen to anything on the network. Sheesh, took * me a day or two to find this bug. */ - qep->mregs->mconfig = new_mconfig; + qep->mconfig = new_mconfig; + qep->mregs->mconfig = qep->mconfig; /* Let us get going again. */ dev->tbusy = 0; @@ -904,10 +664,16 @@ static inline void qec_init_once(struct sunqec *qecp, struct linux_sbus_device * { unsigned char bsizes = qecp->qec_bursts; - if(bsizes & DMA_BURST32) +#ifdef __sparc_v9__ + if (bsizes & DMA_BURST64) { + qecp->gregs->ctrl = GLOB_CTRL_B64; + } else +#endif + if(bsizes & DMA_BURST32) { qecp->gregs->ctrl = GLOB_CTRL_B32; - else + } else { qecp->gregs->ctrl = GLOB_CTRL_B16; + } /* Packetsize only used in 100baseT BigMAC configurations, * set it to zero just to be on the safe side. @@ -926,10 +692,10 @@ static inline void qec_init_once(struct sunqec *qecp, struct linux_sbus_device * } /* Four QE's per QEC card. */ -static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int qec_ether_init(struct net_device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; - struct device *qe_devs[4]; + struct net_device *qe_devs[4]; struct sunqe *qeps[4]; struct linux_sbus_device *qesdevs[4]; struct sunqec *qecp; @@ -1001,28 +767,30 @@ static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *s num_qranges = (i / sizeof(struct linux_prom_ranges)); /* Now, apply all the ranges, QEC ranges then the SBUS ones for each QE. */ - for(i = 0; i < 4; i++) { - for(j = 0; j < 2; j++) { - int k; - - for(k = 0; k < num_qranges; k++) - if(qesdevs[i]->reg_addrs[j].which_io == - qranges[k].ot_child_space) - break; - if(k >= num_qranges) - printk("QuadEther: Aieee, bogus QEC range for " - "space %08x\n",qesdevs[i]->reg_addrs[j].which_io); - qesdevs[i]->reg_addrs[j].which_io = qranges[k].ot_parent_space; - qesdevs[i]->reg_addrs[j].phys_addr += qranges[k].ot_parent_base; - } + if (sdev->ranges_applied == 0) { + for(i = 0; i < 4; i++) { + for(j = 0; j < 2; j++) { + int k; + + for(k = 0; k < num_qranges; k++) + if(qesdevs[i]->reg_addrs[j].which_io == + qranges[k].ot_child_space) + break; + if(k >= num_qranges) + printk("QuadEther: Aieee, bogus QEC range for " + "space %08x\n",qesdevs[i]->reg_addrs[j].which_io); + qesdevs[i]->reg_addrs[j].which_io = qranges[k].ot_parent_space; + qesdevs[i]->reg_addrs[j].phys_addr += qranges[k].ot_parent_base; + } - prom_apply_sbus_ranges(qesdevs[i]->my_bus, &qesdevs[i]->reg_addrs[0], - 2, qesdevs[i]); + prom_apply_sbus_ranges(qesdevs[i]->my_bus, &qesdevs[i]->reg_addrs[0], + 2, qesdevs[i]); + } + prom_apply_sbus_ranges(sdev->my_bus, &sdev->reg_addrs[0], + sdev->num_registers, sdev); } /* Now map in the registers, QEC globals first. */ - prom_apply_sbus_ranges(sdev->my_bus, &sdev->reg_addrs[0], - sdev->num_registers, sdev); qecp->gregs = sparc_alloc_io(sdev->reg_addrs[0].phys_addr, 0, sizeof(struct qe_globreg), "QEC Global Registers", @@ -1093,13 +861,10 @@ static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *s sparc_dvma_malloc(PAGE_SIZE, "QE Init Block", &qeps[i]->qblock_dvma); - if(sparc_cpu_model == sun4c) - qeps[i]->sun4c_buffers = (struct sunqe_buffers *) - sparc_dvma_malloc(sizeof(struct sunqe_buffers), - "QE RX/TX Buffers", - &qeps[i]->s4c_buf_dvma); - else - qeps[i]->sun4c_buffers = 0; + qeps[i]->buffers = (struct sunqe_buffers *) + sparc_dvma_malloc(sizeof(struct sunqe_buffers), + "QE RX/TX Buffers", + &qeps[i]->buffers_dvma); /* Stop this QE. */ qe_stop(qeps[i]); @@ -1108,10 +873,7 @@ static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *s for(i = 0; i < 4; i++) { qe_devs[i]->open = qe_open; qe_devs[i]->stop = qe_close; - if(sparc_cpu_model == sun4c) - qe_devs[i]->hard_start_xmit = sun4c_qe_start_xmit; - else - qe_devs[i]->hard_start_xmit = qe_start_xmit; + qe_devs[i]->hard_start_xmit = qe_start_xmit; qe_devs[i]->get_stats = qe_get_stats; qe_devs[i]->set_multicast_list = qe_set_multicast; qe_devs[i]->irq = sdev->irqs[0]; @@ -1119,25 +881,16 @@ static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *s ether_setup(qe_devs[i]); } - /* QEC receives interrupts from each QE, then it send the actual + /* QEC receives interrupts from each QE, then it sends the actual * IRQ to the cpu itself. Since QEC is the single point of * interrupt for all QE channels we register the IRQ handler * for it now. */ - if(sparc_cpu_model == sun4c) { - if(request_irq(sdev->irqs[0], &sun4c_qec_interrupt, - SA_SHIRQ, "QuadEther", (void *) qecp)) { - printk("QuadEther: Can't register QEC master irq handler.\n"); - res = EAGAIN; - goto qec_free_devs; - } - } else { - if(request_irq(sdev->irqs[0], &qec_interrupt, - SA_SHIRQ, "QuadEther", (void *) qecp)) { - printk("QuadEther: Can't register QEC master irq handler.\n"); - res = EAGAIN; - goto qec_free_devs; - } + if(request_irq(sdev->irqs[0], &qec_interrupt, + SA_SHIRQ, "QuadEther", (void *) qecp)) { + printk("QuadEther: Can't register QEC master irq handler.\n"); + res = EAGAIN; + goto qec_free_devs; } /* Report the QE channels. */ @@ -1173,7 +926,7 @@ qec_free_devs: return res; } -__initfunc(int qec_probe(struct device *dev)) +int __init qec_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; @@ -1232,9 +985,12 @@ cleanup_module(void) /* Release all four QE channels, then the QEC itself. */ for(i = 0; i < 4; i++) { unregister_netdev(root_qec_dev->qes[i]->dev); - kfree(root_qec_dev->qes[i]); + sparc_free_io(root_qec_dev->qes[i]->qcregs, sizeof(struct qe_creg)); + sparc_free_io(root_qec_dev->qes[i]->mregs, sizeof(struct qe_mregs)); + kfree(root_qec_dev->qes[i]->dev); } free_irq(root_qec_dev->qec_sbus_dev->irqs[0], (void *)root_qec_dev); + sparc_free_io(root_qec_dev->gregs, sizeof(struct qe_globreg)); kfree(root_qec_dev); root_qec_dev = next_qec; } diff --git a/drivers/net/sunqe.h b/drivers/net/sunqe.h index 18b52feda..5a95ba207 100644 --- a/drivers/net/sunqe.h +++ b/drivers/net/sunqe.h @@ -289,29 +289,19 @@ struct qe_txd { #define TX_RING_MAXSIZE 256 #define RX_RING_MAXSIZE 256 -#define TX_RING_SIZE 256 -#define RX_RING_SIZE 256 +#define TX_RING_SIZE 16 +#define RX_RING_SIZE 16 -#define NEXT_RX(num) (((num) + 1) & (RX_RING_SIZE - 1)) -#define NEXT_TX(num) (((num) + 1) & (TX_RING_SIZE - 1)) -#define PREV_RX(num) (((num) - 1) & (RX_RING_SIZE - 1)) -#define PREV_TX(num) (((num) - 1) & (TX_RING_SIZE - 1)) +#define NEXT_RX(num) (((num) + 1) & (RX_RING_MAXSIZE - 1)) +#define NEXT_TX(num) (((num) + 1) & (TX_RING_MAXSIZE - 1)) +#define PREV_RX(num) (((num) - 1) & (RX_RING_MAXSIZE - 1)) +#define PREV_TX(num) (((num) - 1) & (TX_RING_MAXSIZE - 1)) #define TX_BUFFS_AVAIL(qp) \ (((qp)->tx_old <= (qp)->tx_new) ? \ (qp)->tx_old + (TX_RING_SIZE - 1) - (qp)->tx_new : \ (qp)->tx_old - (qp)->tx_new - 1) - -#define SUN4C_TX_BUFFS_AVAIL(qp) \ - (((qp)->tx_old <= (qp)->tx_new) ? \ - (qp)->tx_old + (SUN4C_TX_RING_SIZE - 1) - (qp)->tx_new : \ - (qp)->tx_old - (qp)->tx_new - (TX_RING_SIZE - SUN4C_TX_RING_SIZE)) - - -#define RX_COPY_THRESHOLD 256 -#define RX_BUF_ALLOC_SIZE (1546 + 64) - struct qe_init_block { struct qe_rxd qe_rxd[RX_RING_MAXSIZE]; struct qe_txd qe_txd[TX_RING_MAXSIZE]; @@ -324,72 +314,39 @@ struct sunqe; struct sunqec { struct qe_globreg *gregs; /* QEC Global Registers */ - - struct sunqe *qes[4]; - unsigned int qec_bursts; - struct linux_sbus_device *qec_sbus_dev; - struct sunqec *next_module; + struct sunqe *qes[4]; /* Each child MACE */ + unsigned int qec_bursts; /* Support burst sizes */ + struct linux_sbus_device *qec_sbus_dev; /* QEC's SBUS device */ + struct sunqec *next_module; /* List of all QECs in system */ }; -#define SUN4C_PKT_BUF_SZ 1544 -#define SUN4C_RX_BUFF_SIZE SUN4C_PKT_BUF_SZ -#define SUN4C_TX_BUFF_SIZE SUN4C_PKT_BUF_SZ - -#define SUN4C_RX_RING_SIZE 16 -#define SUN4C_TX_RING_SIZE 16 +#define PKT_BUF_SZ 1664 +#define RXD_PKT_SZ 1664 struct sunqe_buffers { - char tx_buf[SUN4C_TX_RING_SIZE][SUN4C_TX_BUFF_SIZE]; - char pad[2]; /* Align rx_buf for copy_and_sum(). */ - char rx_buf[SUN4C_RX_RING_SIZE][SUN4C_RX_BUFF_SIZE]; + char tx_buf[TX_RING_SIZE][PKT_BUF_SZ]; + char __pad[2]; + char rx_buf[RX_RING_SIZE][PKT_BUF_SZ]; }; #define qebuf_offset(mem, elem) \ ((__u32)((unsigned long)(&(((struct sunqe_buffers *)0)->mem[elem][0])))) -#define SUN4C_NEXT_RX(num) (((num) + 1) & (SUN4C_RX_RING_SIZE - 1)) -#define SUN4C_NEXT_TX(num) (((num) + 1) & (SUN4C_TX_RING_SIZE - 1)) -#define SUN4C_PREV_RX(num) (((num) - 1) & (SUN4C_RX_RING_SIZE - 1)) -#define SUN4C_PREV_TX(num) (((num) - 1) & (SUN4C_TX_RING_SIZE - 1)) - struct sunqe { struct qe_creg *qcregs; /* QEC per-channel Registers */ struct qe_mregs *mregs; /* Per-channel MACE Registers */ struct qe_init_block *qe_block; /* RX and TX descriptors */ __u32 qblock_dvma; /* RX and TX descriptors */ - - struct sk_buff *rx_skbs[RX_RING_SIZE]; - struct sk_buff *tx_skbs[TX_RING_SIZE]; - - int rx_new, tx_new, rx_old, tx_old; - - struct sunqe_buffers *sun4c_buffers; /* CPU visible address. */ - __u32 s4c_buf_dvma; /* DVMA visible address. */ - + int rx_new, rx_old; /* RX ring extents */ + int tx_new, tx_old; /* TX ring extents */ + struct sunqe_buffers *buffers; /* CPU visible address. */ + __u32 buffers_dvma; /* DVMA visible address. */ struct sunqec *parent; - - struct net_device_stats net_stats; /* Statistical counters */ - struct linux_sbus_device *qe_sbusdev; /* QE's SBUS device struct */ - struct device *dev; /* QE's netdevice struct */ - int channel; /* Who am I? */ + unsigned char mconfig; /* Base MACE mconfig value */ + struct net_device_stats net_stats; /* Statistical counters */ + struct linux_sbus_device *qe_sbusdev; /* QE's SBUS device struct */ + struct net_device *dev; /* QE's netdevice struct */ + int channel; /* Who am I? */ }; -/* We use this to acquire receive skb's that we can DMA directly into. */ -#define ALIGNED_RX_SKB_ADDR(addr) \ - ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr)) - -static inline struct sk_buff *qe_alloc_skb(unsigned int length, int gfp_flags) -{ - struct sk_buff *skb; - - skb = alloc_skb(length + 64, gfp_flags); - if(skb) { - int offset = ALIGNED_RX_SKB_ADDR(skb->data); - - if(offset) - skb_reserve(skb, offset); - } - return skb; -} - #endif /* !(_SUNQE_H) */ diff --git a/drivers/net/syncppp.c b/drivers/net/syncppp.c index c741b6287..eee3fceb8 100644 --- a/drivers/net/syncppp.c +++ b/drivers/net/syncppp.c @@ -48,6 +48,7 @@ #include <linux/netdevice.h> #include <linux/inetdevice.h> #include <linux/random.h> +#include <linux/pkt_sched.h> #include <asm/byteorder.h> #include "syncppp.h" @@ -148,7 +149,7 @@ static int debug = 0; * Interface down stub */ -static void if_down(struct device *dev) +static void if_down(struct net_device *dev) { ; } @@ -183,7 +184,7 @@ static void sppp_clear_timeout(struct sppp *p) * Process the received packet. */ -void sppp_input (struct device *dev, struct sk_buff *skb) +void sppp_input (struct net_device *dev, struct sk_buff *skb) { struct ppp_header *h; struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -312,7 +313,7 @@ EXPORT_SYMBOL(sppp_input); * Handle transmit packets. */ -static int sppp_hard_header(struct sk_buff *skb, struct device *dev, __u16 type, +static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, void *daddr, void *saddr, unsigned int len) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -363,7 +364,7 @@ static void sppp_keepalive (unsigned long dummy) for (sp=spppq; sp; sp=sp->pp_next) { - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; /* Keepalive mode disabled or channel down? */ if (! (sp->pp_flags & PP_KEEPALIVE) || @@ -413,7 +414,7 @@ static void sppp_keepalive (unsigned long dummy) static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb) { struct lcp_header *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; int len = skb->len; u8 *p, opt[6]; u32 rmagic; @@ -648,7 +649,7 @@ badreq: static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) { struct cisco_packet *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; if (skb->len != CISCO_PACKET_LEN && skb->len != CISCO_BIG_PACKET_LEN) { if (sp->pp_flags & PP_DEBUG) @@ -705,19 +706,23 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) /* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */ { struct in_device *in_dev; - struct in_ifaddr *ifa, **ifap; + struct in_ifaddr *ifa; u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */ - if ((in_dev=dev->ip_ptr) != NULL) + if ((in_dev=in_dev_get(dev)) != NULL) { - for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; - ifap=&ifa->ifa_next) + read_lock(&in_dev->lock); + for (ifa=in_dev->ifa_list; ifa != NULL; + ifa=ifa->ifa_next) { if (strcmp(dev->name, ifa->ifa_label) == 0) { addr = ifa->ifa_local; mask = ifa->ifa_mask; break; } + } + read_unlock(&in_dev->lock); + in_dev_put(in_dev); } /* I hope both addr and mask are in the net order */ sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask); @@ -736,7 +741,7 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, struct ppp_header *h; struct lcp_header *lh; struct sk_buff *skb; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len, GFP_ATOMIC); @@ -771,7 +776,7 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, } sp->obytes += skb->len; /* Control is high priority so it doesnt get queued behind data */ - skb->priority=1; + skb->priority=TC_PRIO_CONTROL; skb->dev = dev; dev_queue_xmit(skb); } @@ -785,7 +790,7 @@ static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2) struct ppp_header *h; struct cisco_packet *ch; struct sk_buff *skb; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; u32 t = jiffies * 1000/HZ; skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN, @@ -813,13 +818,13 @@ static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2) dev->name, ntohl (ch->type), ch->par1, ch->par2, ch->rel, ch->time0, ch->time1); sp->obytes += skb->len; - skb->priority=1; + skb->priority=TC_PRIO_CONTROL; skb->dev = dev; dev_queue_xmit(skb); } -int sppp_close (struct device *dev) +int sppp_close (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; dev->flags &= ~IFF_RUNNING; @@ -832,7 +837,7 @@ int sppp_close (struct device *dev) EXPORT_SYMBOL(sppp_close); -int sppp_open (struct device *dev) +int sppp_open (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; sppp_close(dev); @@ -844,7 +849,7 @@ int sppp_open (struct device *dev) EXPORT_SYMBOL(sppp_open); -int sppp_reopen (struct device *dev) +int sppp_reopen (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; sppp_close(dev); @@ -863,7 +868,7 @@ int sppp_reopen (struct device *dev) EXPORT_SYMBOL(sppp_reopen); -int sppp_change_mtu(struct device *dev, int new_mtu) +int sppp_change_mtu(struct net_device *dev, int new_mtu) { if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP)) return -EINVAL; @@ -873,7 +878,7 @@ int sppp_change_mtu(struct device *dev, int new_mtu) EXPORT_SYMBOL(sppp_change_mtu); -int sppp_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +int sppp_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -908,7 +913,7 @@ EXPORT_SYMBOL(sppp_do_ioctl); void sppp_attach(struct ppp_device *pd) { - struct device *dev=&pd->dev; + struct net_device *dev=&pd->dev; struct sppp *sp = &pd->sppp; /* Initialize keepalive handler. */ @@ -963,7 +968,7 @@ void sppp_attach(struct ppp_device *pd) EXPORT_SYMBOL(sppp_attach); -void sppp_detach (struct device *dev) +void sppp_detach (struct net_device *dev) { struct sppp **q, *p, *sp = &((struct ppp_device *)dev)->sppp; @@ -1039,7 +1044,7 @@ sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h, static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb) { struct lcp_header *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; int len = skb->len; if (len < 4) @@ -1266,7 +1271,7 @@ static void sppp_print_bytes (u_char *p, u16 len) * cards use. */ -int sppp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *p) +int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) { sppp_input(dev,skb); return 0; diff --git a/drivers/net/syncppp.h b/drivers/net/syncppp.h index 98f16aa0c..c03c720ca 100644 --- a/drivers/net/syncppp.h +++ b/drivers/net/syncppp.h @@ -46,12 +46,12 @@ struct sppp u32 ibytes,obytes; /* Bytes in/out */ u32 ipkts,opkts; /* Packets in/out */ struct timer_list pp_timer; - struct device *pp_if; + struct net_device *pp_if; }; struct ppp_device { - struct device dev; /* Network device */ + struct net_device dev; /* Network device */ struct sppp sppp; /* Synchronous PPP */ }; @@ -73,15 +73,15 @@ struct ppp_device #define IPCP_STATE_OPENED 3 /* IPCP state: opened */ void sppp_attach (struct ppp_device *pd); -void sppp_detach (struct device *dev); -void sppp_input (struct device *dev, struct sk_buff *m); -int sppp_do_ioctl (struct device *dev, struct ifreq *ifr, int cmd); -struct sk_buff *sppp_dequeue (struct device *dev); -int sppp_isempty (struct device *dev); -void sppp_flush (struct device *dev); -int sppp_open (struct device *dev); -int sppp_reopen (struct device *dev); -int sppp_close (struct device *dev); +void sppp_detach (struct net_device *dev); +void sppp_input (struct net_device *dev, struct sk_buff *m); +int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); +struct sk_buff *sppp_dequeue (struct net_device *dev); +int sppp_isempty (struct net_device *dev); +void sppp_flush (struct net_device *dev); +int sppp_open (struct net_device *dev); +int sppp_reopen (struct net_device *dev); +int sppp_close (struct net_device *dev); #endif #define SPPPIOCCISCO (SIOCDEVPRIVATE) diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index f476b6259..cbbee8532 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -46,12 +46,12 @@ -typedef u32 (TLanIntVectorFunc)( struct device *, u16 ); +typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); #ifdef MODULE -static struct device *TLanDevices = NULL; +static struct net_device *TLanDevices = NULL; static int TLanDevicesInstalled = 0; static int aui = 0; @@ -59,6 +59,13 @@ static int sa_int = 0; static int duplex = 0; static int speed = 0; +MODULE_PARM(aui, "i"); +MODULE_PARM(sa_int, "i"); +MODULE_PARM(duplex, "i"); +MODULE_PARM(speed, "i"); +MODULE_PARM(debug, "i"); +EXPORT_NO_SYMBOLS; + #endif @@ -159,57 +166,57 @@ static TLanAdapterEntry TLanAdapterList[] = { static int TLan_PciProbe( u8 *, u8 *, u8 *, u32 *, u32 * ); -static int TLan_Init( struct device * ); -static int TLan_Open(struct device *dev); -static int TLan_StartTx(struct sk_buff *, struct device *); +static int TLan_Init( struct net_device * ); +static int TLan_Open(struct net_device *dev); +static int TLan_StartTx(struct sk_buff *, struct net_device *); static void TLan_HandleInterrupt(int, void *, struct pt_regs *); -static int TLan_Close(struct device *); -static struct net_device_stats *TLan_GetStats( struct device * ); -static void TLan_SetMulticastList( struct device * ); - -static u32 TLan_HandleInvalid( struct device *, u16 ); -static u32 TLan_HandleTxEOF( struct device *, u16 ); -static u32 TLan_HandleStatOverflow( struct device *, u16 ); -static u32 TLan_HandleRxEOF( struct device *, u16 ); -static u32 TLan_HandleDummy( struct device *, u16 ); -static u32 TLan_HandleTxEOC( struct device *, u16 ); -static u32 TLan_HandleStatusCheck( struct device *, u16 ); -static u32 TLan_HandleRxEOC( struct device *, u16 ); +static int TLan_Close(struct net_device *); +static struct net_device_stats *TLan_GetStats( struct net_device * ); +static void TLan_SetMulticastList( struct net_device * ); + +static u32 TLan_HandleInvalid( struct net_device *, u16 ); +static u32 TLan_HandleTxEOF( struct net_device *, u16 ); +static u32 TLan_HandleStatOverflow( struct net_device *, u16 ); +static u32 TLan_HandleRxEOF( struct net_device *, u16 ); +static u32 TLan_HandleDummy( struct net_device *, u16 ); +static u32 TLan_HandleTxEOC( struct net_device *, u16 ); +static u32 TLan_HandleStatusCheck( struct net_device *, u16 ); +static u32 TLan_HandleRxEOC( struct net_device *, u16 ); static void TLan_Timer( unsigned long ); -static void TLan_ResetLists( struct device * ); -static void TLan_FreeLists( struct device * ); +static void TLan_ResetLists( struct net_device * ); +static void TLan_FreeLists( struct net_device * ); static void TLan_PrintDio( u16 ); static void TLan_PrintList( TLanList *, char *, int ); -static void TLan_ReadAndClearStats( struct device *, int ); -static void TLan_ResetAdapter( struct device * ); -static void TLan_FinishReset( struct device * ); -static void TLan_SetMac( struct device *, int areg, char *mac ); - -static void TLan_PhyPrint( struct device * ); -static void TLan_PhyDetect( struct device * ); -static void TLan_PhyPowerDown( struct device * ); -static void TLan_PhyPowerUp( struct device * ); -static void TLan_PhyReset( struct device * ); -static void TLan_PhyStartLink( struct device * ); -static void TLan_PhyFinishAutoNeg( struct device * ); +static void TLan_ReadAndClearStats( struct net_device *, int ); +static void TLan_ResetAdapter( struct net_device * ); +static void TLan_FinishReset( struct net_device * ); +static void TLan_SetMac( struct net_device *, int areg, char *mac ); + +static void TLan_PhyPrint( struct net_device * ); +static void TLan_PhyDetect( struct net_device * ); +static void TLan_PhyPowerDown( struct net_device * ); +static void TLan_PhyPowerUp( struct net_device * ); +static void TLan_PhyReset( struct net_device * ); +static void TLan_PhyStartLink( struct net_device * ); +static void TLan_PhyFinishAutoNeg( struct net_device * ); /* -static int TLan_PhyNop( struct device * ); -static int TLan_PhyInternalCheck( struct device * ); -static int TLan_PhyInternalService( struct device * ); -static int TLan_PhyDp83840aCheck( struct device * ); +static int TLan_PhyNop( struct net_device * ); +static int TLan_PhyInternalCheck( struct net_device * ); +static int TLan_PhyInternalService( struct net_device * ); +static int TLan_PhyDp83840aCheck( struct net_device * ); */ -static int TLan_MiiReadReg( struct device *, u16, u16, u16 * ); +static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * ); static void TLan_MiiSendData( u16, u32, unsigned ); static void TLan_MiiSync( u16 ); -static void TLan_MiiWriteReg( struct device *, u16, u16, u16 ); +static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 ); static void TLan_EeSendStart( u16 ); static int TLan_EeSendByte( u16, u8, int ); static void TLan_EeReceiveByte( u16, u8 *, int ); -static int TLan_EeReadByte( struct device *, u8, u8 * ); +static int TLan_EeReadByte( struct net_device *, u8, u8 * ); static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = { @@ -224,7 +231,7 @@ static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = { }; static inline void -TLan_SetTimer( struct device *dev, u32 ticks, u32 type ) +TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; @@ -275,7 +282,7 @@ TLan_SetTimer( struct device *dev, u32 ticks, u32 type ) extern int init_module(void) { TLanPrivateInfo *priv; - struct device *dev; + struct net_device *dev; size_t dev_size; u8 dfn; u32 index; @@ -299,17 +306,17 @@ extern int init_module(void) memset( TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE ); - dev_size = sizeof(struct device) + sizeof(TLanPrivateInfo); + dev_size = sizeof(struct net_device) + sizeof(TLanPrivateInfo); while ( ( found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index ) ) ) { - dev = (struct device *) kmalloc( dev_size, GFP_KERNEL ); + dev = (struct net_device *) kmalloc( dev_size, GFP_KERNEL ); if ( dev == NULL ) { printk( "TLAN: Could not allocate memory for device.\n" ); continue; } memset( dev, 0, dev_size ); - dev->priv = priv = ( (void *) dev ) + sizeof(struct device); + dev->priv = priv = ( (void *) dev ) + sizeof(struct net_device); dev->name = priv->devName; strcpy( priv->devName, " " ); dev->base_addr = io_base; @@ -352,7 +359,7 @@ extern int init_module(void) /* printk( "TLAN: Found %d device(s).\n", TLanDevicesInstalled ); */ - return ( ( TLanDevicesInstalled >= 0 ) ? 0 : -ENODEV ); + return ( ( TLanDevicesInstalled > 0 ) ? 0 : -ENODEV ); } /* init_module */ @@ -376,7 +383,7 @@ extern int init_module(void) extern void cleanup_module(void) { - struct device *dev; + struct net_device *dev; TLanPrivateInfo *priv; while ( TLanDevicesInstalled ) { @@ -417,7 +424,7 @@ extern void cleanup_module(void) * **************************************************************/ -extern int tlan_probe( struct device *dev ) +extern int tlan_probe( struct net_device *dev ) { TLanPrivateInfo *priv; static int pad_allocated = 0; @@ -554,7 +561,7 @@ int TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 * ); *pci_irq = pdev->irq; - *pci_io_base = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; + *pci_io_base = pdev->resource[0].start; *pci_dfn = pdev->devfn; pci_read_config_byte ( pdev, PCI_REVISION_ID, pci_rev); pci_read_config_word ( pdev, PCI_COMMAND, &pci_command); @@ -609,7 +616,7 @@ int TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 * * **************************************************************/ -int TLan_Init( struct device *dev ) +int TLan_Init( struct net_device *dev ) { int dma_size; int err; @@ -697,7 +704,7 @@ int TLan_Init( struct device *dev ) * **************************************************************/ -int TLan_Open( struct device *dev ) +int TLan_Open( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int err; @@ -757,7 +764,7 @@ int TLan_Open( struct device *dev ) * **************************************************************/ -int TLan_StartTx( struct sk_buff *skb, struct device *dev ) +int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *tail_list; @@ -859,12 +866,12 @@ int TLan_StartTx( struct sk_buff *skb, struct device *dev ) void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 ack; - struct device *dev; + struct net_device *dev; u32 host_cmd; u16 host_int; int type; - dev = (struct device *) dev_id; + dev = (struct net_device *) dev_id; cli(); if ( dev->interrupt ) { @@ -907,7 +914,7 @@ void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) * **************************************************************/ -int TLan_Close(struct device *dev) +int TLan_Close(struct net_device *dev) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; @@ -946,7 +953,7 @@ int TLan_Close(struct device *dev) * **************************************************************/ -struct net_device_stats *TLan_GetStats( struct device *dev ) +struct net_device_stats *TLan_GetStats( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -994,7 +1001,7 @@ struct net_device_stats *TLan_GetStats( struct device *dev ) * **************************************************************/ -void TLan_SetMulticastList( struct device *dev ) +void TLan_SetMulticastList( struct net_device *dev ) { struct dev_mc_list *dmi = dev->mc_list; u32 hash1 = 0; @@ -1068,7 +1075,7 @@ void TLan_SetMulticastList( struct device *dev ) * **************************************************************/ -u32 TLan_HandleInvalid( struct device *dev, u16 host_int ) +u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) { host_int = 0; /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */ @@ -1101,7 +1108,7 @@ u32 TLan_HandleInvalid( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOF( struct device *dev, u16 host_int ) +u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int eoc = 0; @@ -1174,7 +1181,7 @@ u32 TLan_HandleTxEOF( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatOverflow( struct device *dev, u16 host_int ) +u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) { host_int = 0; TLan_ReadAndClearStats( dev, TLAN_RECORD ); @@ -1211,7 +1218,7 @@ u32 TLan_HandleStatOverflow( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOF( struct device *dev, u16 host_int ) +u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 ack = 1; @@ -1335,7 +1342,7 @@ u32 TLan_HandleRxEOF( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleDummy( struct device *dev, u16 host_int ) +u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) { host_int = 0; printk( "TLAN: Test interrupt on %s.\n", dev->name ); @@ -1366,7 +1373,7 @@ u32 TLan_HandleDummy( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOC( struct device *dev, u16 host_int ) +u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *head_list; @@ -1411,7 +1418,7 @@ u32 TLan_HandleTxEOC( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatusCheck( struct device *dev, u16 host_int ) +u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 ack; @@ -1485,7 +1492,7 @@ u32 TLan_HandleStatusCheck( struct device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOC( struct device *dev, u16 host_int ) +u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *head_list; @@ -1548,7 +1555,7 @@ u32 TLan_HandleRxEOC( struct device *dev, u16 host_int ) void TLan_Timer( unsigned long data ) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 elapsed; @@ -1620,7 +1627,7 @@ void TLan_Timer( unsigned long data ) * **************************************************************/ -void TLan_ResetLists( struct device *dev ) +void TLan_ResetLists( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1675,7 +1682,7 @@ void TLan_ResetLists( struct device *dev ) } /* TLan_ResetLists */ -void TLan_FreeLists( struct device *dev ) +void TLan_FreeLists( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1792,7 +1799,7 @@ void TLan_PrintList( TLanList *list, char *type, int num) * **************************************************************/ -void TLan_ReadAndClearStats( struct device *dev, int record ) +void TLan_ReadAndClearStats( struct net_device *dev, int record ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 tx_good, tx_under; @@ -1868,7 +1875,7 @@ void TLan_ReadAndClearStats( struct device *dev, int record ) **************************************************************/ void -TLan_ResetAdapter( struct device *dev ) +TLan_ResetAdapter( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1950,7 +1957,7 @@ TLan_ResetAdapter( struct device *dev ) void -TLan_FinishReset( struct device *dev ) +TLan_FinishReset( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u8 data; @@ -2036,7 +2043,7 @@ TLan_FinishReset( struct device *dev ) * **************************************************************/ -void TLan_SetMac( struct device *dev, int areg, char *mac ) +void TLan_SetMac( struct net_device *dev, int areg, char *mac ) { int i; @@ -2078,7 +2085,7 @@ void TLan_SetMac( struct device *dev, int areg, char *mac ) * ********************************************************************/ -void TLan_PhyPrint( struct device *dev ) +void TLan_PhyPrint( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 i, data0, data1, data2, data3, phy; @@ -2127,7 +2134,7 @@ void TLan_PhyPrint( struct device *dev ) * ********************************************************************/ -void TLan_PhyDetect( struct device *dev ) +void TLan_PhyDetect( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 control; @@ -2174,7 +2181,7 @@ void TLan_PhyDetect( struct device *dev ) -void TLan_PhyPowerDown( struct device *dev ) +void TLan_PhyPowerDown( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 value; @@ -2199,7 +2206,7 @@ void TLan_PhyPowerDown( struct device *dev ) -void TLan_PhyPowerUp( struct device *dev ) +void TLan_PhyPowerUp( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 value; @@ -2220,7 +2227,7 @@ void TLan_PhyPowerUp( struct device *dev ) -void TLan_PhyReset( struct device *dev ) +void TLan_PhyReset( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 phy; @@ -2248,7 +2255,7 @@ void TLan_PhyReset( struct device *dev ) -void TLan_PhyStartLink( struct device *dev ) +void TLan_PhyStartLink( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 ability; @@ -2329,7 +2336,7 @@ void TLan_PhyStartLink( struct device *dev ) -void TLan_PhyFinishAutoNeg( struct device *dev ) +void TLan_PhyFinishAutoNeg( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 an_adv; @@ -2424,7 +2431,7 @@ void TLan_PhyFinishAutoNeg( struct device *dev ) * **************************************************************/ -int TLan_MiiReadReg( struct device *dev, u16 phy, u16 reg, u16 *val ) +int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) { u8 nack; u16 sio, tmp; @@ -2528,13 +2535,13 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) { TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); - TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); + (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); if ( data & i ) TLan_SetBit( TLAN_NET_SIO_MDATA, sio ); else TLan_ClearBit( TLAN_NET_SIO_MDATA, sio ); TLan_SetBit( TLAN_NET_SIO_MCLK, sio ); - TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); + (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); } } /* TLan_MiiSendData */ @@ -2595,7 +2602,7 @@ void TLan_MiiSync( u16 base_port ) * **************************************************************/ -void TLan_MiiWriteReg( struct device *dev, u16 phy, u16 reg, u16 val ) +void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) { u16 sio; int minten; @@ -2824,7 +2831,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) * **************************************************************/ -int TLan_EeReadByte( struct device *dev, u8 ee_addr, u8 *data ) +int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) { int err; diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index fa1f91bbe..8c18dee60 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -156,7 +156,7 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; ****************************************************************/ typedef struct tlan_private_tag { - struct device *nextDevice; + struct net_device *nextDevice; void *dmaStorage; u8 *padBuffer; TLanList *rxList; diff --git a/drivers/net/tulip.c b/drivers/net/tulip.c index c8c329731..b6dbff811 100644 --- a/drivers/net/tulip.c +++ b/drivers/net/tulip.c @@ -367,7 +367,7 @@ struct mediainfo { struct tulip_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; struct tulip_rx_desc rx_ring[RX_RING_SIZE]; struct tulip_tx_desc tx_ring[TX_RING_SIZE]; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ @@ -409,36 +409,36 @@ struct tulip_private { int pad0, pad1; /* Used for 8-byte alignment */ }; -static struct device *tulip_probe1(int pci_bus, int pci_devfn, - struct device *dev, +static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, int chip_id, int options); -static void parse_eeprom(struct device *dev); +static void parse_eeprom(struct net_device *dev); static int read_eeprom(long ioaddr, int location); -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int value); -static void select_media(struct device *dev, int startup); -static int tulip_open(struct device *dev); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static void select_media(struct net_device *dev, int startup); +static int tulip_open(struct net_device *dev); static void tulip_timer(unsigned long data); -static void tulip_tx_timeout(struct device *dev); -static void tulip_init_ring(struct device *dev); -static int tulip_start_xmit(struct sk_buff *skb, struct device *dev); -static int tulip_rx(struct device *dev); +static void tulip_tx_timeout(struct net_device *dev); +static void tulip_init_ring(struct net_device *dev); +static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int tulip_rx(struct net_device *dev); static void tulip_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs); -static int tulip_close(struct device *dev); -static struct enet_statistics *tulip_get_stats(struct device *dev); +static int tulip_close(struct net_device *dev); +static struct enet_statistics *tulip_get_stats(struct net_device *dev); #ifdef HAVE_PRIVATE_IOCTL -static int private_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #endif #ifdef NEW_MULTICAST -static void set_rx_mode(struct device *dev); +static void set_rx_mode(struct net_device *dev); #else -static void set_rx_mode(struct device *dev, int num_addrs, void *addrs); +static void set_rx_mode(struct net_device *dev, int num_addrs, void *addrs); #endif /* A list of all installed Tulip devices, for removing the driver module. */ -static struct device *root_tulip_dev = NULL; +static struct net_device *root_tulip_dev = NULL; /* This 21040 probe no longer uses a large fixed contiguous Rx buffer region, but now receives directly into full-sized skbuffs that are allocated @@ -446,7 +446,7 @@ static struct device *root_tulip_dev = NULL; This allows the probe routine to use the old driver initialization interface. */ -int tulip_probe(struct device *dev) +int tulip_probe(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; /* Static, for multiple probe calls. */ @@ -497,7 +497,7 @@ int tulip_probe(struct device *dev) continue; } #if LINUX_VERSION_CODE >= 0x20155 - pci_ioaddr = pci_find_slot(pci_bus, pci_device_fn)->base_address[0]; + pci_ioaddr = pci_find_slot(pci_bus, pci_device_fn)->resource[0].start; #else pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, &pci_ioaddr); @@ -552,8 +552,8 @@ int tulip_probe(struct device *dev) return cards_found ? 0 : -ENODEV; } -static struct device *tulip_probe1(int pci_bus, int pci_device_fn, - struct device *dev, +static struct net_device *tulip_probe1(int pci_bus, int pci_device_fn, + struct net_device *dev, int chip_id, int board_idx) { static int did_version = 0; /* Already printed version info. */ @@ -572,23 +572,8 @@ static struct device *tulip_probe1(int pci_bus, int pci_device_fn, dev = init_etherdev(dev, 0); -#if LINUX_VERSION_CODE >= 0x20155 irq = pci_find_slot(pci_bus, pci_device_fn)->irq; - ioaddr = pci_find_slot(pci_bus, pci_device_fn)->base_address[0]; -#else - { - u8 pci_irq_line; - u32 pci_ioaddr; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, - &pci_ioaddr); - irq = pci_irq_line; - ioaddr = pci_ioaddr; - } -#endif - /* Remove I/O space marker in bit 0. */ - ioaddr &= ~3; + ioaddr = pci_find_slot(pci_bus, pci_device_fn)->resource[0].start; printk(KERN_INFO "%s: %s at %#3lx,", dev->name, tulip_tbl[chip_id].chip_name, ioaddr); @@ -876,7 +861,7 @@ static const char * block_name[] = {"21140 non-MII", "21140 MII PHY", #define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8)) #endif -static void parse_eeprom(struct device *dev) +static void parse_eeprom(struct net_device *dev) { /* The last media info list parsed, for multiport boards. */ static struct mediatable *last_mediatable = NULL; @@ -1117,7 +1102,7 @@ static int read_eeprom(long ioaddr, int location) #define MDIO_ENB_IN 0x40000 #define MDIO_DATA_READ 0x80000 -static int mdio_read(struct device *dev, int phy_id, int location) +static int mdio_read(struct net_device *dev, int phy_id, int location) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -1162,7 +1147,7 @@ static int mdio_read(struct device *dev, int phy_id, int location) return (retval>>1) & 0xffff; } -static void mdio_write(struct device *dev, int phy_id, int location, int value) +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -1207,7 +1192,7 @@ static void mdio_write(struct device *dev, int phy_id, int location, int value) static int -tulip_open(struct device *dev) +tulip_open(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1384,7 +1369,7 @@ media_picked: } /* Set up the transceiver control registers for the selected media type. */ -static void select_media(struct device *dev, int startup) +static void select_media(struct net_device *dev, int startup) { long ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -1567,7 +1552,7 @@ static void select_media(struct device *dev, int startup) static void tulip_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; u32 csr12 = inl(ioaddr + CSR12); @@ -1766,7 +1751,7 @@ static void tulip_timer(unsigned long data) of available transceivers. */ static void t21142_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); @@ -1829,7 +1814,7 @@ static void t21142_timer(unsigned long data) add_timer(&tp->timer); } -static void t21142_lnk_change( struct device *dev) +static void t21142_lnk_change( struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1881,7 +1866,7 @@ static void t21142_lnk_change( struct device *dev) static void mxic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -1898,7 +1883,7 @@ static void mxic_timer(unsigned long data) static void pnic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); @@ -1981,7 +1966,7 @@ static void pnic_timer(unsigned long data) add_timer(&tp->timer); } -static void tulip_tx_timeout(struct device *dev) +static void tulip_tx_timeout(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2072,7 +2057,7 @@ static void tulip_tx_timeout(struct device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -tulip_init_ring(struct device *dev) +tulip_init_ring(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -2117,7 +2102,7 @@ tulip_init_ring(struct device *dev) } static int -tulip_start_xmit(struct sk_buff *skb, struct device *dev) +tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int entry; @@ -2174,9 +2159,9 @@ tulip_start_xmit(struct sk_buff *skb, struct device *dev) static void tulip_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs) { #ifdef SA_SHIRQ /* Use the now-standard shared IRQ implementation. */ - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; #else - struct device *dev = (struct device *)(irq2dev_map[irq]); + struct net_device *dev = (struct net_device *)(irq2dev_map[irq]); #endif struct tulip_private *tp; @@ -2354,7 +2339,7 @@ static void tulip_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *reg } static int -tulip_rx(struct device *dev) +tulip_rx(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int entry = tp->cur_rx % RX_RING_SIZE; @@ -2465,7 +2450,7 @@ tulip_rx(struct device *dev) } static int -tulip_close(struct device *dev) +tulip_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -2532,7 +2517,7 @@ tulip_close(struct device *dev) } static struct enet_statistics * -tulip_get_stats(struct device *dev) +tulip_get_stats(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2545,7 +2530,7 @@ tulip_get_stats(struct device *dev) #ifdef HAVE_PRIVATE_IOCTL /* Provide ioctl() calls to examine the MII xcvr state. */ -static int private_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2635,9 +2620,9 @@ static inline unsigned ether_crc_le(int length, unsigned char *data) } #ifdef NEW_MULTICAST -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) #else -static void set_rx_mode(struct device *dev, int num_addrs, void *addrs) +static void set_rx_mode(struct net_device *dev, int num_addrs, void *addrs) #endif { long ioaddr = dev->base_addr; @@ -2752,7 +2737,7 @@ static dev_node_t *tulip_attach(dev_locator_t *loc) u16 dev_id; u32 io; u8 bus, devfn; - struct device *dev; + struct net_device *dev; if (loc->bus != LOC_PCI) return NULL; bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; @@ -2774,7 +2759,7 @@ static dev_node_t *tulip_attach(dev_locator_t *loc) static void tulip_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "tulip_detach(%s)\n", node->dev_name); for (devp = &root_tulip_dev; *devp; devp = next) { next = &((struct tulip_private *)(*devp)->priv)->next_module; @@ -2828,7 +2813,7 @@ init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&tulip_ops); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index be7646b65..21275376c 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -86,6 +86,9 @@ static const int multicast_filter_limit = 32; #if defined(__i386__) && !defined(VIA_USE_MEMORY) #define VIA_USE_IO #endif +#if defined(__alpha__) +#define VIA_USE_IO +#endif #ifdef VIA_USE_IO #undef readb #undef readw @@ -106,7 +109,7 @@ static const int multicast_filter_limit = 32; #define RUN_AT(x) (jiffies + (x)) -#if (LINUX_VERSION_CODE >= 0x20100) +#ifdef MODULE char kernel_version[] = UTS_RELEASE; #else #ifndef __alpha__ @@ -250,12 +253,12 @@ struct pci_id_info { const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct device *via_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *via_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = { @@ -344,7 +347,7 @@ struct netdev_private { struct sk_buff* tx_skbuff[TX_RING_SIZE]; unsigned char *tx_buf[TX_RING_SIZE]; /* Tx bounce buffers */ unsigned char *tx_bufs; /* Tx bounce buffer region. */ - struct device *next_module; /* Link for devices of this type. */ + struct net_device *next_module; /* Link for devices of this type. */ struct net_device_stats stats; struct timer_list timer; /* Media monitoring timer. */ unsigned char pci_bus, pci_devfn; @@ -369,33 +372,33 @@ struct netdev_private { unsigned char phys[2]; /* MII device addresses. */ }; -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int value); -static int netdev_open(struct device *dev); -static void check_duplex(struct device *dev); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static int netdev_open(struct net_device *dev); +static void check_duplex(struct net_device *dev); static void netdev_timer(unsigned long data); -static void tx_timeout(struct device *dev); -static void init_ring(struct device *dev); -static int start_tx(struct sk_buff *skb, struct device *dev); +static void tx_timeout(struct net_device *dev); +static void init_ring(struct net_device *dev); +static int start_tx(struct sk_buff *skb, struct net_device *dev); static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); -static int netdev_rx(struct device *dev); -static void netdev_error(struct device *dev, int intr_status); -static void set_rx_mode(struct device *dev); -static struct net_device_stats *get_stats(struct device *dev); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static int netdev_close(struct device *dev); +static int netdev_rx(struct net_device *dev); +static void netdev_error(struct net_device *dev, int intr_status); +static void set_rx_mode(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int netdev_close(struct net_device *dev); /* A list of our installed devices, for removing the driver module. */ -static struct device *root_net_dev = NULL; +static struct net_device *root_net_dev = NULL; /* Ideally we would detect all network cards in slot order. That would be best done a central PCI probe dispatch, which wouldn't work well when dynamically adding drivers. So instead we detect just the cards we know about in slot order. */ -static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[]) +static int pci_etherdev_probe(struct net_device *dev, struct pci_id_info pci_tbl[]) { int cards_found = 0; int pci_index = 0; @@ -431,9 +434,9 @@ static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[]) #if defined(PCI_SUPPORT_VER2) struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); #ifdef VIA_USE_IO - pciaddr = pdev->base_address[0]; + pciaddr = pdev->resource[0].start; #else - pciaddr = pdev->base_address[1]; + pciaddr = pdev->resource[1].start; #endif irq = pdev->irq; #else @@ -503,15 +506,15 @@ static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[]) } #ifndef MODULE -int via_rhine_probe(struct device *dev) +int via_rhine_probe(struct net_device *dev) { printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); return pci_etherdev_probe(dev, pci_tbl); } #endif -static struct device *via_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *via_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx) { struct netdev_private *np; @@ -599,7 +602,7 @@ static struct device *via_probe1(int pci_bus, int pci_devfn, /* Read and write over the MII Management Data I/O (MDIO) interface. */ -static int mdio_read(struct device *dev, int phy_id, int regnum) +static int mdio_read(struct net_device *dev, int phy_id, int regnum) { long ioaddr = dev->base_addr; int boguscnt = 1024; @@ -617,7 +620,7 @@ static int mdio_read(struct device *dev, int phy_id, int regnum) return readw(ioaddr + MIIData); } -static void mdio_write(struct device *dev, int phy_id, int regnum, int value) +static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value) { long ioaddr = dev->base_addr; int boguscnt = 1024; @@ -634,7 +637,7 @@ static void mdio_write(struct device *dev, int phy_id, int regnum, int value) } -static int netdev_open(struct device *dev) +static int netdev_open(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -707,7 +710,7 @@ static int netdev_open(struct device *dev) return 0; } -static void check_duplex(struct device *dev) +static void check_duplex(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -733,7 +736,7 @@ static void check_duplex(struct device *dev) static void netdev_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 10*HZ; @@ -748,7 +751,7 @@ static void netdev_timer(unsigned long data) add_timer(&np->timer); } -static void tx_timeout(struct device *dev) +static void tx_timeout(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -771,7 +774,7 @@ static void tx_timeout(struct device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void init_ring(struct device *dev) +static void init_ring(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; int i; @@ -818,7 +821,7 @@ static void init_ring(struct device *dev) return; } -static int start_tx(struct sk_buff *skb, struct device *dev) +static int start_tx(struct sk_buff *skb, struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; unsigned entry; @@ -877,7 +880,7 @@ static int start_tx(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np; long ioaddr, boguscnt = max_interrupt_work; @@ -988,7 +991,7 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) /* This routine is logically part of the interrupt handler, but isolated for clarity and better register allocation. */ -static int netdev_rx(struct device *dev) +static int netdev_rx(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; int entry = np->cur_rx % RX_RING_SIZE; @@ -1053,6 +1056,7 @@ static int netdev_rx(struct device *dev) np->rx_skbuff[entry] = NULL; } skb->protocol = eth_type_trans(skb, dev); + np->stats.rx_bytes+=skb->len; netif_rx(skb); dev->last_rx = jiffies; np->stats.rx_packets++; @@ -1082,7 +1086,7 @@ static int netdev_rx(struct device *dev) return 0; } -static void netdev_error(struct device *dev, int intr_status) +static void netdev_error(struct net_device *dev, int intr_status) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1123,7 +1127,7 @@ static void netdev_error(struct device *dev, int intr_status) } } -static struct enet_statistics *get_stats(struct device *dev) +static struct enet_statistics *get_stats(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1157,7 +1161,7 @@ static inline u32 ether_crc(int length, unsigned char *data) return crc; } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1188,7 +1192,7 @@ static void set_rx_mode(struct device *dev) writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { u16 *data = (u16 *)&rq->ifr_data; @@ -1209,7 +1213,7 @@ static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) } } -static int netdev_close(struct device *dev) +static int netdev_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct netdev_private *np = (struct netdev_private *)dev->priv; diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c index 22caf3a71..2dd4eaa12 100644 --- a/drivers/net/wavelan.c +++ b/drivers/net/wavelan.c @@ -1616,11 +1616,8 @@ wv_set_frequency(u_long ioaddr, /* I/O port of the card */ if((frequency->e == 0) && (frequency->m >= 0) && (frequency->m < BAND_NUM)) { - /* frequency in units of 250 kHz (as read in the offset register) */ - short bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, 0xD0, 0xF0, 0xF8, 0x150 }; - /* Get frequency offset. */ - freq = bands[frequency->m] >> 1; + freq = channel_bands[frequency->m] >> 1; } /* Verify that the frequency is allowed. */ @@ -1791,6 +1788,7 @@ wv_frequency_list(u_long ioaddr, /* I/O port of the card */ u_short table[10]; /* Authorized frequency table */ long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */ int i; /* index in the table */ + int c = 0; /* Channel number */ /* Read the frequency table. */ fee_read(ioaddr, 0x71 /* frequency table */, table, 10); @@ -1801,6 +1799,12 @@ wv_frequency_list(u_long ioaddr, /* I/O port of the card */ /* Look in the table if the frequency is allowed */ if(table[9 - (freq / 16)] & (1 << (freq % 16))) { + /* Compute approximate channel number */ + while((((channel_bands[c] >> 1) - 24) < freq) && + (c < NELS(channel_bands))) + c++; + list[i].i = c; /* Set the list index */ + /* put in the list */ list[i].m = (((freq + 24) * 5) + 24000L) * 10000; list[i++].e = 1; @@ -1876,7 +1880,7 @@ wl_his_gather(device * dev, * It is here that the wireless extensions are treated (iwconfig). */ static int -wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ +wavelan_ioctl(struct net_device * dev, /* device on which the ioctl is applied */ struct ifreq * rq, /* data passed */ int cmd) /* ioctl number */ { @@ -1969,14 +1973,12 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ } else { - int bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; - psa_read(ioaddr, lp->hacr, (char *)&psa.psa_subband - (char *)&psa, (unsigned char *)&psa.psa_subband, 1); if(psa.psa_subband <= 4) { - wrq->u.freq.m = bands[psa.psa_subband]; + wrq->u.freq.m = fixed_bands[psa.psa_subband]; wrq->u.freq.e = (psa.psa_subband != 0); } else @@ -1986,9 +1988,9 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ case SIOCSIWSENS: /* Set the level threshold. */ - if(!suser()) - return -EPERM; - psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F; + /* We should complain loudly if wrq->u.sens.fixed = 0, because we + * can't set auto mode... */ + psa.psa_thr_pre_set = wrq->u.sens.value & 0x3F; psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa, (unsigned char *) &psa.psa_thr_pre_set, 1); /* update the Wavelan checksum */ @@ -2000,7 +2002,8 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ /* Read the level threshold. */ psa_read(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa, (unsigned char *) &psa.psa_thr_pre_set, 1); - wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F; + wrq->u.sens.value = psa.psa_thr_pre_set & 0x3F; + wrq->u.sens.fixed = 1; break; case SIOCSIWENCODE: @@ -2091,7 +2094,7 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ wrq->u.data.length = sizeof(struct iw_range); /* Set information in the range struct. */ - range.throughput = 1.6 * 1024 * 1024; /* don't argue on this ! */ + range.throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */ range.min_nwid = 0x0000; range.max_nwid = 0xFFFF; @@ -2111,6 +2114,9 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ range.max_qual.level = MMR_SIGNAL_LVL; range.max_qual.noise = MMR_SILENCE_LVL; + range.num_bitrates = 1; + range.bitrate[0] = 2000000; /* 2 Mb/s */ + /* Copy structure to the user buffer. */ if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) ret = -EFAULT; @@ -2234,7 +2240,10 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ case SIOCSIPQTHR: if(!suser()) - return -EPERM; + { + ret = -EPERM; + break; + } psa.psa_quality_thr = *(wrq->u.name) & 0x0F; psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa, (unsigned char *)&psa.psa_quality_thr, 1); @@ -2253,7 +2262,10 @@ wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ case SIOCSIPHISTO: /* Verify that the user is root. */ if(!suser()) - return -EPERM; + { + ret = -EPERM; + break; + } /* Check the number of intervals. */ if(wrq->u.data.length > 16) @@ -4239,13 +4251,13 @@ init_module(void) device * dev; /* Create device and set basic arguments. */ - dev = kmalloc(sizeof(struct device), GFP_KERNEL); + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); if(dev==NULL) { ret = -ENOMEM; break; } - memset(dev, 0x00, sizeof(struct device)); + memset(dev, 0x00, sizeof(struct net_device)); dev->name = name[i]; dev->base_addr = io[i]; dev->irq = irq[i]; @@ -4257,7 +4269,7 @@ init_module(void) { /* Deallocate everything. */ /* Note: if dev->priv is mallocated, there is no way to fail. */ - kfree_s(dev, sizeof(struct device)); + kfree_s(dev, sizeof(struct net_device)); } else { @@ -4310,7 +4322,7 @@ cleanup_module(void) /* Free pieces. */ kfree_s(dev->priv, sizeof(struct net_local)); - kfree_s(dev, sizeof(struct device)); + kfree_s(dev, sizeof(struct net_device)); } #ifdef DEBUG_MODULE_TRACE diff --git a/drivers/net/wavelan.h b/drivers/net/wavelan.h index df9c49344..f55bf48e2 100644 --- a/drivers/net/wavelan.h +++ b/drivers/net/wavelan.h @@ -19,6 +19,8 @@ #ifndef _WAVELAN_H #define _WAVELAN_H +/************************** MAGIC NUMBERS ***************************/ + /* Detection of the WaveLAN card is done by reading the MAC * address from the card and checking it. If you have a non-AT&T * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson), @@ -39,6 +41,25 @@ const char MAC_ADDRESSES[][3] = #define MAXDATAZ (WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU) +/* + * Constants used to convert channels to frequencies + */ + +/* Frequency available in the 2.0 modem, in units of 250 kHz + * (as read in the offset register of the dac area). + * Used to map channel numbers used by `wfreqsel' to frequencies + */ +const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, + 0xD0, 0xF0, 0xF8, 0x150 }; + +/* Frequencies of the 1.0 modem (fixed frequencies). + * Use to map the PSA `subband' to a frequency + * Note : all frequencies apart from the first one need to be multiplied by 10 + */ +const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; + + + /*************************** PC INTERFACE ****************************/ /* diff --git a/drivers/net/wavelan.p.h b/drivers/net/wavelan.p.h index 9a2f16847..fc43ce303 100644 --- a/drivers/net/wavelan.p.h +++ b/drivers/net/wavelan.p.h @@ -32,7 +32,7 @@ * Web page * -------- * I try to maintain a web page with the Wireless LAN Howto at : - * http://www-uk.hpl.hp.com/people/jt/Linux/Wavelan.html + * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html * * Debugging and options * --------------------- @@ -164,7 +164,7 @@ * Marc Meertens <Marc.Meertens@Utrecht.NCR.com>, * Pauline Middelink <middelin@polyware.iaf.nl>, * Robert Morris <rtm@das.harvard.edu>, - * Jean Tourrilhes <jt@hplb.hpl.hp.com>, + * Jean Tourrilhes <jt@hpl.hp.com>, * Girish Welling <welling@paul.rutgers.edu>, * Clark Woodworth <clark@hiway1.exit109.com> * Yongguang Zhang <ygz@isl.hrl.hac.com> @@ -292,9 +292,17 @@ * - Rectify a lot of (useless) debugging code * - Change the way to `#ifdef SET_PSA_CRC' * + * Changes made for release in 2.2.11 & 2.3.13 : + * ------------------------------------------- + * - Change e-mail and web page addresses + * - Watchdog timer is now correctly expressed in HZ, not in jiffies + * - Add channel number to the list of frequencies in range + * - Add the (short) list of bit-rates in range + * - Developp a new sensitivity... (sens.value & sens.fixed) + * * Wishes & dreams: * ---------------- - * - roaming + * - roaming (see Pcmcia driver) */ /***************************** INCLUDES *****************************/ @@ -382,11 +390,11 @@ /************************ CONSTANTS & MACROS ************************/ #ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan.c : v19 (wireless extensions) 20/4/99\n"; +static const char *version = "wavelan.c : v20 (wireless extensions) 29/7/99\n"; #endif /* Watchdog temporisation */ -#define WATCHDOG_JIFFIES 256 /* TODO: express in HZ. */ +#define WATCHDOG_JIFFIES (256*HZ/100) /* Macro to get the number of elements in an array */ #define NELS(a) (sizeof(a) / sizeof(a[0])) @@ -404,7 +412,7 @@ static const char *version = "wavelan.c : v19 (wireless extensions) 20/4/99\n"; /****************************** TYPES ******************************/ /* Shortcuts */ -typedef struct device device; +typedef struct net_device device; typedef struct net_device_stats en_stats; typedef struct iw_statistics iw_stats; typedef struct iw_quality iw_qual; diff --git a/drivers/net/wd.c b/drivers/net/wd.c index 99d2318d0..8a850ca6f 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -45,18 +45,18 @@ static const char *version = static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; -int wd_probe(struct device *dev); -int wd_probe1(struct device *dev, int ioaddr); +int wd_probe(struct net_device *dev); +int wd_probe1(struct net_device *dev, int ioaddr); -static int wd_open(struct device *dev); -static void wd_reset_8390(struct device *dev); -static void wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int wd_open(struct net_device *dev); +static void wd_reset_8390(struct net_device *dev); +static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void wd_block_input(struct device *dev, int count, +static void wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void wd_block_output(struct device *dev, int count, +static void wd_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static int wd_close(struct device *dev); +static int wd_close(struct net_device *dev); #define WD_START_PG 0x00 /* First page of TX buffer */ @@ -86,7 +86,7 @@ struct netdev_entry wd_drv = {"wd", wd_probe1, WD_IO_EXTENT, wd_portlist}; #else -__initfunc(int wd_probe(struct device *dev)) +int __init wd_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -108,7 +108,7 @@ __initfunc(int wd_probe(struct device *dev)) } #endif -__initfunc(int wd_probe1(struct device *dev, int ioaddr)) +int __init wd_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -313,7 +313,7 @@ __initfunc(int wd_probe1(struct device *dev, int ioaddr)) } static int -wd_open(struct device *dev) +wd_open(struct net_device *dev) { int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -332,7 +332,7 @@ wd_open(struct device *dev) } static void -wd_reset_8390(struct device *dev) +wd_reset_8390(struct net_device *dev) { int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -354,7 +354,7 @@ wd_reset_8390(struct device *dev) the start of a page, so we optimize accordingly. */ static void -wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -379,7 +379,7 @@ wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) switch between 8- and 16-bit modes. */ static void -wd_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ unsigned long xfer_start = dev->mem_start + ring_offset - (WD_START_PG<<8); @@ -401,7 +401,7 @@ wd_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offs } static void -wd_block_output(struct device *dev, int count, const unsigned char *buf, +wd_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -419,7 +419,7 @@ wd_block_output(struct device *dev, int count, const unsigned char *buf, static int -wd_close(struct device *dev) +wd_close(struct net_device *dev) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -444,7 +444,7 @@ wd_close(struct device *dev) #define MAX_WD_CARDS 4 /* Max number of wd cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_WD_CARDS] = { 0, }; -static struct device dev_wd[MAX_WD_CARDS] = { +static struct net_device dev_wd[MAX_WD_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -471,7 +471,7 @@ init_module(void) int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - struct device *dev = &dev_wd[this_dev]; + struct net_device *dev = &dev_wd[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -502,7 +502,7 @@ cleanup_module(void) int this_dev; for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - struct device *dev = &dev_wd[this_dev]; + struct net_device *dev = &dev_wd[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; int ioaddr = dev->base_addr - WD_NIC_OFFSET; diff --git a/drivers/net/x25_asy.c b/drivers/net/x25_asy.c index 9f20bf6cd..49d041abc 100644 --- a/drivers/net/x25_asy.c +++ b/drivers/net/x25_asy.c @@ -34,7 +34,7 @@ typedef struct x25_ctrl { char if_name[8]; /* "xasy0\0" .. "xasy99999\0" */ struct x25_asy ctrl; /* X.25 things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } x25_asy_ctrl_t; static x25_asy_ctrl_t **x25_asy_ctrls = NULL; @@ -139,7 +139,7 @@ static inline void x25_asy_free(struct x25_asy *sl) static void x25_asy_changed_mtu(struct x25_asy *sl) { - struct device *dev = sl->dev; + struct net_device *dev = sl->dev; unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; int len; unsigned long flags; @@ -324,7 +324,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty) /* Encapsulate an IP datagram and kick it into a TTY queue. */ -static int x25_asy_xmit(struct sk_buff *skb, struct device *dev) +static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); int err; @@ -481,7 +481,7 @@ static void x25_asy_disconnected(void *token, int reason) /* Open the low-level part of the X.25 channel. Easy! */ -static int x25_asy_open(struct device *dev) +static int x25_asy_open(struct net_device *dev) { struct lapb_register_struct x25_asy_callbacks; struct x25_asy *sl = (struct x25_asy*)(dev->priv); @@ -542,7 +542,7 @@ norbuff: /* Close the low-level part of the X.25 channel. Easy! */ -static int x25_asy_close(struct device *dev) +static int x25_asy_close(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); int err; @@ -663,9 +663,7 @@ static void x25_asy_close_tty(struct tty_struct *tty) if (sl->dev->flags & IFF_UP) { - dev_lock_wait(); (void) dev_close(sl->dev); - dev_unlock_list(); } tty->disc_data = 0; @@ -676,7 +674,7 @@ static void x25_asy_close_tty(struct tty_struct *tty) } -static struct net_device_stats *x25_asy_get_stats(struct device *dev) +static struct net_device_stats *x25_asy_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct x25_asy *sl = (struct x25_asy*)(dev->priv); @@ -806,7 +804,7 @@ static int x25_asy_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) } } -static int x25_asy_open_dev(struct device *dev) +static int x25_asy_open_dev(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); if(sl->tty==NULL) @@ -818,7 +816,7 @@ static int x25_asy_open_dev(struct device *dev) #ifdef MODULE static int x25_asy_init_ctrl_dev(void) #else /* !MODULE */ -__initfunc(int x25_asy_init_ctrl_dev(struct device *dummy)) +int __init x25_asy_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; @@ -869,7 +867,7 @@ __initfunc(int x25_asy_init_ctrl_dev(struct device *dummy)) /* Initialise the X.25 driver. Called by the device init code */ -int x25_asy_init(struct device *dev) +int x25_asy_init(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); diff --git a/drivers/net/x25_asy.h b/drivers/net/x25_asy.h index a48479ce5..5abeceb20 100644 --- a/drivers/net/x25_asy.h +++ b/drivers/net/x25_asy.h @@ -19,7 +19,7 @@ struct x25_asy { /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ /* These are pointers to the malloc()ed frame buffers. */ unsigned char *rbuff; /* receiver buffer */ @@ -53,6 +53,6 @@ struct x25_asy { #define X25_ASY_MAGIC 0x5303 -extern int x25_asy_init(struct device *dev); +extern int x25_asy_init(struct net_device *dev); #endif /* _LINUX_X25_ASY.H */ diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 8d5b232ec..e3b2abb46 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -272,7 +272,7 @@ struct yellowfin_private { struct yellowfin_desc rx_ring[RX_RING_SIZE]; struct yellowfin_desc tx_ring[TX_RING_SIZE*2]; const char *product_name; - struct device *next_module; + struct net_device *next_module; /* The addresses of receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ @@ -316,32 +316,32 @@ MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); #endif -static struct device *yellowfin_probe1(struct device *dev, long ioaddr, +static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, int irq, int chip_id, int options); static int read_eeprom(long ioaddr, int location); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); #ifdef HAVE_PRIVATE_IOCTL -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #endif -static int yellowfin_open(struct device *dev); +static int yellowfin_open(struct net_device *dev); static void yellowfin_timer(unsigned long data); -static void yellowfin_tx_timeout(struct device *dev); -static void yellowfin_init_ring(struct device *dev); -static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev); +static void yellowfin_tx_timeout(struct net_device *dev); +static void yellowfin_init_ring(struct net_device *dev); +static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int yellowfin_rx(struct device *dev); -static void yellowfin_error(struct device *dev, int intr_status); -static int yellowfin_close(struct device *dev); -static struct enet_statistics *yellowfin_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int yellowfin_rx(struct net_device *dev); +static void yellowfin_error(struct net_device *dev, int intr_status); +static int yellowfin_close(struct net_device *dev); +static struct enet_statistics *yellowfin_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed Yellowfin devices, for removing the driver module. */ -static struct device *root_yellowfin_dev = NULL; +static struct net_device *root_yellowfin_dev = NULL; -int yellowfin_probe(struct device *dev) +int yellowfin_probe(struct net_device *dev) { int cards_found = 0; int pci_index = 0; @@ -377,23 +377,10 @@ int yellowfin_probe(struct device *dev) continue; { -#if LINUX_VERSION_CODE >= 0x20155 || PCI_SUPPORT_1 struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[0]; + ioaddr = pdev->resource[0].start; irq = pdev->irq; -#else - u32 pci_ioaddr; - u8 pci_irq_line; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - ioaddr = pci_ioaddr; - irq = pci_irq_line; -#endif } - /* Remove I/O space marker in bit 0. */ - ioaddr &= ~3; if (yellowfin_debug > 2) printk(KERN_INFO "Found %s at I/O %#lx, IRQ %d.\n", @@ -436,7 +423,7 @@ int yellowfin_probe(struct device *dev) return cards_found ? 0 : -ENODEV; } -static struct device *yellowfin_probe1(struct device *dev, long ioaddr, +static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx) { static int did_version = 0; /* Already printed version info. */ @@ -573,7 +560,7 @@ static void mdio_write(long ioaddr, int phy_id, int location, int value) } -static int yellowfin_open(struct device *dev) +static int yellowfin_open(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -658,7 +645,7 @@ static int yellowfin_open(struct device *dev) static void yellowfin_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -696,7 +683,7 @@ static void yellowfin_timer(unsigned long data) } } -static void yellowfin_tx_timeout(struct device *dev) +static void yellowfin_tx_timeout(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -730,7 +717,7 @@ static void yellowfin_tx_timeout(struct device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void yellowfin_init_ring(struct device *dev) +static void yellowfin_init_ring(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; int i; @@ -798,7 +785,7 @@ static void yellowfin_init_ring(struct device *dev) return; } -static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev) +static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; unsigned entry; @@ -872,7 +859,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev) after the Tx thread. */ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct yellowfin_private *yp; long ioaddr, boguscnt = max_interrupt_work; @@ -1034,7 +1021,7 @@ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *reg /* This routine is logically part of the interrupt handler, but separated for clarity and better register allocation. */ -static int yellowfin_rx(struct device *dev) +static int yellowfin_rx(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; int entry = yp->cur_rx % RX_RING_SIZE; @@ -1168,7 +1155,7 @@ static int yellowfin_rx(struct device *dev) return 0; } -static void yellowfin_error(struct device *dev, int intr_status) +static void yellowfin_error(struct net_device *dev, int intr_status) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; @@ -1181,7 +1168,7 @@ static void yellowfin_error(struct device *dev, int intr_status) yp->stats.rx_errors++; } -static int yellowfin_close(struct device *dev) +static int yellowfin_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; @@ -1273,7 +1260,7 @@ static int yellowfin_close(struct device *dev) return 0; } -static struct enet_statistics *yellowfin_get_stats(struct device *dev) +static struct enet_statistics *yellowfin_get_stats(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; return &yp->stats; @@ -1304,7 +1291,7 @@ static inline unsigned ether_crc_le(int length, unsigned char *data) } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1351,7 +1338,7 @@ static void set_rx_mode(struct device *dev) } #ifdef HAVE_PRIVATE_IOCTL -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; @@ -1390,7 +1377,7 @@ int init_module(void) void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_yellowfin_dev) { diff --git a/drivers/net/z85230.c b/drivers/net/z85230.c index 9fea5980d..a802170ce 100644 --- a/drivers/net/z85230.c +++ b/drivers/net/z85230.c @@ -46,7 +46,7 @@ #include <asm/io.h> #define RT_LOCK #define RT_UNLOCK -#include <asm/spinlock.h> +#include <linux/spinlock.h> #include "z85230.h" #include "syncppp.h" @@ -609,7 +609,7 @@ static char reg_init[16]= }; -int z8530_sync_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_open(struct net_device *dev, struct z8530_channel *c) { c->sync = 1; c->mtu = dev->mtu+64; @@ -631,7 +631,7 @@ int z8530_sync_open(struct device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_open); -int z8530_sync_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; c->irqs = &z8530_nop; @@ -646,7 +646,7 @@ int z8530_sync_close(struct device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_close); -int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_dma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -766,7 +766,7 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_dma_open); -int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_dma_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; unsigned long flags; @@ -832,7 +832,7 @@ int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_dma_close); -int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_txdma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -925,7 +925,7 @@ int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_txdma_open); -int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_txdma_close(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; u8 chk; diff --git a/drivers/net/z85230.h b/drivers/net/z85230.h index a2e7f3ea2..0b4b48748 100644 --- a/drivers/net/z85230.h +++ b/drivers/net/z85230.h @@ -320,7 +320,7 @@ struct z8530_channel */ void *private; /* For our owner */ - struct device *netdevice; /* Network layer device */ + struct net_device *netdevice; /* Network layer device */ struct net_device_stats stats; /* Network layer statistics */ /* @@ -397,12 +397,12 @@ extern void z8530_interrupt(int, void *, struct pt_regs *); extern void z8530_describe(struct z8530_dev *, char *mapping,int io); extern int z8530_init(struct z8530_dev *); extern int z8530_shutdown(struct z8530_dev *); -extern int z8530_sync_open(struct device *, struct z8530_channel *); -extern int z8530_sync_close(struct device *, struct z8530_channel *); -extern int z8530_sync_dma_open(struct device *, struct z8530_channel *); -extern int z8530_sync_dma_close(struct device *, struct z8530_channel *); -extern int z8530_sync_txdma_open(struct device *, struct z8530_channel *); -extern int z8530_sync_txdma_close(struct device *, struct z8530_channel *); +extern int z8530_sync_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_close(struct net_device *, struct z8530_channel *); +extern int z8530_sync_dma_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_dma_close(struct net_device *, struct z8530_channel *); +extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *); extern int z8530_channel_load(struct z8530_channel *, u8 *); extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c); diff --git a/drivers/net/znet.c b/drivers/net/znet.c index 0884cb0d8..f48e41e7e 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -180,15 +180,15 @@ struct netidblk { char pad; }; -int znet_probe(struct device *dev); -static int znet_open(struct device *dev); -static int znet_send_packet(struct sk_buff *skb, struct device *dev); +int znet_probe(struct net_device *dev); +static int znet_open(struct net_device *dev); +static int znet_send_packet(struct sk_buff *skb, struct net_device *dev); static void znet_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void znet_rx(struct device *dev); -static int znet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); -static void hardware_init(struct device *dev); +static void znet_rx(struct net_device *dev); +static int znet_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static void hardware_init(struct net_device *dev); static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset); #ifdef notdef @@ -200,7 +200,7 @@ static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, }; BIOS area. We just scan for the signature, and pull the vital parameters out of the structure. */ -__initfunc(int znet_probe(struct device *dev)) +int __init znet_probe(struct net_device *dev) { int i; struct netidblk *netinfo; @@ -283,7 +283,7 @@ __initfunc(int znet_probe(struct device *dev)) } -static int znet_open(struct device *dev) +static int znet_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -314,7 +314,7 @@ static int znet_open(struct device *dev) return 0; } -static int znet_send_packet(struct sk_buff *skb, struct device *dev) +static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -402,7 +402,7 @@ static int znet_send_packet(struct sk_buff *skb, struct device *dev) /* The ZNET interrupt handler. */ static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; int ioaddr; int boguscnt = 20; @@ -465,7 +465,7 @@ static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs) return; } -static void znet_rx(struct device *dev) +static void znet_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -589,7 +589,7 @@ static void znet_rx(struct device *dev) } /* The inverse routine to znet_open(). */ -static int znet_close(struct device *dev) +static int znet_close(struct net_device *dev) { unsigned long flags; int ioaddr = dev->base_addr; @@ -617,7 +617,7 @@ static int znet_close(struct device *dev) /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -632,7 +632,7 @@ static struct net_device_stats *net_get_stats(struct device *dev) mode change persistent, but must be changed if this code is moved to a multiple adaptor environment. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -677,7 +677,7 @@ void show_dma(void) /* Initialize the hardware. We have to do this when the board is open()ed or when we come out of suspend mode. */ -static void hardware_init(struct device *dev) +static void hardware_init(struct net_device *dev) { unsigned long flags; short ioaddr = dev->base_addr; |