pciehp: make pciehp build for powerpc
[safe/jmp/linux-2.6] / drivers / net / r8169.c
index d5afe05..4c2f575 100644 (file)
@@ -92,19 +92,18 @@ VERSION 2.2LK       <2005/01/25>
 #endif /* RTL8169_DEBUG */
 
 #define R8169_MSG_DEFAULT \
-       (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | \
-        NETIF_MSG_IFDOWN)
+       (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
 
 #define TX_BUFFS_AVAIL(tp) \
        (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
 
 #ifdef CONFIG_R8169_NAPI
 #define rtl8169_rx_skb                 netif_receive_skb
-#define rtl8169_rx_hwaccel_skb         vlan_hwaccel_rx
+#define rtl8169_rx_hwaccel_skb         vlan_hwaccel_receive_skb
 #define rtl8169_rx_quota(count, quota) min(count, quota)
 #else
 #define rtl8169_rx_skb                 netif_rx
-#define rtl8169_rx_hwaccel_skb         vlan_hwaccel_receive_skb
+#define rtl8169_rx_hwaccel_skb         vlan_hwaccel_rx
 #define rtl8169_rx_quota(count, quota) count
 #endif
 
@@ -114,11 +113,11 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
 static int num_media = 0;
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
+static const int max_interrupt_work = 20;
 
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC. */
-static int multicast_filter_limit = 32;
+static const int multicast_filter_limit = 32;
 
 /* MAC address length */
 #define MAC_ADDR_LEN   6
@@ -171,7 +170,7 @@ enum phy_version {
 #define _R(NAME,MAC,MASK) \
        { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
 
-const static struct {
+static const struct {
        const char *name;
        u8 mac_version;
        u32 RxConfigMask;       /* Clears the bits supported by this chip */
@@ -185,8 +184,10 @@ const static struct {
 
 static struct pci_device_id rtl8169_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8169), },
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8129), },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK,       0x4300), },
        { PCI_DEVICE(0x16ec,                    0x0116), },
+       { PCI_VENDOR_ID_LINKSYS,                0x1032, PCI_ANY_ID, 0x0024, },
        {0,},
 };
 
@@ -287,6 +288,20 @@ enum RTL8169_register_content {
        TxInterFrameGapShift = 24,
        TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
 
+       /* Config1 register p.24 */
+       PMEnable        = (1 << 0),     /* Power Management Enable */
+
+       /* Config3 register p.25 */
+       MagicPacket     = (1 << 5),     /* Wake up when receives a Magic Packet */
+       LinkUp          = (1 << 4),     /* Wake up when the cable connection is re-established */
+
+       /* Config5 register p.27 */
+       BWF             = (1 << 6),     /* Accept Broadcast wakeup frame */
+       MWF             = (1 << 5),     /* Accept Multicast wakeup frame */
+       UWF             = (1 << 4),     /* Accept Unicast wakeup frame */
+       LanWake         = (1 << 1),     /* LanWake enable/disable */
+       PMEStatus       = (1 << 0),     /* PME status can be reset by PCI RST# */
+
        /* TBICSR p.28 */
        TBIReset        = 0x80000000,
        TBILoopback     = 0x40000000,
@@ -433,6 +448,7 @@ struct rtl8169_private {
        unsigned int (*phy_reset_pending)(void __iomem *);
        unsigned int (*link_ok)(void __iomem *);
        struct work_struct task;
+       unsigned wol_enabled : 1;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -484,13 +500,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
        int i;
 
        RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed writing to the specified MII register */
                if (!(RTL_R32(PHYAR) & 0x80000000)) 
                        break;
-               udelay(100);
+               udelay(25);
        }
 }
 
@@ -499,15 +514,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr)
        int i, value = -1;
 
        RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
-       udelay(1000);
 
-       for (i = 2000; i > 0; i--) {
+       for (i = 20; i > 0; i--) {
                /* Check if the RTL8169 has completed retrieving data from the specified MII register */
                if (RTL_R32(PHYAR) & 0x80000000) {
                        value = (int) (RTL_R32(PHYAR) & 0xFFFF);
                        break;
                }
-               udelay(100);
+               udelay(25);
        }
        return value;
 }
@@ -609,6 +623,80 @@ static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
        *duplex = p->duplex;
 }
 
