]> xenbits.xensource.com Git - xenclient/kernel.git/commitdiff
imported patch r8169-backport-to-2.6.18 r8169-update-from-git
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:59 +0000 (12:05 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:59 +0000 (12:05 +0000)
drivers/net/r8169.c

index 6572425046210a1037c2c62b0e8d13e89ad62513..c00b48ad890e6baa999447b8f2d9c6d498446cad 100644 (file)
@@ -393,10 +393,7 @@ enum features {
 struct rtl8169_private {
        void __iomem *mmio_addr;        /* memory map physical address */
        struct pci_dev *pci_dev;        /* Index of PCI device */
-       struct net_device *dev;
-#ifdef CONFIG_R8169_NAPI
-       struct napi_struct napi;
-#endif
+       struct net_device_stats stats;
        spinlock_t lock;                /* spin lock flag */
        u32 msg_enable;
        int chipset;
@@ -429,7 +426,7 @@ struct rtl8169_private {
        void (*hw_start)(struct net_device *);
        unsigned int (*phy_reset_pending)(void __iomem *);
        unsigned int (*link_ok)(void __iomem *);
-       struct delayed_work task;
+       struct work_struct task;
        unsigned features;
 };
 
@@ -446,7 +443,8 @@ MODULE_VERSION(RTL8169_VERSION);
 
 static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
+static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance,
+                             struct pt_regs *regs);
 static int rtl8169_init_ring(struct net_device *dev);
 static void rtl_hw_start(struct net_device *dev);
 static int rtl8169_close(struct net_device *dev);
@@ -454,13 +452,13 @@ static void rtl_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
 static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
 static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
-                               void __iomem *, u32 budget);
+                               void __iomem *);
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
 static void rtl8169_down(struct net_device *dev);
 static void rtl8169_rx_clear(struct rtl8169_private *tp);
 
 #ifdef CONFIG_R8169_NAPI
-static int rtl8169_poll(struct napi_struct *napi, int budget);
+static int rtl8169_poll(struct net_device *dev, int *budget);
 #endif
 
 static const unsigned int rtl8169_rx_config =
@@ -1008,14 +1006,9 @@ struct rtl8169_counters {
        __le16  tx_underun;
 };
 
-static int rtl8169_get_sset_count(struct net_device *dev, int sset)
+static int rtl8169_get_stats_count(struct net_device *dev)
 {
-       switch (sset) {
-       case ETH_SS_STATS:
-               return ARRAY_SIZE(rtl8169_gstrings);
-       default:
-               return -EOPNOTSUPP;
-       }
+       return ARRAY_SIZE(rtl8169_gstrings);
 }
 
 static void rtl8169_get_ethtool_stats(struct net_device *dev,
@@ -1072,7 +1065,7 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
        }
 }
 
-static const struct ethtool_ops rtl8169_ethtool_ops = {
+static struct ethtool_ops rtl8169_ethtool_ops = {
        .get_drvinfo            = rtl8169_get_drvinfo,
        .get_regs_len           = rtl8169_get_regs_len,
        .get_link               = ethtool_op_get_link,
@@ -1081,16 +1074,20 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
        .get_msglevel           = rtl8169_get_msglevel,
        .set_msglevel           = rtl8169_set_msglevel,
        .get_rx_csum            = rtl8169_get_rx_csum,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
        .set_rx_csum            = rtl8169_set_rx_csum,
        .set_tx_csum            = ethtool_op_set_tx_csum,
+       .get_sg                 = ethtool_op_get_sg,
        .set_sg                 = ethtool_op_set_sg,
+       .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_sset_count         = rtl8169_get_sset_count,
+       .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,
@@ -1402,7 +1399,7 @@ static void rtl8169_netpoll(struct net_device *dev)
        struct pci_dev *pdev = tp->pci_dev;
 
        disable_irq(pdev->irq);
-       rtl8169_interrupt(pdev->irq, dev);
+       rtl8169_interrupt(pdev->irq, dev, NULL);
        enable_irq(pdev->irq);
 }
 #endif
@@ -1614,9 +1611,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out;
        }
 
+       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
        tp = netdev_priv(dev);
