[][kernel][mt7988][eth][Make the LRO and RSS coexistence]
[Description]
Refactor ETH driver that make the LRO and RSS coexistence.
Without this patch, Users are unable to enable both LRO and RSS at the
same time.
[Release-log]
N/A
Change-Id: Ia518149134649b56777e9362cafc044b816b7d75
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8118481
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 1c1eb75..8794512 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2130,45 +2130,9 @@
return NETDEV_TX_OK;
}
-static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth)
-{
- int i;
- struct mtk_rx_ring *ring;
- int idx;
-
- for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) {
- struct mtk_rx_dma *rxd;
-
- if (!IS_NORMAL_RING(i) && !IS_HW_LRO_RING(i))
- continue;
-
- ring = ð->rx_ring[i];
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
- rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
- if (rxd->rxd2 & RX_DMA_DONE) {
- ring->calc_idx_update = true;
- return ring;
- }
- }
-
- return NULL;
-}
-
static void mtk_update_rx_cpu_idx(struct mtk_eth *eth, struct mtk_rx_ring *ring)
{
- int i;
-
- if (!eth->hwlro)
- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
- else {
- for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) {
- ring = ð->rx_ring[i];
- if (ring->calc_idx_update) {
- ring->calc_idx_update = false;
- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
- }
- }
- }
+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg);
}
static int mtk_poll_rx(struct napi_struct *napi, int budget,
@@ -2192,12 +2156,6 @@
dma_addr_t dma_addr = 0;
int mac = 0;
- if (eth->hwlro)
- ring = mtk_get_rx_ring(eth);
-
- if (unlikely(!ring))
- goto rx_done;
-
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
data = ring->data[idx];
@@ -2918,6 +2876,17 @@
/* no use PPE cpu reason */
mtk_w32(eth, 0xffffffff, MTK_PDMA_LRO_CTRL_DW1);
+ /* Set perLRO GRP INT */
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(1)),
+ MTK_RX_DONE_INT(MTK_HW_LRO_RING(1)), MTK_PDMA_INT_GRP1);
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(2)),
+ MTK_RX_DONE_INT(MTK_HW_LRO_RING(2)), MTK_PDMA_INT_GRP2);
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(3)),
+ MTK_RX_DONE_INT(MTK_HW_LRO_RING(3)), MTK_PDMA_INT_GRP3);
+ }
+
return 0;
}
@@ -3171,9 +3140,12 @@
mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
/* Set perRSS GRP INT */
- mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(1)), MTK_PDMA_INT_GRP1);
- mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(2)), MTK_PDMA_INT_GRP2);
- mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(3)), MTK_PDMA_INT_GRP3);
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(0)),
+ MTK_RX_DONE_INT(MTK_RSS_RING(0)), MTK_PDMA_INT_GRP1);
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(1)),
+ MTK_RX_DONE_INT(MTK_RSS_RING(1)), MTK_PDMA_INT_GRP2);
+ mtk_m32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(2)),
+ MTK_RX_DONE_INT(MTK_RSS_RING(2)), MTK_PDMA_INT_GRP3);
/* Set GRP INT */
mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP);
@@ -3306,9 +3278,8 @@
return err;
if (eth->hwlro) {
- i = (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) ? 1 : 4;
- for (; i < MTK_MAX_RX_RING_NUM; i++) {
- err = mtk_rx_alloc(eth, i, MTK_RX_FLAGS_HWLRO);
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+ err = mtk_rx_alloc(eth, MTK_HW_LRO_RING(i), MTK_RX_FLAGS_HWLRO);
if (err)
return err;
}
@@ -3318,8 +3289,8 @@
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
- err = mtk_rx_alloc(eth, i, MTK_RX_FLAGS_NORMAL);
+ for (i = 0; i < MTK_RX_RSS_NUM; i++) {
+ err = mtk_rx_alloc(eth, MTK_RSS_RING(i), MTK_RX_FLAGS_NORMAL);
if (err)
return err;
}
@@ -3362,16 +3333,15 @@
if (eth->hwlro) {
mtk_hwlro_rx_uninit(eth);
- i = (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) ? 4 : 1;
- for (; i < MTK_MAX_RX_RING_NUM; i++)
- mtk_rx_clean(eth, ð->rx_ring[i], 0);
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++)
+ mtk_rx_clean(eth, ð->rx_ring[MTK_HW_LRO_RING(i)], 0);
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
mtk_rss_uninit(eth);
- for (i = 1; i < MTK_RX_NAPI_NUM; i++)
- mtk_rx_clean(eth, ð->rx_ring[i], 1);
+ for (i = 0; i < MTK_RX_RSS_NUM; i++)
+ mtk_rx_clean(eth, ð->rx_ring[MTK_RSS_RING(i)], 1);
}
if (eth->scratch_head) {
@@ -3399,6 +3369,10 @@
struct mtk_eth *eth = rx_napi->eth;
struct mtk_rx_ring *ring = rx_napi->rx_ring;
+ if (unlikely(!(mtk_r32(eth, eth->soc->reg_map->pdma.irq_status) &
+ MTK_RX_DONE_INT(ring->ring_no))))
+ return IRQ_NONE;
+
if (likely(napi_schedule_prep(&rx_napi->napi))) {
mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(ring->ring_no));
__napi_schedule(&rx_napi->napi);
@@ -3603,9 +3577,16 @@
mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(0));
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
- napi_enable(ð->rx_napi[i].napi);
- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(i));
+ for (i = 0; i < MTK_RX_RSS_NUM; i++) {
+ napi_enable(ð->rx_napi[MTK_RSS_RING(i)].napi);
+ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(MTK_RSS_RING(i)));
+ }
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+ napi_enable(ð->rx_napi[MTK_HW_LRO_RING(i)].napi);
+ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)));
}
}
@@ -3717,9 +3698,16 @@
napi_disable(ð->rx_napi[0].napi);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(i));
- napi_disable(ð->rx_napi[i].napi);
+ for (i = 0; i < MTK_RX_RSS_NUM; i++) {
+ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(MTK_RSS_RING(i)));
+ napi_disable(ð->rx_napi[MTK_RSS_RING(i)].napi);
+ }
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(MTK_HW_LRO_RING(i)));
+ napi_disable(ð->rx_napi[MTK_HW_LRO_RING(i)].napi);
}
}
@@ -3791,14 +3779,23 @@
rx_napi->irq_grp_no = 2;
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
- rx_napi = ð->rx_napi[i];
+ for (i = 0; i < MTK_RX_RSS_NUM; i++) {
+ rx_napi = ð->rx_napi[MTK_RSS_RING(i)];
rx_napi->eth = eth;
- rx_napi->rx_ring = ð->rx_ring[i];
+ rx_napi->rx_ring = ð->rx_ring[MTK_RSS_RING(i)];
rx_napi->irq_grp_no = 2 + i;
}
}
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+ rx_napi = ð->rx_napi[MTK_HW_LRO_RING(i)];
+ rx_napi->eth = eth;
+ rx_napi->rx_ring = ð->rx_ring[MTK_HW_LRO_RING(i)];
+ rx_napi->irq_grp_no = 2;
+ }
+ }
+
return 0;
}
@@ -5131,18 +5128,32 @@
goto err_free_dev;
err = devm_request_irq(eth->dev, eth->irq_pdma[0],
- mtk_handle_irq_rx, 0,
+ mtk_handle_irq_rx, IRQF_SHARED,
dev_name(eth->dev), ð->rx_napi[0]);
if (err)
goto err_free_dev;
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
+ for (i = 0; i < MTK_RX_RSS_NUM; i++) {
+ err = devm_request_irq(eth->dev,
+ eth->irq_pdma[MTK_RSS_RING(i)],
+ mtk_handle_irq_rx, IRQF_SHARED,
+ dev_name(eth->dev),
+ ð->rx_napi[MTK_RSS_RING(i)]);
+ if (err)
+ goto err_free_dev;
+ }
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
+ i = (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2) ||
+ MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) ? 0 : 1;
+ for (; i < MTK_HW_LRO_RING_NUM; i++) {
err = devm_request_irq(eth->dev,
eth->irq_pdma[i],
- mtk_handle_irq_rx, 0,
+ mtk_handle_irq_rx, IRQF_SHARED,
dev_name(eth->dev),
- ð->rx_napi[i]);
+ ð->rx_napi[MTK_HW_LRO_RING(i)]);
if (err)
goto err_free_dev;
}
@@ -5183,9 +5194,16 @@
MTK_NAPI_WEIGHT);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++)
- netif_napi_add(ð->dummy_dev, ð->rx_napi[i].napi,
+ for (i = 0; i < MTK_RX_RSS_NUM; i++)
+ netif_napi_add(ð->dummy_dev, ð->rx_napi[MTK_RSS_RING(i)].napi,
+ mtk_napi_rx, MTK_NAPI_WEIGHT);
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO)) {
+ for (i = 0; i < MTK_HW_LRO_RING_NUM; i++) {
+ netif_napi_add(ð->dummy_dev, ð->rx_napi[MTK_HW_LRO_RING(i)].napi,
mtk_napi_rx, MTK_NAPI_WEIGHT);
+ }
}
mtketh_debugfs_init(eth);
@@ -5371,7 +5389,7 @@
static const struct mtk_soc_data mt7988_data = {
.reg_map = &mt7988_reg_map,
.ana_rgc3 = 0x128,
- .caps = MT7988_CAPS,
+ .caps = MT7988_CAPS | MTK_HWLRO,
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7988_CLKS_BITMAP,
.required_pctl = false,
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 737031e..fe8bdee 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -52,7 +52,7 @@
#define MTK_QRX_OFFSET 0x10
-#define MTK_HW_LRO_DMA_SIZE 8
+#define MTK_HW_LRO_DMA_SIZE 512
#define MTK_MAX_LRO_RX_LENGTH (4096 * 3)
#define MTK_MAX_LRO_IP_CNT 2
@@ -220,6 +220,7 @@
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
#define MTK_MAX_RX_RING_NUM (8)
#define MTK_HW_LRO_RING_NUM (4)
+#define MTK_HW_LRO_RING(x) ((x) + 4)
#define IS_HW_LRO_RING(ring_no) (((ring_no) > 3) && ((ring_no) < 8))
#define MTK_PDMA_LRO_CTRL_DW0 (PDMA_BASE + 0x408)
#define MTK_LRO_ALT_SCORE_DELTA (PDMA_BASE + 0x41c)
@@ -233,6 +234,7 @@
#else
#define MTK_MAX_RX_RING_NUM (4)
#define MTK_HW_LRO_RING_NUM (3)
+#define MTK_HW_LRO_RING(x) ((x) + 1)
#define IS_HW_LRO_RING(ring_no) (((ring_no) > 0) && ((ring_no) < 4))
#define MTK_PDMA_LRO_CTRL_DW0 (PDMA_BASE + 0x180)
#define MTK_LRO_ALT_SCORE_DELTA (PDMA_BASE + 0x24c)
@@ -266,8 +268,9 @@
#else
#define MTK_PDMA_RSS_GLO_CFG 0x2800
#endif
-#define MTK_RX_NAPI_NUM (4)
-#define MTK_RSS_RING(x) (x)
+#define MTK_RX_NAPI_NUM (8)
+#define MTK_RX_RSS_NUM (3)
+#define MTK_RSS_RING(x) ((x) + 1)
#define MTK_RSS_EN BIT(0)
#define MTK_RSS_CFG_REQ BIT(2)
#define MTK_RSS_IPV6_STATIC_HASH (0x7 << 8)