diff options
author | Iyappan Subramanian <isubramanian@apm.com> | 2015-03-25 15:19:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-27 17:18:48 -0400 |
commit | 6772b653f8c2fd0a54a23da28a0a761685deec85 (patch) | |
tree | 5d9c988da6042571368ec71b383a83cdc2c597d2 /drivers/net/ethernet/apm | |
parent | d31346494bd2b1185949dc64ab6467186b80fb05 (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.c | 141 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 6 |
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 | |||
468 | static 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 | |||
481 | static 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 | ||
453 | static int xgene_enet_open(struct net_device *ndev) | 494 | static 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 | ||
1056 | static 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 | |||
1070 | static 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 | |||
980 | static int xgene_enet_probe(struct platform_device *pdev) | 1083 | static 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; |