[NET]: Rework dev_base via list_head (v3)
[safe/jmp/linux-2.6] / drivers / net / ioc3-eth.c
index ae71ed5..f749e07 100644 (file)
@@ -28,9 +28,8 @@
  */
 
 #define IOC3_NAME      "ioc3-eth"
-#define IOC3_VERSION   "2.6.3-3"
+#define IOC3_VERSION   "2.6.3-4"
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -58,7 +57,6 @@
 #include <net/ip.h>
 
 #include <asm/byteorder.h>
-#include <asm/checksum.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -116,7 +114,7 @@ static inline void ioc3_stop(struct ioc3_private *ip);
 static void ioc3_init(struct net_device *dev);
 
 static const char ioc3_str[] = "IOC3 Ethernet";
-static struct ethtool_ops ioc3_ethtool_ops;
+static const struct ethtool_ops ioc3_ethtool_ops;
 
 /* We use this to acquire receive skb's that we can DMA directly into. */
 
@@ -145,7 +143,7 @@ static inline struct sk_buff * ioc3_alloc_skb(unsigned long length,
 static inline unsigned long ioc3_map(void *ptr, unsigned long vdev)
 {
 #ifdef CONFIG_SGI_IP27
-       vdev <<= 58;   /* Shift to PCI64_ATTR_VIRTUAL */
+       vdev <<= 57;   /* Shift to PCI64_ATTR_VIRTUAL */
 
        return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF |
               ((unsigned long)ptr & TO_PHYS_MASK);
@@ -635,8 +633,6 @@ static inline void ioc3_rx(struct ioc3_private *ip)
 
                        ip->rx_skbs[rx_entry] = NULL;   /* Poison  */
 
-                       new_skb->dev = priv_netdev(ip);
-
                        /* Because we reserve afterwards. */
                        skb_put(new_skb, (1664 + RX_OFFSET));
                        rxb = (struct ioc3_erxbuf *) new_skb->data;
@@ -751,7 +747,7 @@ static void ioc3_error(struct ioc3_private *ip, u32 eisr)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread.  */
-static irqreturn_t ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
+static irqreturn_t ioc3_interrupt(int irq, void *_dev)
 {
        struct net_device *dev = (struct net_device *)_dev;
        struct ioc3_private *ip = netdev_priv(dev);
@@ -838,13 +834,17 @@ static int ioc3_mii_init(struct ioc3_private *ip)
        }
 
        ip->mii.phy_id = i;
+
+out:
+       return res;
+}
+
+static void ioc3_mii_start(struct ioc3_private *ip)
+{
        ip->ioc3_timer.expires = jiffies + (12 * HZ)/10;  /* 1.2 sec. */
        ip->ioc3_timer.data = (unsigned long) ip;
        ip->ioc3_timer.function = &ioc3_timer;
        add_timer(&ip->ioc3_timer);
-
-out:
-       return res;
 }
 
 static inline void ioc3_clean_rx_ring(struct ioc3_private *ip)
@@ -938,7 +938,6 @@ static void ioc3_alloc_rings(struct net_device *dev)
                        }
 
                        ip->rx_skbs[i] = skb;
-                       skb->dev = dev;
 
                        /* Because we reserve afterwards. */
                        skb_put(skb, (1664 + RX_OFFSET));
@@ -1018,7 +1017,7 @@ static void ioc3_init(struct net_device *dev)
        struct ioc3_private *ip = netdev_priv(dev);
        struct ioc3 *ioc3 = ip->regs;
 
-       del_timer(&ip->ioc3_timer);             /* Kill if running      */
+       del_timer_sync(&ip->ioc3_timer);        /* Kill if running      */
 
        ioc3_w_emcr(EMCR_RST);                  /* Reset                */
        (void) ioc3_r_emcr();                   /* Flush WB             */
