* [PATCH net-next v1 0/3] drivers: net: xgene: Add separate tx completion ring
@ 2015-03-25 19:19 ` Iyappan Subramanian
0 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: davem, netdev, devicetree
Cc: linux-arm-kernel, kchudgar, patches, Iyappan Subramanian
SGMII based 1GbE and 10GbE interfaces support multiple interrupts.
Adding separate tx completion descriptor ring and associating a dedicated irq for the TX completion.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
Iyappan Subramanian (3):
Documentation: dts: xgene: Update interrupt field description
dtb: xgene: Add interrupt for Tx completion
drivers: net: xgene: Add separate tx completion ring
.../devicetree/bindings/net/apm-xgene-enet.txt | 5 +-
arch/arm64/boot/dts/apm/apm-storm.dtsi | 9 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 141 ++++++++++++++++++---
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 6 +
4 files changed, 137 insertions(+), 24 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v1 0/3] drivers: net: xgene: Add separate tx completion ring
@ 2015-03-25 19:19 ` Iyappan Subramanian
0 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: linux-arm-kernel
SGMII based 1GbE and 10GbE interfaces support multiple interrupts.
Adding separate tx completion descriptor ring and associating a dedicated irq for the TX completion.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
Iyappan Subramanian (3):
Documentation: dts: xgene: Update interrupt field description
dtb: xgene: Add interrupt for Tx completion
drivers: net: xgene: Add separate tx completion ring
.../devicetree/bindings/net/apm-xgene-enet.txt | 5 +-
arch/arm64/boot/dts/apm/apm-storm.dtsi | 9 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 141 ++++++++++++++++++---
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 6 +
4 files changed, 137 insertions(+), 24 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v1 1/3] Documentation: dts: xgene: Update interrupt field description
2015-03-25 19:19 ` Iyappan Subramanian
@ 2015-03-25 19:19 ` Iyappan Subramanian
-1 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: davem, netdev, devicetree
Cc: linux-arm-kernel, kchudgar, patches, Iyappan Subramanian
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
index dc7961b..f55aa28 100644
--- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
+++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
@@ -14,7 +14,10 @@ Required properties for all the ethernet interfaces:
- "enet_csr": Ethernet control and status register address space
- "ring_csr": Descriptor ring control and status register address space
- "ring_cmd": Descriptor ring command register address space
-- interrupts: Ethernet main interrupt
+- interrupts: Two interrupt specifiers can be specified.
+ - First is the Rx interrupt. This irq is mandatory.
+ - Second is the Tx completion interrupt.
+ This is supported only on SGMII based 1GbE and 10GbE interfaces.
- port-id: Port number (0 or 1)
- clocks: Reference to the clock entry.
- local-mac-address: MAC address assigned to this device
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v1 1/3] Documentation: dts: xgene: Update interrupt field description
@ 2015-03-25 19:19 ` Iyappan Subramanian
0 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
index dc7961b..f55aa28 100644
--- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
+++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
@@ -14,7 +14,10 @@ Required properties for all the ethernet interfaces:
- "enet_csr": Ethernet control and status register address space
- "ring_csr": Descriptor ring control and status register address space
- "ring_cmd": Descriptor ring command register address space
-- interrupts: Ethernet main interrupt
+- interrupts: Two interrupt specifiers can be specified.
+ - First is the Rx interrupt. This irq is mandatory.
+ - Second is the Tx completion interrupt.
+ This is supported only on SGMII based 1GbE and 10GbE interfaces.
- port-id: Port number (0 or 1)
- clocks: Reference to the clock entry.
- local-mac-address: MAC address assigned to this device
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v1 2/3] dtb: xgene: Add interrupt for Tx completion
2015-03-25 19:19 ` Iyappan Subramanian
@ 2015-03-25 19:19 ` Iyappan Subramanian
-1 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: davem, netdev, devicetree
Cc: linux-arm-kernel, kchudgar, patches, Iyappan Subramanian
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm/apm-storm.dtsi | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index c1eb691..e74f6e0 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -638,7 +638,8 @@
<0x0 0x1f200000 0x0 0Xc300>,
<0x0 0x1B000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0xA0 0x4>;
+ interrupts = <0x0 0xA0 0x4>,
+ <0x0 0xA1 0x4>;
dma-coherent;
clocks = <&sge0clk 0>;
local-mac-address = [00 00 00 00 00 00];
@@ -652,7 +653,8 @@
<0x0 0x1f200000 0x0 0Xc300>,
<0x0 0x1B000000 0x0 0X8000>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0xAC 0x4>;
+ interrupts = <0x0 0xAC 0x4>,
+ <0x0 0xAD 0x4>;
port-id = <1>;
dma-coherent;
clocks = <&sge1clk 0>;
@@ -667,7 +669,8 @@
<0x0 0x1f600000 0x0 0Xc300>,
<0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0x60 0x4>;
+ interrupts = <0x0 0x60 0x4>,
+ <0x0 0x61 0x4>;
dma-coherent;
clocks = <&xge0clk 0>;
/* mac address will be overwritten by the bootloader */
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v1 2/3] dtb: xgene: Add interrupt for Tx completion
@ 2015-03-25 19:19 ` Iyappan Subramanian
0 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm/apm-storm.dtsi | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index c1eb691..e74f6e0 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -638,7 +638,8 @@
<0x0 0x1f200000 0x0 0Xc300>,
<0x0 0x1B000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0xA0 0x4>;
+ interrupts = <0x0 0xA0 0x4>,
+ <0x0 0xA1 0x4>;
dma-coherent;
clocks = <&sge0clk 0>;
local-mac-address = [00 00 00 00 00 00];
@@ -652,7 +653,8 @@
<0x0 0x1f200000 0x0 0Xc300>,
<0x0 0x1B000000 0x0 0X8000>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0xAC 0x4>;
+ interrupts = <0x0 0xAC 0x4>,
+ <0x0 0xAD 0x4>;
port-id = <1>;
dma-coherent;
clocks = <&sge1clk 0>;
@@ -667,7 +669,8 @@
<0x0 0x1f600000 0x0 0Xc300>,
<0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
- interrupts = <0x0 0x60 0x4>;
+ interrupts = <0x0 0x60 0x4>,
+ <0x0 0x61 0x4>;
dma-coherent;
clocks = <&xge0clk 0>;
/* mac address will be overwritten by the bootloader */
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v1 3/3] drivers: net: xgene: Add separate tx completion ring
2015-03-25 19:19 ` Iyappan Subramanian
@ 2015-03-25 19:19 ` Iyappan Subramanian
-1 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
kchudgar-qTEPVZfXA3Y, patches-qTEPVZfXA3Y, Iyappan Subramanian
- 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-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
---
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 141 +++++++++++++++++++----
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 6146a993..40d3530 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)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct device *dev = ndev_to_dev(ndev);
+ struct xgene_enet_desc_ring *ring;
int ret;
- ret = devm_request_irq(dev, pdata->rx_ring->irq, xgene_enet_rx_irq,
- IRQF_SHARED, ndev->name, pdata->rx_ring);
- if (ret) {
- netdev_err(ndev, "rx%d interrupt request failed\n",
- pdata->rx_ring->irq);
+ ring = pdata->rx_ring;
+ ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+ IRQF_SHARED, ring->irq_name, ring);
+ if (ret)
+ netdev_err(ndev, "Failed to request irq %s\n", ring->irq_name);
+
+ if (pdata->cq_cnt) {
+ ring = pdata->tx_ring->cp_ring;
+ ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+ IRQF_SHARED, ring->irq_name, ring);
+ if (ret) {
+ netdev_err(ndev, "Failed to request irq %s\n",
+ ring->irq_name);
+ }
}
return ret;
@@ -448,6 +458,37 @@ static void xgene_enet_free_irq(struct net_device *ndev)
pdata = netdev_priv(ndev);
dev = ndev_to_dev(ndev);
devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring);
+
+ if (pdata->cq_cnt) {
+ devm_free_irq(dev, pdata->tx_ring->cp_ring->irq,
+ pdata->tx_ring->cp_ring);
+ }
+}
+
+static void xgene_enet_napi_enable(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ napi_enable(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ napi_enable(napi);
+ }
+}
+
+static void xgene_enet_napi_disable(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ napi_disable(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ napi_disable(napi);
+ }
}
static int xgene_enet_open(struct net_device *ndev)
@@ -462,7 +503,7 @@ static int xgene_enet_open(struct net_device *ndev)
ret = xgene_enet_register_irq(ndev);
if (ret)
return ret;
- napi_enable(&pdata->rx_ring->napi);
+ xgene_enet_napi_enable(pdata);
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
phy_start(pdata->phy_dev);
@@ -486,7 +527,7 @@ static int xgene_enet_close(struct net_device *ndev)
else
cancel_delayed_work_sync(&pdata->link_work);
- napi_disable(&pdata->rx_ring->napi);
+ xgene_enet_napi_disable(pdata);
xgene_enet_free_irq(ndev);
xgene_enet_process_ring(pdata->rx_ring, -1);
@@ -580,6 +621,8 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
if (ring) {
if (ring->cp_ring && ring->cp_ring->cp_skb)
devm_kfree(dev, ring->cp_ring->cp_skb);
+ if (ring->cp_ring && pdata->cq_cnt)
+ xgene_enet_free_desc_ring(ring->cp_ring);
xgene_enet_free_desc_ring(ring);
}
@@ -673,6 +716,12 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
rx_ring->nbufpool = NUM_BUFPOOL;
rx_ring->buf_pool = buf_pool;
rx_ring->irq = pdata->rx_irq;
+ if (!pdata->cq_cnt) {
+ snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
+ ndev->name);
+ } else {
+ snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx", ndev->name);
+ }
buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
sizeof(struct sk_buff *), GFP_KERNEL);
if (!buf_pool->rx_skb) {
@@ -694,7 +743,22 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
}
pdata->tx_ring = tx_ring;
- cp_ring = pdata->rx_ring;
+ if (!pdata->cq_cnt) {
+ cp_ring = pdata->rx_ring;
+ } else {
+ /* allocate tx completion descriptor ring */
+ ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
+ cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+ RING_CFGSIZE_16KB,
+ ring_id);
+ if (!cp_ring) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ cp_ring->irq = pdata->txc_irq;
+ snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc", ndev->name);
+ }
+
cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
sizeof(struct sk_buff *), GFP_KERNEL);
if (!cp_ring->cp_skb) {
@@ -853,14 +917,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return -ENOMEM;
}
- ret = platform_get_irq(pdev, 0);
- if (ret <= 0) {
- dev_err(dev, "Unable to get ENET Rx IRQ\n");
- ret = ret ? : -ENXIO;
- return ret;
- }
- pdata->rx_irq = ret;
-
ret = xgene_get_port_id(dev, pdata);
if (ret)
return ret;
@@ -882,6 +938,24 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return -ENODEV;
}
+ ret = platform_get_irq(pdev, 0);
+ if (ret <= 0) {
+ dev_err(dev, "Unable to get ENET Rx IRQ\n");
+ ret = ret ? : -ENXIO;
+ return ret;
+ }
+ pdata->rx_irq = ret;
+
+ if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII) {
+ ret = platform_get_irq(pdev, 1);
+ if (ret <= 0) {
+ dev_err(dev, "Unable to get ENET Tx completion IRQ\n");
+ ret = ret ? : -ENXIO;
+ return ret;
+ }
+ pdata->txc_irq = ret;
+ }
+
pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
/* Firmware may have set up the clock already. */
@@ -950,11 +1024,13 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
pdata->mac_ops = &xgene_sgmac_ops;
pdata->port_ops = &xgene_sgport_ops;
pdata->rm = RM1;
+ pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
break;
default:
pdata->mac_ops = &xgene_xgmac_ops;
pdata->port_ops = &xgene_xgport_ops;
pdata->rm = RM0;
+ pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
break;
}
@@ -977,12 +1053,38 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
}
+static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ netif_napi_add(pdata->ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
+ NAPI_POLL_WEIGHT);
+ }
+}
+
+static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ netif_napi_del(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ netif_napi_del(napi);
+ }
+}
+
static int xgene_enet_probe(struct platform_device *pdev)
{
struct net_device *ndev;
struct xgene_enet_pdata *pdata;
struct device *dev = &pdev->dev;
- struct napi_struct *napi;
struct xgene_mac_ops *mac_ops;
int ret;
@@ -1024,8 +1126,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
if (ret)
goto err;
- napi = &pdata->rx_ring->napi;
- netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+ xgene_enet_napi_add(pdata);
mac_ops = pdata->mac_ops;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
ret = xgene_enet_mdio_config(pdata);
@@ -1052,7 +1153,7 @@ static int xgene_enet_remove(struct platform_device *pdev)
mac_ops->rx_disable(pdata);
mac_ops->tx_disable(pdata);
- netif_napi_del(&pdata->rx_ring->napi);
+ xgene_enet_napi_del(pdata);
xgene_enet_mdio_remove(pdata);
xgene_enet_delete_desc_rings(pdata);
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 b93ed21..8f3d232 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 @@
#define START_BP_BUFNUM_1 0x2A
#define START_RING_NUM_1 264
+#define IRQ_ID_SIZE 16
+#define XGENE_MAX_TXC_RINGS 1
+
#define PHY_POLL_LINK_ON (10 * HZ)
#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
@@ -63,6 +66,7 @@ struct xgene_enet_desc_ring {
u16 tail;
u16 slots;
u16 irq;
+ char irq_name[IRQ_ID_SIZE];
u32 size;
u32 state[NUM_RING_CONFIG];
void __iomem *cmd_base;
@@ -117,6 +121,8 @@ struct xgene_enet_pdata {
u32 cp_qcnt_hi;
u32 cp_qcnt_low;
u32 rx_irq;
+ u32 txc_irq;
+ u8 cq_cnt;
void __iomem *eth_csr_addr;
void __iomem *eth_ring_if_addr;
void __iomem *eth_diag_csr_addr;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v1 3/3] drivers: net: xgene: Add separate tx completion ring
@ 2015-03-25 19:19 ` Iyappan Subramanian
0 siblings, 0 replies; 10+ messages in thread
From: Iyappan Subramanian @ 2015-03-25 19:19 UTC (permalink / raw)
To: linux-arm-kernel
- 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>
---
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 141 +++++++++++++++++++----
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 6146a993..40d3530 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)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct device *dev = ndev_to_dev(ndev);
+ struct xgene_enet_desc_ring *ring;
int ret;
- ret = devm_request_irq(dev, pdata->rx_ring->irq, xgene_enet_rx_irq,
- IRQF_SHARED, ndev->name, pdata->rx_ring);
- if (ret) {
- netdev_err(ndev, "rx%d interrupt request failed\n",
- pdata->rx_ring->irq);
+ ring = pdata->rx_ring;
+ ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+ IRQF_SHARED, ring->irq_name, ring);
+ if (ret)
+ netdev_err(ndev, "Failed to request irq %s\n", ring->irq_name);
+
+ if (pdata->cq_cnt) {
+ ring = pdata->tx_ring->cp_ring;
+ ret = devm_request_irq(dev, ring->irq, xgene_enet_rx_irq,
+ IRQF_SHARED, ring->irq_name, ring);
+ if (ret) {
+ netdev_err(ndev, "Failed to request irq %s\n",
+ ring->irq_name);
+ }
}
return ret;
@@ -448,6 +458,37 @@ static void xgene_enet_free_irq(struct net_device *ndev)
pdata = netdev_priv(ndev);
dev = ndev_to_dev(ndev);
devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring);
+
+ if (pdata->cq_cnt) {
+ devm_free_irq(dev, pdata->tx_ring->cp_ring->irq,
+ pdata->tx_ring->cp_ring);
+ }
+}
+
+static void xgene_enet_napi_enable(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ napi_enable(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ napi_enable(napi);
+ }
+}
+
+static void xgene_enet_napi_disable(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ napi_disable(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ napi_disable(napi);
+ }
}
static int xgene_enet_open(struct net_device *ndev)
@@ -462,7 +503,7 @@ static int xgene_enet_open(struct net_device *ndev)
ret = xgene_enet_register_irq(ndev);
if (ret)
return ret;
- napi_enable(&pdata->rx_ring->napi);
+ xgene_enet_napi_enable(pdata);
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
phy_start(pdata->phy_dev);
@@ -486,7 +527,7 @@ static int xgene_enet_close(struct net_device *ndev)
else
cancel_delayed_work_sync(&pdata->link_work);
- napi_disable(&pdata->rx_ring->napi);
+ xgene_enet_napi_disable(pdata);
xgene_enet_free_irq(ndev);
xgene_enet_process_ring(pdata->rx_ring, -1);
@@ -580,6 +621,8 @@ static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata)
if (ring) {
if (ring->cp_ring && ring->cp_ring->cp_skb)
devm_kfree(dev, ring->cp_ring->cp_skb);
+ if (ring->cp_ring && pdata->cq_cnt)
+ xgene_enet_free_desc_ring(ring->cp_ring);
xgene_enet_free_desc_ring(ring);
}
@@ -673,6 +716,12 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
rx_ring->nbufpool = NUM_BUFPOOL;
rx_ring->buf_pool = buf_pool;
rx_ring->irq = pdata->rx_irq;
+ if (!pdata->cq_cnt) {
+ snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx-txc",
+ ndev->name);
+ } else {
+ snprintf(rx_ring->irq_name, IRQ_ID_SIZE, "%s-rx", ndev->name);
+ }
buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots,
sizeof(struct sk_buff *), GFP_KERNEL);
if (!buf_pool->rx_skb) {
@@ -694,7 +743,22 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
}
pdata->tx_ring = tx_ring;
- cp_ring = pdata->rx_ring;
+ if (!pdata->cq_cnt) {
+ cp_ring = pdata->rx_ring;
+ } else {
+ /* allocate tx completion descriptor ring */
+ ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++);
+ cp_ring = xgene_enet_create_desc_ring(ndev, ring_num++,
+ RING_CFGSIZE_16KB,
+ ring_id);
+ if (!cp_ring) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ cp_ring->irq = pdata->txc_irq;
+ snprintf(cp_ring->irq_name, IRQ_ID_SIZE, "%s-txc", ndev->name);
+ }
+
cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots,
sizeof(struct sk_buff *), GFP_KERNEL);
if (!cp_ring->cp_skb) {
@@ -853,14 +917,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return -ENOMEM;
}
- ret = platform_get_irq(pdev, 0);
- if (ret <= 0) {
- dev_err(dev, "Unable to get ENET Rx IRQ\n");
- ret = ret ? : -ENXIO;
- return ret;
- }
- pdata->rx_irq = ret;
-
ret = xgene_get_port_id(dev, pdata);
if (ret)
return ret;
@@ -882,6 +938,24 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return -ENODEV;
}
+ ret = platform_get_irq(pdev, 0);
+ if (ret <= 0) {
+ dev_err(dev, "Unable to get ENET Rx IRQ\n");
+ ret = ret ? : -ENXIO;
+ return ret;
+ }
+ pdata->rx_irq = ret;
+
+ if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII) {
+ ret = platform_get_irq(pdev, 1);
+ if (ret <= 0) {
+ dev_err(dev, "Unable to get ENET Tx completion IRQ\n");
+ ret = ret ? : -ENXIO;
+ return ret;
+ }
+ pdata->txc_irq = ret;
+ }
+
pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
/* Firmware may have set up the clock already. */
@@ -950,11 +1024,13 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
pdata->mac_ops = &xgene_sgmac_ops;
pdata->port_ops = &xgene_sgport_ops;
pdata->rm = RM1;
+ pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
break;
default:
pdata->mac_ops = &xgene_xgmac_ops;
pdata->port_ops = &xgene_xgport_ops;
pdata->rm = RM0;
+ pdata->cq_cnt = XGENE_MAX_TXC_RINGS;
break;
}
@@ -977,12 +1053,38 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
}
+static void xgene_enet_napi_add(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ netif_napi_add(pdata->ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ netif_napi_add(pdata->ndev, napi, xgene_enet_napi,
+ NAPI_POLL_WEIGHT);
+ }
+}
+
+static void xgene_enet_napi_del(struct xgene_enet_pdata *pdata)
+{
+ struct napi_struct *napi;
+
+ napi = &pdata->rx_ring->napi;
+ netif_napi_del(napi);
+
+ if (pdata->cq_cnt) {
+ napi = &pdata->tx_ring->cp_ring->napi;
+ netif_napi_del(napi);
+ }
+}
+
static int xgene_enet_probe(struct platform_device *pdev)
{
struct net_device *ndev;
struct xgene_enet_pdata *pdata;
struct device *dev = &pdev->dev;
- struct napi_struct *napi;
struct xgene_mac_ops *mac_ops;
int ret;
@@ -1024,8 +1126,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
if (ret)
goto err;
- napi = &pdata->rx_ring->napi;
- netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+ xgene_enet_napi_add(pdata);
mac_ops = pdata->mac_ops;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
ret = xgene_enet_mdio_config(pdata);
@@ -1052,7 +1153,7 @@ static int xgene_enet_remove(struct platform_device *pdev)
mac_ops->rx_disable(pdata);
mac_ops->tx_disable(pdata);
- netif_napi_del(&pdata->rx_ring->napi);
+ xgene_enet_napi_del(pdata);
xgene_enet_mdio_remove(pdata);
xgene_enet_delete_desc_rings(pdata);
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 b93ed21..8f3d232 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 @@
#define START_BP_BUFNUM_1 0x2A
#define START_RING_NUM_1 264
+#define IRQ_ID_SIZE 16
+#define XGENE_MAX_TXC_RINGS 1
+
#define PHY_POLL_LINK_ON (10 * HZ)
#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
@@ -63,6 +66,7 @@ struct xgene_enet_desc_ring {
u16 tail;
u16 slots;
u16 irq;
+ char irq_name[IRQ_ID_SIZE];
u32 size;
u32 state[NUM_RING_CONFIG];
void __iomem *cmd_base;
@@ -117,6 +121,8 @@ struct xgene_enet_pdata {
u32 cp_qcnt_hi;
u32 cp_qcnt_low;
u32 rx_irq;
+ u32 txc_irq;
+ u8 cq_cnt;
void __iomem *eth_csr_addr;
void __iomem *eth_ring_if_addr;
void __iomem *eth_diag_csr_addr;
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v1 0/3] drivers: net: xgene: Add separate tx completion ring
2015-03-25 19:19 ` Iyappan Subramanian
@ 2015-03-27 21:21 ` David Miller
-1 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2015-03-27 21:21 UTC (permalink / raw)
To: isubramanian; +Cc: netdev, devicetree, linux-arm-kernel, kchudgar, patches
From: Iyappan Subramanian <isubramanian@apm.com>
Date: Wed, 25 Mar 2015 12:19:09 -0700
> SGMII based 1GbE and 10GbE interfaces support multiple interrupts.
> Adding separate tx completion descriptor ring and associating a dedicated irq for the TX completion.
>
> Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
> Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Series applied, thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v1 0/3] drivers: net: xgene: Add separate tx completion ring
@ 2015-03-27 21:21 ` David Miller
0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2015-03-27 21:21 UTC (permalink / raw)
To: linux-arm-kernel
From: Iyappan Subramanian <isubramanian@apm.com>
Date: Wed, 25 Mar 2015 12:19:09 -0700
> SGMII based 1GbE and 10GbE interfaces support multiple interrupts.
> Adding separate tx completion descriptor ring and associating a dedicated irq for the TX completion.
>
> Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
> Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Series applied, thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-03-27 21:21 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-25 19:19 [PATCH net-next v1 0/3] drivers: net: xgene: Add separate tx completion ring Iyappan Subramanian
2015-03-25 19:19 ` Iyappan Subramanian
2015-03-25 19:19 ` [PATCH net-next v1 1/3] Documentation: dts: xgene: Update interrupt field description Iyappan Subramanian
2015-03-25 19:19 ` Iyappan Subramanian
2015-03-25 19:19 ` [PATCH net-next v1 2/3] dtb: xgene: Add interrupt for Tx completion Iyappan Subramanian
2015-03-25 19:19 ` Iyappan Subramanian
[not found] ` <1427311152-30333-1-git-send-email-isubramanian-qTEPVZfXA3Y@public.gmane.org>
2015-03-25 19:19 ` [PATCH net-next v1 3/3] drivers: net: xgene: Add separate tx completion ring Iyappan Subramanian
2015-03-25 19:19 ` Iyappan Subramanian
2015-03-27 21:21 ` [PATCH net-next v1 0/3] " David Miller
2015-03-27 21:21 ` David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.