Merge tag 'r8169-upstream-20061204-00' of git://electric-eye.fr.zoreil.com/home/romie...
authorJeff Garzik <jeff@garzik.org>
Thu, 7 Dec 2006 10:05:58 +0000 (05:05 -0500)
committerJeff Garzik <jeff@garzik.org>
Thu, 7 Dec 2006 10:05:58 +0000 (05:05 -0500)
1  2 
drivers/net/r8169.c

diff --combined drivers/net/r8169.c
index 85a392fab5cc4dbc1541033cc35d5aa5401dc2b6,2379d83768d6adafa6a412dafece896553313a10..f83b41d4cb0e64f8374b55b894bf916171b8a479
@@@ -225,6 -225,7 +225,7 @@@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tb
  
  static int rx_copybreak = 200;
  static int use_dac;
+ static int ignore_parity_err;
  static struct {
        u32 msg_enable;
  } debug = { -1 };
@@@ -424,7 -425,6 +425,7 @@@ struct ring_info 
  struct rtl8169_private {
        void __iomem *mmio_addr;        /* memory map physical address */
        struct pci_dev *pci_dev;        /* Index of PCI device */
 +      struct net_device *dev;
        struct net_device_stats stats;  /* statistics of net device */
        spinlock_t lock;                /* spin lock flag */
        u32 msg_enable;
        void (*phy_reset_enable)(void __iomem *);
        unsigned int (*phy_reset_pending)(void __iomem *);
        unsigned int (*link_ok)(void __iomem *);
 -      struct work_struct task;
 +      struct delayed_work task;
        unsigned wol_enabled : 1;
  };
  
@@@ -470,6 -470,8 +471,8 @@@ module_param(use_dac, int, 0)
  MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
  module_param_named(debug, debug.msg_enable, int, 0);
  MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
+ module_param_named(ignore_parity_err, ignore_parity_err, bool, 0);
+ MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(RTL8169_VERSION);
  
@@@ -1284,11 -1286,6 +1287,6 @@@ static void rtl8169_hw_phy_config(struc
        /* Shazam ! */
  
        if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
-               mdio_write(ioaddr, 31, 0x0001);
-               mdio_write(ioaddr,  9, 0x273a);
-               mdio_write(ioaddr, 14, 0x7bfb);
-               mdio_write(ioaddr, 27, 0x841e);
                mdio_write(ioaddr, 31, 0x0002);
                mdio_write(ioaddr,  1, 0x90d0);
                mdio_write(ioaddr, 31, 0x0000);
@@@ -1511,7 -1508,6 +1509,7 @@@ rtl8169_init_one(struct pci_dev *pdev, 
        SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
        tp = netdev_priv(dev);
 +      tp->dev = dev;
        tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
  
        /* enable device (incl. PCI PM wakeup and hotplug setup) */
@@@ -1784,7 -1780,7 +1782,7 @@@ static int rtl8169_open(struct net_devi
        if (retval < 0)
                goto err_free_rx;
  
 -      INIT_WORK(&tp->task, NULL, dev);
 +      INIT_DELAYED_WORK(&tp->task, NULL);
  
        rtl8169_hw_start(dev);
  
@@@ -1817,12 -1813,25 +1815,25 @@@ static void rtl8169_hw_reset(void __iom
        RTL_R8(ChipCmd);
  }
  
- static void
- rtl8169_hw_start(struct net_device *dev)
+ static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
+ {
+       void __iomem *ioaddr = tp->mmio_addr;
+       u32 cfg = rtl8169_rx_config;
+       cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+       RTL_W32(RxConfig, cfg);
+       /* Set DMA burst size and Interframe Gap Time */
+       RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
+               (InterFrameGap << TxInterFrameGapShift));
+ }
+ static void rtl8169_hw_start(struct net_device *dev)
  {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        struct pci_dev *pdev = tp->pci_dev;
+       u16 cmd;
        u32 i;
  
        /* Soft reset the chip. */
                msleep_interruptible(1);
        }
  
+       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+               RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
+       }
        if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
                pci_write_config_word(pdev, 0x68, 0x00);
                pci_write_config_word(pdev, 0x69, 0x08);
  
        /* Undocumented stuff. */
        if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
-               u16 cmd;
                /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
                if ((RTL_R8(Config2) & 0x07) & 0x01)
                        RTL_W32(0x7c, 0x0007ffff);
                pci_write_config_word(pdev, PCI_COMMAND, cmd);
        }
  
        RTL_W8(Cfg9346, Cfg9346_Unlock);