+static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+       u8 options;
+
+       wol->wolopts = 0;
+
+#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
+       wol->supported = WAKE_ANY;
+
+       spin_lock_irq(&tp->lock);
+
+       options = RTL_R8(Config1);
+       if (!(options & PMEnable))
+               goto out_unlock;
+
+       options = RTL_R8(Config3);
+       if (options & LinkUp)
+               wol->wolopts |= WAKE_PHY;
+       if (options & MagicPacket)
+               wol->wolopts |= WAKE_MAGIC;
+
+       options = RTL_R8(Config5);
+       if (options & UWF)
+               wol->wolopts |= WAKE_UCAST;
+       if (options & BWF)
+               wol->wolopts |= WAKE_BCAST;
+       if (options & MWF)
+               wol->wolopts |= WAKE_MCAST;
+
+out_unlock:
+       spin_unlock_irq(&tp->lock);
+}
+
+static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+       int i;
+       static struct {
+               u32 opt;
+               u16 reg;
+               u8  mask;
+       } cfg[] = {
+               { WAKE_ANY,   Config1, PMEnable },
+               { WAKE_PHY,   Config3, LinkUp },
+               { WAKE_MAGIC, Config3, MagicPacket },
+               { WAKE_UCAST, Config5, UWF },
+               { WAKE_BCAST, Config5, BWF },
+               { WAKE_MCAST, Config5, MWF },
+               { WAKE_ANY,   Config5, LanWake }
+       };
+
+       spin_lock_irq(&tp->lock);
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+       for (i = 0; i < ARRAY_SIZE(cfg); i++) {
+               u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
+               if (wol->wolopts & cfg[i].opt)
+                       options |= cfg[i].mask;
+               RTL_W8(cfg[i].reg, options);
+       }
+
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
+       tp->wol_enabled = (wol->wolopts) ? 1 : 0;
+
+       spin_unlock_irq(&tp->lock);
+
+       return 0;
+}
+
 static void rtl8169_get_drvinfo(struct net_device *dev,
                                struct ethtool_drvinfo *info)
 {
@@ -677,6 +765,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 
                if (duplex == DUPLEX_HALF)
                        auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
+
+               if (duplex == DUPLEX_FULL)
+                       auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
        }
 
        tp->phy_auto_nego_reg = auto_nego;
@@ -1024,9 +1115,12 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
        .get_tso                = ethtool_op_get_tso,
        .set_tso                = ethtool_op_set_tso,
        .get_regs               = rtl8169_get_regs,
+       .get_wol                = rtl8169_get_wol,
+       .set_wol                = rtl8169_set_wol,
        .get_strings            = rtl8169_get_strings,
        .get_stats_count        = rtl8169_get_stats_count,
        .get_ethtool_stats      = rtl8169_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1312,7 +1406,7 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        dev = alloc_etherdev(sizeof (*tp));
        if (dev == NULL) {
                if (netif_msg_drv(&debug))
-                       printk(KERN_ERR PFX "unable to alloc new ethernet\n");
+                       dev_err(&pdev->dev, "unable to alloc new ethernet\n");
                goto err_out;
        }
 
@@ -1324,10 +1418,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        /* enable device (incl. PCI PM wakeup and hotplug setup) */
        rc = pci_enable_device(pdev);
        if (rc < 0) {
-               if (netif_msg_probe(tp)) {
-                       printk(KERN_ERR PFX "%s: enable failure\n",
-                              pci_name(pdev));
-               }
+               if (netif_msg_probe(tp))
+                       dev_err(&pdev->dev, "enable failure\n");
                goto err_out_free_dev;
        }
 
@@ -1343,39 +1435,32 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
                pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
                acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
        } else {
-               if (netif_msg_probe(tp)) {
-                       printk(KERN_ERR PFX
-                              "Cannot find PowerManagement capability. "
-                              "Aborting.\n");
-               }
-               goto err_out_mwi;
+               if (netif_msg_probe(tp))
+                       dev_err(&pdev->dev,
+                              "PowerManagement capability not found.\n");
        }
 
        /* make sure PCI base addr 1 is MMIO */
        if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-               if (netif_msg_probe(tp)) {
-                       printk(KERN_ERR PFX
+               if (netif_msg_probe(tp))
+                       dev_err(&pdev->dev,
                               "region #1 not an MMIO resource, aborting\n");
-               }
                rc = -ENODEV;
                goto err_out_mwi;
        }
        /* check for weird/broken PCI region reporting */
        if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
-               if (netif_msg_probe(tp)) {
-                       printk(KERN_ERR PFX
+               if (netif_msg_probe(tp))
+                       dev_err(&pdev->dev,
                               "Invalid PCI region size(s), aborting\n");
-               }
                rc = -ENODEV;
                goto err_out_mwi;
        }
 
        rc = pci_request_regions(pdev, MODULENAME);
        if (rc < 0) {
-               if (netif_msg_probe(tp)) {
-                       printk(KERN_ERR PFX "%s: could not request regions.\n",
-                              pci_name(pdev));
-               }
+               if (netif_msg_probe(tp))
+                       dev_err(&pdev->dev, "could not request regions.\n");
                goto err_out_mwi;
        }
 
