| From 5a8454a960379567f438f55eda39635a54a7bfbf Mon Sep 17 00:00:00 2001 |
| From: Peter Chiu <chui-hao.chiu@mediatek.com> |
| Date: Wed, 19 Apr 2023 18:32:41 +0800 |
| Subject: [PATCH 2003/2032] mtk: wifi: mt76: add random early drop support |
| |
| --- |
| mt7996/debugfs.c | 1 + |
| mt7996/mac.c | 7 ++++ |
| mt7996/mcu.c | 81 ++++++++++++++++++++++++++++++++++++++++++-- |
| mt7996/mcu.h | 4 ++- |
| mt7996/mt7996.h | 5 ++- |
| mt7996/mtk_debugfs.c | 23 +++++++++++++ |
| mt7996/mtk_mcu.c | 26 ++++++++++++++ |
| mt7996/mtk_mcu.h | 24 +++++++++++++ |
| 8 files changed, 167 insertions(+), 4 deletions(-) |
| |
| diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c |
| index dff9e467..01f98b2e 100644 |
| --- a/mt7996/debugfs.c |
| +++ b/mt7996/debugfs.c |
| @@ -629,6 +629,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data) |
| seq_printf(file, "Tx attempts: %8u (MPDUs)\n", attempts); |
| seq_printf(file, "Tx success: %8u (MPDUs)\n", success); |
| seq_printf(file, "Tx PER: %u%%\n", per); |
| + seq_printf(file, "Tx RED drop: %8u\n", phy->red_drop); |
| |
| mt7996_txbf_stat_read_phy(phy, file); |
| |
| diff --git a/mt7996/mac.c b/mt7996/mac.c |
| index 6fa46e46..64cec164 100644 |
| --- a/mt7996/mac.c |
| +++ b/mt7996/mac.c |
| @@ -1176,6 +1176,13 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) |
| |
| wcid->stats.tx_retries += tx_retries; |
| wcid->stats.tx_failed += tx_failed; |
| + |
| + if (FIELD_GET(MT_TXFREE_INFO_STAT, info) == 2) { |
| + struct mt7996_phy *mphy = |
| + __mt7996_phy(dev, wcid->phy_idx); |
| + |
| + mphy->red_drop++; |
| + } |
| continue; |
| } |
| |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index 2cdaf845..be21dd62 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -3145,8 +3145,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev) |
| if (ret) |
| return ret; |
| |
| - return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), |
| - MCU_WA_PARAM_RED, 0, 0); |
| + return mt7996_mcu_red_config(dev, |
| + mtk_wed_device_active(&dev->mt76.mmio.wed)); |
| } |
| |
| int mt7996_mcu_init(struct mt7996_dev *dev) |
| @@ -3178,6 +3178,83 @@ out: |
| skb_queue_purge(&dev->mt76.mcu.res_q); |
| } |
| |
| +static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev) |
| +{ |
| +#define RED_TOKEN_SRC_CNT 4 |
| +#define RED_TOKEN_CONFIG 2 |
| + struct { |
| + __le32 arg0; |
| + __le32 arg1; |
| + __le32 arg2; |
| + |
| + u8 mode; |
| + u8 version; |
| + u8 _rsv[4]; |
| + __le16 len; |
| + |
| + __le16 tcp_offset; |
| + __le16 priority_offset; |
| + __le16 token_per_src[RED_TOKEN_SRC_CNT]; |
| + __le16 token_thr_per_src[RED_TOKEN_SRC_CNT]; |
| + |
| + u8 _rsv2[604]; |
| + } __packed req = { |
| + .arg0 = cpu_to_le32(MCU_WA_PARAM_RED_CONFIG), |
| + |
| + .mode = RED_TOKEN_CONFIG, |
| + .len = cpu_to_le16(sizeof(req) - sizeof(__le32) * 3), |
| + |
| + .tcp_offset = cpu_to_le16(200), |
| + .priority_offset = cpu_to_le16(255), |
| + }; |
| + u8 i; |
| + |
| + for (i = 0; i < RED_TOKEN_SRC_CNT; i++) { |
| + req.token_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE); |
| + req.token_thr_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE); |
| + } |
| + |
| + if (!mtk_wed_device_active(&dev->mt76.mmio.wed)) |
| + req.token_per_src[RED_TOKEN_SRC_CNT - 1] = |
| + cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE); |
| + |
| + return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET), |
| + &req, sizeof(req), false); |
| +} |
| + |
| +int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable) |
| +{ |
| +#define RED_DISABLE 0 |
| +#define RED_BY_WA_ENABLE 2 |
| + struct { |
| + u8 __rsv1[4]; |
| + |
| + __le16 tag; |
| + __le16 len; |
| + u8 enable; |
| + u8 __rsv2[3]; |
| + } __packed req = { |
| + .tag = cpu_to_le16(UNI_VOW_RED_ENABLE), |
| + .len = cpu_to_le16(sizeof(req) - 4), |
| + .enable = enable ? RED_BY_WA_ENABLE : RED_DISABLE, |
| + }; |
| + int ret; |
| + |
| + ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req, |
| + sizeof(req), true); |
| + |
| + if (ret) |
| + return ret; |
| + |
| + ret = mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), |
| + MCU_WA_PARAM_RED_EN, enable, 0); |
| + |
| + if (ret || !enable) |
| + return ret; |
| + |
| + return mt7996_mcu_wa_red_config(dev); |
| +} |
| + |
| int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans) |
| { |
| struct { |
| diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| index 398bf3d2..4fa399bc 100644 |
| --- a/mt7996/mcu.h |
| +++ b/mt7996/mcu.h |
| @@ -346,8 +346,9 @@ enum { |
| enum { |
| MCU_WA_PARAM_PDMA_RX = 0x04, |
| MCU_WA_PARAM_CPU_UTIL = 0x0b, |
| - MCU_WA_PARAM_RED = 0x0e, |
| + MCU_WA_PARAM_RED_EN = 0x0e, |
| MCU_WA_PARAM_HW_PATH_HIF_VER = 0x2f, |
| + MCU_WA_PARAM_RED_CONFIG = 0x40, |
| }; |
| |
| enum mcu_mmps_mode { |
| @@ -919,6 +920,7 @@ enum { |
| UNI_VOW_DRR_CTRL, |
| UNI_VOW_RX_AT_AIRTIME_EN = 0x0b, |
| UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e, |
| + UNI_VOW_RED_ENABLE = 0x18, |
| }; |
| |
| enum { |
| diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| index 2227c08a..b0eb5d91 100644 |
| --- a/mt7996/mt7996.h |
| +++ b/mt7996/mt7996.h |
| @@ -352,6 +352,7 @@ struct mt7996_phy { |
| bool has_aux_rx; |
| |
| struct mt7996_scs_ctrl scs_ctrl; |
| + u32 red_drop; |
| |
| u8 muru_onoff; |
| |
| @@ -718,6 +719,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set) |
| int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans); |
| int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val); |
| int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); |
| +int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable); |
| int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl); |
| int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level); |
| int mt7996_mcu_trigger_assert(struct mt7996_dev *dev); |
| @@ -891,11 +893,12 @@ void mt7996_mcu_set_ppdu_tx_type(struct mt7996_phy *phy, u8 ppdu_type); |
| void mt7996_mcu_set_nusers_ofdma(struct mt7996_phy *phy, u8 type, u8 ofdma_user_cnt); |
| void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type); |
| void mt7996_tm_update_channel(struct mt7996_phy *phy); |
| + |
| +int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val); |
| #endif |
| |
| #ifdef CONFIG_NET_MEDIATEK_SOC_WED |
| int mt7996_dma_rro_init(struct mt7996_dev *dev); |
| #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ |
| |
| - |
| #endif |
| diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c |
| index c4cdbcdc..03f88780 100644 |
| --- a/mt7996/mtk_debugfs.c |
| +++ b/mt7996/mtk_debugfs.c |
| @@ -3015,6 +3015,27 @@ static int mt7996_muru_prot_thr_set(void *data, u64 val) |
| DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_prot_thr, NULL, |
| mt7996_muru_prot_thr_set, "%lld\n"); |
| |
| +static int |
| +mt7996_red_config_set(void *data, u64 val) |
| +{ |
| + struct mt7996_dev *dev = data; |
| + |
| + return mt7996_mcu_red_config(dev, !!val); |
| +} |
| + |
| +DEFINE_DEBUGFS_ATTRIBUTE(fops_red_config, NULL, |
| + mt7996_red_config_set, "%lld\n"); |
| + |
| +static int |
| +mt7996_vow_drr_dbg(void *data, u64 val) |
| +{ |
| + struct mt7996_dev *dev = data; |
| + |
| + return mt7996_mcu_set_vow_drr_dbg(dev, (u32)val); |
| +} |
| +DEFINE_DEBUGFS_ATTRIBUTE(fops_vow_drr_dbg, NULL, |
| + mt7996_vow_drr_dbg, "%lld\n"); |
| + |
| int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir) |
| { |
| struct mt7996_dev *dev = phy->dev; |
| @@ -3092,6 +3113,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir) |
| mt7996_wtbl_read); |
| |
| debugfs_create_devm_seqfile(dev->mt76.dev, "token", dir, mt7996_token_read); |
| + debugfs_create_file("red", 0200, dir, dev, &fops_red_config); |
| + debugfs_create_file("vow_drr_dbg", 0200, dir, dev, &fops_vow_drr_dbg); |
| |
| debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable); |
| debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable); |
| diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c |
| index f70bd0be..9a6636fd 100644 |
| --- a/mt7996/mtk_mcu.c |
| +++ b/mt7996/mtk_mcu.c |
| @@ -1254,4 +1254,30 @@ void mt7996_mcu_set_cert(struct mt7996_phy *phy, u8 type) |
| sizeof(req), false); |
| } |
| |
| +int mt7996_mcu_set_vow_drr_dbg(struct mt7996_dev *dev, u32 val) |
| +{ |
| +#define MT7996_VOW_DEBUG_MODE 0xe |
| + struct { |
| + u8 __rsv1[4]; |
| + |
| + __le16 tag; |
| + __le16 len; |
| + u8 __rsv2[4]; |
| + __le32 action; |
| + __le32 val; |
| + u8 __rsv3[8]; |
| + } __packed req = { |
| + .tag = cpu_to_le16(UNI_VOW_DRR_CTRL), |
| + .len = cpu_to_le16(sizeof(req) - 4), |
| + .action = cpu_to_le32(MT7996_VOW_DEBUG_MODE), |
| + .val = cpu_to_le32(val), |
| + }; |
| + |
| + if (val & ~VOW_DRR_DBG_FLAGS) |
| + return -EINVAL; |
| + |
| + return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req, |
| + sizeof(req), true); |
| +} |
| + |
| #endif |
| diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h |
| index 252ae98e..1568f10e 100644 |
| --- a/mt7996/mtk_mcu.h |
| +++ b/mt7996/mtk_mcu.h |
| @@ -1035,6 +1035,30 @@ enum muru_vendor_ctrl { |
| MU_CTRL_DL_USER_CNT, |
| MU_CTRL_UL_USER_CNT, |
| }; |
| + |
| +enum { |
| + VOW_DRR_DBG_DUMP_BMP = BIT(0), |
| + VOW_DRR_DBG_EST_AT_PRINT = BIT(1), |
| + VOW_DRR_DBG_ADJ_GLOBAL_THLD = BIT(21), |
| + VOW_DRR_DBG_PRN_LOUD = BIT(22), |
| + VOW_DRR_DBG_PRN_ADJ_STA = BIT(23), |
| + VOW_DRR_DBG_FIX_CR = GENMASK(27, 24), |
| + VOW_DRR_DBG_CLR_FIX_CR = BIT(28), |
| + VOW_DRR_DBG_DISABLE = BIT(29), |
| + VOW_DRR_DBG_DUMP_CR = BIT(30), |
| + VOW_DRR_DBG_PRN = BIT(31) |
| +}; |
| + |
| +#define VOW_DRR_DBG_FLAGS (VOW_DRR_DBG_DUMP_BMP | \ |
| + VOW_DRR_DBG_EST_AT_PRINT | \ |
| + VOW_DRR_DBG_ADJ_GLOBAL_THLD | \ |
| + VOW_DRR_DBG_PRN_LOUD | \ |
| + VOW_DRR_DBG_PRN_ADJ_STA | \ |
| + VOW_DRR_DBG_FIX_CR | \ |
| + VOW_DRR_DBG_CLR_FIX_CR | \ |
| + VOW_DRR_DBG_DISABLE | \ |
| + VOW_DRR_DBG_DUMP_CR | \ |
| + VOW_DRR_DBG_PRN) |
| #endif |
| |
| #endif |
| -- |
| 2.18.0 |
| |