-       tp->dev = dev;
        tp->pci_dev = pdev;
        tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
 
@@ -1765,7 +1762,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->set_mac_address = rtl_set_mac_address;
 
 #ifdef CONFIG_R8169_NAPI
-       netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
+       dev->poll = rtl8169_poll;
+       dev->weight = R8169_NAPI_WEIGHT;
 #endif
 
 #ifdef CONFIG_R8169_VLAN
@@ -1877,7 +1875,7 @@ static int rtl8169_open(struct net_device *dev)
        if (retval < 0)
                goto err_free_rx_1;
 
-       INIT_DELAYED_WORK(&tp->task, NULL);
+       INIT_WORK(&tp->task, NULL, dev);
 
        smp_mb();
 
@@ -1887,10 +1885,6 @@ static int rtl8169_open(struct net_device *dev)
        if (retval < 0)
                goto err_release_ring_2;
 
-#ifdef CONFIG_R8169_NAPI
-       napi_enable(&tp->napi);
-#endif
-
        rtl_hw_start(dev);
 
        rtl8169_request_timer(dev);
@@ -2197,9 +2191,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
        if (ret < 0)
                goto out;
 
-#ifdef CONFIG_R8169_NAPI
-       napi_enable(&tp->napi);
-#endif
+       netif_poll_enable(dev);
 
        rtl_hw_start(dev);
 
@@ -2257,7 +2249,7 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
        if (!skb)
                goto err_out;
 
-       skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
+       skb_reserve(skb, align ? ((pad - 1) & (u32)skb->data) : pad);
 
        mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
                                 PCI_DMA_FROMDEVICE);
@@ -2369,17 +2361,17 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
                                dev_kfree_skb(skb);
                                tx_skb->skb = NULL;
                        }
-                       tp->dev->stats.tx_dropped++;
+                       tp->stats.tx_dropped++;
                }
        }
        tp->cur_tx = tp->dirty_tx = 0;
 }
 
-static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
+static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *))
 {
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       PREPARE_DELAYED_WORK(&tp->task, task);
+       PREPARE_WORK(&tp->task, task, dev);
        schedule_delayed_work(&tp->task, 4);
 }
 
@@ -2391,24 +2383,17 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
        synchronize_irq(dev->irq);
 
        /* Wait for any pending NAPI task to complete */
-#ifdef CONFIG_R8169_NAPI
-       napi_disable(&tp->napi);
-#endif
+       netif_poll_disable(dev);
 
        rtl8169_irq_mask_and_ack(ioaddr);
 
-#ifdef CONFIG_R8169_NAPI
-       tp->intr_mask = 0xffff;
-       RTL_W16(IntrMask, tp->intr_event);
-       napi_enable(&tp->napi);
-#endif
+       netif_poll_enable(dev);
 }
 
-static void rtl8169_reinit_task(struct work_struct *work)
+static void rtl8169_reinit_task(void *_data)
 {
-       struct rtl8169_private *tp =
-               container_of(work, struct rtl8169_private, task.work);
-       struct net_device *dev = tp->dev;
+       struct net_device *dev = _data;
+       struct rtl8169_private *tp = netdev_priv(dev);
        int ret;
 
        rtnl_lock();
@@ -2432,11 +2417,10 @@ out_unlock:
        rtnl_unlock();
 }
 
