Commit 0ed577e7 authored by Siddharth Vadapalli's avatar Siddharth Vadapalli Committed by Jakub Kicinski

net: ethernet: ti: am65-cpsw: Add RX DMA Channel Teardown Quirk

In TI's AM62x/AM64x SoCs, successful teardown of RX DMA Channel raises an
interrupt. The process of servicing this interrupt involves flushing all
pending RX DMA descriptors and clearing the teardown completion marker
(TDCM). The am65_cpsw_nuss_rx_packets() function invoked from the RX
NAPI callback services the interrupt. Thus, it is necessary to wait for
this handler to run, drain all packets and clear TDCM, before calling
napi_disable() in am65_cpsw_nuss_common_stop() function post channel
teardown. If napi_disable() executes before ensuring that TDCM is
cleared, the TDCM remains set when the interfaces are down, resulting in
an interrupt storm when the interfaces are brought up again.

Since the interrupt raised to indicate the RX DMA Channel teardown is
specific to the AM62x and AM64x SoCs, add a quirk for it.

Fixes: 4f7cce27 ("net: ethernet: ti: am65-cpsw: add support for am64x cpsw3g")
Co-developed-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: default avatarSiddharth Vadapalli <s-vadapalli@ti.com>
Reviewed-by: default avatarRoger Quadros <rogerq@kernel.org>
Link: https://lore.kernel.org/r/20230209084432.189222-1-s-vadapalli@ti.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ec76d0c2
...@@ -501,7 +501,15 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common) ...@@ -501,7 +501,15 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)
k3_udma_glue_disable_tx_chn(common->tx_chns[i].tx_chn); k3_udma_glue_disable_tx_chn(common->tx_chns[i].tx_chn);
} }
reinit_completion(&common->tdown_complete);
k3_udma_glue_tdown_rx_chn(common->rx_chns.rx_chn, true); k3_udma_glue_tdown_rx_chn(common->rx_chns.rx_chn, true);
if (common->pdata.quirks & AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ) {
i = wait_for_completion_timeout(&common->tdown_complete, msecs_to_jiffies(1000));
if (!i)
dev_err(common->dev, "rx teardown timeout\n");
}
napi_disable(&common->napi_rx); napi_disable(&common->napi_rx);
for (i = 0; i < AM65_CPSW_MAX_RX_FLOWS; i++) for (i = 0; i < AM65_CPSW_MAX_RX_FLOWS; i++)
...@@ -721,6 +729,8 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common, ...@@ -721,6 +729,8 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
if (cppi5_desc_is_tdcm(desc_dma)) { if (cppi5_desc_is_tdcm(desc_dma)) {
dev_dbg(dev, "%s RX tdown flow: %u\n", __func__, flow_idx); dev_dbg(dev, "%s RX tdown flow: %u\n", __func__, flow_idx);
if (common->pdata.quirks & AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ)
complete(&common->tdown_complete);
return 0; return 0;
} }
...@@ -2672,7 +2682,7 @@ static const struct am65_cpsw_pdata j721e_pdata = { ...@@ -2672,7 +2682,7 @@ static const struct am65_cpsw_pdata j721e_pdata = {
}; };
static const struct am65_cpsw_pdata am64x_cpswxg_pdata = { static const struct am65_cpsw_pdata am64x_cpswxg_pdata = {
.quirks = 0, .quirks = AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ,
.ale_dev_id = "am64-cpswxg", .ale_dev_id = "am64-cpswxg",
.fdqring_mode = K3_RINGACC_RING_MODE_RING, .fdqring_mode = K3_RINGACC_RING_MODE_RING,
}; };
......
...@@ -90,6 +90,7 @@ struct am65_cpsw_rx_chn { ...@@ -90,6 +90,7 @@ struct am65_cpsw_rx_chn {
}; };
#define AM65_CPSW_QUIRK_I2027_NO_TX_CSUM BIT(0) #define AM65_CPSW_QUIRK_I2027_NO_TX_CSUM BIT(0)
#define AM64_CPSW_QUIRK_DMA_RX_TDOWN_IRQ BIT(1)
struct am65_cpsw_pdata { struct am65_cpsw_pdata {
u32 quirks; u32 quirks;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment