VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / net / 3c59x.c
index a450864..ab2e61a 100644 (file)
@@ -238,12 +238,6 @@ static int vortex_debug = VORTEX_DEBUG;
 static int vortex_debug = 1;
 #endif
 
-#ifndef __OPTIMIZE__
-#error You must compile this file with the correct options!
-#error See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -446,6 +440,7 @@ enum vortex_chips {
        CH_3C905B_2,
        CH_3C905B_FX,
        CH_3C905C,
+       CH_3C9202,
        CH_3C980,
        CH_3C9805,
 
@@ -520,12 +515,14 @@ static struct vortex_chip_info {
        {"3c905B-FX Cyclone 100baseFx",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
        {"3c905C Tornado",
-        PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+       PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+       {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
+        PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
        {"3c980 Cyclone",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+
        {"3c980C Python-T",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
-
        {"3cSOHO100-TX Hurricane",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
        {"3c555 Laptop Hurricane",
@@ -536,9 +533,9 @@ static struct vortex_chip_info {
        {"3c556B Laptop Hurricane",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
                                        WNO_XCVR_PWR|HAS_HWCKSM, 128, },
+
        {"3c575 [Megahertz] 10/100 LAN  CardBus",
        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-
        {"3c575 Boomerang CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
        {"3CCFE575BT Cyclone CardBus",
@@ -550,10 +547,10 @@ static struct vortex_chip_info {
        {"3CCFE656 Cyclone CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        INVERT_LED_PWR|HAS_HWCKSM, 128, },
+
        {"3CCFEM656B Cyclone+Winmodem CardBus",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        INVERT_LED_PWR|HAS_HWCKSM, 128, },
-
        {"3CXFEM656C Tornado+Winmodem CardBus",                 /* From pcmcia-cs-3.1.5 */
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
                                                                        MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
@@ -563,15 +560,15 @@ static struct vortex_chip_info {
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
        {"3c982 Hydra Dual Port A",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+
        {"3c982 Hydra Dual Port B",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-
        {"3c905B-T4",
         PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
        {"3c920B-EMB-WNM Tornado",
         PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 
-       {0,}, /* 0 terminated list. */
+       {NULL,}, /* NULL terminated list. */
 };
 
 
@@ -597,6 +594,7 @@ static struct pci_device_id vortex_pci_tbl[] = {
        { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
        { 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
        { 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
+       { 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 },
        { 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
        { 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
 
@@ -884,7 +882,7 @@ static struct media_table {
 static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
                                   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
-static void vortex_down(struct net_device *dev);
+static void vortex_down(struct net_device *dev, int final);
 static int vortex_open(struct net_device *dev);
 static void mdio_sync(long ioaddr, int bits);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
@@ -948,7 +946,7 @@ static int vortex_suspend (struct pci_dev *pdev, u32 state)
        if (dev && dev->priv) {
                if (netif_running(dev)) {
                        netif_device_detach(dev);
-                       vortex_down(dev);
+                       vortex_down(dev, 1);
                }
        }
        return 0;
@@ -1697,7 +1695,7 @@ vortex_up(struct net_device *dev)
                for (i = 0; i < RX_RING_SIZE; i++)      /* AKPM: this is done in vortex_open, too */
                        vp->rx_ring[i].status = 0;
                for (i = 0; i < TX_RING_SIZE; i++)
-                       vp->tx_skbuff[i] = 0;
+                       vp->tx_skbuff[i] = NULL;
                outl(0, ioaddr + DownListPtr);
        }
        /* Set receiver mode: presumably accept b-case and phys addr only. */
@@ -1762,7 +1760,7 @@ vortex_open(struct net_device *dev)
                        for (j = 0; j < i; j++) {
                                if (vp->rx_skbuff[j]) {
                                        dev_kfree_skb(vp->rx_skbuff[j]);
-                                       vp->rx_skbuff[j] = 0;
+                                       vp->rx_skbuff[j] = NULL;
                                }
                        }
                        retval = -ENOMEM;
@@ -1940,9 +1938,9 @@ static void vortex_tx_timeout(struct net_device *dev)
                        unsigned long flags;
                        local_irq_save(flags);
                        if (vp->full_bus_master_tx)
-                               boomerang_interrupt(dev->irq, dev, 0);
+                               boomerang_interrupt(dev->irq, dev, NULL);
                        else
-                               vortex_interrupt(dev->irq, dev, 0);
+                               vortex_interrupt(dev->irq, dev, NULL);
                        local_irq_restore(flags);
                }
        }
@@ -2059,7 +2057,8 @@ vortex_error(struct net_device *dev, int status)
                                printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
 
                        /* In this case, blow the card away */
-                       vortex_down(dev);
+                       /* Must not enter D3 or we can't legally issue the reset! */
+                       vortex_down(dev, 0);
                        issue_and_wait(dev, TotalReset | 0xff);
                        vortex_up(dev);         /* AKPM: bug.  vortex_up() assumes that the rx ring is full. It may not be. */
                } else if (fifo_diag & 0x0400)
@@ -2420,7 +2419,7 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                                le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
                                        dev_kfree_skb_irq(skb);
-                                       vp->tx_skbuff[entry] = 0;
+                                       vp->tx_skbuff[entry] = NULL;
                                } else {
                                        printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
                                }
@@ -2656,7 +2655,7 @@ rx_oom_timer(unsigned long arg)
 }
 
 static void
-vortex_down(struct net_device *dev)
+vortex_down(struct net_device *dev, int final_down)
 {
        struct vortex_private *vp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
@@ -2685,7 +2684,7 @@ vortex_down(struct net_device *dev)
        if (vp->full_bus_master_tx)
                outl(0, ioaddr + DownListPtr);
 
-       if (VORTEX_PCI(vp) && vp->enable_wol) {
+       if (final_down && VORTEX_PCI(vp) && vp->enable_wol) {
                pci_save_state(VORTEX_PCI(vp), vp->power_state);
                acpi_set_WOL(dev);
        }
@@ -2699,7 +2698,7 @@ vortex_close(struct net_device *dev)
        int i;
 
        if (netif_device_present(dev))
-               vortex_down(dev);
+               vortex_down(dev, 1);
 
        if (vortex_debug > 1) {
                printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
@@ -2725,7 +2724,7 @@ vortex_close(struct net_device *dev)
                                pci_unmap_single(       VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr),
                                                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
                                dev_kfree_skb(vp->rx_skbuff[i]);
-                               vp->rx_skbuff[i] = 0;
+                               vp->rx_skbuff[i] = NULL;
                        }
        }
        if (vp->full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */
@@ -2744,7 +2743,7 @@ vortex_close(struct net_device *dev)
                                pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
                                dev_kfree_skb(skb);
-                               vp->tx_skbuff[i] = 0;
+                               vp->tx_skbuff[i] = NULL;
                        }
                }
        }
@@ -2869,7 +2868,7 @@ static struct ethtool_ops vortex_ethtool_ops = {
        .get_drvinfo =          vortex_get_drvinfo,
 };
 
-static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct vortex_private *vp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
@@ -2904,6 +2903,30 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        return retval;
 }
 
+/*
+ *     Must power the device up to do MDIO operations
+ */
+static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       int err;
+       struct vortex_private *vp = netdev_priv(dev);
+       int state = 0;
+
+       if(VORTEX_PCI(vp))
+               state = VORTEX_PCI(vp)->current_state;
+
+       /* The kernel core really should have pci_get_power_state() */
+
+       if(state != 0)
+               pci_set_power_state(VORTEX_PCI(vp), 0);
+       err = vortex_do_ioctl(dev, rq, cmd);
+       if(state != 0)
+               pci_set_power_state(VORTEX_PCI(vp), state);
+
+       return err;
+}
+
+
 /* Pre-Cyclone chips have no documented multicast filter, so the only
    multicast setting is to receive all multicast frames.  At least
    the chip has a very clean way to set the mode, unlike many others. */
@@ -3059,14 +3082,14 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
         * here
         */
        unregister_netdev(dev);
-       /* Should really use issue_and_wait() here */
-       outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
 
        if (VORTEX_PCI(vp) && vp->enable_wol) {
                pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */
                if (vp->pm_state_valid)
                        pci_restore_state(VORTEX_PCI(vp), vp->power_state);
        }
+       /* Should really use issue_and_wait() here */
+       outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
 
        pci_free_consistent(pdev,
                                                sizeof(struct boom_rx_desc) * RX_RING_SIZE