aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/apm
diff options
context:
space:
mode:
authorIyappan Subramanian <isubramanian@apm.com>2015-04-28 16:52:39 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-30 16:03:13 -0400
commitbc1b7c132a09d84a22e1a15a76d2eb6eb916d217 (patch)
treed3e4567b44beed1bd76e1298e548739b2d27e683 /drivers/net/ethernet/apm
parented9b7da019ea01dcead9f1d231bf03ab033f5f9c (diff)
drivers: net: xgene: Add 10GbE support with ring manager v2
Signed-off-by: Iyappan Subramanian <isubramanian@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_hw.h1
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c141
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.h17
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c1
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h17
5 files changed, 152 insertions, 25 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 1dbc10a63458..5176fcb9f413 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -102,6 +102,7 @@ enum xgene_enet_rm {
102 102
103#define BLOCK_ETH_CSR_OFFSET 0x2000 103#define BLOCK_ETH_CSR_OFFSET 0x2000
104#define BLOCK_ETH_RING_IF_OFFSET 0x9000 104#define BLOCK_ETH_RING_IF_OFFSET 0x9000
105#define BLOCK_ETH_CLKRST_CSR_OFFSET 0xc000
105#define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000 106#define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000
106 107
107#define BLOCK_ETH_MAC_OFFSET 0x0000 108#define BLOCK_ETH_MAC_OFFSET 0x0000
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index b3bbc6872bd5..513bfa4fb790 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -28,6 +28,8 @@
28#define RES_RING_CSR 1 28#define RES_RING_CSR 1
29#define RES_RING_CMD 2 29#define RES_RING_CMD 2
30 30
31static const struct of_device_id xgene_enet_of_match[];
32
31static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool) 33static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
32{ 34{
33 struct xgene_enet_raw_desc16 *raw_desc; 35 struct xgene_enet_raw_desc16 *raw_desc;
@@ -632,6 +634,25 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
632 } 634 }
633} 635}
634 636
637static bool is_irq_mbox_required(struct xgene_enet_pdata *pdata,
638 struct xgene_enet_desc_ring *ring)
639{
640 if ((pdata->enet_id == XGENE_ENET2) &&
641 (xgene_enet_ring_owner(ring->id) == RING_OWNER_CPU)) {
642 return true;
643 }
644
645 return false;
646}
647
648static void __iomem *xgene_enet_ring_cmd_base(struct xgene_enet_pdata *pdata,
649 struct xgene_enet_desc_ring *ring)
650{
651 u8 num_ring_id_shift = pdata->ring_ops->num_ring_id_shift;
652
653 return pdata->ring_cmd_addr + (ring->num << num_ring_id_shift);
654}
655
635static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( 656static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
636 struct net_device *ndev, u32 ring_num, 657 struct net_device *ndev, u32 ring_num,
637 enum xgene_enet_ring_cfgsize cfgsize, u32 ring_id) 658 enum xgene_enet_ring_cfgsize cfgsize, u32 ring_id)
@@ -663,7 +684,18 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
663 } 684 }
664 ring->size = size; 685 ring->size = size;
665 686
666 ring->cmd_base = pdata->ring_cmd_addr + (ring->num << 6); 687 if (is_irq_mbox_required(pdata, ring)) {
688 ring->irq_mbox_addr = dma_zalloc_coherent(dev, INTR_MBOX_SIZE,
689 &ring->irq_mbox_dma, GFP_KERNEL);
690 if (!ring->irq_mbox_addr) {
691 dma_free_coherent(dev, size, ring->desc_addr,
692 ring->dma);
693 devm_kfree(dev, ring);
694 return NULL;
695 }
696 }
697
698 ring->cmd_base = xgene_enet_ring_cmd_base(pdata, ring);
667 ring->cmd = ring->cmd_base + INC_DEC_CMD_ADDR; 699 ring->cmd = ring->cmd_base + INC_DEC_CMD_ADDR;
668 ring = pdata->ring_ops->setup(ring); 700 ring = pdata->ring_ops->setup(ring);
669 netdev_dbg(ndev, "ring info: num=%d size=%d id=%d slots=%d\n", 701 netdev_dbg(ndev, "ring info: num=%d size=%d id=%d slots=%d\n",
@@ -677,12 +709,34 @@ static u16 xgene_enet_get_ring_id(enum xgene_ring_owner owner, u8 bufnum)
677 return (owner << 6) | (bufnum & GENMASK(5, 0)); 709 return (owner << 6) | (bufnum & GENMASK(5, 0));
678} 710}
679 711
712static enum xgene_ring_owner xgene_derive_ring_owner(struct xgene_enet_pdata *p)
713{
714 enum xgene_ring_owner owner;
715
716 if (p->enet_id == XGENE_ENET1) {
717 switch (p->phy_mode) {
718 case PHY_INTERFACE_MODE_SGMII:
719 owner = RING_OWNER_ETH0;
720 break;
721 default:
722 owner = (!p->port_id) ? RING_OWNER_ETH0 :
723 RING_OWNER_ETH1;
724 break;
725 }
726 } else {
727 owner = (!p->port_id) ? RING_OWNER_ETH0 : RING_OWNER_ETH1;
728 }
729
730 return owner;
731}
732
680static int xgene_enet_create_desc_rings(struct net_device *ndev) 733static int xgene_enet_create_desc_rings(struct net_device *ndev)
681{ 734{
682 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 735 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
683 struct device *dev = ndev_to_dev(ndev); 736 struct device *dev = ndev_to_dev(ndev);
684 struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring; 737 struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring;
685 struct xgene_enet_desc_ring *buf_pool = NULL; 738 struct xgene_enet_desc_ring *buf_pool = NULL;
739 enum xgene_ring_owner owner;
686 u8 cpu_bufnum = pdata->cpu_bufnum; 740 u8 cpu_bufnum = pdata->cpu_bufnum;
687 u8 eth_bufnum = pdata->eth_bufnum; 741 u8 eth_bufnum = pdata->eth_bufnum;
688 u8 bp_bufnum = pdata->bp_bufnum; 742 u8 bp_bufnum = pdata->bp_bufnum;
@@ -691,6 +745,7 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
691 int ret; 745 int ret;
692 746
693 /* allocate rx descriptor ring */ 747 /* allocate rx descriptor ring */
748 owner = xgene_derive_ring_owner(pdata);
694 ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++); 749 ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
695 rx_ring = xgene_enet_create_desc_ring(ndev, ring_num++, 750 rx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
696 RING_CFGSIZE_16KB, ring_id); 751 RING_CFGSIZE_16KB, ring_id);
@@ -700,7 +755,8 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
700 } 755 }
701 756
702 /* allocate buffer pool for receiving packets */ 757 /* allocate buffer pool for receiving packets */
703 ring_id = xgene_enet_get_ring_id(RING_OWNER_ETH0, bp_bufnum++); 758 owner = xgene_derive_ring_owner(pdata);
759 ring_id = xgene_enet_get_ring_id(owner, bp_bufnum++);
704 buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++, 760 buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++,
705 RING_CFGSIZE_2KB, ring_id); 761 RING_CFGSIZE_2KB, ring_id);
706 if (!buf_pool) { 762 if (!buf_pool) {
@@ -729,7 +785,8 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
729 pdata->rx_ring = rx_ring; 785 pdata->rx_ring = rx_ring;
730 786
731 /* allocate tx descriptor ring */ 787 /* allocate tx descriptor ring */
732 ring_id = xgene_enet_get_ring_id(RING_OWNER_ETH0, eth_bufnum++); 788 owner = xgene_derive_ring_owner(pdata);
789 ring_id = xgene_enet_get_ring_id(owner, eth_bufnum++);
733 tx_ring = xgene_enet_create_desc_ring(ndev, ring_num++, 790 tx_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
734 RING_CFGSIZE_16KB, ring_id); 791 RING_CFGSIZE_16KB, ring_id);
735 if (!tx_ring) { 792 if (!tx_ring) {
@@ -957,7 +1014,10 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
957 pdata->clk = NULL; 1014 pdata->clk = NULL;
958 } 1015 }
959 1016
960 base_addr = pdata->base_addr - (pdata->port_id * MAC_OFFSET); 1017 if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
1018 base_addr = pdata->base_addr - (pdata->port_id * MAC_OFFSET);
1019 else
1020 base_addr = pdata->base_addr;
961 pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET; 1021 pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET;
962 pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET; 1022 pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET;
963 pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET; 1023 pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET;
@@ -1029,24 +1089,44 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
1029 break; 1089 break;
1030 } 1090 }
1031 1091
1032 switch (pdata->port_id) { 1092 if (pdata->enet_id == XGENE_ENET1) {
1033 case 0: 1093 switch (pdata->port_id) {
1034 pdata->cpu_bufnum = START_CPU_BUFNUM_0; 1094 case 0:
1035 pdata->eth_bufnum = START_ETH_BUFNUM_0; 1095 pdata->cpu_bufnum = START_CPU_BUFNUM_0;
1036 pdata->bp_bufnum = START_BP_BUFNUM_0; 1096 pdata->eth_bufnum = START_ETH_BUFNUM_0;
1037 pdata->ring_num = START_RING_NUM_0; 1097 pdata->bp_bufnum = START_BP_BUFNUM_0;
1038 break; 1098 pdata->ring_num = START_RING_NUM_0;
1039 case 1: 1099 break;
1040 pdata->cpu_bufnum = START_CPU_BUFNUM_1; 1100 case 1:
1041 pdata->eth_bufnum = START_ETH_BUFNUM_1; 1101 pdata->cpu_bufnum = START_CPU_BUFNUM_1;
1042 pdata->bp_bufnum = START_BP_BUFNUM_1; 1102 pdata->eth_bufnum = START_ETH_BUFNUM_1;
1043 pdata->ring_num = START_RING_NUM_1; 1103 pdata->bp_bufnum = START_BP_BUFNUM_1;
1044 break; 1104 pdata->ring_num = START_RING_NUM_1;
1045 default: 1105 break;
1046 break; 1106 default:
1107 break;
1108 }
1109 pdata->ring_ops = &xgene_ring1_ops;
1110 } else {
1111 switch (pdata->port_id) {
1112 case 0:
1113 pdata->cpu_bufnum = X2_START_CPU_BUFNUM_0;
1114 pdata->eth_bufnum = X2_START_ETH_BUFNUM_0;
1115 pdata->bp_bufnum = X2_START_BP_BUFNUM_0;
1116 pdata->ring_num = X2_START_RING_NUM_0;
1117 break;
1118 case 1:
1119 pdata->cpu_bufnum = X2_START_CPU_BUFNUM_1;
1120 pdata->eth_bufnum = X2_START_ETH_BUFNUM_1;
1121 pdata->bp_bufnum = X2_START_BP_BUFNUM_1;
1122 pdata->ring_num = X2_START_RING_NUM_1;
1123 break;
1124 default:
1125 break;
1126 }
1127 pdata->rm = RM0;
1128 pdata->ring_ops = &xgene_ring2_ops;
1047 } 1129 }
1048
1049 pdata->ring_ops = &xgene_ring1_ops;
1050} 1130}
1051 1131
1052static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata) 1132static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
@@ -1082,6 +1162,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
1082 struct xgene_enet_pdata *pdata; 1162 struct xgene_enet_pdata *pdata;
1083 struct device *dev = &pdev->dev; 1163 struct device *dev = &pdev->dev;
1084 struct xgene_mac_ops *mac_ops; 1164 struct xgene_mac_ops *mac_ops;
1165 const struct of_device_id *of_id;
1085 int ret; 1166 int ret;
1086 1167
1087 ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata)); 1168 ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata));
@@ -1100,6 +1181,17 @@ static int xgene_enet_probe(struct platform_device *pdev)
1100 NETIF_F_GSO | 1181 NETIF_F_GSO |
1101 NETIF_F_GRO; 1182 NETIF_F_GRO;
1102 1183
1184#ifdef CONFIG_OF
1185 of_id = of_match_device(xgene_enet_of_match, &pdev->dev);
1186 if (of_id) {
1187 pdata->enet_id = (enum xgene_enet_id)of_id->data;
1188 if (!pdata->enet_id) {
1189 free_netdev(ndev);
1190 return -ENODEV;
1191 }
1192 }
1193#endif
1194
1103 ret = xgene_enet_get_resources(pdata); 1195 ret = xgene_enet_get_resources(pdata);
1104 if (ret) 1196 if (ret)
1105 goto err; 1197 goto err;
@@ -1171,9 +1263,10 @@ MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
1171 1263
1172#ifdef CONFIG_OF 1264#ifdef CONFIG_OF
1173static const struct of_device_id xgene_enet_of_match[] = { 1265static const struct of_device_id xgene_enet_of_match[] = {
1174 {.compatible = "apm,xgene-enet",}, 1266 {.compatible = "apm,xgene-enet", .data = (void *)XGENE_ENET1},
1175 {.compatible = "apm,xgene1-sgenet",}, 1267 {.compatible = "apm,xgene1-sgenet", .data = (void *)XGENE_ENET1},
1176 {.compatible = "apm,xgene1-xgenet",}, 1268 {.compatible = "apm,xgene1-xgenet", .data = (void *)XGENE_ENET1},
1269 {.compatible = "apm,xgene2-xgenet", .data = (void *)XGENE_ENET2},
1177 {}, 1270 {},
1178}; 1271};
1179 1272
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index a44f4a3e9388..ef1887be9428 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -35,6 +35,7 @@
35#include <linux/if_vlan.h> 35#include <linux/if_vlan.h>
36#include <linux/phy.h> 36#include <linux/phy.h>
37#include "xgene_enet_hw.h" 37#include "xgene_enet_hw.h"
38#include "xgene_enet_ring2.h"
38 39
39#define XGENE_DRV_VERSION "v1.0" 40#define XGENE_DRV_VERSION "v1.0"
40#define XGENE_ENET_MAX_MTU 1536 41#define XGENE_ENET_MAX_MTU 1536
@@ -51,12 +52,27 @@
51#define START_BP_BUFNUM_1 0x2A 52#define START_BP_BUFNUM_1 0x2A
52#define START_RING_NUM_1 264 53#define START_RING_NUM_1 264
53 54
55#define X2_START_CPU_BUFNUM_0 0
56#define X2_START_ETH_BUFNUM_0 0
57#define X2_START_BP_BUFNUM_0 0x20
58#define X2_START_RING_NUM_0 0
59
60#define X2_START_CPU_BUFNUM_1 0xc
61#define X2_START_ETH_BUFNUM_1 0
62#define X2_START_BP_BUFNUM_1 0x20
63#define X2_START_RING_NUM_1 256
64
54#define IRQ_ID_SIZE 16 65#define IRQ_ID_SIZE 16
55#define XGENE_MAX_TXC_RINGS 1 66#define XGENE_MAX_TXC_RINGS 1
56 67
57#define PHY_POLL_LINK_ON (10 * HZ) 68#define PHY_POLL_LINK_ON (10 * HZ)
58#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5) 69#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
59 70
71enum xgene_enet_id {
72 XGENE_ENET1 = 1,
73 XGENE_ENET2
74};
75
60/* software context of a descriptor ring */ 76/* software context of a descriptor ring */
61struct xgene_enet_desc_ring { 77struct xgene_enet_desc_ring {
62 struct net_device *ndev; 78 struct net_device *ndev;
@@ -124,6 +140,7 @@ struct xgene_enet_pdata {
124 int phy_speed; 140 int phy_speed;
125 struct clk *clk; 141 struct clk *clk;
126 struct platform_device *pdev; 142 struct platform_device *pdev;
143 enum xgene_enet_id enet_id;
127 struct xgene_enet_desc_ring *tx_ring; 144 struct xgene_enet_desc_ring *tx_ring;
128 struct xgene_enet_desc_ring *rx_ring; 145 struct xgene_enet_desc_ring *rx_ring;
129 char *dev_name; 146 char *dev_name;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index a18a9d1f1143..27ba2fe3fca6 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -122,7 +122,6 @@ static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
122 122
123 return true; 123 return true;
124} 124}
125
126static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata, 125static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
127 u32 rd_addr, u32 *rd_data) 126 u32 rd_addr, u32 *rd_data)
128{ 127{
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index 5a5296a6d1df..d07ee5ea3046 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -24,6 +24,23 @@
24#define BLOCK_AXG_MAC_OFFSET 0x0800 24#define BLOCK_AXG_MAC_OFFSET 0x0800
25#define BLOCK_AXG_MAC_CSR_OFFSET 0x2000 25#define BLOCK_AXG_MAC_CSR_OFFSET 0x2000
26 26
27#define XGENET_SRST_ADDR 0x0000
28#define XGENET_CLKEN_ADDR 0x0008
29
30#define CSR_CLK BIT(0)
31#define XGENET_CLK BIT(1)
32#define PCS_CLK BIT(3)
33#define AN_REF_CLK BIT(4)
34#define AN_CLK BIT(5)
35#define AD_CLK BIT(6)
36
37#define CSR_RST BIT(0)
38#define XGENET_RST BIT(1)
39#define PCS_RST BIT(3)
40#define AN_REF_RST BIT(4)
41#define AN_RST BIT(5)
42#define AD_RST BIT(6)
43
27#define AXGMAC_CONFIG_0 0x0000 44#define AXGMAC_CONFIG_0 0x0000
28#define AXGMAC_CONFIG_1 0x0004 45#define AXGMAC_CONFIG_1 0x0004
29#define HSTMACRST BIT(31) 46#define HSTMACRST BIT(31)