-static void rtl8169_reset_task(struct work_struct *work)
+static void rtl8169_reset_task(void *_data)
 {
-       struct rtl8169_private *tp =
-               container_of(work, struct rtl8169_private, task.work);
-       struct net_device *dev = tp->dev;
+       struct net_device *dev = _data;
+       struct rtl8169_private *tp = netdev_priv(dev);
 
        rtnl_lock();
 
@@ -2445,7 +2429,7 @@ static void rtl8169_reset_task(struct work_struct *work)
 
        rtl8169_wait_for_quiescence(dev);
 
-       rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0);
+       rtl8169_rx_interrupt(dev, tp, tp->mmio_addr);
        rtl8169_tx_clear(tp);
 
        if (tp->dirty_rx == tp->cur_rx) {
@@ -2480,7 +2464,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
 {
        struct skb_shared_info *info = skb_shinfo(skb);
        unsigned int cur_frag, entry;
-       struct TxDesc * uninitialized_var(txd);
+       struct TxDesc * txd;
 
        entry = tp->cur_tx;
        for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
@@ -2522,7 +2506,7 @@ static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
                        return LargeSend | ((mss & MSSMask) << MSSShift);
        }
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               const struct iphdr *ip = ip_hdr(skb);
+               const struct iphdr *ip = skb->nh.iph;
 
                if (ip->protocol == IPPROTO_TCP)
                        return IPCS | TCPCS;
@@ -2609,7 +2593,7 @@ err_stop:
        netif_stop_queue(dev);
        ret = NETDEV_TX_BUSY;
 err_update_stats:
-       dev->stats.tx_dropped++;
+       tp->stats.tx_dropped++;
        goto out;
 }
 
@@ -2684,8 +2668,8 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
                if (status & DescOwn)
                        break;
 
-               dev->stats.tx_bytes += len;
-               dev->stats.tx_packets++;
+               tp->stats.tx_bytes += len;
+               tp->stats.tx_packets++;
 
                rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
 
@@ -2734,17 +2718,17 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
                skb->ip_summed = CHECKSUM_NONE;
 }
 
-static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
+static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff,
                                       struct rtl8169_private *tp, int pkt_size,
                                       dma_addr_t addr)
 {
        struct sk_buff *skb;
-       bool done = false;
+       int done = 0;
 
        if (pkt_size >= rx_copybreak)
                goto out;
 
-       skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN);
+       skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
        if (!skb)
                goto out;
 
@@ -2753,21 +2737,21 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
        skb_reserve(skb, NET_IP_ALIGN);
        skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
        *sk_buff = skb;
-       done = true;
+       done = 1;
 out:
        return done;
 }
 
 static int rtl8169_rx_interrupt(struct net_device *dev,
                                struct rtl8169_private *tp,
-                               void __iomem *ioaddr, u32 budget)
+                               void __iomem *ioaddr)
 {
        unsigned int cur_rx, rx_left;
        unsigned int delta, count;
 
        cur_rx = tp->cur_rx;
        rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
-       rx_left = rtl8169_rx_quota(rx_left, budget);
+       rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
 
        for (; rx_left > 0; rx_left--, cur_rx++) {
                unsigned int entry = cur_rx % NUM_RX_DESC;
@@ -2785,14 +2769,14 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                                       "%s: Rx ERROR. status = %08x\n",
                                       dev->name, status);
                        }
-                       dev->stats.rx_errors++;
+                       tp->stats.rx_errors++;
                        if (status & (RxRWT | RxRUNT))
-                               dev->stats.rx_length_errors++;
+                               tp->stats.rx_length_errors++;
                        if (status & RxCRC)
-                               dev->stats.rx_crc_errors++;
+                               tp->stats.rx_crc_errors++;
                        if (status & RxFOVF) {
                                rtl8169_schedule_work(dev, rtl8169_reset_task);
-                               dev->stats.rx_fifo_errors++;
+                               tp->stats.rx_fifo_errors++;
                        }
                        rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
                } else {
@@ -2807,8 +2791,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                         * sized frames.
                         */
                        if (unlikely(rtl8169_fragmented_frame(status))) {
-                               dev->stats.rx_dropped++;
-                               dev->stats.rx_length_errors++;
+                               tp->stats.rx_dropped++;
+                               tp->stats.rx_length_errors++;
                                rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
                                continue;
                        }
@@ -2825,6 +2809,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                                tp->Rx_skbuff[entry] = NULL;
                        }
 
+                       skb->dev = dev;
                        skb_put(skb, pkt_size);
                        skb->protocol = eth_type_trans(skb, dev);
 
@@ -2832,8 +2817,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                                rtl8169_rx_skb(skb);
 
                        dev->last_rx = jiffies;
-                       dev->stats.rx_bytes += pkt_size;
-                       dev->stats.rx_packets++;
+                       tp->stats.rx_bytes += pkt_size;
+                       tp->stats.rx_packets++;
                }
 
                /* Work around for AMD plateform. */
