[][Add Ethernet HW LRO support depending on hw_capability]
[Description]
Add Ethernet HW LRO support and related debug interface
depending on hw_capability.
---------Debug method 1 - Auto learn table---------
- Dump aggregated flows:
$ cat /proc/mtketh/hw_lro_auto_tlb
- Modify MAX_AGGREGATED_CNT:
$ echo 0 [setting] > /proc/mtketh/hw_lro_auto_tlb
- Modify MAX_AGG_TIME:
$ echo 1 [setting] > /proc/mtketh/hw_lro_auto_tlb
- Modify AGE_TIME:
$ echo 2 [setting] > /proc/mtketh/hw_lro_auto_tlb
- Modify AUTO_LEARN_LRO_ELIGIBLE_THRESHOLD:
$ echo 3 [setting] > /proc/mtketh/hw_lro_auto_tlb
- Enable/Disable LRO:
$ echo 4 [1/0] > /proc/mtketh/hw_lro_auto_tlb
---------Debug method 2 - per LRO ring statistics--------
- Dump each LRO rings' statistics, which includes packet count,
packet length, flush reason, etc.
$ cat /proc/mtketh/hw_lro_stats
[Release-log]
N/A
Change-Id: I2359ac177b81077bb7c95ee5fae2f32aadda521f
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4588327
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 2bac3e6..d02b248 100755
--- 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
@@ -43,7 +43,6 @@
#define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
#define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1))
-#define MTK_MAX_RX_RING_NUM 4
#define MTK_HW_LRO_DMA_SIZE 8
#define MTK_MAX_LRO_RX_LENGTH (4096 * 3)
@@ -72,6 +71,11 @@
/* Frame Engine Interrupt Grouping Register */
#define MTK_FE_INT_GRP 0x20
+/* Frame Engine LRO auto-learn table info */
+#define MTK_FE_ALT_CF8 0x300
+#define MTK_FE_ALT_SGL_CFC 0x304
+#define MTK_FE_ALT_SEQ_CFC 0x308
+
/* CDMP Ingress Control Register */
#define MTK_CDMQ_IG_CTRL 0x1400
#define MTK_CDMQ_STAG_EN BIT(0)
@@ -132,12 +136,41 @@
#define MTK_PRX_CRX_IDX_CFG(x) (MTK_PRX_CRX_IDX0 + (x * 0x10))
/* PDMA HW LRO Control Registers */
-#define MTK_PDMA_LRO_CTRL_DW0 (PDMA_BASE + 0x180)
-#define MTK_LRO_EN BIT(0)
+#define BITS(m, n) (~(BIT(m) - 1) & ((BIT(n) - 1) | BIT(n)))
+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+#define MTK_MAX_RX_RING_NUM (8)
+#define MTK_HW_LRO_RING_NUM (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)
+#define MTK_LRO_RX_RING0_CTRL_DW1 (PDMA_BASE + 0x438)
+#define MTK_LRO_RX_RING0_CTRL_DW2 (PDMA_BASE + 0x43c)
+#define MTK_LRO_RX_RING0_CTRL_DW3 (PDMA_BASE + 0x440)
+#define MTK_L3_CKS_UPD_EN BIT(19)
+#define MTK_LRO_CRSN_BNW BIT(22)
+#define MTK_LRO_RING_RELINGUISH_REQ (0xf << 24)
+#define MTK_LRO_RING_RELINGUISH_DONE (0xf << 28)
+#else
+#define MTK_MAX_RX_RING_NUM (4)
+#define MTK_HW_LRO_RING_NUM (3)
+#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)
+#define MTK_LRO_RX_RING0_CTRL_DW1 (PDMA_BASE + 0x328)
+#define MTK_LRO_RX_RING0_CTRL_DW2 (PDMA_BASE + 0x32c)
+#define MTK_LRO_RX_RING0_CTRL_DW3 (PDMA_BASE + 0x330)
+#define MTK_LRO_CRSN_BNW BIT(6)
#define MTK_L3_CKS_UPD_EN BIT(7)
+#define MTK_LRO_RING_RELINGUISH_REQ (0x7 << 26)
+#define MTK_LRO_RING_RELINGUISH_DONE (0x7 << 29)
+#endif
+
+#define IS_NORMAL_RING(ring_no) ((ring_no) == 0)
+#define MTK_LRO_EN BIT(0)
#define MTK_LRO_ALT_PKT_CNT_MODE BIT(21)
-#define MTK_LRO_RING_RELINQUISH_REQ (0x7 << 26)
-#define MTK_LRO_RING_RELINQUISH_DONE (0x7 << 29)
+#define MTK_LRO_L4_CTRL_PSH_EN BIT(23)
+#define MTK_CTRL_DW0_SDL_OFFSET (3)
+#define MTK_CTRL_DW0_SDL_MASK BITS(3, 18)
#define MTK_PDMA_LRO_CTRL_DW1 (MTK_PDMA_LRO_CTRL_DW0 + 0x04)
#define MTK_PDMA_LRO_CTRL_DW2 (MTK_PDMA_LRO_CTRL_DW0 + 0x08)
@@ -147,9 +180,15 @@
/* PDMA Global Configuration Register */
#define MTK_PDMA_GLO_CFG (PDMA_BASE + 0x204)
+#define MTK_RX_DMA_LRO_EN BIT(8)
#define MTK_MULTI_EN BIT(10)
#define MTK_PDMA_SIZE_8DWORDS (1 << 4)
+/* PDMA Global Configuration Register */
+#define MTK_PDMA_RX_CFG (PDMA_BASE + 0x210)
+#define MTK_PDMA_LRO_SDL (0x3000)
+#define MTK_RX_CFG_SDL_OFFSET (16)
+
/* PDMA Reset Index Register */
#define MTK_PDMA_RST_IDX (PDMA_BASE + 0x208)
#define MTK_PST_DRX_IDX0 BIT(16)
@@ -171,22 +210,27 @@
/* PDMA Interrupt Mask Register */
#define MTK_PDMA_INT_MASK (PDMA_BASE + 0x228)
-/* PDMA HW LRO Alter Flow Delta Register */
-#define MTK_PDMA_LRO_ALT_SCORE_DELTA (PDMA_BASE + 0x24c)
-
/* PDMA Interrupt grouping registers */
#define MTK_PDMA_INT_GRP1 (PDMA_BASE + 0x250)
#define MTK_PDMA_INT_GRP2 (PDMA_BASE + 0x254)
/* PDMA HW LRO IP Setting Registers */
+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+#define MTK_LRO_RX_RING0_DIP_DW0 (PDMA_BASE + 0x414)
+#else
#define MTK_LRO_RX_RING0_DIP_DW0 (PDMA_BASE + 0x304)
+#endif
#define MTK_LRO_DIP_DW0_CFG(x) (MTK_LRO_RX_RING0_DIP_DW0 + (x * 0x40))
#define MTK_RING_MYIP_VLD BIT(9)
+/* PDMA HW LRO ALT Debug Registers */
+#define MTK_LRO_ALT_DBG (PDMA_BASE + 0x440)
+#define MTK_LRO_ALT_INDEX_OFFSET (8)
+
+/* PDMA HW LRO ALT Data Registers */
+#define MTK_LRO_ALT_DBG_DATA (PDMA_BASE + 0x444)
+
/* PDMA HW LRO Ring Control Registers */
-#define MTK_LRO_RX_RING0_CTRL_DW1 (PDMA_BASE + 0x328)
-#define MTK_LRO_RX_RING0_CTRL_DW2 (PDMA_BASE + 0x32c)
-#define MTK_LRO_RX_RING0_CTRL_DW3 (PDMA_BASE + 0x330)
#define MTK_LRO_CTRL_DW1_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW1 + (x * 0x40))
#define MTK_LRO_CTRL_DW2_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW2 + (x * 0x40))
#define MTK_LRO_CTRL_DW3_CFG(x) (MTK_LRO_RX_RING0_CTRL_DW3 + (x * 0x40))
@@ -198,6 +242,35 @@
#define MTK_RING_MAX_AGG_CNT_L ((MTK_HW_LRO_MAX_AGG_CNT & 0x3f) << 26)
#define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3)
+/* LRO_RX_RING_CTRL_DW masks */
+#define MTK_LRO_RING_AGG_TIME_MASK BITS(10, 25)
+#define MTK_LRO_RING_AGG_CNT_L_MASK BITS(26, 31)
+#define MTK_LRO_RING_AGG_CNT_H_MASK BITS(0, 1)
+#define MTK_LRO_RING_AGE_TIME_L_MASK BITS(22, 31)
+#define MTK_LRO_RING_AGE_TIME_H_MASK BITS(0, 5)
+
+/* LRO_RX_RING_CTRL_DW0 offsets */
+#define MTK_RX_IPV6_FORCE_OFFSET (0)
+#define MTK_RX_IPV4_FORCE_OFFSET (1)
+
+/* LRO_RX_RING_CTRL_DW1 offsets */
+#define MTK_LRO_RING_AGE_TIME_L_OFFSET (22)
+
+/* LRO_RX_RING_CTRL_DW2 offsets */
+#define MTK_LRO_RING_AGE_TIME_H_OFFSET (0)
+#define MTK_RX_MODE_OFFSET (6)
+#define MTK_RX_PORT_VALID_OFFSET (8)
+#define MTK_RX_MYIP_VALID_OFFSET (9)
+#define MTK_LRO_RING_AGG_TIME_OFFSET (10)
+#define MTK_LRO_RING_AGG_CNT_L_OFFSET (26)
+
+/* LRO_RX_RING_CTRL_DW3 offsets */
+#define MTK_LRO_RING_AGG_CNT_H_OFFSET (0)
+
+/* LRO_RX_RING_STP_DTP_DW offsets */
+#define MTK_RX_TCP_DEST_PORT_OFFSET (0)
+#define MTK_RX_TCP_SRC_PORT_OFFSET (16)
+
/* QDMA TX Queue Configuration Registers */
#define MTK_QTX_CFG(x) (QDMA_BASE + (x * 0x10))
#define QDMA_RES_THRES 4
@@ -379,6 +452,8 @@
#define RX_DMA_LSO BIT(30)
#define RX_DMA_PLEN0(_x) (((_x) & MTK_RX_DMA_BUF_LEN) << MTK_RX_DMA_BUF_SHIFT)
#define RX_DMA_GET_PLEN0(_x) (((_x) >> MTK_RX_DMA_BUF_SHIFT) & MTK_RX_DMA_BUF_LEN)
+#define RX_DMA_GET_AGG_CNT(_x) (((_x) >> 2) & 0xff)
+#define RX_DMA_GET_REV(_x) (((_x) >> 10) & 0x1f)
#define RX_DMA_VTAG BIT(15)
/* QDMA descriptor rxd3 */
@@ -402,6 +477,10 @@
#define RX_DMA_TCI_V2(_x) (((_x) >> 1) & (VLAN_PRIO_MASK | VLAN_VID_MASK))
#define RX_DMA_VPID_V2(x3, x4) ((((x3) & 1) << 15) | (((x4) >> 17) & 0x7fff))
+/* PDMA V2 descriptor rxd6 */
+#define RX_DMA_GET_FLUSH_RSN_V2(_x) ((_x) & 0x7)
+#define RX_DMA_GET_AGG_CNT_V2(_x) (((_x) >> 16) & 0xff)
+
/* PHY Indirect Access Control registers */
#define MTK_PHY_IAC 0x10004
#define PHY_IAC_ACCESS BIT(31)
@@ -778,6 +857,7 @@
* @frag_size: How big can each fragment be
* @buf_size: The size of each packet buffer
* @calc_idx: The current head of ring
+ * @ring_no: The index of ring
*/
struct mtk_rx_ring {
struct mtk_rx_dma *dma;
@@ -789,6 +869,7 @@
bool calc_idx_update;
u16 calc_idx;
u32 crx_idx_reg;
+ u32 ring_no;
};
enum mkt_eth_capabilities {
@@ -1057,6 +1138,7 @@
/* the struct describing the SoC. these are declared in the soc_xyz.c files */
extern const struct of_device_id of_mtk_match[];
+extern u32 mtk_hwlro_stats_ebl;
/* read the hardware status register */
void mtk_stats_update_mac(struct mtk_mac *mac);