[][openwrt][mt7988][eth][Add dynamic RSS support for Jaguar]
[Description]
Add dynamic RSS support for Jaguar, which is quite
necessary for software path performance tuning.
In the previous commit (id: 7514813), we loosen the limitaions
of FE interrupt number, and then extend Rx path into
4-RSS rings. That commit makes it possible to dynamically
switch among 2/3/4-RSS rings by simply modifying indirection
table. So we add new proc interface for controlling
the number of RSS Rx rings.
[Usage]
- Show how many RSS Rx rings we're using now:
$ cat /proc/mtketh/rss_ctrl
- Chang the number of RSS Rx rings (options: 2~4):
$ echo [num] > /proc/mtketh/rss_ctrl
If without this patch, it's unable to dynamically
control RSS Rx rings.
[Release-log]
N/A
Change-Id: Id5a8c91dcc7c5560d31eb9083e497b89ca35fa03
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7561271
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index 9987630..189d409 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -41,8 +41,10 @@
u32 hw_lro_norule_flush_cnt[MTK_HW_LRO_RING_NUM];
u32 mtk_hwlro_stats_ebl;
u32 dbg_show_level;
+u32 cur_rss_num;
-static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb;
+static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb,
+ *proc_rss_ctrl;
typedef int (*mtk_lro_dbg_func) (int par);
struct mtk_eth_debug {
@@ -1124,6 +1126,60 @@
.release = single_release
};
+ssize_t rss_ctrl_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *data)
+{
+ char buf[32];
+ char *p_buf;
+ char *p_token = NULL;
+ char *p_delimiter = " \t";
+ long num = 4;
+ u32 len = count;
+ int ret;
+
+ if (len >= sizeof(buf)) {
+ pr_info("Input handling fail!\n");
+ return -1;
+ }
+
+ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+
+ p_buf = buf;
+ p_token = strsep(&p_buf, p_delimiter);
+ if (!p_token)
+ num = 4;
+ else
+ ret = kstrtol(p_token, 10, &num);
+
+ if (!mtk_rss_set_indr_tbl(g_eth, num))
+ cur_rss_num = num;
+
+ return count;
+}
+
+int rss_ctrl_read(struct seq_file *seq, void *v)
+{
+ pr_info("ADMA is using %d-RSS.\n", cur_rss_num);
+ return 0;
+}
+
+static int rss_ctrl_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rss_ctrl_read, 0);
+}
+
+static const struct file_operations rss_ctrl_fops = {
+ .owner = THIS_MODULE,
+ .open = rss_ctrl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = rss_ctrl_write,
+ .release = single_release
+};
+
void hw_lro_stats_update(u32 ring_no, struct mtk_rx_dma_v2 *rxd)
{
struct mtk_eth *eth = g_eth;
@@ -1837,6 +1893,17 @@
if (!proc_dbg_regs)
pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_DBG_REGS);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
+ proc_rss_ctrl =
+ proc_create(PROCREG_RSS_CTRL, 0, proc_reg_dir,
+ &rss_ctrl_fops);
+ if (!proc_rss_ctrl)
+ pr_info("!! FAIL to create %s PROC !!\n",
+ PROCREG_RSS_CTRL);
+
+ cur_rss_num = g_eth->soc->rss_num;
+ }
+
if (g_eth->hwlro) {
proc_hw_lro_stats =
proc_create(PROCREG_HW_LRO_STATS, 0, proc_reg_dir,
@@ -1881,6 +1948,9 @@
if (proc_dbg_regs)
remove_proc_entry(PROCREG_DBG_REGS, proc_reg_dir);
+ if (proc_rss_ctrl)
+ remove_proc_entry(PROCREG_RSS_CTRL, proc_reg_dir);
+
if (g_eth->hwlro) {
if (proc_hw_lro_stats)
remove_proc_entry(PROCREG_HW_LRO_STATS, proc_reg_dir);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
index ec7167b..3e7c137 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
@@ -61,6 +61,7 @@
#define PROCREG_RXRING "rx_ring"
#define PROCREG_DIR "mtketh"
#define PROCREG_DBG_REGS "dbg_regs"
+#define PROCREG_RSS_CTRL "rss_ctrl"
#define PROCREG_HW_LRO_STATS "hw_lro_stats"
#define PROCREG_HW_LRO_AUTO_TLB "hw_lro_auto_tlb"
#define PROCREG_RESET_EVENT "reset_event"
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 02f1d34..8f94fc5 100755
--- 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
@@ -3015,6 +3015,24 @@
return 0;
}
+int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num)
+{
+ u32 i, config;
+
+ if (num <= 0 || num > MTK_RX_NAPI_NUM)
+ return -EOPNOTSUPP;
+
+ for (i = 0, config = 0; i < 16; i++) {
+ config <<= 2;
+ config |= (i % num);
+ }
+
+ for (i = 0; i < 8; i++)
+ mtk_w32(eth, config, MTK_RSS_INDR_TABLE_DW(i));
+
+ return 0;
+}
+
static int mtk_rss_init(struct mtk_eth *eth)
{
u32 val;
@@ -3045,14 +3063,7 @@
mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
/* Select the size of indirection table */
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW0);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW1);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW2);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW3);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW4);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW5);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW6);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW7);
+ mtk_rss_set_indr_tbl(eth, eth->soc->rss_num);
/* Pause */
val |= MTK_RSS_CFG_REQ;
@@ -4911,6 +4922,7 @@
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4927,6 +4939,7 @@
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rx_dma_l4_valid = RX_DMA_L4_VALID,
@@ -4944,6 +4957,7 @@
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4960,6 +4974,7 @@
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4977,6 +4992,7 @@
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4994,6 +5010,7 @@
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -5011,6 +5028,7 @@
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -5028,6 +5046,7 @@
.required_clks = MT7988_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 4,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -5044,6 +5063,7 @@
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
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 7465188..06c2b0a 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
@@ -267,15 +267,8 @@
#define MTK_RSS_CFG_REQ BIT(2)
#define MTK_RSS_IPV6_STATIC_HASH (0x7 << 8)
#define MTK_RSS_IPV4_STATIC_HASH (0x7 << 12)
-#define MTK_RSS_INDR_TABLE_DW0 (MTK_PDMA_RSS_GLO_CFG + 0x50)
-#define MTK_RSS_INDR_TABLE_DW1 (MTK_PDMA_RSS_GLO_CFG + 0x54)
-#define MTK_RSS_INDR_TABLE_DW2 (MTK_PDMA_RSS_GLO_CFG + 0x58)
-#define MTK_RSS_INDR_TABLE_DW3 (MTK_PDMA_RSS_GLO_CFG + 0x5C)
-#define MTK_RSS_INDR_TABLE_DW4 (MTK_PDMA_RSS_GLO_CFG + 0x60)
-#define MTK_RSS_INDR_TABLE_DW5 (MTK_PDMA_RSS_GLO_CFG + 0x64)
-#define MTK_RSS_INDR_TABLE_DW6 (MTK_PDMA_RSS_GLO_CFG + 0x68)
-#define MTK_RSS_INDR_TABLE_DW7 (MTK_PDMA_RSS_GLO_CFG + 0x6C)
-#define MTK_RSS_INDR_TABLE_SIZE4 0x39393939
+#define MTK_RSS_INDR_TABLE_DW(x) (MTK_PDMA_RSS_GLO_CFG + 0x50 + \
+ ((x) * 0x4))
/* PDMA Global Configuration Register */
#define MTK_PDMA_GLO_CFG (PDMA_BASE + 0x204)
@@ -1614,6 +1607,7 @@
struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
+ u32 rss_num;
u64 caps;
u64 required_clks;
bool required_pctl;
@@ -1870,4 +1864,5 @@
int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num);
#endif /* MTK_ETH_H */