Commit 6294512b authored by Tony Zelenoff's avatar Tony Zelenoff Committed by David S. Miller

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: default avatarTony Zelenoff <antonz@parallels.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3e1d83f7
...@@ -1917,7 +1917,7 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter) ...@@ -1917,7 +1917,7 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
return num_alloc; return num_alloc;
} }
static void atl1_intr_rx(struct atl1_adapter *adapter) static int atl1_intr_rx(struct atl1_adapter *adapter, int budget)
{ {
int i, count; int i, count;
u16 length; u16 length;
...@@ -1933,7 +1933,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter) ...@@ -1933,7 +1933,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean); rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
while (1) { while (count < budget) {
rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean); rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
i = 1; i = 1;
if (likely(rrd->xsz.valid)) { /* packet valid */ if (likely(rrd->xsz.valid)) { /* packet valid */
...@@ -2032,7 +2032,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter) ...@@ -2032,7 +2032,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
__vlan_hwaccel_put_tag(skb, vlan_tag); __vlan_hwaccel_put_tag(skb, vlan_tag);
} }
netif_rx(skb); netif_receive_skb(skb);
/* let protocol layer free skb */ /* let protocol layer free skb */
buffer_info->skb = NULL; buffer_info->skb = NULL;
...@@ -2065,6 +2065,8 @@ static void atl1_intr_rx(struct atl1_adapter *adapter) ...@@ -2065,6 +2065,8 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
spin_unlock(&adapter->mb_lock); spin_unlock(&adapter->mb_lock);
} }
return count;
} }
static void atl1_intr_tx(struct atl1_adapter *adapter) static void atl1_intr_tx(struct atl1_adapter *adapter)
...@@ -2439,6 +2441,33 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, ...@@ -2439,6 +2441,33 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
static int atl1_rx_clean(struct napi_struct *napi, int budget)
{
struct atl1_adapter *adapter = container_of(napi, struct atl1_adapter, napi);
int work_done = atl1_intr_rx(adapter, budget);
/* Let's come again to process some more packets */
if (work_done >= budget)
return work_done;
napi_complete(napi);
/* re-enable Interrupt */
iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
return work_done;
}
static inline int atl1_sched_rx(struct atl1_adapter* adapter)
{
if (likely(napi_schedule_prep(&adapter->napi))) {
__napi_schedule(&adapter->napi);
return 1;
}
dev_printk(KERN_ERR, &adapter->pdev->dev,
"rx: INTs must be disabled!");
return 0;
}
/* /*
* atl1_intr - Interrupt Handler * atl1_intr - Interrupt Handler
* @irq: interrupt number * @irq: interrupt number
...@@ -2503,8 +2532,9 @@ static irqreturn_t atl1_intr(int irq, void *data) ...@@ -2503,8 +2532,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
atl1_intr_tx(adapter); atl1_intr_tx(adapter);
/* rx event */ /* rx event */
if (status & ISR_CMB_RX) if (status & ISR_CMB_RX && atl1_sched_rx(adapter))
alt1_intr_rx(adapter); /* Go away with INTs disabled */
return IRQ_HANDLED;
/* rx exception */ /* rx exception */
if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
...@@ -2515,7 +2545,8 @@ static irqreturn_t atl1_intr(int irq, void *data) ...@@ -2515,7 +2545,8 @@ static irqreturn_t atl1_intr(int irq, void *data)
&adapter->pdev->dev, &adapter->pdev->dev,
"rx exception, ISR = 0x%x\n", "rx exception, ISR = 0x%x\n",
status); status);
atl1_intr_rx(adapter); if (atl1_sched_rx(adapter))
return IRQ_HANDLED;
} }
if (--max_ints < 0) if (--max_ints < 0)
...@@ -2600,6 +2631,7 @@ static s32 atl1_up(struct atl1_adapter *adapter) ...@@ -2600,6 +2631,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
if (unlikely(err)) if (unlikely(err))
goto err_up; goto err_up;
napi_enable(&adapter->napi);
atlx_irq_enable(adapter); atlx_irq_enable(adapter);
atl1_check_link(adapter); atl1_check_link(adapter);
netif_start_queue(netdev); netif_start_queue(netdev);
...@@ -2616,6 +2648,7 @@ static void atl1_down(struct atl1_adapter *adapter) ...@@ -2616,6 +2648,7 @@ static void atl1_down(struct atl1_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
napi_disable(&adapter->napi);
netif_stop_queue(netdev); netif_stop_queue(netdev);
del_timer_sync(&adapter->phy_config_timer); del_timer_sync(&adapter->phy_config_timer);
adapter->phy_timer_pending = false; adapter->phy_timer_pending = false;
...@@ -2972,6 +3005,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, ...@@ -2972,6 +3005,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->netdev_ops = &atl1_netdev_ops; netdev->netdev_ops = &atl1_netdev_ops;
netdev->watchdog_timeo = 5 * HZ; netdev->watchdog_timeo = 5 * HZ;
netif_napi_add(netdev, &adapter->napi, atl1_rx_clean, 64);
netdev->ethtool_ops = &atl1_ethtool_ops; netdev->ethtool_ops = &atl1_ethtool_ops;
adapter->bd_number = cards_found; adapter->bd_number = cards_found;
......
...@@ -758,6 +758,7 @@ struct atl1_adapter { ...@@ -758,6 +758,7 @@ struct atl1_adapter {
u16 link_speed; u16 link_speed;
u16 link_duplex; u16 link_duplex;
spinlock_t lock; spinlock_t lock;
struct napi_struct napi;
struct work_struct tx_timeout_task; struct work_struct tx_timeout_task;
struct work_struct link_chg_task; struct work_struct link_chg_task;
struct work_struct pcie_dma_to_rst_task; struct work_struct pcie_dma_to_rst_task;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment