aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros
diff options
context:
space:
mode:
authorTony Zelenoff <antonz@parallels.com>2012-04-13 02:09:48 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-15 12:55:08 -0400
commit0dbab2fb1dbb2ca749a0787c784528892ecb76d4 (patch)
tree68db0cd99848f8cde61da186b8fcef177caee669 /drivers/net/ethernet/atheros
parent6294512bbe5288a29f146a3cd12921bda8bce4eb (diff)
atl1: add napi process of tx interrupts
Make the tx ints processing same as rx ones via napi. The idea got from e1000. The interrupt disabling is still not fine grained. Signed-off-by: Tony Zelenoff <antonz@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index b7a6484c5e0..d57422e3138 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2069,12 +2069,13 @@ rrd_ok:
2069 return count; 2069 return count;
2070} 2070}
2071 2071
2072static void atl1_intr_tx(struct atl1_adapter *adapter) 2072static int atl1_intr_tx(struct atl1_adapter *adapter)
2073{ 2073{
2074 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; 2074 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
2075 struct atl1_buffer *buffer_info; 2075 struct atl1_buffer *buffer_info;
2076 u16 sw_tpd_next_to_clean; 2076 u16 sw_tpd_next_to_clean;
2077 u16 cmb_tpd_next_to_clean; 2077 u16 cmb_tpd_next_to_clean;
2078 int count = 0;
2078 2079
2079 sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean); 2080 sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
2080 cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); 2081 cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
@@ -2094,12 +2095,16 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
2094 2095
2095 if (++sw_tpd_next_to_clean == tpd_ring->count) 2096 if (++sw_tpd_next_to_clean == tpd_ring->count)
2096 sw_tpd_next_to_clean = 0; 2097 sw_tpd_next_to_clean = 0;
2098
2099 count++;
2097 } 2100 }
2098 atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean); 2101 atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
2099 2102
2100 if (netif_queue_stopped(adapter->netdev) && 2103 if (netif_queue_stopped(adapter->netdev) &&
2101 netif_carrier_ok(adapter->netdev)) 2104 netif_carrier_ok(adapter->netdev))
2102 netif_wake_queue(adapter->netdev); 2105 netif_wake_queue(adapter->netdev);
2106
2107 return count;
2103} 2108}
2104 2109
2105static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring) 2110static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
@@ -2441,11 +2446,14 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
2441 return NETDEV_TX_OK; 2446 return NETDEV_TX_OK;
2442} 2447}
2443 2448
2444static int atl1_rx_clean(struct napi_struct *napi, int budget) 2449static int atl1_rings_clean(struct napi_struct *napi, int budget)
2445{ 2450{
2446 struct atl1_adapter *adapter = container_of(napi, struct atl1_adapter, napi); 2451 struct atl1_adapter *adapter = container_of(napi, struct atl1_adapter, napi);
2447 int work_done = atl1_intr_rx(adapter, budget); 2452 int work_done = atl1_intr_rx(adapter, budget);
2448 2453
2454 if (atl1_intr_tx(adapter))
2455 work_done = budget;
2456
2449 /* Let's come again to process some more packets */ 2457 /* Let's come again to process some more packets */
2450 if (work_done >= budget) 2458 if (work_done >= budget)
2451 return work_done; 2459 return work_done;
@@ -2456,7 +2464,7 @@ static int atl1_rx_clean(struct napi_struct *napi, int budget)
2456 return work_done; 2464 return work_done;
2457} 2465}
2458 2466
2459static inline int atl1_sched_rx(struct atl1_adapter* adapter) 2467static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter)
2460{ 2468{
2461 if (likely(napi_schedule_prep(&adapter->napi))) { 2469 if (likely(napi_schedule_prep(&adapter->napi))) {
2462 __napi_schedule(&adapter->napi); 2470 __napi_schedule(&adapter->napi);
@@ -2527,12 +2535,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
2527 atl1_check_for_link(adapter); 2535 atl1_check_for_link(adapter);
2528 } 2536 }
2529 2537
2530 /* transmit event */ 2538 /* transmit or receive event */
2531 if (status & ISR_CMB_TX) 2539 if (status & (ISR_CMB_TX | ISR_CMB_RX) &&
2532 atl1_intr_tx(adapter); 2540 atl1_sched_rings_clean(adapter))
2533
2534 /* rx event */
2535 if (status & ISR_CMB_RX && atl1_sched_rx(adapter))
2536 /* Go away with INTs disabled */ 2541 /* Go away with INTs disabled */
2537 return IRQ_HANDLED; 2542 return IRQ_HANDLED;
2538 2543
@@ -2545,7 +2550,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
2545 &adapter->pdev->dev, 2550 &adapter->pdev->dev,
2546 "rx exception, ISR = 0x%x\n", 2551 "rx exception, ISR = 0x%x\n",
2547 status); 2552 status);
2548 if (atl1_sched_rx(adapter)) 2553 if (atl1_sched_rings_clean(adapter))
2549 return IRQ_HANDLED; 2554 return IRQ_HANDLED;
2550 } 2555 }
2551 2556
@@ -3005,7 +3010,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
3005 3010
3006 netdev->netdev_ops = &atl1_netdev_ops; 3011 netdev->netdev_ops = &atl1_netdev_ops;
3007 netdev->watchdog_timeo = 5 * HZ; 3012 netdev->watchdog_timeo = 5 * HZ;
3008 netif_napi_add(netdev, &adapter->napi, atl1_rx_clean, 64); 3013 netif_napi_add(netdev, &adapter->napi, atl1_rings_clean, 64);
3009 3014
3010 netdev->ethtool_ops = &atl1_ethtool_ops; 3015 netdev->ethtool_ops = &atl1_ethtool_ops;
3011 adapter->bd_number = cards_found; 3016 adapter->bd_number = cards_found;