drivers/video/msm: update to new kernel
[safe/jmp/linux-2.6] / drivers / net / starfire.c
index c49214f..a36e2b5 100644 (file)
@@ -27,8 +27,8 @@
 */
 
 #define DRV_NAME       "starfire"
-#define DRV_VERSION    "2.0"
-#define DRV_RELDATE    "June 27, 2006"
+#define DRV_VERSION    "2.1"
+#define DRV_RELDATE    "July  6, 2008"
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
 #include <linux/mm.h>
+#include <linux/firmware.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#include "starfire_firmware.h"
 /*
  * The current frame processor firmware fails to checksum a fragment
  * of length 1. If and when this is fixed, the #define below can be removed.
 #define VLAN_SUPPORT
 #endif
 
-#ifndef CONFIG_ADAPTEC_STARFIRE_NAPI
-#undef HAVE_NETDEV_POLL
-#endif
-
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -177,53 +173,21 @@ static int full_duplex[MAX_UNITS] = {0, };
 #define skb_first_frag_len(skb)        skb_headlen(skb)
 #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
 
-#ifdef HAVE_NETDEV_POLL
-#define init_poll(dev, np) \
-       netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work)
-#define netdev_rx(dev, np, ioaddr) \
-do { \
-       u32 intr_enable; \
-       if (netif_rx_schedule_prep(dev, &np->napi)) { \
-               __netif_rx_schedule(dev, &np->napi); \
-               intr_enable = readl(ioaddr + IntrEnable); \
-               intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
-               writel(intr_enable, ioaddr + IntrEnable); \
-               readl(ioaddr + IntrEnable); /* flush PCI posting buffers */ \
-       } else { \
-               /* Paranoia check */ \
-               intr_enable = readl(ioaddr + IntrEnable); \
-               if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
-                       printk(KERN_INFO "%s: interrupt while in polling mode!\n", dev->name); \
-                       intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
-                       writel(intr_enable, ioaddr + IntrEnable); \
-               } \
-       } \
-} while (0)
-#define netdev_receive_skb(skb) netif_receive_skb(skb)
-#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid)
-static int     netdev_poll(struct napi_struct *napi, int budget);
-#else  /* not HAVE_NETDEV_POLL */
-#define init_poll(dev, np)
-#define netdev_receive_skb(skb) netif_rx(skb)
-#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid)
-#define netdev_rx(dev, np, ioaddr) \
-do { \
-       int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \
-       __netdev_rx(dev, &quota);\
-} while (0)
-#endif /* not HAVE_NETDEV_POLL */
-/* end of compatibility code */
-
+/* Firmware names */
+#define FIRMWARE_RX    "adaptec/starfire_rx.bin"
+#define FIRMWARE_TX    "adaptec/starfire_tx.bin"
 
 /* These identify the driver base version and may not be removed. */
-static char version[] =
+static const char version[] __devinitconst =
 KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
+" (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+MODULE_FIRMWARE(FIRMWARE_RX);
+MODULE_FIRMWARE(FIRMWARE_TX);
 
 module_param(max_interrupt_work, int, 0);
 module_param(mtu, int, 0);
@@ -631,10 +595,11 @@ static int        netdev_open(struct net_device *dev);
 static void    check_duplex(struct net_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 netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void    netdev_error(struct net_device *dev, int intr_status);
 static int     __netdev_rx(struct net_device *dev, int *quota);
+static int     netdev_poll(struct napi_struct *napi, int budget);
 static void    refill_rx_ring(struct net_device *dev);
 static void    netdev_error(struct net_device *dev, int intr_status);
 static void    set_rx_mode(struct net_device *dev);
@@ -683,6 +648,24 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 #endif /* VLAN_SUPPORT */
 
 
+static const struct net_device_ops netdev_ops = {
+       .ndo_open               = netdev_open,
+       .ndo_stop               = netdev_close,
+       .ndo_start_xmit         = start_tx,
+       .ndo_tx_timeout         = tx_timeout,
+       .ndo_get_stats          = get_stats,
+       .ndo_set_multicast_list = &set_rx_mode,
+       .ndo_do_ioctl           = netdev_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+#ifdef VLAN_SUPPORT
+       .ndo_vlan_rx_register   = netdev_vlan_rx_register,
+       .ndo_vlan_rx_add_vid    = netdev_vlan_rx_add_vid,
+       .ndo_vlan_rx_kill_vid   = netdev_vlan_rx_kill_vid,
+#endif
+};
+
 static int __devinit starfire_init_one(struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
 {
@@ -694,7 +677,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        void __iomem *base;
        int drv_flags, io_size;
        int boguscnt;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -746,11 +728,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        if (enable_hw_cksum)
                dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 #endif /* ZEROCOPY */
+
 #ifdef VLAN_SUPPORT
        dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
-       dev->vlan_rx_register = netdev_vlan_rx_register;
-       dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid;
-       dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid;
 #endif /* VLAN_RX_KILL_VID */
 #ifdef ADDR_64BITS
        dev->features |= NETIF_F_HIGHDMA;
@@ -846,27 +826,21 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
                }
        }
 
-       /* The chip-specific entries in the device structure. */
-       dev->open = &netdev_open;
-       dev->hard_start_xmit = &start_tx;
-       dev->tx_timeout = tx_timeout;
+       dev->netdev_ops = &netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
-       init_poll(dev, np);
-       dev->stop = &netdev_close;
-       dev->get_stats = &get_stats;
-       dev->set_multicast_list = &set_rx_mode;
-       dev->do_ioctl = &netdev_ioctl;
        SET_ETHTOOL_OPS(dev, &ethtool_ops);
 
+       netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work);
+
        if (mtu)
                dev->mtu = mtu;
 
        if (register_netdev(dev))
                goto err_out_cleardev;
 
