aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;