X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fsun3lance.c;h=c62e85d89f4173e78d0a4c9227463d865800f0a4;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=f0512a498b5efb53454e03e611f9b520f0e829d7;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index f0512a498..c62e85d89 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -1,24 +1,24 @@ /* sun3lance.c: Ethernet driver for SUN3 Lance chip */ /* - Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net). + 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 General 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. + 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). + 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.2 1/12/2001 Sam Creasey (sammy@sammy.net)\n"; @@ -36,13 +36,13 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne #include #include #include +#include +#include #include #include -#include #include #include -#include #include #include #include @@ -56,7 +56,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne /* sun3/60 addr/irq for the lance chip. If your sun is different, change this. */ #define LANCE_OBIO 0x120000 -#define LANCE_IRQ IRQ3 +#define LANCE_IRQ IRQ_AUTO_3 /* Debug level: * 0 = silent, print only serious errors @@ -72,7 +72,7 @@ static int lance_debug = LANCE_DEBUG; #else static int lance_debug = 1; #endif -MODULE_PARM(lance_debug, "i"); +module_param(lance_debug, int, 0); MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)"); MODULE_LICENSE("GPL"); @@ -163,7 +163,7 @@ struct lance_private { #define MEM lp->mem #define DREG lp->iobase[0] #define AREG lp->iobase[1] -#define REGA(a) ( AREG = (a), DREG ) +#define REGA(a) (*( AREG = (a), &DREG )) /* Definitions for the Lance */ @@ -238,7 +238,7 @@ 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 irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); +static irqreturn_t lance_interrupt( int irq, void *dev_id); 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 ); @@ -287,7 +287,7 @@ struct net_device * __init sun3lance_probe(int unit) out1: #ifdef CONFIG_SUN3 - iounmap((void *)dev->base_addr); + iounmap((void __iomem *)dev->base_addr); #endif out: free_netdev(dev); @@ -295,9 +295,9 @@ out: } static int __init lance_probe( struct net_device *dev) -{ +{ unsigned long ioaddr; - + struct lance_private *lp; int i; static int did_version; @@ -314,7 +314,7 @@ static int __init lance_probe( struct net_device *dev) /* test to see if there's really a lance here */ /* (CSRO_INIT shouldn't be readable) */ - + ioaddr_probe = (volatile unsigned short *)ioaddr; tmp1 = ioaddr_probe[0]; tmp2 = ioaddr_probe[1]; @@ -327,7 +327,7 @@ static int __init lance_probe( struct net_device *dev) ioaddr_probe[1] = tmp2; #ifdef CONFIG_SUN3 - iounmap((void *)ioaddr); + iounmap((void __iomem *)ioaddr); #endif return 0; } @@ -340,9 +340,9 @@ static int __init lance_probe( struct net_device *dev) lp->iobase = (volatile unsigned short *)ioaddr; dev->base_addr = (unsigned long)ioaddr; /* informational only */ - REGA(CSR0) = CSR0_STOP; + REGA(CSR0) = CSR0_STOP; - request_irq(LANCE_IRQ, lance_interrupt, SA_INTERRUPT, "SUN3 Lance", dev); + request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev); dev->irq = (unsigned short)LANCE_IRQ; @@ -379,7 +379,7 @@ static int __init lance_probe( struct net_device *dev) DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n", dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head), - (dvma_vtob(MEM->tx_head)))); + (dvma_vtob(MEM->tx_head)))); if (did_version++ == 0) printk( version ); @@ -390,7 +390,7 @@ static int __init lance_probe( struct net_device *dev) dev->stop = &lance_close; dev->get_stats = &lance_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->set_mac_address = 0; + dev->set_mac_address = NULL; // KLUDGE -- REMOVE ME set_bit(__LINK_STATE_PRESENT, &dev->state); @@ -428,7 +428,7 @@ static int lance_open( struct net_device *dev ) DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA; netif_start_queue(dev); - + DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); return( 0 ); @@ -450,7 +450,7 @@ static void lance_init_ring( struct net_device *dev ) for( i = 0; i < TX_RING_SIZE; i++ ) { MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]); MEM->tx_head[i].flag = 0; - MEM->tx_head[i].base_hi = + MEM->tx_head[i].base_hi = (dvma_vtob(MEM->tx_data[i])) >>16; MEM->tx_head[i].length = 0; MEM->tx_head[i].misc = 0; @@ -459,7 +459,7 @@ static void lance_init_ring( struct net_device *dev ) for( i = 0; i < RX_RING_SIZE; i++ ) { MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]); MEM->rx_head[i].flag = RMD1_OWN_CHIP; - MEM->rx_head[i].base_hi = + MEM->rx_head[i].base_hi = (dvma_vtob(MEM->rx_data[i])) >> 16; MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000; MEM->rx_head[i].msg_length = 0; @@ -543,22 +543,22 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) lance_init_ring(dev); REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT; - + netif_start_queue(dev); dev->trans_start = jiffies; - + return 0; } - + /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ /* Block a timer-based transmit from overlapping with us by stopping the queue for a bit... */ - + netif_stop_queue(dev); - + if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) { printk( "%s: tx queue lock!.\n", dev->name); /* don't clear dev->tbusy flag. */ @@ -594,7 +594,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) printk(" data at 0x%08x len %d\n", (int)skb->data, (int)skb->len ); } -#endif +#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... */ local_irq_save(flags); @@ -633,7 +633,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) lp->lock = 0; if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) == - TMD1_OWN_HOST) + TMD1_OWN_HOST) netif_start_queue(dev); local_irq_restore(flags); @@ -643,7 +643,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) /* The LANCE interrupt handler. */ -static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t lance_interrupt( int irq, void *dev_id) { struct net_device *dev = dev_id; struct lance_private *lp = netdev_priv(dev); @@ -658,10 +658,10 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) if (in_interrupt) DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name )); in_interrupt = 1; - + still_more: flush_cache_all(); - + AREG = CSR0; csr0 = DREG; @@ -681,22 +681,22 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) // 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]); - + 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++; @@ -706,7 +706,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) if (status & (TMD3_UFLO | TMD3_BUFF)) { lp->stats.tx_fifo_errors++; printk("%s: Tx FIFO error\n", - dev->name); + dev->name); REGA(CSR0) = CSR0_STOP; REGA(CSR3) = CSR3_BSWP; lance_init_ring(dev); @@ -714,11 +714,11 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) return IRQ_HANDLED; } } 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)); } @@ -737,7 +737,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) 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. */ @@ -779,10 +779,10 @@ static int lance_rx( struct net_device *dev ) 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, - to Russ Nelson: Even with + 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 */ @@ -807,7 +807,7 @@ static int lance_rx( struct net_device *dev ) 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; @@ -834,7 +834,7 @@ static int lance_rx( struct net_device *dev ) 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; @@ -915,7 +915,7 @@ static void set_multicast_list( struct net_device *dev ) if (dev->flags & IFF_PROMISC) { /* Log any net taps. */ - DPRINTK( 1, ( "%s: Promiscuous mode enabled.\n", dev->name )); + DPRINTK( 3, ( "%s: Promiscuous mode enabled.\n", dev->name )); REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */ } else { short multicast_table[4]; @@ -945,7 +945,7 @@ static void set_multicast_list( struct net_device *dev ) static struct net_device *sun3lance_dev; -int init_module(void) +int __init init_module(void) { sun3lance_dev = sun3lance_probe(-1); if (IS_ERR(sun3lance_dev)) @@ -953,11 +953,11 @@ int init_module(void) return 0; } -void cleanup_module(void) +void __exit cleanup_module(void) { unregister_netdev(sun3lance_dev); #ifdef CONFIG_SUN3 - iounmap((void *)sun3lance_dev->base_addr); + iounmap((void __iomem *)sun3lance_dev->base_addr); #endif free_netdev(sun3lance_dev); }