@@ -1388,10 +1473,9 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        } else {
                rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                if (rc < 0) {
-                       if (netif_msg_probe(tp)) {
-                               printk(KERN_ERR PFX
+                       if (netif_msg_probe(tp))
+                               dev_err(&pdev->dev,
                                       "DMA configuration failed.\n");
-                       }
                        goto err_out_free_res;
                }
        }
@@ -1402,7 +1486,7 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
        if (ioaddr == NULL) {
                if (netif_msg_probe(tp))
-                       printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
+                       dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
                rc = -EIO;
                goto err_out_free_res;
        }
@@ -1434,14 +1518,19 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        if (i < 0) {
                /* Unknown chip: assume array element #0, original RTL-8169 */
                if (netif_msg_probe(tp)) {
-                       printk(KERN_DEBUG PFX "PCI device %s: "
+                       dev_printk(KERN_DEBUG, &pdev->dev,
                               "unknown chip version, assuming %s\n",
-                              pci_name(pdev), rtl_chip_info[0].name);
+                              rtl_chip_info[0].name);
                }
                i++;
        }
        tp->chipset = i;
 
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+       RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
+       RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
        *ioaddr_out = ioaddr;
        *dev_out = dev;
 out:
@@ -1511,6 +1600,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Get MAC address.  FIXME: read EEPROM */
        for (i = 0; i < MAC_ADDR_LEN; i++)
                dev->dev_addr[i] = RTL_R8(MAC0 + i);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        dev->open = rtl8169_open;
        dev->hard_start_xmit = rtl8169_start_xmit;
@@ -1611,49 +1701,6 @@ rtl8169_remove_one(struct pci_dev *pdev)
        pci_set_drvdata(pdev, NULL);
 }
 
-#ifdef CONFIG_PM
-
-static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct rtl8169_private *tp = netdev_priv(dev);
-       void __iomem *ioaddr = tp->mmio_addr;
-       unsigned long flags;
-
-       if (!netif_running(dev))
-               return 0;
-       
-       netif_device_detach(dev);
-       netif_stop_queue(dev);
-       spin_lock_irqsave(&tp->lock, flags);
-
-       /* Disable interrupts, stop Rx and Tx */
-       RTL_W16(IntrMask, 0);
-       RTL_W8(ChipCmd, 0);
-               
-       /* Update the error counts. */
-       tp->stats.rx_missed_errors += RTL_R32(RxMissed);
-       RTL_W32(RxMissed, 0);
-       spin_unlock_irqrestore(&tp->lock, flags);
-       
-       return 0;
-}
-
-static int rtl8169_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-
-       if (!netif_running(dev))
-           return 0;
-
-       netif_device_attach(dev);
-       rtl8169_hw_start(dev);
-
-       return 0;
-}
-                                                                                
-#endif /* CONFIG_PM */
-
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
                                  struct net_device *dev)
 {
@@ -1671,7 +1718,7 @@ static int rtl8169_open(struct net_device *dev)
        rtl8169_set_rxbufsize(tp, dev);
 
        retval =
-           request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
+           request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
        if (retval < 0)
                goto out;
 
@@ -2117,7 +2164,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
 static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
 {
        if (dev->features & NETIF_F_TSO) {
-               u32 mss = skb_shinfo(skb)->tso_size;
+               u32 mss = skb_shinfo(skb)->gso_size;
 
                if (mss)
                        return LargeSend | ((mss & MSSMask) << MSSShift);
@@ -2167,8 +2214,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
                len = skb->len;
 
                if (unlikely(len < ETH_ZLEN)) {
-                       skb = skb_padto(skb, ETH_ZLEN);
-                       if (!skb)
+                       if (skb_padto(skb, ETH_ZLEN))
                                goto err_update_stats;
                        len = ETH_ZLEN;
                }
@@ -2514,7 +2560,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        } while (boguscnt > 0);
 
        if (boguscnt <= 0) {
-               if (net_ratelimit() && netif_msg_intr(tp)) {
+               if (netif_msg_intr(tp) && net_ratelimit() ) {
                        printk(KERN_WARNING
                               "%s: Too much work at interrupt!\n", dev->name);
                }
@@ -2699,6 +2745,56 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
        return &tp->stats;
 }
 
+#ifdef CONFIG_PM
+
+static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct rtl8169_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
+
+       if (!netif_running(dev))
+               goto out;
+
+       netif_device_detach(dev);
+       netif_stop_queue(dev);
+
+       spin_lock_irq(&tp->lock);
+
+       rtl8169_asic_down(ioaddr);
+
+       tp->stats.rx_missed_errors += RTL_R32(RxMissed);
+       RTL_W32(RxMissed, 0);
+
+       spin_unlock_irq(&tp->lock);
+
+       pci_save_state(pdev);
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+out:
+       return 0;
+}
+
+static int rtl8169_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       if (!netif_running(dev))
+               goto out;
+
+       netif_device_attach(dev);
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_wake(pdev, PCI_D0, 0);
+
+       rtl8169_schedule_work(dev, rtl8169_reset_task);
+out:
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
 static struct pci_driver rtl8169_pci_driver = {
        .name           = MODULENAME,
        .id_table       = rtl8169_pci_tbl,