aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/atlx
diff options
context:
space:
mode:
authorTony Zelenoff <antonz@parallels.com>2012-04-13 02:09:47 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-15 12:55:07 -0400
commit6294512bbe5288a29f146a3cd12921bda8bce4eb (patch)
treef6ecff9eee161330b2fc0953afa13ae2e0e795d5 /drivers/net/ethernet/atheros/atlx
parent3e1d83f711cda05e326d8a4baa6fa34ee18ad7b8 (diff)
atl1: make driver napi compatible
This is first step, here there is no fine interrupt disabling which cause TX/ERR interrupts stalling when RX scheduled ints processed. Signed-off-by: Tony Zelenoff <antonz@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/atlx')
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c46
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.h1
2 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index c63152886b3e..b7a6484c5e05 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -1917,7 +1917,7 @@ next:
1917 return num_alloc; 1917 return num_alloc;
1918} 1918}
1919 1919
1920static void atl1_intr_rx(struct atl1_adapter *adapter) 1920static int atl1_intr_rx(struct atl1_adapter *adapter, int budget)
1921{ 1921{
1922 int i, count; 1922 int i, count;
1923 u16 length; 1923 u16 length;
@@ -1933,7 +1933,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
1933 1933
1934 rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean); 1934 rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
1935 1935
1936 while (1) { 1936 while (count < budget) {
1937 rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean); 1937 rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
1938 i = 1; 1938 i = 1;
1939 if (likely(rrd->xsz.valid)) { /* packet valid */ 1939 if (likely(rrd->xsz.valid)) { /* packet valid */
@@ -2032,7 +2032,7 @@ rrd_ok:
2032 2032
2033 __vlan_hwaccel_put_tag(skb, vlan_tag); 2033 __vlan_hwaccel_put_tag(skb, vlan_tag);
2034 } 2034 }
2035 netif_rx(skb); 2035 netif_receive_skb(skb);
2036 2036
2037 /* let protocol layer free skb */ 2037 /* let protocol layer free skb */
2038 buffer_info->skb = NULL; 2038 buffer_info->skb = NULL;
@@ -2065,6 +2065,8 @@ rrd_ok:
2065 iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); 2065 iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
2066 spin_unlock(&adapter->mb_lock); 2066 spin_unlock(&adapter->mb_lock);
2067 } 2067 }
2068
2069 return count;
2068} 2070}
2069 2071
2070static void atl1_intr_tx(struct atl1_adapter *adapter) 2072static void atl1_intr_tx(struct atl1_adapter *adapter)
@@ -2439,6 +2441,33 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
2439 return NETDEV_TX_OK; 2441 return NETDEV_TX_OK;
2440} 2442}
2441 2443
2444static int atl1_rx_clean(struct napi_struct *napi, int budget)
2445{
2446 struct atl1_adapter *adapter = container_of(napi, struct atl1_adapter, napi);
2447 int work_done = atl1_intr_rx(adapter, budget);
2448
2449 /* Let's come again to process some more packets */
2450 if (work_done >= budget)
2451 return work_done;
2452
2453 napi_complete(napi);
2454 /* re-enable Interrupt */
2455 iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
2456 return work_done;
2457}
2458
2459static inline int atl1_sched_rx(struct atl1_adapter* adapter)
2460{
2461 if (likely(napi_schedule_prep(&adapter->napi))) {
2462 __napi_schedule(&adapter->napi);
2463 return 1;
2464 }
2465
2466 dev_printk(KERN_ERR, &adapter->pdev->dev,
2467 "rx: INTs must be disabled!");
2468 return 0;
2469}
2470
2442/* 2471/*
2443 * atl1_intr - Interrupt Handler 2472 * atl1_intr - Interrupt Handler
2444 * @irq: interrupt number 2473 * @irq: interrupt number
@@ -2503,8 +2532,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
2503 atl1_intr_tx(adapter); 2532 atl1_intr_tx(adapter);
2504 2533
2505 /* rx event */ 2534 /* rx event */
2506 if (status & ISR_CMB_RX) 2535 if (status & ISR_CMB_RX && atl1_sched_rx(adapter))
2507 alt1_intr_rx(adapter); 2536 /* Go away with INTs disabled */
2537 return IRQ_HANDLED;
2508 2538
2509 /* rx exception */ 2539 /* rx exception */
2510 if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | 2540 if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
@@ -2515,7 +2545,8 @@ static irqreturn_t atl1_intr(int irq, void *data)
2515 &adapter->pdev->dev, 2545 &adapter->pdev->dev,
2516 "rx exception, ISR = 0x%x\n", 2546 "rx exception, ISR = 0x%x\n",
2517 status); 2547 status);
2518 atl1_intr_rx(adapter); 2548 if (atl1_sched_rx(adapter))
2549 return IRQ_HANDLED;
2519 } 2550 }
2520 2551
2521 if (--max_ints < 0) 2552 if (--max_ints < 0)
@@ -2600,6 +2631,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
2600 if (unlikely(err)) 2631 if (unlikely(err))
2601 goto err_up; 2632 goto err_up;
2602 2633
2634 napi_enable(&adapter->napi);
2603 atlx_irq_enable(adapter); 2635 atlx_irq_enable(adapter);
2604 atl1_check_link(adapter); 2636 atl1_check_link(adapter);
2605 netif_start_queue(netdev); 2637 netif_start_queue(netdev);
@@ -2616,6 +2648,7 @@ static void atl1_down(struct atl1_adapter *adapter)
2616{ 2648{
2617 struct net_device *netdev = adapter->netdev; 2649 struct net_device *netdev = adapter->netdev;
2618 2650
2651 napi_disable(&adapter->napi);
2619 netif_stop_queue(netdev); 2652 netif_stop_queue(netdev);
2620 del_timer_sync(&adapter->phy_config_timer); 2653 del_timer_sync(&adapter->phy_config_timer);
2621 adapter->phy_timer_pending = false; 2654 adapter->phy_timer_pending = false;
@@ -2972,6 +3005,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2972 3005
2973 netdev->netdev_ops = &atl1_netdev_ops; 3006 netdev->netdev_ops = &atl1_netdev_ops;
2974 netdev->watchdog_timeo = 5 * HZ; 3007 netdev->watchdog_timeo = 5 * HZ;
3008 netif_napi_add(netdev, &adapter->napi, atl1_rx_clean, 64);
2975 3009
2976 netdev->ethtool_ops = &atl1_ethtool_ops; 3010 netdev->ethtool_ops = &atl1_ethtool_ops;
2977 adapter->bd_number = cards_found; 3011 adapter->bd_number = cards_found;
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h
index 109d6da8be97..71bb50dfc5fa 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.h
+++ b/drivers/net/ethernet/atheros/atlx/atl1.h
@@ -758,6 +758,7 @@ struct atl1_adapter {
758 u16 link_speed; 758 u16 link_speed;
759 u16 link_duplex; 759 u16 link_duplex;
760 spinlock_t lock; 760 spinlock_t lock;
761 struct napi_struct napi;
761 struct work_struct tx_timeout_task; 762 struct work_struct tx_timeout_task;
762 struct work_struct link_chg_task; 763 struct work_struct link_chg_task;
763 struct work_struct pcie_dma_to_rst_task; 764 struct work_struct pcie_dma_to_rst_task;