X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fseeq8005.c;h=48c64fb20eecf164b9022aae727e6dc86e8f5290;hb=569f0c4d909c7f73de634abcdc36344cb72de36a;hp=efd0f235020fb4e7099174d70232aece63581c0d;hpb=5b057c6b1a25d57edf2b4d1e956e50936480a9ff;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index efd0f23..48c64fb 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -20,7 +20,7 @@ static const char version[] = /* Sources: SEEQ 8005 databook - + Version history: 1.00 Public release. cosmetic changes (no warnings now) 0.68 Turning per- packet,interrupt debug messages off - testing for release. @@ -67,7 +67,6 @@ static unsigned int net_debug = NET_DEBUG; /* Information that need to be kept for each board. */ struct net_local { - struct net_device_stats stats; unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */ long open_time; /* Useless example local info. */ }; @@ -83,10 +82,9 @@ static int seeq8005_probe1(struct net_device *dev, int ioaddr); static int seeq8005_open(struct net_device *dev); static void seeq8005_timeout(struct net_device *dev); static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t seeq8005_interrupt(int irq, void *dev_id); 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 ;->. */ @@ -95,7 +93,7 @@ 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. If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 1, always return failure. @@ -160,6 +158,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) int old_dmaar; int old_rear; int retval; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005")) return -ENODEV; @@ -196,11 +195,11 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) retval = -ENODEV; goto out; } - + old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */ old_cfg1 = inw(SEEQ_CFG1); old_dmaar = inw(SEEQ_DMAAR); - + if (net_debug>4) { printk("seeq8005: stat = 0x%04x\n",old_stat); printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1); @@ -208,7 +207,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) printk("seeq8005: raer = 0x%04x\n",old_rear); printk("seeq8005: dmaar= 0x%04x\n",old_dmaar); } - + outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */ outw( 0, SEEQ_DMAAR); /* set starting PROM address */ outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */ @@ -236,7 +235,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */ udelay(5); outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD); - + if (net_debug) { printk("seeq8005: prom sum = 0x%08x\n",j); for(j=0; j<32; j+=16) { @@ -256,10 +255,10 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) } } -#if 0 - /* +#if 0 + /* * testing the packet buffer memory doesn't work yet - * but all other buffer accesses do + * but all other buffer accesses do * - fixing is not a priority */ if (net_debug>1) { /* test packet buffer memory */ @@ -303,22 +302,23 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]); + dev->dev_addr[i] = SA_prom[i+6]; + printk("%s", print_mac(mac, dev->dev_addr)); if (dev->irq == 0xff) ; /* Do nothing: a user-level program will set it. */ else if (dev->irq < 2) { /* "Auto-IRQ" */ unsigned long cookie = probe_irq_on(); - + outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD ); dev->irq = probe_irq_off(cookie); - + if (net_debug >= 2) printk(" autoirq is %d\n", dev->irq); } else if (dev->irq == 2) /* Fixup for users that don't know that IRQ 2 is really IRQ 9, - * or don't know which one to set. + * or don't know which one to set. */ dev->irq = 9; @@ -338,7 +338,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) dev->hard_start_xmit = seeq8005_send_packet; dev->tx_timeout = seeq8005_timeout; dev->watchdog_timeo = HZ/20; - dev->get_stats = seeq8005_get_stats; dev->set_multicast_list = set_multicast_list; dev->flags &= ~IFF_MULTICAST; @@ -348,7 +347,7 @@ out: return retval; } - + /* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. @@ -391,7 +390,6 @@ static void seeq8005_timeout(struct net_device *dev) static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); short length = skb->len; unsigned char *buf; @@ -404,16 +402,16 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); - - hardware_send_packet(dev, buf, length); + + hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; - lp->stats.tx_bytes += length; + dev->stats.tx_bytes += length; dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ return 0; } - + /* * wait_for_buffer * @@ -426,18 +424,18 @@ inline void wait_for_buffer(struct net_device * dev) int ioaddr = dev->base_addr; unsigned long tmp; int status; - + tmp = jiffies + HZ; while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp)) cpu_relax(); - + if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT) outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); } - + /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) +static irqreturn_t seeq8005_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct net_local *lp; @@ -452,7 +450,7 @@ static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * re if (net_debug >2) { printk("%s: int, status=0x%04x\n",dev->name,status); } - + if (status & SEEQSTAT_WINDOW_INT) { handled = 1; outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); @@ -463,7 +461,7 @@ static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * re if (status & SEEQSTAT_TX_INT) { handled = 1; outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); - lp->stats.tx_packets++; + dev->stats.tx_packets++; netif_wake_queue(dev); /* Inform upper layers. */ } if (status & SEEQSTAT_RX_INT) { @@ -500,42 +498,42 @@ static void seeq8005_rx(struct net_device *dev) wait_for_buffer(dev); next_packet = ntohs(inw(SEEQ_BUFFER)); pkt_hdr = inw(SEEQ_BUFFER); - + if (net_debug>2) { printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr); } - + if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */ return; /* Done for now */ } - + if ((pkt_hdr & SEEQPKTS_DONE)==0) break; - + if (next_packet < lp->receive_ptr) { pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4; } else { pkt_len = next_packet - lp->receive_ptr - 4; } - + if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */ printk("%s: recv packet ring corrupt, resetting board\n",dev->name); seeq8005_init(dev,1); return; } - + lp->receive_ptr = next_packet; - + if (net_debug>2) { printk("%s: recv len=0x%04x\n",dev->name,pkt_len); } if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */ - lp->stats.rx_errors++; - if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++; - if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++; - if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++; - if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++; + dev->stats.rx_errors++; + if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++; + if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++; + if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++; + if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++; /* skip over this packet */ outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA); @@ -547,15 +545,14 @@ static void seeq8005_rx(struct net_device *dev) skb = dev_alloc_skb(pkt_len); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } - skb->dev = dev; skb_reserve(skb, 2); /* align data on 16 byte */ buf = skb_put(skb,pkt_len); - + insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1); - + if (net_debug>2) { char * p = buf; printk("%s: recv ",dev->name); @@ -568,8 +565,8 @@ static void seeq8005_rx(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN)); @@ -588,7 +585,7 @@ static int seeq8005_close(struct net_device *dev) lp->open_time = 0; netif_stop_queue(dev); - + /* Flush the Tx and disable Rx here. */ outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD); @@ -600,15 +597,6 @@ static int seeq8005_close(struct net_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 net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - - 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 @@ -627,7 +615,7 @@ static void set_multicast_list(struct net_device *dev) * hmm, not even sure if my matching works _anyway_ - seem to be receiving * _everything_ . . . */ - + if (num_addrs) { /* Enable promiscuous mode */ outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1); dev->flags|=IFF_PROMISC; @@ -642,26 +630,26 @@ void seeq8005_init(struct net_device *dev, int startp) struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int i; - + outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */ udelay(5); - + outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */ /* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */ outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1); - + for(i=0;i<6;i++) { /* set Station address */ outb(dev->dev_addr[i], SEEQ_BUFFER); udelay(2); } - + outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */ outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */ - + lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */ outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */ - + outw( 0x00ff, SEEQ_REA); /* Receive Area End */ if (net_debug>4) { @@ -670,13 +658,13 @@ void seeq8005_init(struct net_device *dev, int startp) outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); outw( 0, SEEQ_DMAAR); outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1); - + for(i=0;i<6;i++) { printk("%02x ",inb(SEEQ_BUFFER)); } printk("\n"); } - + outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1); outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2); outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD); @@ -689,9 +677,9 @@ void seeq8005_init(struct net_device *dev, int startp) printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2)); printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA)); printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR)); - + } -} +} static void hardware_send_packet(struct net_device * dev, char *buf, int length) @@ -704,32 +692,32 @@ static void hardware_send_packet(struct net_device * dev, char *buf, int length) if (net_debug>4) { printk("%s: send 0x%04x\n",dev->name,length); } - + /* Set FIFO to writemode and set packet-buffer address */ outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD); outw( transmit_ptr, SEEQ_DMAAR); - + /* output SEEQ Packet header barfage */ outw( htons(length + 4), SEEQ_BUFFER); outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER ); - + /* blat the buffer */ outsw( SEEQ_BUFFER, buf, (length +1) >> 1); /* paranoia !! */ outw( 0, SEEQ_BUFFER); outw( 0, SEEQ_BUFFER); - + /* set address of start of transmit chain */ outw( transmit_ptr, SEEQ_TPR); - + /* drain FIFO */ tmp = jiffies; while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ)) mb(); - + /* doit ! */ outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD); - + } @@ -742,7 +730,7 @@ module_param(irq, int, 0); MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address"); MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number"); -int init_module(void) +int __init init_module(void) { dev_seeq = seeq8005_probe(-1); if (IS_ERR(dev_seeq)) @@ -750,7 +738,7 @@ int init_module(void) return 0; } -void cleanup_module(void) +void __exit cleanup_module(void) { unregister_netdev(dev_seeq); release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT); @@ -758,7 +746,7 @@ void cleanup_module(void) } #endif /* MODULE */ - + /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"