aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/adi
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2014-07-24 05:52:59 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-25 02:35:42 -0400
commit159945af1e40db5c15766d9fe6d465d7213cc860 (patch)
tree9399c244aade0702915d2c6956d893a6ab043725 /drivers/net/ethernet/adi
parent6b53dafe23fd1f1228c7dd9b8a1323e757966160 (diff)
bfin_mac: convert bfin Ethernet driver to NAPI framework
Ethernet RX DMA buffers are polled in NAPI work queue other than received directly in DMA RX interrupt handler. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/adi')
-rw-r--r--drivers/net/ethernet/adi/Kconfig3
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.c79
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.h3
3 files changed, 53 insertions, 32 deletions
diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig
index f952fff6a9a9..c9cd3592ab73 100644
--- a/drivers/net/ethernet/adi/Kconfig
+++ b/drivers/net/ethernet/adi/Kconfig
@@ -52,8 +52,7 @@ config BFIN_TX_DESC_NUM
52config BFIN_RX_DESC_NUM 52config BFIN_RX_DESC_NUM
53 int "Number of receive buffer packets" 53 int "Number of receive buffer packets"
54 depends on BFIN_MAC 54 depends on BFIN_MAC
55 range 20 100 if BFIN_MAC_USE_L1 55 range 20 64
56 range 20 800
57 default "20" 56 default "20"
58 ---help--- 57 ---help---
59 Set the number of buffer packets used in driver. 58 Set the number of buffer packets used in driver.
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index 7ae74d450e8f..afa66847e10b 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -1218,11 +1218,11 @@ out:
1218#define RX_ERROR_MASK (RX_LONG | RX_ALIGN | RX_CRC | RX_LEN | \ 1218#define RX_ERROR_MASK (RX_LONG | RX_ALIGN | RX_CRC | RX_LEN | \
1219 RX_FRAG | RX_ADDR | RX_DMAO | RX_PHY | RX_LATE | RX_RANGE) 1219 RX_FRAG | RX_ADDR | RX_DMAO | RX_PHY | RX_LATE | RX_RANGE)
1220 1220
1221static void bfin_mac_rx(struct net_device *dev) 1221static void bfin_mac_rx(struct bfin_mac_local *lp)
1222{ 1222{
1223 struct net_device *dev = lp->ndev;
1223 struct sk_buff *skb, *new_skb; 1224 struct sk_buff *skb, *new_skb;
1224 unsigned short len; 1225 unsigned short len;
1225 struct bfin_mac_local *lp __maybe_unused = netdev_priv(dev);
1226#if defined(BFIN_MAC_CSUM_OFFLOAD) 1226#if defined(BFIN_MAC_CSUM_OFFLOAD)
1227 unsigned int i; 1227 unsigned int i;
1228 unsigned char fcs[ETH_FCS_LEN + 1]; 1228 unsigned char fcs[ETH_FCS_LEN + 1];
@@ -1256,7 +1256,7 @@ static void bfin_mac_rx(struct net_device *dev)
1256 current_rx_ptr->skb = new_skb; 1256 current_rx_ptr->skb = new_skb;
1257 current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; 1257 current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
1258 1258
1259 len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN); 1259 len = (unsigned short)(current_rx_ptr->status.status_word & RX_FRLEN);
1260 /* Deduce Ethernet FCS length from Ethernet payload length */ 1260 /* Deduce Ethernet FCS length from Ethernet payload length */
1261 len -= ETH_FCS_LEN; 1261 len -= ETH_FCS_LEN;
1262 skb_put(skb, len); 1262 skb_put(skb, len);
@@ -1294,7 +1294,8 @@ static void bfin_mac_rx(struct net_device *dev)
1294 } 1294 }
1295#endif 1295#endif
1296 1296
1297 netif_rx(skb); 1297 napi_gro_receive(&lp->napi, skb);
1298
1298 dev->stats.rx_packets++; 1299 dev->stats.rx_packets++;
1299 dev->stats.rx_bytes += len; 1300 dev->stats.rx_bytes += len;
1300out: 1301out:
@@ -1302,41 +1303,52 @@ out:
1302 current_rx_ptr = current_rx_ptr->next; 1303 current_rx_ptr = current_rx_ptr->next;
1303} 1304}
1304 1305
1306static int bfin_mac_poll(struct napi_struct *napi, int budget)
1307{
1308 int i = 0;
1309 struct bfin_mac_local *lp = container_of(napi,
1310 struct bfin_mac_local,
1311 napi);
1312
1313 while (current_rx_ptr->status.status_word != 0 && i < budget) {
1314 bfin_mac_rx(lp);
1315 i++;
1316 }
1317
1318 if (i < budget) {
1319 napi_complete(napi);
1320 if (test_and_clear_bit(BFIN_MAC_RX_IRQ_DISABLED, &lp->flags))
1321 enable_irq(IRQ_MAC_RX);
1322 }
1323
1324 return i;
1325}
1326
1305/* interrupt routine to handle rx and error signal */ 1327/* interrupt routine to handle rx and error signal */
1306static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id) 1328static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id)
1307{ 1329{
1308 struct net_device *dev = dev_id; 1330 struct bfin_mac_local *lp = netdev_priv(dev_id);
1309 int number = 0; 1331 u32 status;
1310 1332
1311get_one_packet: 1333 status = bfin_read_DMA1_IRQ_STATUS();
1312 if (current_rx_ptr->status.status_word == 0) { 1334
1313 /* no more new packet received */ 1335 bfin_write_DMA1_IRQ_STATUS(status | DMA_DONE | DMA_ERR);
1314 if (number == 0) { 1336 if (status & DMA_DONE) {
1315 if (current_rx_ptr->next->status.status_word != 0) { 1337 disable_irq_nosync(IRQ_MAC_RX);
1316 current_rx_ptr = current_rx_ptr->next; 1338 set_bit(BFIN_MAC_RX_IRQ_DISABLED, &lp->flags);
1317 goto real_rx; 1339 napi_schedule(&lp->napi);
1318 }
1319 }
1320 bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
1321 DMA_DONE | DMA_ERR);
1322 return IRQ_HANDLED;
1323 } 1340 }
1324 1341
1325real_rx: 1342 return IRQ_HANDLED;
1326 bfin_mac_rx(dev);
1327 number++;
1328 goto get_one_packet;
1329} 1343}
1330 1344
1331#ifdef CONFIG_NET_POLL_CONTROLLER 1345#ifdef CONFIG_NET_POLL_CONTROLLER
1332static void bfin_mac_poll(struct net_device *dev) 1346static void bfin_mac_poll_controller(struct net_device *dev)
1333{ 1347{
1334 struct bfin_mac_local *lp = netdev_priv(dev); 1348 struct bfin_mac_local *lp = netdev_priv(dev);
1335 1349
1336 disable_irq(IRQ_MAC_RX);
1337 bfin_mac_interrupt(IRQ_MAC_RX, dev); 1350 bfin_mac_interrupt(IRQ_MAC_RX, dev);
1338 tx_reclaim_skb(lp); 1351 tx_reclaim_skb(lp);
1339 enable_irq(IRQ_MAC_RX);
1340} 1352}
1341#endif /* CONFIG_NET_POLL_CONTROLLER */ 1353#endif /* CONFIG_NET_POLL_CONTROLLER */
1342 1354
@@ -1428,14 +1440,13 @@ static void bfin_mac_timeout(struct net_device *dev)
1428 tx_list_head = tx_list_head->next; 1440 tx_list_head = tx_list_head->next;
1429 } 1441 }
1430 1442
1431 if (netif_queue_stopped(lp->ndev)) 1443 if (netif_queue_stopped(dev))
1432 netif_wake_queue(lp->ndev); 1444 netif_wake_queue(dev);
1433 1445
1434 bfin_mac_enable(lp->phydev); 1446 bfin_mac_enable(lp->phydev);
1435 1447
1436 /* We can accept TX packets again */ 1448 /* We can accept TX packets again */
1437 dev->trans_start = jiffies; /* prevent tx timeout */ 1449 dev->trans_start = jiffies; /* prevent tx timeout */
1438 netif_wake_queue(dev);
1439} 1450}
1440 1451
1441static void bfin_mac_multicast_hash(struct net_device *dev) 1452static void bfin_mac_multicast_hash(struct net_device *dev)
@@ -1562,6 +1573,7 @@ static int bfin_mac_open(struct net_device *dev)
1562 return ret; 1573 return ret;
1563 pr_debug("hardware init finished\n"); 1574 pr_debug("hardware init finished\n");
1564 1575
1576 napi_enable(&lp->napi);
1565 netif_start_queue(dev); 1577 netif_start_queue(dev);
1566 netif_carrier_on(dev); 1578 netif_carrier_on(dev);
1567 1579
@@ -1579,6 +1591,7 @@ static int bfin_mac_close(struct net_device *dev)
1579 pr_debug("%s: %s\n", dev->name, __func__); 1591 pr_debug("%s: %s\n", dev->name, __func__);
1580 1592
1581 netif_stop_queue(dev); 1593 netif_stop_queue(dev);
1594 napi_disable(&lp->napi);
1582 netif_carrier_off(dev); 1595 netif_carrier_off(dev);
1583 1596
1584 phy_stop(lp->phydev); 1597 phy_stop(lp->phydev);
@@ -1604,7 +1617,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = {
1604 .ndo_validate_addr = eth_validate_addr, 1617 .ndo_validate_addr = eth_validate_addr,
1605 .ndo_change_mtu = eth_change_mtu, 1618 .ndo_change_mtu = eth_change_mtu,
1606#ifdef CONFIG_NET_POLL_CONTROLLER 1619#ifdef CONFIG_NET_POLL_CONTROLLER
1607 .ndo_poll_controller = bfin_mac_poll, 1620 .ndo_poll_controller = bfin_mac_poll_controller,
1608#endif 1621#endif
1609}; 1622};
1610 1623
@@ -1689,6 +1702,9 @@ static int bfin_mac_probe(struct platform_device *pdev)
1689 lp->tx_reclaim_timer.data = (unsigned long)lp; 1702 lp->tx_reclaim_timer.data = (unsigned long)lp;
1690 lp->tx_reclaim_timer.function = tx_reclaim_skb_timeout; 1703 lp->tx_reclaim_timer.function = tx_reclaim_skb_timeout;
1691 1704
1705 lp->flags = 0;
1706 netif_napi_add(ndev, &lp->napi, bfin_mac_poll, CONFIG_BFIN_RX_DESC_NUM);
1707
1692 spin_lock_init(&lp->lock); 1708 spin_lock_init(&lp->lock);
1693 1709
1694 /* now, enable interrupts */ 1710 /* now, enable interrupts */
@@ -1723,6 +1739,7 @@ out_err_phc:
1723out_err_reg_ndev: 1739out_err_reg_ndev:
1724 free_irq(IRQ_MAC_RX, ndev); 1740 free_irq(IRQ_MAC_RX, ndev);
1725out_err_request_irq: 1741out_err_request_irq:
1742 netif_napi_del(&lp->napi);
1726out_err_mii_probe: 1743out_err_mii_probe:
1727 mdiobus_unregister(lp->mii_bus); 1744 mdiobus_unregister(lp->mii_bus);
1728 mdiobus_free(lp->mii_bus); 1745 mdiobus_free(lp->mii_bus);
@@ -1743,6 +1760,8 @@ static int bfin_mac_remove(struct platform_device *pdev)
1743 1760
1744 unregister_netdev(ndev); 1761 unregister_netdev(ndev);
1745 1762
1763 netif_napi_del(&lp->napi);
1764
1746 free_irq(IRQ_MAC_RX, ndev); 1765 free_irq(IRQ_MAC_RX, ndev);
1747 1766
1748 free_netdev(ndev); 1767 free_netdev(ndev);
diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
index 6dec86ac97cd..d1217db70db4 100644
--- a/drivers/net/ethernet/adi/bfin_mac.h
+++ b/drivers/net/ethernet/adi/bfin_mac.h
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#define TX_RECLAIM_JIFFIES (HZ / 5) 28#define TX_RECLAIM_JIFFIES (HZ / 5)
29#define BFIN_MAC_RX_IRQ_DISABLED 1
29 30
30struct dma_descriptor { 31struct dma_descriptor {
31 struct dma_descriptor *next_dma_desc; 32 struct dma_descriptor *next_dma_desc;
@@ -80,6 +81,8 @@ struct bfin_mac_local {
80 int irq_wake_requested; 81 int irq_wake_requested;
81 struct timer_list tx_reclaim_timer; 82 struct timer_list tx_reclaim_timer;
82 struct net_device *ndev; 83 struct net_device *ndev;
84 struct napi_struct napi;
85 unsigned long flags;
83 86
84 /* Data for EMAC_VLAN1 regs */ 87 /* Data for EMAC_VLAN1 regs */
85 u16 vlan1_mask, vlan2_mask; 88 u16 vlan1_mask, vlan2_mask;