@@ -1064,7 +1063,7 @@ static int ioc3_open(struct net_device *dev)
 {
        struct ioc3_private *ip = netdev_priv(dev);
 
-       if (request_irq(dev->irq, ioc3_interrupt, SA_SHIRQ, ioc3_str, dev)) {
+       if (request_irq(dev->irq, ioc3_interrupt, IRQF_SHARED, ioc3_str, dev)) {
                printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
 
                return -EAGAIN;
@@ -1073,6 +1072,7 @@ static int ioc3_open(struct net_device *dev)
        ip->ehar_h = 0;
        ip->ehar_l = 0;
        ioc3_init(dev);
+       ioc3_mii_start(ip);
 
        netif_start_queue(dev);
        return 0;
@@ -1082,7 +1082,7 @@ static int ioc3_close(struct net_device *dev)
 {
        struct ioc3_private *ip = netdev_priv(dev);
 
-       del_timer(&ip->ioc3_timer);
+       del_timer_sync(&ip->ioc3_timer);
 
        netif_stop_queue(dev);
 
@@ -1276,6 +1276,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_stop;
        }
 
+       ioc3_mii_start(ip);
        ioc3_ssram_disc(ip);
        ioc3_get_eaddr(ip);
 
@@ -1316,6 +1317,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 out_stop:
        ioc3_stop(ip);
+       del_timer_sync(&ip->ioc3_timer);
        ioc3_free_rings(ip);
 out_res:
        pci_release_regions(pdev);
@@ -1337,6 +1339,8 @@ static void __devexit ioc3_remove_one (struct pci_dev *pdev)
        struct ioc3 *ioc3 = ip->regs;
 
        unregister_netdev(dev);
+       del_timer_sync(&ip->ioc3_timer);
+
        iounmap(ioc3);
        pci_release_regions(pdev);
        free_netdev(dev);
@@ -1388,10 +1392,10 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
         * MAC header which should not be summed and the TCP/UDP pseudo headers
         * manually.
         */
-       if (skb->ip_summed == CHECKSUM_HW) {
-               int proto = ntohs(skb->nh.iph->protocol);
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               const struct iphdr *ih = ip_hdr(skb);
+               const int proto = ntohs(ih->protocol);
                unsigned int csoff;
-               struct iphdr *ih = skb->nh.iph;
                uint32_t csum, ehsum;
                uint16_t *eh;
 
@@ -1418,11 +1422,11 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                csoff = ETH_HLEN + (ih->ihl << 2);
                if (proto == IPPROTO_UDP) {
                        csoff += offsetof(struct udphdr, check);
-                       skb->h.uh->check = csum;
+                       udp_hdr(skb)->check = csum;
                }
                if (proto == IPPROTO_TCP) {
                        csoff += offsetof(struct tcphdr, check);
-                       skb->h.th->check = csum;
+                       tcp_hdr(skb)->check = csum;
                }
 
                w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT);
@@ -1439,7 +1443,7 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (len <= 104) {
                /* Short packet, let's copy it directly into the ring.  */
-               memcpy(desc->data, skb->data, skb->len);
+               skb_copy_from_linear_data(skb, desc->data, skb->len);
                if (len < ETH_ZLEN) {
                        /* Very short packet, pad with zeros at the end. */
                        memset(desc->data + len, 0, ETH_ZLEN - len);
@@ -1494,6 +1498,7 @@ static void ioc3_timeout(struct net_device *dev)
        ioc3_stop(ip);
        ioc3_init(dev);
        ioc3_mii_init(ip);
+       ioc3_mii_start(ip);
 
        spin_unlock_irq(&ip->ioc3_lock);
 
@@ -1581,7 +1586,7 @@ static u32 ioc3_get_link(struct net_device *dev)
        return rc;
 }
 
-static struct ethtool_ops ioc3_ethtool_ops = {
+static const struct ethtool_ops ioc3_ethtool_ops = {
        .get_drvinfo            = ioc3_get_drvinfo,
        .get_settings           = ioc3_get_settings,
        .set_settings           = ioc3_set_settings,
@@ -1612,8 +1617,6 @@ static void ioc3_set_multicast_list(struct net_device *dev)
        netif_stop_queue(dev);                          /* Lock out others. */
 
        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous.  */
-               /* Unconditionally log net taps.  */
-               printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
                ip->emcr |= EMCR_PROMISC;
                ioc3_w_emcr(ip->emcr);
                (void) ioc3_r_emcr();