vmxnet3: make bit twiddle routines inline
[linux-2.6.git] / drivers / net / cs89x0.c
index 0e79cef..d325e01 100644 (file)
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -170,22 +170,12 @@ static char version[] __initdata =
 /* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
    them to system IRQ numbers. This mapping is card specific and is set to
    the configuration of the Cirrus Eval board for this chip. */
-#if defined(CONFIG_SH_HICOSH4)
-static unsigned int netcard_portlist[] __used __initdata =
-   { 0x0300, 0};
-static unsigned int cs8900_irq_map[] = {1,0,0,0};
-#elif defined(CONFIG_MACH_IXDP2351)
+#if defined(CONFIG_MACH_IXDP2351)
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
 #elif defined(CONFIG_ARCH_IXDP2X01)
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_ARCH_PNX010X)
-#include <mach/gpio.h>
-#define CIRRUS_DEFAULT_BASE    IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000)      /* = Physical address 0x48200000 */
-#define CIRRUS_DEFAULT_IRQ     VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
-static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
-static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
 #elif defined(CONFIG_MACH_MX31ADS)
 #include <mach/board-mx31ads.h>
 static unsigned int netcard_portlist[] __used __initdata = {
@@ -218,7 +208,6 @@ static unsigned int net_debug = DEBUGGING;
 
 /* Information that need to be kept for each board. */
 struct net_local {
-       struct net_device_stats stats;
        int chip_type;          /* one of: CS8900, CS8920, CS8920M */
        char chip_revision;     /* revision letter of the chip ('A'...) */
        int send_cmd;           /* the proper send command: TX_NOW, TX_AFTER_381, or TX_AFTER_ALL */
@@ -257,7 +246,7 @@ 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 net_device *dev, void *addr);
-static void count_rx_errors(int status, struct net_local *lp);
+static void count_rx_errors(int status, struct net_device *dev);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void net_poll_controller(struct net_device *dev);
 #endif
@@ -372,18 +361,6 @@ writeword(unsigned long base_addr, int portno, u16 value)
 {
        __raw_writel(value, base_addr + (portno << 1));
 }
-#elif defined(CONFIG_ARCH_PNX010X)
-static u16
-readword(unsigned long base_addr, int portno)
-{
-       return inw(base_addr + (portno << 1));
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
-       outw(value, base_addr + (portno << 1));
-}
 #else
 static u16
 readword(unsigned long base_addr, int portno)
@@ -546,30 +523,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
 #endif
         }
 
-#ifdef CONFIG_ARCH_PNX010X
-       initialize_ebi();
-
-       /* Map GPIO registers for the pins connected to the CS8900a. */
-       if (map_cirrus_gpio() < 0)
-               return -ENODEV;
-
-       reset_cirrus();
-
-       /* Map event-router registers. */
-       if (map_event_router() < 0)
-               return -ENODEV;
-
-       enable_cirrus_irq();
-
-       unmap_cirrus_gpio();
-       unmap_event_router();
-
-       dev->base_addr = ioaddr;
-
-       for (i = 0 ; i < 3 ; i++)
-               readreg(dev, 0);
-#endif
-
        /* Grab the region so we can find another board if autoIRQ fails. */
        /* WTF is going on here? */
        if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
@@ -579,12 +532,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
                goto out1;
        }
 
-#ifdef CONFIG_SH_HICOSH4
-       /* truely reset the chip */
-       writeword(ioaddr, ADD_PORT, 0x0114);
-       writeword(ioaddr, DATA_PORT, 0x0040);
-#endif
-
        /* if they give us an odd I/O address, then do ONE write to
            the address port, to get it back to address zero, where we
            expect to find the EISA signature word. An IO with a base of 0x3
@@ -650,37 +597,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
           the driver will always do *something* instead of complain that
           adapter_cnf is 0. */
 
