aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/apm
diff options
context:
space:
mode:
authorIyappan Subramanian <isubramanian@apm.com>2015-03-25 15:19:12 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-27 17:18:48 -0400
commit6772b653f8c2fd0a54a23da28a0a761685deec85 (patch)
tree5d9c988da6042571368ec71b383a83cdc2c597d2 /drivers/net/ethernet/apm
parentd31346494bd2b1185949dc64ab6467186b80fb05 (diff)
drivers: net: xgene: Add separate tx completion ring
- Added wrapper functions around napi_add, napi_del, napi_enable and napi_disable - Moved platform_get_irq function call after reading phy_mode - Associating the new irq to tx completion for the supported ethernet interfaces Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> Signed-off-by: Keyur Chudgar <kchudgar@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/apm')
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c141
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.h6
2 files changed, 127 insertions, 20 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 6146a993a136..40d3530d7f30 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -428,13 +428,23 @@ static int xgene_enet_register_irq(struct net_device *ndev)
428{ 428{
429 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 429 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
430 struct device *dev = ndev_to_dev(ndev); 430 struct device *dev = ndev_to_dev(ndev);
431 struct xgene_enet_desc_ring *ring;
431 int ret; 432 int ret;
432 433
433 ret = devm_request_irq(dev, pdata->rx_ring->irq, xgene_enet_rx_irq, 434 ring = pdata->rx_ring;
434 IRQF_SHARED, ndev->name, pdata->rx_ring); 435 ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
435 if (ret) { 436 IRQF_SHARED, ring->irq_name, ring);
436 netdev_err(ndev, "rx%d interrupt request failed\n", 437 if (ret)
437 pdata->rx_ring->irq); 438 netdev_err(ndev, "Failed to request irq %s\n", ring->irq_name);
439
440 if (pdata->cq_cnt) {
441 ring = pdata->tx_ring->cp_ring;
442 ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
443 IRQF_SHARED, ring->irq_name, ring);
444 if (ret) {
445 netdev_err(ndev, "Failed to request irq %s\n",
446 ring->irq_name);
447 }
438 } 448 }
439 449
440 return ret; 450 return ret;
@@ -448,6 +458,37 @@ static void xgene_enet_free_irq(struct net_device *ndev)
448 pdata = netdev_priv(ndev); 458 pdata = netdev_priv(ndev);
449 dev = ndev_to_dev(ndev); 459 dev = ndev_to_dev(ndev);
450 devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring); 460 devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring);
461
462 if (pdata->cq_cnt) {
463 devm_free_irq(dev, pdata->tx_ring->cp_ring->irq,
464 pdata->tx_ring->cp_ring);
465 }
466}
467
468static void xgene_enet_napi_enable(struct xgene_enet_pdata *pdata)
469{
470 struct napi_struct *napi;
471
472 napi = &pdata->rx_ring->napi;
473 napi_enable(napi);
474
475 if (pdata->cq_cnt) {
476 napi = &pdata->tx_ring->cp_ring->napi;
477 napi_enable(napi);
478 }
479}
480
481static void xgene_enet_napi_disable(struct xgene_enet_pdata *pdata)
482{
483 struct napi_struct *napi;
484
485 napi = &pdata->rx_ring->napi;
486 napi_disable(napi);
487
488 if (pdata->cq_cnt) {
489 napi = &pdata->tx_ring->cp_ring->napi;
490 napi_disable(napi);
491 }
451} 492}
452 493
453static int xgene_enet_open(struct net_device *ndev) 494static int xgene_enet_open(struct net_device *ndev)
@@ -462,7 +503,7 @@ static int xgene_enet_open(struct net_device *ndev)
462 ret = xgene_enet_register_irq(ndev); 503 ret = xgene_enet_register_irq(ndev);
463 if (ret) 504 if (ret)
464 return ret; 505 return ret;
465 napi_enable(&pdata->rx_ring->napi); 506 xgene_enet_napi_enable(pdata);
466 507
467 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) 508 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
468 phy_start(pdata->phy_dev); 509 phy_start(pdata->phy_dev);
@@ -486,7 +527,7 @@ static int xgene_enet_close(struct net_device *ndev)
486 else 527 else
487 cancel_delayed_work_sync(&pdata->link_work); 528 cancel_delayed_work_sync(&pdata->link_work);
488 529
489 napi_disable(&pdata->rx_ring->napi); 530 xgene_enet_napi_disable(pdata);
490 xgene_enet_free_irq(ndev); 531 xgene_enet_free_irq(ndev);
491 xgene_enet_process_ring(pdata->rx_ring, -1); 532 xgene_enet_process_ring(pdata->rx_ring, -1);
492 533
@@ -580,6 +621,8 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
580 if (ring) { 621 if (ring) {
581 if (ring->cp_ring && ring->cp_ring->cp_skb) 622 if (ring->cp_ring && ring->cp_ring->cp_skb)
582 devm_kfree(dev, ring->cp_ring->cp_skb); 623 devm_kfree(dev, ring->cp_ring->cp_skb);
624 if (ring->cp_ring && pdata->cq_cnt)
625 xgene_enet_free_desc_ring(ring->cp_ring);
583 xgene_enet_free_desc_ring(ring); 626 xgene_enet_free_desc_ring(ring);
584 } 627 }
585 628
@@ -673,6 +716,12 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
673 rx_ring->nbufpool = NUM_BUFPOOL; 716 rx_ring->nbufpool = NUM_BUFPOOL;
674 rx_ring->buf_pool = buf_pool; 717 rx_ring->buf_pool = buf_pool;
675 rx_ring->irq = pdata->rx_irq; 718 rx_ring->irq = pdata->rx_irq;
719 if (!pdata->cq_cnt) {
720 snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
721 ndev->name);
722 } else {
723 snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx", ndev->name);
724 }
676 buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots, 725 buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
677 sizeof(struct sk_buff *), GFP_KERNEL); 726 sizeof(struct sk_buff *), GFP_KERNEL);
678 if (!buf_pool->rx_skb) { 727 if (!buf_pool->rx_skb) {
@@ -694,7 +743,22 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
694 } 743 }
695 pdata->tx_ring = tx_ring; 744 pdata->tx_ring = tx_ring;
696 745
697 cp_ring = pdata->rx_ring; 746 if (!pdata->cq_cnt) {
747 cp_ring = pdata->rx_ring;
748 } else {
749 /* allocate tx completion descriptor ring */
750 ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
751 cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
752 RING_CFGSIZE_16KB,
753 ring_id);
754 if (!cp_ring) {
755 ret = -ENOMEM;
756 goto err;
757 }
758 cp_ring->irq = pdata->txc_irq;
759 snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc", ndev->name);
760 }
761
698 cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots, 762 cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
699 sizeof(struct sk_buff *), GFP_KERNEL); 763 sizeof(struct sk_buff *), GFP_KERNEL);
700 if (!cp_ring->cp_skb) { 764 if (!cp_ring->cp_skb) {
@@ -853,14 +917,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
853 return -ENOMEM; 917 return -ENOMEM;
854 } 918 }
855 919
856 ret = platform_get_irq(pdev, 0);
857 if (ret <= 0) {
858 dev_err(dev, "Unable to get ENET Rx IRQ\n");
859 ret = ret ? : -ENXIO;
860 return ret;
861 }
862 pdata->rx_irq = ret;
863
864 ret = xgene_get_port_id(dev, pdata); 920 ret = xgene_get_port_id(dev, pdata);
865 if (ret) 921 if (ret)
866 return ret; 922 return ret;
@@ -882,6 +938,24 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
882 return -ENODEV; 938 return -ENODEV;
883 } 939 }
884 940
941 ret = platform_get_irq(pdev, 0);
942 if (ret <= 0) {
943 dev_err(dev, "Unable to get ENET Rx IRQ\n");
944 ret = ret ? : -ENXIO;
945 return ret;
946 }
947 pdata->rx_irq = ret;
948
949 if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII) {
950 ret = platform_get_irq(pdev, 1);
951 if (ret <= 0) {
952 dev_err(dev, "Unable to get ENET Tx completion IRQ\n");
953 ret = ret ? : -ENXIO;
954 return ret;
955 }
956 pdata->txc_irq = ret;
957 }
958
885 pdata->clk = devm_clk_get(&pdev->dev, NULL); 959 pdata->clk = devm_clk_get(&pdev->dev, NULL);
886 if (IS_ERR(pdata->clk)) { 960 if (IS_ERR(pdata->clk)) {
887 /* Firmware may have set up the clock already. */ 961 /* Firmware may have set up the clock already. */
@@ -950,11 +1024,13 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
950 pdata->mac_ops = &xgene_sgmac_ops; 1024 pdata->mac_ops = &xgene_sgmac_ops;
951 pdata->port_ops = &xgene_sgport_ops; 1025 pdata->port_ops = &xgene_sgport_ops;
952 pdata->rm = RM1; 1026 pdata->rm = RM1;
1027 pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
953 break; 1028 break;
954 default: 1029 default:
955 pdata->mac_ops = &xgene_xgmac_ops; 1030 pdata->mac_ops = &xgene_xgmac_ops;
956 pdata->port_ops = &xgene_xgport_ops; 1031 pdata->port_ops = &xgene_xgport_ops;
957 pdata->rm = RM0; 1032 pdata->rm = RM0;
1033 pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
958 break; 1034 break;
959 } 1035 }
960 1036
@@ -977,12 +1053,38 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
977 1053
978} 1054}
979 1055
1056static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
1057{
1058 struct napi_struct *napi;
1059
1060 napi = &pdata->rx_ring->napi;
1061 netif_napi_add(pdata->ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
1062
1063 if (pdata->cq_cnt) {
1064 napi = &pdata->tx_ring->cp_ring->napi;
1065 netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
1066 NAPI_POLL_WEIGHT);
1067 }
1068}
1069
1070static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
1071{
1072 struct napi_struct *napi;
1073
1074 napi = &pdata->rx_ring->napi;
1075 netif_napi_del(napi);
1076
1077 if (pdata->cq_cnt) {
1078 napi = &pdata->tx_ring->cp_ring->napi;
1079 netif_napi_del(napi);
1080 }
1081}
1082
980static int xgene_enet_probe(struct platform_device *pdev) 1083static int xgene_enet_probe(struct platform_device *pdev)
981{ 1084{
982 struct net_device *ndev; 1085 struct net_device *ndev;
983 struct xgene_enet_pdata *pdata; 1086 struct xgene_enet_pdata *pdata;
984 struct device *dev = &pdev->dev; 1087 struct device *dev = &pdev->dev;
985 struct napi_struct *napi;
986 struct xgene_mac_ops *mac_ops; 1088 struct xgene_mac_ops *mac_ops;
987 int ret; 1089 int ret;
988 1090
@@ -1024,8 +1126,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
1024 if (ret) 1126 if (ret)
1025 goto err; 1127 goto err;
1026 1128
1027 napi = &pdata->rx_ring->napi; 1129 xgene_enet_napi_add(pdata);
1028 netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
1029 mac_ops = pdata->mac_ops; 1130 mac_ops = pdata->mac_ops;
1030 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) 1131 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
1031 ret = xgene_enet_mdio_config(pdata); 1132 ret = xgene_enet_mdio_config(pdata);
@@ -1052,7 +1153,7 @@ static int xgene_enet_remove(struct platform_device *pdev)
1052 mac_ops->rx_disable(pdata); 1153 mac_ops->rx_disable(pdata);
1053 mac_ops->tx_disable(pdata); 1154 mac_ops->tx_disable(pdata);
1054 1155
1055 netif_napi_del(&pdata->rx_ring->napi); 1156 xgene_enet_napi_del(pdata);
1056 xgene_enet_mdio_remove(pdata); 1157 xgene_enet_mdio_remove(pdata);
1057 xgene_enet_delete_desc_rings(pdata); 1158 xgene_enet_delete_desc_rings(pdata);
1058 unregister_netdev(ndev); 1159 unregister_netdev(ndev);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index b93ed21a157f..8f3d232b09bc 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -51,6 +51,9 @@
51#define START_BP_BUFNUM_1 0x2A 51#define START_BP_BUFNUM_1 0x2A
52#define START_RING_NUM_1 264 52#define START_RING_NUM_1 264
53 53
54#define IRQ_ID_SIZE 16
55#define XGENE_MAX_TXC_RINGS 1
56
54#define PHY_POLL_LINK_ON (10 * HZ) 57#define PHY_POLL_LINK_ON (10 * HZ)
55#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5) 58#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
56 59
@@ -63,6 +66,7 @@ struct xgene_enet_desc_ring {
63 u16 tail; 66 u16 tail;
64 u16 slots; 67 u16 slots;
65 u16 irq; 68 u16 irq;
69 char irq_name[IRQ_ID_SIZE];
66 u32 size; 70 u32 size;
67 u32 state[NUM_RING_CONFIG]; 71 u32 state[NUM_RING_CONFIG];
68 void __iomem *cmd_base; 72 void __iomem *cmd_base;
@@ -117,6 +121,8 @@ struct xgene_enet_pdata {
117 u32 cp_qcnt_hi; 121 u32 cp_qcnt_hi;
118 u32 cp_qcnt_low; 122 u32 cp_qcnt_low;
119 u32 rx_irq; 123 u32 rx_irq;
124 u32 txc_irq;
125 u8 cq_cnt;
120 void __iomem *eth_csr_addr; 126 void __iomem *eth_csr_addr;
121 void __iomem *eth_ring_if_addr; 127 void __iomem *eth_ring_if_addr;
122 void __iomem *eth_diag_csr_addr; 128 void __iomem *eth_diag_csr_addr;