diff options
author | David S. Miller <davem@davemloft.net> | 2015-03-18 19:44:13 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-18 19:44:13 +0300 |
commit | a61bfa65facebd64403c94ebdab50323ce8942b2 (patch) | |
tree | 50c2fbf77074eeb0bfbd24879c2d5b71a23b4766 | |
parent | e7a9eee53cf10cb32fb28ccaacfa98a6220b7276 (diff) | |
parent | ca6264545a9ffa855e8c49c1d7d8f4ab4b2a9af7 (diff) | |
download | linux-a61bfa65facebd64403c94ebdab50323ce8942b2.tar.xz |
Merge branch 'xgene-next'
Keyur Chudgar says:
====================
drivers: net: xgene: Add second SGMII based 1G interface
This patch adds support for second SGMII based 1G interface.
====================
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 2 | ||||
-rw-r--r-- | arch/arm64/boot/dts/apm/apm-mustang.dts | 4 | ||||
-rw-r--r-- | arch/arm64/boot/dts/apm/apm-storm.dtsi | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 10 |
7 files changed, 98 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt index 6151999c5dca..dc7961b33076 100644 --- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt @@ -15,6 +15,7 @@ Required properties for all the ethernet interfaces: - "ring_csr": Descriptor ring control and status register address space - "ring_cmd": Descriptor ring command register address space - interrupts: Ethernet main interrupt +- port-id: Port number (0 or 1) - clocks: Reference to the clock entry. - local-mac-address: MAC address assigned to this device - phy-connection-type: Interface type between ethernet device and PHY device @@ -49,6 +50,7 @@ Example: <0x0 0X10000000 0x0 0X200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x3c 0x4>; + port-id = <0>; clocks = <&menetclk 0>; local-mac-address = [00 01 73 00 00 01]; phy-connection-type = "rgmii"; diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts index 2e25de0800b9..83578e766b94 100644 --- a/arch/arm64/boot/dts/apm/apm-mustang.dts +++ b/arch/arm64/boot/dts/apm/apm-mustang.dts @@ -45,6 +45,10 @@ status = "ok"; }; +&sgenet1 { + status = "ok"; +}; + &xgenet { status = "ok"; }; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index a857794432d6..c1eb6911e539 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -186,6 +186,16 @@ clock-output-names = "sge0clk"; }; + sge1clk: sge1clk@1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + csr-mask = <0xc>; + clock-output-names = "sge1clk"; + }; + xge0clk: xge0clk@1f61c000 { compatible = "apm,xgene-device-clock"; #clock-cells = <1>; @@ -635,6 +645,21 @@ phy-connection-type = "sgmii"; }; + sgenet1: ethernet@1f210030 { + compatible = "apm,xgene1-sgenet"; + status = "disabled"; + reg = <0x0 0x1f210030 0x0 0xd100>, + <0x0 0x1f200000 0x0 0Xc300>, + <0x0 0x1B000000 0x0 0X8000>; + reg-names = "enet_csr", "ring_csr", "ring_cmd"; + interrupts = <0x0 0xAC 0x4>; + port-id = <1>; + dma-coherent; + clocks = <&sge1clk 0>; + local-mac-address = [00 00 00 00 00 00]; + phy-connection-type = "sgmii"; + }; + xgenet: ethernet@1f610000 { compatible = "apm,xgene1-xgenet"; status = "disabled"; diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index ec45f3256f0e..d9bc89d69266 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h @@ -97,6 +97,8 @@ enum xgene_enet_rm { #define QCOHERENT BIT(4) #define RECOMBBUF BIT(27) +#define MAC_OFFSET 0x30 + #define BLOCK_ETH_CSR_OFFSET 0x2000 #define BLOCK_ETH_RING_IF_OFFSET 0x9000 #define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000 diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index edb843650eed..6146a993a136 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -645,9 +645,11 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev) struct device *dev = ndev_to_dev(ndev); struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring; struct xgene_enet_desc_ring *buf_pool = NULL; - u8 cpu_bufnum = 0, eth_bufnum = START_ETH_BUFNUM; - u8 bp_bufnum = START_BP_BUFNUM; - u16 ring_id, ring_num = START_RING_NUM; + u8 cpu_bufnum = pdata->cpu_bufnum; + u8 eth_bufnum = pdata->eth_bufnum; + u8 bp_bufnum = pdata->bp_bufnum; + u16 ring_num = pdata->ring_num; + u16 ring_id; int ret; /* allocate rx descriptor ring */ @@ -752,6 +754,22 @@ static const struct net_device_ops xgene_ndev_ops = { .ndo_set_mac_address = xgene_enet_set_mac_address, }; +static int xgene_get_port_id(struct device *dev, struct xgene_enet_pdata *pdata) +{ + u32 id = 0; + int ret; + + ret = device_property_read_u32(dev, "port-id", &id); + if (!ret && id > 1) { + dev_err(dev, "Incorrect port-id specified\n"); + return -ENODEV; + } + + pdata->port_id = id; + + return 0; +} + static int xgene_get_mac_address(struct device *dev, unsigned char *addr) { @@ -843,6 +861,10 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) } pdata->rx_irq = ret; + ret = xgene_get_port_id(dev, pdata); + if (ret) + return ret; + if (xgene_get_mac_address(dev, ndev->dev_addr) != ETH_ALEN) eth_hw_addr_random(ndev); @@ -866,13 +888,13 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) pdata->clk = NULL; } - base_addr = pdata->base_addr; + base_addr = pdata->base_addr - (pdata->port_id * MAC_OFFSET); pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET; pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET; pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET; if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII || pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) { - pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET; + pdata->mcx_mac_addr = pdata->base_addr + BLOCK_ETH_MAC_OFFSET; pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET; } else { pdata->mcx_mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET; @@ -935,6 +957,24 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata) pdata->rm = RM0; break; } + + switch (pdata->port_id) { + case 0: + pdata->cpu_bufnum = START_CPU_BUFNUM_0; + pdata->eth_bufnum = START_ETH_BUFNUM_0; + pdata->bp_bufnum = START_BP_BUFNUM_0; + pdata->ring_num = START_RING_NUM_0; + break; + case 1: + pdata->cpu_bufnum = START_CPU_BUFNUM_1; + pdata->eth_bufnum = START_ETH_BUFNUM_1; + pdata->bp_bufnum = START_BP_BUFNUM_1; + pdata->ring_num = START_RING_NUM_1; + break; + default: + break; + } + } static int xgene_enet_probe(struct platform_device *pdev) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h index c2d465c3db66..b93ed21a157f 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h @@ -41,9 +41,15 @@ #define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN) #define NUM_PKT_BUF 64 #define NUM_BUFPOOL 32 -#define START_ETH_BUFNUM 2 -#define START_BP_BUFNUM 0x22 -#define START_RING_NUM 8 + +#define START_CPU_BUFNUM_0 0 +#define START_ETH_BUFNUM_0 2 +#define START_BP_BUFNUM_0 0x22 +#define START_RING_NUM_0 8 +#define START_CPU_BUFNUM_1 12 +#define START_ETH_BUFNUM_1 10 +#define START_BP_BUFNUM_1 0x2A +#define START_RING_NUM_1 264 #define PHY_POLL_LINK_ON (10 * HZ) #define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5) @@ -125,6 +131,11 @@ struct xgene_enet_pdata { struct xgene_mac_ops *mac_ops; struct xgene_port_ops *port_ops; struct delayed_work link_work; + u32 port_id; + u8 cpu_bufnum; + u8 eth_bufnum; + u8 bp_bufnum; + u16 ring_num; }; struct xgene_indirect_ctl { diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c index f5d4f68c288c..f27fb6f2a93b 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c @@ -226,6 +226,7 @@ static u32 xgene_enet_link_status(struct xgene_enet_pdata *p) static void xgene_sgmac_init(struct xgene_enet_pdata *p) { u32 data, loop = 10; + u32 offset = p->port_id * 4; xgene_sgmac_reset(p); @@ -272,9 +273,9 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p) xgene_enet_wr_csr(p, RSIF_RAM_DBG_REG0_ADDR, 0); /* Bypass traffic gating */ - xgene_enet_wr_csr(p, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); + xgene_enet_wr_csr(p, CFG_LINK_AGGR_RESUME_0_ADDR + offset, TX_PORT0); xgene_enet_wr_csr(p, CFG_BYPASS_ADDR, RESUME_TX); - xgene_enet_wr_csr(p, SG_RX_DV_GATE_REG_0_ADDR, RESUME_RX0); + xgene_enet_wr_csr(p, SG_RX_DV_GATE_REG_0_ADDR + offset, RESUME_RX0); } static void xgene_sgmac_rxtx(struct xgene_enet_pdata *p, u32 bits, bool set) @@ -330,13 +331,14 @@ static void xgene_enet_cle_bypass(struct xgene_enet_pdata *p, u32 dst_ring_num, u16 bufpool_id) { u32 data, fpsel; + u32 offset = p->port_id * MAC_OFFSET; data = CFG_CLE_BYPASS_EN0; - xgene_enet_wr_csr(p, CLE_BYPASS_REG0_0_ADDR, data); + xgene_enet_wr_csr(p, CLE_BYPASS_REG0_0_ADDR + offset, data); fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; data = CFG_CLE_DSTQID0(dst_ring_num) | CFG_CLE_FPSEL0(fpsel); - xgene_enet_wr_csr(p, CLE_BYPASS_REG1_0_ADDR, data); + xgene_enet_wr_csr(p, CLE_BYPASS_REG1_0_ADDR + offset, data); } static void xgene_enet_shutdown(struct xgene_enet_pdata *p) |