-#ifdef CONFIG_SH_HICOSH4
-       if (1) {
-               /* For the HiCO.SH4 board, things are different: we don't
-                  have EEPROM, but there is some data in flash, so we go
-                  get it there directly (MAC). */
-               __u16 *confd;
-               short cnt;
-               if (((* (volatile __u32 *) 0xa0013ff0) & 0x00ffffff)
-                       == 0x006c3000) {
-                       confd = (__u16*) 0xa0013fc0;
-               } else {
-                       confd = (__u16*) 0xa001ffc0;
-               }
-               cnt = (*confd++ & 0x00ff) >> 1;
-               while (--cnt > 0) {
-                       __u16 j = *confd++;
-
-                       switch (j & 0x0fff) {
-                       case PP_IA:
-                               for (i = 0; i < ETH_ALEN/2; i++) {
-                                       dev->dev_addr[i*2] = confd[i] & 0xFF;
-                                       dev->dev_addr[i*2+1] = confd[i] >> 8;
-                               }
-                               break;
-                       }
-                       j = (j >> 12) + 1;
-                       confd += j;
-                       cnt -= j;
-               }
-       } else
-#endif
 
         if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
              (EEPROM_OK|EEPROM_PRESENT)) {
@@ -735,11 +651,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
         printk("\n");
 
        /* First check to see if an EEPROM is attached. */
-#ifdef CONFIG_SH_HICOSH4 /* no EEPROM on HiCO, don't hazzle with it here */
-       if (1) {
-               printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
-       } else
-#endif
+
        if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
                printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
        else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
@@ -902,7 +814,6 @@ get_dma_channel(struct net_device *dev)
                        return;
                }
        }
-       return;
 }
 
 static void
@@ -984,7 +895,7 @@ dma_rx(struct net_device *dev)
                        dev->name, (unsigned long)bp, status, length);
        }
        if ((status & RX_OK) == 0) {
-               count_rx_errors(status, lp);
+               count_rx_errors(status, dev);
                goto skip_this_frame;
        }
 
@@ -993,7 +904,7 @@ dma_rx(struct net_device *dev)
        if (skb == NULL) {
                if (net_debug)  /* I don't think we want to do this to a stressed system */
                        printk("%s: Memory squeeze, dropping packet.\n", dev->name);
-               lp->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
 
                /* AKPM: advance bp to the next frame */
 skip_this_frame:
@@ -1023,8 +934,8 @@ skip_this_frame:
        }
         skb->protocol=eth_type_trans(skb,dev);
        netif_rx(skb);
-       lp->stats.rx_packets++;
-       lp->stats.rx_bytes += length;
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += length;
 }
 
 #endif /* ALLOW_DMA */
@@ -1277,7 +1188,6 @@ net_open(struct net_device *dev)
        int i;
        int ret;
 
-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
        if (dev->irq < 2) {
                /* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1306,7 +1216,6 @@ net_open(struct net_device *dev)
                }
        }
        else
-#endif
        {
 #ifndef CONFIG_CS89x0_NONISA_IRQ
                if (((1 << dev->irq) & lp->irq_map) == 0) {
@@ -1392,9 +1301,6 @@ net_open(struct net_device *dev)
        case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
         default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
         }
-#ifdef CONFIG_ARCH_PNX010X
-       result = A_CNF_10B_T;
-#endif
         if (!result) {
                 printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
 release_dma:
@@ -1553,8 +1459,7 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
        /* Write the contents of the packet */
        writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
        spin_unlock_irqrestore(&lp->lock, flags);
-       lp->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
+       dev->stats.tx_bytes += skb->len;
        dev_kfree_skb (skb);
 
        /*
@@ -1600,18 +1505,23 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
                        net_rx(dev);
                        break;
                case ISQ_TRANSMITTER_EVENT:
-                       lp->stats.tx_packets++;
+                       dev->stats.tx_packets++;
                        netif_wake_queue(dev);  /* Inform upper layers. */
                        if ((status & ( TX_OK |
                                        TX_LOST_CRS |
                                        TX_SQE_ERROR |
                                        TX_LATE_COL |
                                        TX_16_COL)) != TX_OK) {
-                               if ((status & TX_OK) == 0) lp->stats.tx_errors++;
-                               if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
-                               if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
-                               if (status & TX_LATE_COL) lp->stats.tx_window_errors++;
-                               if (status & TX_16_COL) lp->stats.tx_aborted_errors++;
+                               if ((status & TX_OK) == 0)
+                                       dev->stats.tx_errors++;
+                               if (status & TX_LOST_CRS)
+                                       dev->stats.tx_carrier_errors++;
+                               if (status & TX_SQE_ERROR)
+                                       dev->stats.tx_heartbeat_errors++;
+                               if (status & TX_LATE_COL)
+                                       dev->stats.tx_window_errors++;
+                               if (status & TX_16_COL)
+                                       dev->stats.tx_aborted_errors++;
                        }
                        break;
                case ISQ_BUFFER_EVENT:
@@ -1653,10 +1563,10 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
 #endif
                        break;
                case ISQ_RX_MISS_EVENT:
-                       lp->stats.rx_missed_errors += (status >>6);
+                       dev->stats.rx_missed_errors += (status >> 6);
                        break;
                case ISQ_TX_COL_EVENT:
-                       lp->stats.collisions += (status >>6);
+                       dev->stats.collisions += (status >> 6);
                        break;
                }
        }
