Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[safe/jmp/linux-2.6] / drivers / net / fec_8xx / fec_main.c
index e17a144..ca8d2e8 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -37,7 +35,7 @@
 #include <asm/mpc8xx.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
-#include <asm/commproc.h>
+#include <asm/cpm1.h>
 
 #include "fec_8xx.h"
 
@@ -467,9 +465,9 @@ void fec_stop(struct net_device *dev)
 }
 
 /* common receive function */
-static int fec_enet_rx_common(struct net_device *dev, int *budget)
+static int fec_enet_rx_common(struct fec_enet_private *ep,
+                             struct net_device *dev, int budget)
 {
-       struct fec_enet_private *fep = netdev_priv(dev);
        fec_t *fecp = fep->fecp;
        const struct fec_platform_info *fpi = fep->fpi;
        cbd_t *bdp;
@@ -477,14 +475,6 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
        int received = 0;
        __u16 pkt_len, sc;
        int curidx;
-       int rx_work_limit;
-
-       if (fpi->use_napi) {
-               rx_work_limit = min(dev->quota, *budget);
-
-               if (!netif_running(dev))
-                       return 0;
-       }
 
        /*
         * First, grab all of the stats for the incoming packet.
@@ -532,11 +522,6 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
                        BUG_ON(skbn == NULL);
 
                } else {
-
-                       /* napi, got packet but no quota */
-                       if (fpi->use_napi && --rx_work_limit < 0)
-                               break;
-
                        skb = fep->rx_skbuff[curidx];
                        BUG_ON(skb == NULL);
 
@@ -552,7 +537,9 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
                                skbn = dev_alloc_skb(pkt_len + 2);
                                if (skbn != NULL) {
                                        skb_reserve(skbn, 2);   /* align IP header */
-                                       memcpy(skbn->data, skb->data, pkt_len);
+                                       skb_copy_from_linear_data(skb,
+                                                                 skbn->data,
+                                                                 pkt_len);
                                        /* swap */
                                        skbt = skb;
                                        skb = skbn;
@@ -562,7 +549,6 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
                                skbn = dev_alloc_skb(ENET_RX_FRSIZE);
 
                        if (skbn != NULL) {
-                               skb->dev = dev;
                                skb_put(skb, pkt_len);  /* Make room */
                                skb->protocol = eth_type_trans(skb, dev);
                                received++;
@@ -600,25 +586,24 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
                 * able to keep up at the expense of system resources.
                 */
                FW(fecp, r_des_active, 0x01000000);
+
+               if (received >= budget)
+                       break;
+
        }
 
        fep->cur_rx = bdp;
 
        if (fpi->use_napi) {
-               dev->quota -= received;
-               *budget -= received;
+               if (received < budget) {
+                       netif_rx_complete(dev, &fep->napi);
 
-               if (rx_work_limit < 0)
-                       return 1;       /* not done */
-
-               /* done */
-               netif_rx_complete(dev);
-
-               /* enable RX interrupt bits */
-               FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB);
+                       /* enable RX interrupt bits */
+                       FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB);
+               }
        }
 
-       return 0;
+       return received;
 }
 
 static void fec_enet_tx(struct net_device *dev)
@@ -708,7 +693,7 @@ static void fec_enet_tx(struct net_device *dev)
  * This is called from the MPC core interrupt.
  */
 static irqreturn_t
-fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+fec_enet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct fec_enet_private *fep;
@@ -744,12 +729,12 @@ fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                if ((int_events & FEC_ENET_RXF) != 0) {
                        if (!fpi->use_napi)
-                               fec_enet_rx_common(dev, NULL);
+                               fec_enet_rx_common(fep, dev, ~0);
                        else {
-                               if (netif_rx_schedule_prep(dev)) {
+                               if (netif_rx_schedule_prep(dev, &fep->napi)) {
                                        /* disable rx interrupts */
                                        FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB);
-                                       __netif_rx_schedule(dev);
+                                       __netif_rx_schedule(dev, &fep->napi);
                                } else {
                                        printk(KERN_ERR DRV_MODULE_NAME
                                               ": %s driver bug! interrupt while in poll!\n",
@@ -768,7 +753,7 @@ fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 /* This interrupt occurs when the PHY detects a link change. */
 static irqreturn_t
-fec_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+fec_mii_link_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct fec_enet_private *fep;
@@ -894,10 +879,13 @@ static int fec_enet_open(struct net_device *dev)
        const struct fec_platform_info *fpi = fep->fpi;
        unsigned long flags;
 
+       napi_enable(&fep->napi);
+
        /* Install our interrupt handler. */
        if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) {
                printk(KERN_ERR DRV_MODULE_NAME
                       ": %s Could not allocate FEC IRQ!", dev->name);
+               napi_disable(&fep->napi);
                return -EINVAL;
        }
 
@@ -908,6 +896,7 @@ static int fec_enet_open(struct net_device *dev)
                printk(KERN_ERR DRV_MODULE_NAME
                       ": %s Could not allocate PHY IRQ!", dev->name);
                free_irq(fpi->fec_irq, dev);
+               napi_disable(&fep->napi);
                return -EINVAL;
        }
 
@@ -933,6 +922,7 @@ static int fec_enet_close(struct net_device *dev)
        unsigned long flags;
 
        netif_stop_queue(dev);
+       napi_disable(&fep->napi);
        netif_carrier_off(dev);
 
        if (fpi->use_mdio)
@@ -956,9 +946,12 @@ static struct net_device_stats *fec_enet_get_stats(struct net_device *dev)
        return &fep->stats;
 }
 
-static int fec_enet_poll(struct net_device *dev, int *budget)
+static int fec_enet_poll(struct napi_struct *napi, int budget)
 {
-       return fec_enet_rx_common(dev, budget);
+       struct fec_enet_private *fep = container_of(napi, struct fec_enet_private, napi);
+       struct net_device *dev = fep->dev;
+
+       return fec_enet_rx_common(fep, dev, budget);
 }
 
 /*************************************************************************/
@@ -1043,9 +1036,7 @@ static const struct ethtool_ops fec_ethtool_ops = {
        .get_link       = ethtool_op_get_link,
        .get_msglevel   = fec_get_msglevel,
        .set_msglevel   = fec_set_msglevel,
-       .get_tx_csum    = ethtool_op_get_tx_csum,
        .set_tx_csum    = ethtool_op_set_tx_csum,       /* local! */
-       .get_sg         = ethtool_op_get_sg,
        .set_sg         = ethtool_op_set_sg,
        .get_regs       = fec_get_regs,
 };
@@ -1105,9 +1096,9 @@ int fec_8xx_init_one(const struct fec_platform_info *fpi,
                err = -ENOMEM;
                goto err;
        }
-       SET_MODULE_OWNER(dev);
 
        fep = netdev_priv(dev);
+       fep->dev = dev;
 
        /* partial reset of FEC */
        fec_whack_reset(fecp);
@@ -1173,10 +1164,9 @@ int fec_8xx_init_one(const struct fec_platform_info *fpi,
        dev->get_stats = fec_enet_get_stats;
        dev->set_multicast_list = fec_set_multicast_list;
        dev->set_mac_address = fec_set_mac_address;
-       if (fpi->use_napi) {
-               dev->poll = fec_enet_poll;
-               dev->weight = fpi->napi_weight;
-       }
+       netif_napi_add(dev, &fec->napi,
+                      fec_enet_poll, fpi->napi_weight);
+
        dev->ethtool_ops = &fec_ethtool_ops;
        dev->do_ioctl = fec_ioctl;