-       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
               dev->name, netdrv_tbl[chip_idx].name, base,
-              print_mac(mac, dev->dev_addr), irq);
+              dev->dev_addr, irq);
 
        if (drv_flags & CanHaveMII) {
                int phy, phy_idx = 0;
@@ -922,9 +896,9 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
        void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2);
        int result, boguscnt=1000;
        /* ??? Should we add a busy-wait here? */
-       do
+       do {
                result = readl(mdio_addr);
-       while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
+       while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
        if (boguscnt == 0)
                return 0;
        if ((result & 0xffff) == 0xffff)
@@ -944,9 +918,12 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 
 static int netdev_open(struct net_device *dev)
 {
+       const struct firmware *fw_rx, *fw_tx;
+       const __be32 *fw_rx_data, *fw_tx_data;
        struct netdev_private *np = netdev_priv(dev);
        void __iomem *ioaddr = np->base;
        int i, retval;
+       size_t tx_size, rx_size;
        size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
 
        /* Do we ever need to reset the chip??? */
@@ -1054,9 +1031,8 @@ static int netdev_open(struct net_device *dev)
 
        writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
 
-#ifdef HAVE_NETDEV_POLL
        napi_enable(&np->napi);
-#endif
+
        netif_start_queue(dev);
 
        if (debug > 1)
@@ -1083,11 +1059,40 @@ static int netdev_open(struct net_device *dev)
        writel(ETH_P_8021Q, ioaddr + VlanType);
 #endif /* VLAN_SUPPORT */
 
+       retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev);
+       if (retval) {
+               printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+                      FIRMWARE_RX);
+               return retval;
+       }
+       if (fw_rx->size % 4) {
+               printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+                      fw_rx->size, FIRMWARE_RX);
+               retval = -EINVAL;
+               goto out_rx;
+       }
+       retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev);
+       if (retval) {
+               printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+                      FIRMWARE_TX);
+               goto out_rx;
+       }
+       if (fw_tx->size % 4) {
+               printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+                      fw_tx->size, FIRMWARE_TX);
+               retval = -EINVAL;
+               goto out_tx;
+       }
+       fw_rx_data = (const __be32 *)&fw_rx->data[0];
+       fw_tx_data = (const __be32 *)&fw_tx->data[0];
+       rx_size = fw_rx->size / 4;
+       tx_size = fw_tx->size / 4;
+
        /* Load Rx/Tx firmware into the frame processors */
-       for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
-               writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
-       for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
-               writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
+       for (i = 0; i < rx_size; i++)
+               writel(be32_to_cpup(&fw_rx_data[i]), ioaddr + RxGfpMem + i * 4);
+       for (i = 0; i < tx_size; i++)
+               writel(be32_to_cpup(&fw_tx_data[i]), ioaddr + TxGfpMem + i * 4);
        if (enable_hw_cksum)
                /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
                writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
@@ -1099,7 +1104,11 @@ static int netdev_open(struct net_device *dev)
                printk(KERN_DEBUG "%s: Done netdev_open().\n",
                       dev->name);
 
-       return 0;
+out_tx:
+       release_firmware(fw_tx);
+out_rx:
+       release_firmware(fw_rx);
+       return retval;
 }
 
 
@@ -1214,7 +1223,7 @@ static void init_ring(struct net_device *dev)
 }
 
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct netdev_private *np = netdev_priv(dev);
        unsigned int entry;