@@ -1664,23 +1574,24 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
 }
 
 static void
-count_rx_errors(int status, struct net_local *lp)
+count_rx_errors(int status, struct net_device *dev)
 {
-       lp->stats.rx_errors++;
-       if (status & RX_RUNT) lp->stats.rx_length_errors++;
-       if (status & RX_EXTRA_DATA) lp->stats.rx_length_errors++;
-       if (status & RX_CRC_ERROR) if (!(status & (RX_EXTRA_DATA|RX_RUNT)))
+       dev->stats.rx_errors++;
+       if (status & RX_RUNT)
+               dev->stats.rx_length_errors++;
+       if (status & RX_EXTRA_DATA)
+               dev->stats.rx_length_errors++;
+       if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA|RX_RUNT)))
                /* per str 172 */
-               lp->stats.rx_crc_errors++;
-       if (status & RX_DRIBBLE) lp->stats.rx_frame_errors++;
-       return;
+               dev->stats.rx_crc_errors++;
+       if (status & RX_DRIBBLE)
+               dev->stats.rx_frame_errors++;
 }
 
 /* We have a good packet(s), get it/them out of the buffers. */
 static void
 net_rx(struct net_device *dev)
 {
-       struct net_local *lp = netdev_priv(dev);
        struct sk_buff *skb;
        int status, length;
 
@@ -1689,7 +1600,7 @@ net_rx(struct net_device *dev)
        length = readword(ioaddr, RX_FRAME_PORT);
 
        if ((status & RX_OK) == 0) {
-               count_rx_errors(status, lp);
+               count_rx_errors(status, dev);
                return;
        }
 
@@ -1699,7 +1610,7 @@ net_rx(struct net_device *dev)
 #if 0          /* Again, this seems a cruel thing to do */
                printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 #endif
-               lp->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                return;
        }
        skb_reserve(skb, 2);    /* longword align L3 header */
@@ -1716,8 +1627,8 @@ net_rx(struct net_device *dev)
 
         skb->protocol=eth_type_trans(skb,dev);
        netif_rx(skb);
-       lp->stats.rx_packets++;
-       lp->stats.rx_bytes += length;
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += length;
 }
 
 #if ALLOW_DMA
@@ -1768,11 +1679,11 @@ net_get_stats(struct net_device *dev)
 
        spin_lock_irqsave(&lp->lock, flags);
        /* Update the statistics from the device registers. */
-       lp->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
-       lp->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
+       dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
+       dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
        spin_unlock_irqrestore(&lp->lock, flags);
 
-       return &lp->stats;
+       return &dev->stats;
 }
 
 static void set_multicast_list(struct net_device *dev)
@@ -1785,7 +1696,7 @@ static void set_multicast_list(struct net_device *dev)
        {
                lp->rx_mode = RX_ALL_ACCEPT;
        }
-       else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
+       else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
        {
                /* The multicast-accept list is initialized to accept-all, and we
                   rely on higher-level filtering for now. */