@@ -2865,7 +2850,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
        return count;
 }
 
-static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
+static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
        struct net_device *dev = dev_instance;
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -2916,8 +2901,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                        RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
                        tp->intr_mask = ~tp->napi_event;
 
-               if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
-                       __netif_rx_schedule(dev, &tp->napi);
+                       if (likely(netif_rx_schedule_prep(dev)))
+                               __netif_rx_schedule(dev);
                        else if (netif_msg_intr(tp)) {
                                printk(KERN_INFO "%s: interrupt %04x in poll\n",
                                       dev->name, status);
@@ -2927,7 +2912,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 #else
                /* Rx interrupt */
                if (status & (RxOK | RxOverflow | RxFIFOOver))
-                       rtl8169_rx_interrupt(dev, tp, ioaddr, ~(u32)0);
+                       rtl8169_rx_interrupt(dev, tp, ioaddr);
 
                /* Tx interrupt */
                if (status & (TxOK | TxErr))
@@ -2950,18 +2935,20 @@ out:
 }
 
 #ifdef CONFIG_R8169_NAPI
-static int rtl8169_poll(struct napi_struct *napi, int budget)
+static int rtl8169_poll(struct net_device *dev, int *budget)
 {
-       struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
-       struct net_device *dev = tp->dev;
+       unsigned int work_done, work_to_do = min(*budget, dev->quota);
+       struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       int work_done;
 
-       work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget);
+       work_done = rtl8169_rx_interrupt(dev, tp, ioaddr);
        rtl8169_tx_interrupt(dev, tp, ioaddr);
 
-       if (work_done < budget) {
-               netif_rx_complete(dev, napi);
+       *budget -= work_done;
+       dev->quota -= work_done;
+
+       if (work_done < work_to_do) {
+               netif_rx_complete(dev);
                tp->intr_mask = 0xffff;
                /*
                 * 20040426: the barrier is not strictly required but the
@@ -2973,7 +2960,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
                RTL_W16(IntrMask, tp->intr_event);
        }
 
-       return work_done;
+       return (work_done >= work_to_do);
 }
 #endif
 
@@ -2988,7 +2975,7 @@ static void rtl8169_down(struct net_device *dev)
        netif_stop_queue(dev);
 
 #ifdef CONFIG_R8169_NAPI
-       napi_disable(&tp->napi);
+       netif_poll_disable(dev);
 #endif
 
 core_down:
@@ -2997,7 +2984,7 @@ core_down:
        rtl8169_asic_down(ioaddr);
 
        /* Update the error counts. */
-       dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+       tp->stats.rx_missed_errors += RTL_R32(RxMissed);
        RTL_W32(RxMissed, 0);
 
        spin_unlock_irq(&tp->lock);
@@ -3038,6 +3025,8 @@ static int rtl8169_close(struct net_device *dev)
 
        free_irq(dev->irq, dev);
 
+       netif_poll_enable(dev);
+
        pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
                            tp->RxPhyAddr);
        pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
@@ -3124,12 +3113,12 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 
        if (netif_running(dev)) {
                spin_lock_irqsave(&tp->lock, flags);
-               dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+               tp->stats.rx_missed_errors += RTL_R32(RxMissed);
                RTL_W32(RxMissed, 0);
                spin_unlock_irqrestore(&tp->lock, flags);
        }
 
-       return &dev->stats;
+       return &tp->stats;
 }
 
 #ifdef CONFIG_PM
@@ -3150,7 +3139,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 
        rtl8169_asic_down(ioaddr);
 
-       dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+       tp->stats.rx_missed_errors += RTL_R32(RxMissed);
        RTL_W32(RxMissed, 0);
 
        spin_unlock_irq(&tp->lock);
@@ -3197,7 +3186,7 @@ static struct pci_driver rtl8169_pci_driver = {
 
 static int __init rtl8169_init_module(void)
 {
-       return pci_register_driver(&rtl8169_pci_driver);
+       return pci_module_init(&rtl8169_pci_driver);
 }
 
 static void __exit rtl8169_cleanup_module(void)