@@ -1227,7 +1236,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
         */
        if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) {
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
 #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
@@ -1302,7 +1311,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 
@@ -1330,8 +1339,28 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
 
                handled = 1;
 
-               if (intr_status & (IntrRxDone | IntrRxEmpty))
-                       netdev_rx(dev, np, ioaddr);
+               if (intr_status & (IntrRxDone | IntrRxEmpty)) {
+                       u32 enable;
+
+                       if (likely(napi_schedule_prep(&np->napi))) {
+                               __napi_schedule(&np->napi);
+                               enable = readl(ioaddr + IntrEnable);
+                               enable &= ~(IntrRxDone | IntrRxEmpty);
+                               writel(enable, ioaddr + IntrEnable);
+                               /* flush PCI posting buffers */
+                               readl(ioaddr + IntrEnable);
+                       } else {
+                               /* Paranoia check */
+                               enable = readl(ioaddr + IntrEnable);
+                               if (enable & (IntrRxDone | IntrRxEmpty)) {
+                                       printk(KERN_INFO
+                                              "%s: interrupt while in poll!\n",
+                                              dev->name);
+                                       enable &= ~(IntrRxDone | IntrRxEmpty);
+                                       writel(enable, ioaddr + IntrEnable);
+                               }
+                       }
+               }
 
                /* Scavenge the skbuff list based on the Tx-done queue.
                   There are redundant checks here that may be cleaned up
@@ -1411,8 +1440,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
 }
 
 
-/* This routine is logically part of the interrupt/poll handler, but separated
-   for clarity, code sharing between NAPI/non-NAPI, and better register allocation. */
+/*
+ * This routine is logically part of the interrupt/poll handler, but separated
+ * for clarity and better register allocation.
+ */
 static int __netdev_rx(struct net_device *dev, int *quota)
 {
        struct netdev_private *np = netdev_priv(dev);
@@ -1472,13 +1503,8 @@ static int __netdev_rx(struct net_device *dev, int *quota)
 #ifndef final_version                  /* Remove after testing. */
                /* You will want this info for the initial debug. */
                if (debug > 5) {
-                       DECLARE_MAC_BUF(mac);
-                       DECLARE_MAC_BUF(mac2);
-
-                       printk(KERN_DEBUG "  Rx data %s %s"
-                              " %2.2x%2.2x.\n",
-                              print_mac(mac, &skb->data[0]),
-                              print_mac(mac2, &skb->data[6]),
+                       printk(KERN_DEBUG "  Rx data %pM %pM %2.2x%2.2x.\n",
+                              skb->data, skb->data + 6,
                               skb->data[12], skb->data[13]);
                }
 #endif
@@ -1508,14 +1534,20 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                }
 #ifdef VLAN_SUPPORT
                if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
-                       if (debug > 4)
-                               printk(KERN_DEBUG "  netdev_rx() vlanid = %d\n", le16_to_cpu(desc->vlanid));
-                       /* vlan_netdev_receive_skb() expects a packet with the VLAN tag stripped out */
-                       vlan_netdev_receive_skb(skb, np->vlgrp, le16_to_cpu(desc->vlanid) & VLAN_VID_MASK);
+                       u16 vlid = le16_to_cpu(desc->vlanid);
+
+                       if (debug > 4) {
+                               printk(KERN_DEBUG "  netdev_rx() vlanid = %d\n",
+                                      vlid);
+                       }
+                       /*
+                        * vlan_hwaccel_rx expects a packet with the VLAN tag
+                        * stripped out.
+                        */
+                       vlan_hwaccel_rx(skb, np->vlgrp, vlid);
                } else
 #endif /* VLAN_SUPPORT */
-                       netdev_receive_skb(skb);
-               dev->last_rx = jiffies;
+                       netif_receive_skb(skb);
                np->stats.rx_packets++;
 
        next_rx:
@@ -1523,6 +1555,11 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                desc->status = 0;
                np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE;
        }
+
+       if (*quota == 0) {      /* out of rx quota */
+               retcode = 1;
+               goto out;
+       }
        writew(np->rx_done, np->base + CompletionQConsumerIdx);
 
  out:
@@ -1533,8 +1570,6 @@ static int __netdev_rx(struct net_device *dev, int *quota)
        return retcode;
 }
 
-
-#ifdef HAVE_NETDEV_POLL
 static int netdev_poll(struct napi_struct *napi, int budget)
 {
        struct netdev_private *np = container_of(napi, struct netdev_private, napi);
@@ -1552,7 +1587,7 @@ static int netdev_poll(struct napi_struct *napi, int budget)
                intr_status = readl(ioaddr + IntrStatus);
        } while (intr_status & (IntrRxDone | IntrRxEmpty));
 
-       netif_rx_complete(dev, napi);
+       napi_complete(napi);
        intr_status = readl(ioaddr + IntrEnable);
        intr_status |= IntrRxDone | IntrRxEmpty;
        writel(intr_status, ioaddr + IntrEnable);
@@ -1565,8 +1600,6 @@ static int netdev_poll(struct napi_struct *napi, int budget)
        /* Restart Rx engine if stopped. */
        return budget - quota;
 }
-#endif /* HAVE_NETDEV_POLL */
-
 
 static void refill_rx_ring(struct net_device *dev)
 {
@@ -1907,9 +1940,8 @@ static int netdev_close(struct net_device *dev)
        int i;
 
        netif_stop_queue(dev);
-#ifdef HAVE_NETDEV_POLL
+
        napi_disable(&np->napi);
-#endif
 
        if (debug > 1) {
                printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
@@ -2045,11 +2077,8 @@ static int __init starfire_init (void)
 /* when a module, this is printed whether or not devices are found in probe */
 #ifdef MODULE
        printk(version);
-#ifdef HAVE_NETDEV_POLL
+
        printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
-#else
-       printk(KERN_INFO DRV_NAME ": polling (NAPI) disabled\n");
-#endif
 #endif
 
        /* we can do this test only at run-time... sigh */