+       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_04))
+               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        RTL_W8(EarlyTxThres, EarlyTxThld);
  
        /* Low hurts. Let's disable the filtering. */
        RTL_W16(RxMaxSize, 16383);
  
-       /* Set Rx Config register */
-       i = rtl8169_rx_config |
-               (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-       RTL_W32(RxConfig, i);
+       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_04))
+               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+               rtl8169_set_rx_tx_config_registers(tp);
  
-       /* Set DMA burst size and Interframe Gap Time */
-       RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
-               (InterFrameGap << TxInterFrameGapShift));
+       cmd = RTL_R16(CPlusCmd);
+       RTL_W16(CPlusCmd, cmd);
  
-       tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW;
+       tp->cp_cmd |= cmd | PCIMulRW;
  
        if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
            (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
        RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
        RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
        RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
-       RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+       if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
+           (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
+               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+               rtl8169_set_rx_tx_config_registers(tp);
+       }
        RTL_W8(Cfg9346, Cfg9346_Lock);
  
        /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
@@@ -1992,7 -2018,7 +2020,7 @@@ static int rtl8169_alloc_rx_skb(struct 
        if (!skb)
                goto err_out;
  
-       skb_reserve(skb, align);
+       skb_reserve(skb, (align - 1) & (u32)skb->data);
        *sk_buff = skb;
  
        mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
@@@ -2107,11 -2133,11 +2135,11 @@@ static void rtl8169_tx_clear(struct rtl
        tp->cur_tx = tp->dirty_tx = 0;
  }
  
 -static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *))
 +static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
  {
        struct rtl8169_private *tp = netdev_priv(dev);
  
 -      PREPARE_WORK(&tp->task, task, dev);
 +      PREPARE_DELAYED_WORK(&tp->task, task);
        schedule_delayed_work(&tp->task, 4);
  }
  
@@@ -2130,11 -2156,9 +2158,11 @@@ static void rtl8169_wait_for_quiescence
        netif_poll_enable(dev);
  }
  
 -static void rtl8169_reinit_task(void *_data)
 +static void rtl8169_reinit_task(struct work_struct *work)
  {
 -      struct net_device *dev = _data;
 +      struct rtl8169_private *tp =
 +              container_of(work, struct rtl8169_private, task.work);
 +      struct net_device *dev = tp->dev;
        int ret;
  
        if (netif_running(dev)) {
        }
  }
  
 -static void rtl8169_reset_task(void *_data)
 +static void rtl8169_reset_task(struct work_struct *work)
  {
 -      struct net_device *dev = _data;
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      struct rtl8169_private *tp =
 +              container_of(work, struct rtl8169_private, task.work);
 +      struct net_device *dev = tp->dev;
  
        if (!netif_running(dev))
                return;
@@@ -2355,12 -2378,17 +2383,17 @@@ static void rtl8169_pcierr_interrupt(st
        /*
         * The recovery sequence below admits a very elaborated explanation:
         * - it seems to work;
-        * - I did not see what else could be done.
+        * - I did not see what else could be done;
+        * - it makes iop3xx happy.
         *
         * Feel free to adjust to your needs.
         */
-       pci_write_config_word(pdev, PCI_COMMAND,
-                             pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+       if (ignore_parity_err)
+               pci_cmd &= ~PCI_COMMAND_PARITY;
+       else
+               pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
+       pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
  
        pci_write_config_word(pdev, PCI_STATUS,
                pci_status & (PCI_STATUS_DETECTED_PARITY |
                tp->cp_cmd &= ~PCIDAC;
                RTL_W16(CPlusCmd, tp->cp_cmd);
                dev->features &= ~NETIF_F_HIGHDMA;
-               rtl8169_schedule_work(dev, rtl8169_reinit_task);
        }
  
        rtl8169_hw_reset(ioaddr);
+       rtl8169_schedule_work(dev, rtl8169_reinit_task);
  }
  
  static void
@@@ -2457,7 -2486,7 +2491,7 @@@ static inline int rtl8169_try_rx_copy(s
  
                skb = dev_alloc_skb(pkt_size + align);
                if (skb) {
-                       skb_reserve(skb, align);
+                       skb_reserve(skb, (align - 1) & (u32)skb->data);
                        eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
                        *sk_buff = skb;
                        rtl8169_mark_to_asic(desc, rx_buf_sz);