145 lines
3.9 KiB
Diff
145 lines
3.9 KiB
Diff
|
Index: linux-2.6.24/drivers/net/adm5120sw.c
|
||
|
===================================================================
|
||
|
--- linux-2.6.24.orig/drivers/net/adm5120sw.c
|
||
|
+++ linux-2.6.24/drivers/net/adm5120sw.c
|
||
|
@@ -93,8 +93,14 @@
|
||
|
/* ------------------------------------------------------------------------ */
|
||
|
|
||
|
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_de
|
||
|
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(in
|
||
|
|
||
|
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_port
|
||
|
|
||
|
/* ------------------------------------------------------------------------ */
|
||
|
|
||
|
+#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_de
|
||
|
return 0;
|
||
|
|
||
|
err:
|
||
|
+ adm5120_if_napi_disable(dev);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
@@ -818,6 +844,7 @@ static int adm5120_if_stop(struct net_de
|
||
|
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_all
|
||
|
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_all
|
||
|
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;
|
||
|
}
|
||
|
|