switch to 2.6.24
[openwrt/staging/wigyori.git] / target / linux / adm5120 / files / drivers / net / adm5120sw.c
index ff933cf7cf8ad4e44655115217e0b1f6c4a87ee0..8f3610e90755f0df870ff06e318a9dfab4465c69 100644 (file)
 /* ------------------------------------------------------------------------ */
 
 struct adm5120_if_priv {
+       struct net_device *dev;
+
        unsigned int    vlan_no;
        unsigned int    port_mask;
+
+#ifdef CONFIG_ADM5120_SWITCH_NAPI
+       struct napi_struct napi;
+#endif
 };
 
 struct dma_desc {
@@ -333,7 +339,6 @@ static void sw_dump_regs(void)
        SW_DBG("rlda: %08X\n", t);
 }
 
-
 /* ------------------------------------------------------------------------ */
 
 static inline void adm5120_rx_dma_update(struct dma_desc *desc,
@@ -495,9 +500,11 @@ static void adm5120_switch_tx(void)
 }
 
 #ifdef CONFIG_ADM5120_SWITCH_NAPI
-static int adm5120_if_poll(struct net_device *dev, int *budget)
+static int adm5120_if_poll(struct napi_struct *napi, int limit)
 {
-       int limit = min(dev->quota, *budget);
+       struct adm5120_if_priv *priv = container_of(napi,
+                               struct adm5120_if_priv, napi);
+       struct net_device *dev = priv->dev;
        int done;
        u32 status;
 
@@ -509,13 +516,10 @@ static int adm5120_if_poll(struct net_device *dev, int *budget)
        SW_DBG("%s: processing RX ring\n", dev->name);
        done = adm5120_switch_rx(limit);
 
-       *budget -= done;
-       dev->quota -= done;
-
        status = sw_int_status() & SWITCH_INTS_POLL;
        if ((done < limit) && (!status)) {
                SW_DBG("disable polling mode for %s\n", dev->name);
-               netif_rx_complete(dev);
+               netif_rx_complete(dev, napi);
                sw_int_unmask(SWITCH_INTS_POLL);
                return 0;
        }
@@ -541,10 +545,12 @@ static irqreturn_t adm5120_switch_irq(int irq, void *dev_id)
 
        if (status & SWITCH_INTS_POLL) {
                struct net_device *dev = dev_id;
+               struct adm5120_if_priv *priv = netdev_priv(dev);
+
                sw_dump_intr_mask("poll ints", status);
                SW_DBG("enable polling mode for %s\n", dev->name);
                sw_int_mask(SWITCH_INTS_POLL);
-               netif_rx_schedule(dev);
+               netif_rx_schedule(dev, &priv->napi);
        }
 #else
        sw_int_ack(status);
@@ -779,12 +785,31 @@ static void adm5120_switch_set_vlan_ports(unsigned int vlan, u32 ports)
 
 /* ------------------------------------------------------------------------ */
 
+#ifdef CONFIG_ADM5120_SWITCH_NAPI
+static inline void adm5120_if_napi_enable(struct net_device *dev)
+{
+       struct adm5120_if_priv *priv = netdev_priv(dev);
+       napi_enable(&priv->napi);
+}
+
+static inline void adm5120_if_napi_disable(struct net_device *dev)
+{
+       struct adm5120_if_priv *priv = netdev_priv(dev);
+       napi_disable(&priv->napi);
+}
+#else
+static inline void adm5120_if_napi_enable(struct net_device *dev) {}
+static inline void adm5120_if_napi_disable(struct net_device *dev) {}
+#endif /* CONFIG_ADM5120_SWITCH_NAPI */
+
 static int adm5120_if_open(struct net_device *dev)
 {
        u32 t;
        int err;
        int i;
 
+       adm5120_if_napi_enable(dev);
+
        err = request_irq(dev->irq, adm5120_switch_irq,
                (IRQF_SHARED | IRQF_DISABLED), dev->name, dev);
        if (err) {
@@ -809,6 +834,7 @@ static int adm5120_if_open(struct net_device *dev)
        return 0;
 
 err:
+       adm5120_if_napi_disable(dev);
        return err;
 }
 
@@ -818,6 +844,7 @@ static int adm5120_if_stop(struct net_device *dev)
        int i;
 
        netif_stop_queue(dev);
+       adm5120_if_napi_disable(dev);
 
        /* disable port if not assigned to other devices */
        t = sw_read_reg(SWITCH_REG_PORT_CONF0);
@@ -1001,6 +1028,9 @@ static struct net_device *adm5120_if_alloc(void)
        if (!dev)
                return NULL;
 
+       priv = netdev_priv(dev);
+       priv->dev = dev;
+
        dev->irq                = ADM5120_IRQ_SWITCH;
        dev->open               = adm5120_if_open;
        dev->hard_start_xmit    = adm5120_if_hard_start_xmit;
@@ -1010,13 +1040,11 @@ static struct net_device *adm5120_if_alloc(void)
        dev->tx_timeout         = adm5120_if_tx_timeout;
        dev->watchdog_timeo     = TX_TIMEOUT;
        dev->set_mac_address    = adm5120_if_set_mac_address;
+
 #ifdef CONFIG_ADM5120_SWITCH_NAPI
-       dev->poll               = adm5120_if_poll;
-       dev->weight             = 64;
+       netif_napi_add(dev, &priv->napi, adm5120_if_poll, 64);
 #endif
 
-       SET_MODULE_OWNER(dev);
-
        return dev;
 }