diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
commit | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch) | |
tree | 40b1cb534496a7f1ca0f5c314a523c69f1fee464 /drivers/net/hydra.c | |
parent | 7206675c40394c78a90e74812bbdbf8cf3cca1be (diff) |
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'drivers/net/hydra.c')
-rw-r--r-- | drivers/net/hydra.c | 742 |
1 files changed, 372 insertions, 370 deletions
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index aea36d412..ca0e019ce 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -27,15 +27,15 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <linux/init.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/bootinfo.h> #include <asm/amigaints.h> #include <asm/amigahw.h> -#include <asm/zorro.h> +#include <linux/zorro.h> #include "hydra.h" @@ -48,11 +48,11 @@ #undef HYDRA_DEBUG /* define this for (lots of) debugging information */ #if 0 /* currently hardwired to one transmit buffer */ - #define TX_RING_SIZE 5 - #define RX_RING_SIZE 16 + #define TX_RING_SIZE 5 + #define RX_RING_SIZE 16 #else - #define TX_RING_SIZE 1 - #define RX_RING_SIZE 8 + #define TX_RING_SIZE 1 + #define RX_RING_SIZE 8 #endif #define ETHER_MIN_LEN 64 @@ -66,8 +66,8 @@ * the CIA accesses here are uses to make sure the minimum time * requirement between NIC chip selects is met. */ -#define WRITE_REG(reg, val) (ciaa.pra, ((u_char)(*(nicbase+(reg))=val))) -#define READ_REG(reg) (ciaa.pra, ((u_char)(*(nicbase+(reg))))) +#define WRITE_REG(reg, val) (ciaa.pra, ((u8)(*(nicbase+(reg))=val))) +#define READ_REG(reg) (ciaa.pra, ((u8)(*(nicbase+(reg))))) /* mask value for the interrupts we use */ #define NIC_INTS (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | ISR_CNT) @@ -79,23 +79,23 @@ * Private Device Data */ struct hydra_private - { - u_char *hydra_base; - u_char *hydra_nic_base; - u_short tx_page_start; - u_short rx_page_start; - u_short rx_page_stop; - u_short next_pkt; - struct enet_statistics stats; - int key; - }; +{ + u8 *hydra_base; + u8 *hydra_nic_base; + u16 tx_page_start; + u16 rx_page_start; + u16 rx_page_stop; + u16 next_pkt; + struct net_device_stats stats; + int key; +}; static int hydra_open(struct device *dev); static int hydra_start_xmit(struct sk_buff *skb, struct device *dev); -static void hydra_interrupt(int irq, struct pt_regs *fp, void *data); -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u_char *nicbase); +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 enet_statistics *hydra_get_stats(struct device *dev); +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); #endif @@ -107,8 +107,8 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); #if defined (__GNUC__) && defined (__mc68000__) && defined (USE_ASM) -static __inline__ void *memcpyw(u_short *dest, u_short *src, int len) - { +static __inline__ void *memcpyw(u16 *dest, u16 *src, int len) +{ __asm__(" move.l %0,%/a1; move.l %1,%/a0; move.l %2,%/d0 \n\t" " cmpi.l #2,%/d0 \n\t" "1: bcs.s 2f \n\t" @@ -134,462 +134,462 @@ static __inline__ void *memcpyw(u_short *dest, u_short *src, int len) /* this one here relies on the fact that _writes_ to hydra memory */ /* are guaranteed to be of even length. (reads can be arbitrary) */ -static void memcpyw(u_short *dest, u_short *src, int len) +/* + * FIXME: Surely we should be using the OS generic stuff and do + * + * memcpy(dest,src,(len+1)&~1); + * + * Can a 68K guy with this card check that ? - better yet + * use a copy/checksum on it. + */ + +static void memcpyw(u16 *dest, u16 *src, int len) { - if(len & 1) - len++; + if(len & 1) + len++; - while (len >= 2) { - *(dest++) = *(src++); - len -= 2; - } - + while (len >= 2) + { + *(dest++) = *(src++); + len -= 2; + } } #endif -int hydra_probe(struct device *dev) - { - struct hydra_private *priv; - u_long board; - int key; - struct ConfigDev *cd; - int j; +__initfunc(int hydra_probe(struct device *dev)) +{ + struct hydra_private *priv; + u32 board; + int key; + struct ConfigDev *cd; + int j; #ifdef HYDRA_DEBUG printk("hydra_probe(%x)\n", dev); #endif - if ((key = zorro_find(MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, 0, 0))) { - cd = zorro_get_board(key); - if((board = (u_long) cd->cd_BoardAddr)) - { - for(j = 0; j < ETHER_ADDR_LEN; j++) - dev->dev_addr[j] = *((u_char *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j)); + if ((key = zorro_find(MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, 0, 0))) + { + cd = zorro_get_board(key); + if((board = (u32) cd->cd_BoardAddr)) + { + for(j = 0; j < ETHER_ADDR_LEN; j++) + dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j)); - printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", - dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - - init_etherdev(dev, 0); + printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", + dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + init_etherdev(dev, 0); - dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL); - priv = (struct hydra_private *)dev->priv; - memset(priv, 0, sizeof(struct hydra_private)); + dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL); + priv = (struct hydra_private *)dev->priv; + memset(priv, 0, sizeof(struct hydra_private)); - priv->hydra_base = (u_char *) ZTWO_VADDR(board); - priv->hydra_nic_base = (u_char *) ZTWO_VADDR(board) + HYDRA_NIC_BASE; - priv->key = key; + priv->hydra_base = (u8 *) ZTWO_VADDR(board); + priv->hydra_nic_base = (u8 *) ZTWO_VADDR(board) + HYDRA_NIC_BASE; + priv->key = key; - dev->open = &hydra_open; - dev->stop = &hydra_close; - dev->hard_start_xmit = &hydra_start_xmit; - dev->get_stats = &hydra_get_stats; + dev->open = &hydra_open; + dev->stop = &hydra_close; + dev->hard_start_xmit = &hydra_start_xmit; + dev->get_stats = &hydra_get_stats; #ifdef HAVE_MULTICAST - dev->set_multicast_list = &hydra_set_multicast_list; + dev->set_multicast_list = &set_multicast_list; #endif - zorro_config_board(key, 0); - return(0); - } - } - return(ENODEV); - } + + /* + * Cannot yet do multicast + */ + dev->flags&=~IFF_MULTICAST; + zorro_config_board(key, 0); + return(0); + } + } + return(ENODEV); +} static int hydra_open(struct device *dev) - { - struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u_char *nicbase = priv->hydra_nic_base; -#ifdef HAVE_MULTICAST - int i; -#endif +{ + struct hydra_private *priv = (struct hydra_private *)dev->priv; + volatile u8 *nicbase = priv->hydra_nic_base; + int i; #ifdef HYDRA_DEBUG - printk("hydra_open(0x%x)\n", dev); + printk("hydra_open(0x%x)\n", dev); #endif - /* first, initialize the private structure */ - priv->tx_page_start = 0; /* these are 256 byte buffers for NS8390 */ - priv->rx_page_start = 6; - priv->rx_page_stop = 62; /* these values are hard coded for now */ + /* first, initialize the private structure */ + priv->tx_page_start = 0; /* these are 256 byte buffers for NS8390 */ + priv->rx_page_start = 6; + priv->rx_page_stop = 62; /* these values are hard coded for now */ - /* Reset the NS8390 NIC */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); + /* Reset the NS8390 NIC */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); - /* be sure that the NIC is in stopped state */ - while(!(READ_REG(NIC_ISR) & ISR_RST)); + /* be sure that the NIC is in stopped state */ + while(!(READ_REG(NIC_ISR) & ISR_RST)); - /* word transfer, big endian bytes, loopback, FIFO threshold 4 bytes */ - WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0); + /* word transfer, big endian bytes, loopback, FIFO threshold 4 bytes */ + WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0); - /* clear remote byte count registers */ - WRITE_REG(NIC_RBCR0, 0); - WRITE_REG(NIC_RBCR1, 0); + /* clear remote byte count registers */ + WRITE_REG(NIC_RBCR0, 0); + WRITE_REG(NIC_RBCR1, 0); - /* accept packets addressed to this card and also broadcast packets */ - WRITE_REG(NIC_RCR, NIC_RCRBITS); + /* accept packets addressed to this card and also broadcast packets */ + WRITE_REG(NIC_RCR, NIC_RCRBITS); - /* enable loopback mode 1 */ - WRITE_REG(NIC_TCR, TCR_LB1); + /* enable loopback mode 1 */ + WRITE_REG(NIC_TCR, TCR_LB1); - /* initialize receive buffer ring */ - WRITE_REG(NIC_PSTART, priv->rx_page_start); - WRITE_REG(NIC_PSTOP, priv->rx_page_stop); - WRITE_REG(NIC_BNDRY, priv->rx_page_start); + /* initialize receive buffer ring */ + WRITE_REG(NIC_PSTART, priv->rx_page_start); + WRITE_REG(NIC_PSTOP, priv->rx_page_stop); + WRITE_REG(NIC_BNDRY, priv->rx_page_start); - /* clear interrupts */ - WRITE_REG(NIC_ISR, 0xff); + /* clear interrupts */ + WRITE_REG(NIC_ISR, 0xff); - /* enable interrupts */ - WRITE_REG(NIC_IMR, NIC_INTS); + /* enable interrupts */ + WRITE_REG(NIC_IMR, NIC_INTS); - /* set the ethernet hardware address */ - WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_STOP); /* goto page 1 */ + /* set the ethernet hardware address */ + WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_STOP); /* goto page 1 */ - WRITE_REG(NIC_PAR0, dev->dev_addr[0]); - WRITE_REG(NIC_PAR1, dev->dev_addr[1]); - WRITE_REG(NIC_PAR2, dev->dev_addr[2]); - WRITE_REG(NIC_PAR3, dev->dev_addr[3]); - WRITE_REG(NIC_PAR4, dev->dev_addr[4]); - WRITE_REG(NIC_PAR5, dev->dev_addr[5]); + WRITE_REG(NIC_PAR0, dev->dev_addr[0]); + WRITE_REG(NIC_PAR1, dev->dev_addr[1]); + WRITE_REG(NIC_PAR2, dev->dev_addr[2]); + WRITE_REG(NIC_PAR3, dev->dev_addr[3]); + WRITE_REG(NIC_PAR4, dev->dev_addr[4]); + WRITE_REG(NIC_PAR5, dev->dev_addr[5]); -#ifdef HAVE_MULTICAST - /* clear multicast hash table */ - for(i = 0; i < 8; i++) - WRITE_REG(NIC_MAR0 + 2*i, 0); -#endif + /* clear multicast hash table */ + for(i = 0; i < 8; i++) + WRITE_REG(NIC_MAR0 + 2*i, 0); - priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */ - WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */ + priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */ + WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */ - /* goto page 0, start NIC */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); + /* goto page 0, start NIC */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); - /* take interface out of loopback */ - WRITE_REG(NIC_TCR, 0); + /* take interface out of loopback */ + WRITE_REG(NIC_TCR, 0); - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; - if(!add_isr(IRQ_AMIGA_PORTS, hydra_interrupt, 0, dev, "Hydra Ethernet")) - return(-EAGAIN); + if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, 0, "Hydra Ethernet", dev)) + return(-EAGAIN); - MOD_INC_USE_COUNT; + MOD_INC_USE_COUNT; - return(0); - } + return(0); +} static int hydra_close(struct device *dev) { - struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u_char *nicbase = priv->hydra_nic_base; - int n = 5000; + struct hydra_private *priv = (struct hydra_private *)dev->priv; + volatile u8 *nicbase = priv->hydra_nic_base; + int n = 5000; - dev->start = 0; - dev->tbusy = 1; + dev->start = 0; + dev->tbusy = 1; #ifdef HYDRA_DEBUG - printk("%s: Shutting down ethercard\n", dev->name); - printk("%s: %d packets missed\n", dev->name, priv->stats.rx_missed_errors); + printk("%s: Shutting down ethercard\n", dev->name); + printk("%s: %d packets missed\n", dev->name, priv->stats.rx_missed_errors); #endif - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); - /* wait for NIC to stop (what a nice timeout..) */ - while(((READ_REG(NIC_ISR) & ISR_RST) == 0) && --n); + /* wait for NIC to stop (what a nice timeout..) */ + while(((READ_REG(NIC_ISR) & ISR_RST) == 0) && --n); - remove_isr(IRQ_AMIGA_PORTS, hydra_interrupt, dev); + free_irq(IRQ_AMIGA_PORTS, dev); - MOD_DEC_USE_COUNT; + MOD_DEC_USE_COUNT; - return(0); + return(0); } -static void hydra_interrupt(int irq, struct pt_regs *fp, void *data) - { - volatile u_char *nicbase; +static void hydra_interrupt(int irq, void *data, struct pt_regs *fp) +{ + volatile u8 *nicbase; - struct device *dev = (struct device *) data; - struct hydra_private *priv; - u_short intbits; + struct device *dev = (struct device *) data; + struct hydra_private *priv; + u16 intbits; - if(dev == NULL) - { - printk("hydra_interrupt(): irq for unknown device\n"); - return; - } + if(dev == NULL) + { + printk("hydra_interrupt(): irq for unknown device\n"); + return; + } -/* this is not likely a problem - i think */ - if(dev->interrupt) - printk("%s: re-entering the interrupt handler\n", dev->name); + /* this is not likely a problem - i think */ + if(dev->interrupt) + printk("%s: re-entering the interrupt handler\n", dev->name); - dev->interrupt = 1; + dev->interrupt = 1; - priv = (struct hydra_private *) dev->priv; - nicbase = (u_char *) priv->hydra_nic_base; + priv = (struct hydra_private *) dev->priv; + nicbase = (u8 *) priv->hydra_nic_base; - /* select page 0 */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); + /* select page 0 */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); - intbits = READ_REG(NIC_ISR) & NIC_INTS; - if(intbits == 0) + intbits = READ_REG(NIC_ISR) & NIC_INTS; + if(intbits == 0) { - dev->interrupt = 0; - return; - } + dev->interrupt = 0; + return; + } /* acknowledge all interrupts, by clearing the interrupt flag */ WRITE_REG(NIC_ISR, intbits); if((intbits & ISR_PTX) && !(intbits & ISR_TXE)) - { - dev->tbusy = 0; - mark_bh(NET_BH); - } + { + dev->tbusy = 0; + mark_bh(NET_BH); + } if((intbits & ISR_PRX) && !(intbits & ISR_RXE))/* packet received OK */ - hydra_rx(dev, priv, nicbase); + hydra_rx(dev, priv, nicbase); if(intbits & ISR_TXE) - priv->stats.tx_errors++; + priv->stats.tx_errors++; if(intbits & ISR_RXE) - priv->stats.rx_errors++; + priv->stats.rx_errors++; - if(intbits & ISR_CNT) { - /* - * read the tally counters and (currently) ignore the values - * might be useful because of bugs of some versions of the 8390 NIC - */ + if(intbits & ISR_CNT) + { + /* + * read the tally counters and (currently) ignore the values + * might be useful because of bugs of some versions of the 8390 NIC + */ #ifdef HYDRA_DEBUG - printk("hydra_interrupt(): ISR_CNT\n"); + printk("hydra_interrupt(): ISR_CNT\n"); #endif - (void)READ_REG(NIC_CNTR0); - (void)READ_REG(NIC_CNTR1); - (void)READ_REG(NIC_CNTR2); + (void)READ_REG(NIC_CNTR0); + (void)READ_REG(NIC_CNTR1); + (void)READ_REG(NIC_CNTR2); } if(intbits & ISR_OVW) - { - #ifdef HYDRA_DEBUG - WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); + { +#ifdef HYDRA_DEBUG + WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); /* another one just too much for me to comprehend - basically this could */ /* only occur because of invalid access to hydra ram, thus invalidating */ /* the interrupt bits read - in average usage these do not occur at all */ - printk("hydra_interrupt(): overwrite warning, NIC_ISR %02x, NIC_CURR %02x\n", - intbits, READ_REG(NIC_CURR)); - WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); - #endif + printk("hydra_interrupt(): overwrite warning, NIC_ISR %02x, NIC_CURR %02x\n", + intbits, READ_REG(NIC_CURR)); + WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); +#endif - /* overwrite warning occurred, stop NIC & check the BOUNDARY pointer */ - /* FIXME - real overwrite handling needed !! */ - - printk("hydra_interrupt(): overwrite warning, resetting NIC\n"); - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); - while(!(READ_REG(NIC_ISR) & ISR_RST)); - /* wait for NIC to reset */ - WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0); - WRITE_REG(NIC_RBCR0, 0); - WRITE_REG(NIC_RBCR1, 0); - WRITE_REG(NIC_RCR, NIC_RCRBITS); - WRITE_REG(NIC_TCR, TCR_LB1); - WRITE_REG(NIC_PSTART, priv->rx_page_start); - WRITE_REG(NIC_PSTOP, priv->rx_page_stop); - WRITE_REG(NIC_BNDRY, priv->rx_page_start); - WRITE_REG(NIC_ISR, 0xff); - WRITE_REG(NIC_IMR, NIC_INTS); -/* currently this _won't_ reset my hydra, even though it is */ -/* basically the same code as in the board init - any ideas? */ - - priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */ - WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */ + /* overwrite warning occurred, stop NIC & check the BOUNDARY pointer */ + /* FIXME - real overwrite handling needed !! */ + + printk("hydra_interrupt(): overwrite warning, resetting NIC\n"); + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP); + while(!(READ_REG(NIC_ISR) & ISR_RST)); + /* wait for NIC to reset */ + WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0); + WRITE_REG(NIC_RBCR0, 0); + WRITE_REG(NIC_RBCR1, 0); + WRITE_REG(NIC_RCR, NIC_RCRBITS); + WRITE_REG(NIC_TCR, TCR_LB1); + WRITE_REG(NIC_PSTART, priv->rx_page_start); + WRITE_REG(NIC_PSTOP, priv->rx_page_stop); + WRITE_REG(NIC_BNDRY, priv->rx_page_start); + WRITE_REG(NIC_ISR, 0xff); + WRITE_REG(NIC_IMR, NIC_INTS); + /* currently this _won't_ reset my hydra, even though it is */ + /* basically the same code as in the board init - any ideas? */ + + priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */ + WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); - - WRITE_REG(NIC_TCR, 0); - } + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); - dev->interrupt = 0; - return; + WRITE_REG(NIC_TCR, 0); + } + + dev->interrupt = 0; + return; } /* * packet transmit routine */ + static int hydra_start_xmit(struct sk_buff *skb, struct device *dev) - { - struct hydra_private *priv = (struct hydra_private *)dev->priv; - volatile u_char *nicbase = priv->hydra_nic_base; - int len, len1; +{ + struct hydra_private *priv = (struct hydra_private *)dev->priv; + volatile u8 *nicbase = priv->hydra_nic_base; + int len, len1; /* Transmitter timeout, serious problems. */ - if(dev->tbusy) + if(dev->tbusy) { - int tickssofar = jiffies - dev->trans_start; - if(tickssofar < 20) - return(1); - WRITE_REG(NIC_CR, CR_STOP); - printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, 0); - priv->stats.tx_errors++; - - - dev->tbusy = 0; - dev->trans_start = jiffies; - - return(0); + int tickssofar = jiffies - dev->trans_start; + if(tickssofar < 20) + return(1); + WRITE_REG(NIC_CR, CR_STOP); + printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, 0); + priv->stats.tx_errors++; + dev->tbusy = 0; + dev->trans_start = jiffies; + return(0); } + len=skb->len; - if(skb == NULL) - { - dev_tint(dev); - return(0); - } - - if((len = skb->len) <= 0) - return(0); - - /* fill in a tx ring entry */ + /* fill in a tx ring entry */ #ifdef HYDRA_DEBUG - printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); + printk("TX pkt type 0x%04x from ", ((u16 *)skb->data)[6]); { int i; - u_char *ptr = &((u_char *)skb->data)[6]; + u8 *ptr = &((u8 *)skb->data)[6]; for (i = 0; i < 6; i++) printk("%02x", ptr[i]); } printk(" to "); { int i; - u_char *ptr = (u_char *)skb->data; + u8 *ptr = (u8 *)skb->data; for (i = 0; i < 6; i++) printk("%02x", ptr[i]); } printk(" data 0x%08x len %d\n", (int)skb->data, len); #endif - /* - * make sure that the packet size is at least the minimum - * allowed ethernet packet length. - * (possibly should also clear the unused space...) - * note: minimum packet length is 64, including CRC - */ - len1 = len; - if(len < (ETHER_MIN_LEN-4)) - len = (ETHER_MIN_LEN-1); - - /* make sure we've got an even number of bytes to copy to hydra's mem */ - if(len & 1) len++; - - if((u_long)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000) - printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8))); - - /* copy the packet data to the transmit buffer - in the ethernet card RAM */ - memcpyw((u_short *)(priv->hydra_base + (priv->tx_page_start << 8)), - (u_short *)skb->data, len); - /* clear the unused space */ -/* for(; len1<len; len1++) - (u_short)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0; -*/ - dev_kfree_skb(skb, FREE_WRITE); + /* + * make sure that the packet size is at least the minimum + * allowed ethernet packet length. + * (FIXME: Should also clear the unused space...) + * note: minimum packet length is 64, including CRC + */ + len1 = len; - priv->stats.tx_packets++; + if(len < (ETHER_MIN_LEN-4)) + len = (ETHER_MIN_LEN-1); - cli(); - /* make sure we are on the correct page */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); + /* make sure we've got an even number of bytes to copy to hydra's mem */ + if(len & 1) len++; - /* here we configure the transmit page start register etc */ - /* notice that this code is hardwired to one transmit buffer */ - WRITE_REG(NIC_TPSR, priv->tx_page_start); - WRITE_REG(NIC_TBCR0, len & 0xff); - WRITE_REG(NIC_TBCR1, len >> 8); + if((u32)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000) + printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8))); - /* commit the packet to the wire */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA | CR_TXP); - sti(); + /* copy the packet data to the transmit buffer + in the ethernet card RAM */ + memcpyw((u16 *)(priv->hydra_base + (priv->tx_page_start << 8)), + (u16 *)skb->data, len); + /* clear the unused space */ + for(; len1<len; len1++) + (u16)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0; + dev_kfree_skb(skb, FREE_WRITE); - dev->trans_start = jiffies; + priv->stats.tx_packets++; - return(0); - } + cli(); + /* make sure we are on the correct page */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START); + + /* here we configure the transmit page start register etc */ + /* notice that this code is hardwired to one transmit buffer */ + WRITE_REG(NIC_TPSR, priv->tx_page_start); + WRITE_REG(NIC_TBCR0, len & 0xff); + WRITE_REG(NIC_TBCR1, len >> 8); + /* commit the packet to the wire */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA | CR_TXP); + sti(); -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u_char *nicbase) - { - volatile u_short *board_ram_ptr; - struct sk_buff *skb; - int hdr_next_pkt, pkt_len, len1, boundary; + dev->trans_start = jiffies; + return(0); +} - /* remove packet(s) from the ring and commit them to TCP layer */ - WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */ - while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */ - { - board_ram_ptr = (u_short *)(priv->hydra_base + (priv->next_pkt << 8)); + +static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u8 *nicbase) +{ + volatile u16 *board_ram_ptr; + struct sk_buff *skb; + int hdr_next_pkt, pkt_len, len1, boundary; + + + /* remove packet(s) from the ring and commit them to TCP layer */ + WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */ + while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */ + { + board_ram_ptr = (u16 *)(priv->hydra_base + (priv->next_pkt << 8)); #ifdef HYDRA_DEBUG - printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr); + printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr); #endif - /* the following must be done with two steps, or - GCC optimizes it to a byte access to Hydra memory, - which doesn't work... */ - hdr_next_pkt = board_ram_ptr[0]; - hdr_next_pkt >>= 8; + /* the following must be done with two steps, or + GCC optimizes it to a byte access to Hydra memory, + which doesn't work... */ + hdr_next_pkt = board_ram_ptr[0]; + hdr_next_pkt >>= 8; - pkt_len = board_ram_ptr[1]; - pkt_len = ((pkt_len >> 8) | ((pkt_len & 0xff) << 8)); + pkt_len = board_ram_ptr[1]; + pkt_len = ((pkt_len >> 8) | ((pkt_len & 0xff) << 8)); #ifdef HYDRA_DEBUG - printk("hydra_interrupt(): hdr_next_pkt = 0x%02x, len = %d\n", hdr_next_pkt, pkt_len); + printk("hydra_interrupt(): hdr_next_pkt = 0x%02x, len = %d\n", hdr_next_pkt, pkt_len); #endif - if(pkt_len >= ETHER_MIN_LEN && pkt_len <= ETHER_MAX_LEN) - { - /* note that board_ram_ptr is u_short */ - /* CRC is not included in the packet length */ - - pkt_len -= 4; - skb = dev_alloc_skb(pkt_len+2); - if(skb == NULL) - { - printk("%s: memory squeeze, dropping packet.\n", dev->name); - priv->stats.rx_dropped++; - } - else - { - skb->dev = dev; - skb_reserve(skb, 2); + if(pkt_len >= ETHER_MIN_LEN && pkt_len <= ETHER_MAX_LEN) + { + /* note that board_ram_ptr is u16 */ + /* CRC is not included in the packet length */ - if(hdr_next_pkt < priv->next_pkt && hdr_next_pkt != priv->rx_page_start) - { - /* here, the packet is wrapped */ - len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4; - - memcpyw((u_short *)skb_put(skb, len1), (u_short *)(board_ram_ptr+2), len1); - memcpyw((u_short *)skb_put(skb, pkt_len-len1), (u_short *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1); - + pkt_len -= 4; + skb = dev_alloc_skb(pkt_len+2); + if(skb == NULL) + { + printk(KERN_INFO "%s: memory squeeze, dropping packet.\n", dev->name); + priv->stats.rx_dropped++; + } + else + { + skb->dev = dev; + skb_reserve(skb, 2); + if(hdr_next_pkt < priv->next_pkt && hdr_next_pkt != priv->rx_page_start) + { + /* here, the packet is wrapped */ + len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4; + + memcpyw((u16 *)skb_put(skb, len1), (u16 *)(board_ram_ptr+2), len1); + memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1); + #ifdef HYDRA_DEBUG - printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1); + printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1); #endif - } /* ... here, packet is not wrapped */ - else memcpyw((u_short *) skb_put(skb, pkt_len), (u_short *)(board_ram_ptr+2), pkt_len); - } - /* if(skb == NULL) ... */ - } - else - { - WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); - printk("hydra_interrupt(): invalid packet len: %d, NIC_CURR = %02x\n", pkt_len, READ_REG(NIC_CURR)); + } /* ... here, packet is not wrapped */ + else + memcpyw((u16 *) skb_put(skb, pkt_len), (u16 *)(board_ram_ptr+2), pkt_len); + } + } + else + { + WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); + printk("hydra_interrupt(): invalid packet len: %d, NIC_CURR = %02x\n", pkt_len, READ_REG(NIC_CURR)); /* this is the error i kept getting until i switched to 0.9.10. it still doesn't mean that the bug would have gone away - so be alarmed. the packet is likely @@ -597,45 +597,47 @@ being fetched from a wrong memory location - but why - dunno note-for-v2.1: not really problem anymore. hasn't been for a long time. */ - - WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); - /* should probably reset the NIC here ?? */ - - hydra_open(dev); /* FIXME - i shouldn't really be doing this. */ - return; - } + + WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); + /* should probably reset the NIC here ?? */ + + hydra_open(dev); /* FIXME - i shouldn't really be doing this. */ + return; + } - /* now, update the next_pkt pointer */ - if(hdr_next_pkt < priv->rx_page_stop) priv->next_pkt = hdr_next_pkt; - else printk("hydra_interrupt(): invalid next_pkt pointer %d\n", hdr_next_pkt); + /* now, update the next_pkt pointer */ + if(hdr_next_pkt < priv->rx_page_stop) + priv->next_pkt = hdr_next_pkt; + else + printk("hydra_interrupt(): invalid next_pkt pointer %d\n", hdr_next_pkt); - /* update the boundary pointer */ - boundary = priv->next_pkt - 1; - if(boundary < priv->rx_page_start) - boundary = priv->rx_page_stop - 1; + /* update the boundary pointer */ + boundary = priv->next_pkt - 1; + if(boundary < priv->rx_page_start) + boundary = priv->rx_page_stop - 1; - /* set NIC to page 0 to update the NIC_BNDRY register */ - WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); - WRITE_REG(NIC_BNDRY, boundary); + /* set NIC to page 0 to update the NIC_BNDRY register */ + WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA); + WRITE_REG(NIC_BNDRY, boundary); - /* select page1 to access the NIC_CURR register */ - WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); + /* select page1 to access the NIC_CURR register */ + WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA); - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - priv->stats.rx_packets++; + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + priv->stats.rx_packets++; - } - return; - } + } + return; +} -static struct enet_statistics *hydra_get_stats(struct device *dev) +static struct net_device_stats *hydra_get_stats(struct device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; #if 0 - u_char *board = priv->hydra_base; + u8 *board = priv->hydra_base; short saved_addr; #endif @@ -646,14 +648,14 @@ static struct enet_statistics *hydra_get_stats(struct device *dev) #ifdef HAVE_MULTICAST static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) - { - struct hydra_private *priv = (struct hydra_private *)dev->priv; - u_char *board = priv->hydra_base; +{ + struct hydra_private *priv = (struct hydra_private *)dev->priv; + u8 *board = priv->hydra_base; - /* yes, this code is also waiting for someone to complete.. :) */ - /* (personally i don't care about multicasts at all :) */ - return; - } + /* yes, this code is also waiting for someone to complete.. :) */ + /* (personally i don't care about multicasts at all :) */ + return; +} #endif |