[rdkb][common][bsp][Refactor and sync wifi from openwrt]
[Description]
3a2eef0b [MAC80211][Release][Update release note for Filogic 880/860 MLO Beta release]
cfbd2411 [MAC80211][Release][Filogic 880/860 MLO Beta release]
6c180e3f [MAC80211][WiFi7][misc][Add Eagle BE14000 efem default bin]
a55f34db [MAC80211][Release][Prepare for Filogic 880/860 release]
5b45ebca [MAC80211][WiFi7][hostapd][Add puncture bitmap to ucode]
95bbea73 [MAC80211][WiFi6][mt76][Add PID to only report data-frame TX rate]
b15ced26 [MAC80211][WiFi6][hostapd][Fix DFS channel selection issue]
d59133cb [MAC80211][WiFi6][mt76][Fix pse info not correct information]
3921b4b2 [MAC80211][WiFi6][mt76][Fix incomplete QoS-map setting to FW]
4e7690c7 [MAC80211][WiFi6/7][app][Change ATECHANNEL mapping cmd]
eb37af90 [MAC80211][WiFi7][app][Add support for per-packet bw & primary selection]
0ea82adf [MAC80211][WiFi6][core][Fix DFS CAC issue after CSA]
[Release-log]
Change-Id: I9bec97ec1b2e1c49ed43a812a07a5b21fcbb70a6
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0040-mtk-mt76-mt7996-add-support-spatial-reuse-debug-comm.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0040-mtk-mt76-mt7996-add-support-spatial-reuse-debug-comm.patch
new file mode 100644
index 0000000..6bbd559
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0040-mtk-mt76-mt7996-add-support-spatial-reuse-debug-comm.patch
@@ -0,0 +1,397 @@
+From cb8632560f8055d6af142932abf723d54af5c25e Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Mon, 10 Jul 2023 11:47:29 +0800
+Subject: [PATCH 040/199] mtk: mt76: mt7996: add support spatial reuse debug
+ commands
+
+This commit adds the following debug commands in debugfs:
+1. sr_enable: enable/disable spatial reuse feature. Default is on.
+2. sr_enhanced_enable: enable/disable enhanced spatial reuse feature.
+Default is on. This feature is mtk proprietary feature.
+3. sr_stats: Check the Spatial reuse tx statistics.
+4. sr_scene_cond: Check the result of mtk scene detection algorithm. Mtk
+scene detection algorithm in firmware may decide whether current
+environment can SR Tx or not.
+
+To learn more details of these commands, please check:
+https://wiki.mediatek.inc/display/APKB/mt76+Phy+feature+debug+Cheetsheet#mt76PhyfeaturedebugCheetsheet-SpatialReuse
+
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/main.c | 6 +++
+ mt7996/mcu.c | 8 ++++
+ mt7996/mt7996.h | 6 +++
+ mt7996/mtk_debugfs.c | 82 ++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.c | 111 +++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_mcu.h | 56 ++++++++++++++++++++++
+ 7 files changed, 270 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 5a1b4d0d..726f5e9d 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1051,6 +1051,7 @@ enum {
+ MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
+ MCU_UNI_EVENT_SCAN_DONE = 0x0e,
+ MCU_UNI_EVENT_RDD_REPORT = 0x11,
++ MCU_UNI_EVENT_SR = 0x25,
+ MCU_UNI_EVENT_ROC = 0x27,
+ MCU_UNI_EVENT_TX_DONE = 0x2d,
+ MCU_UNI_EVENT_BF = 0x33,
+diff --git a/mt7996/main.c b/mt7996/main.c
+index a51fc696..f7819a85 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -6,6 +6,9 @@
+ #include "mt7996.h"
+ #include "mcu.h"
+ #include "mac.h"
++#ifdef CONFIG_MTK_DEBUG
++#include "mtk_mcu.h"
++#endif
+
+ static bool mt7996_dev_running(struct mt7996_dev *dev)
+ {
+@@ -86,6 +89,9 @@ int mt7996_run(struct ieee80211_hw *hw)
+ goto out;
+
+ #ifdef CONFIG_MTK_DEBUG
++ phy->sr_enable = true;
++ phy->enhanced_sr_enable = true;
++
+ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
+ dev->dbg.sku_disable ? 0 : phy->sku_limit_en);
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 40860f9f..362af7aa 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -717,6 +717,14 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ case MCU_UNI_EVENT_WED_RRO:
+ mt7996_mcu_wed_rro_event(dev, skb);
+ break;
++#ifdef CONFIG_MTK_DEBUG
++ case MCU_UNI_EVENT_SR:
++ mt7996_mcu_rx_sr_event(dev, skb);
++ break;
++#endif
++ case MCU_UNI_EVENT_THERMAL:
++ mt7996_mcu_rx_thermal_notify(dev, skb);
++ break;
+ #ifdef CONFIG_NL80211_TESTMODE
+ case MCU_UNI_EVENT_TESTMODE_CTRL:
+ mt7996_tm_rf_test_event(dev, skb);
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 01a5abdf..20fa4221 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -357,6 +357,10 @@ struct mt7996_phy {
+ spinlock_t amnt_lock;
+ struct mt7996_air_monitor_ctrl amnt_ctrl;
+ #endif
++#ifdef CONFIG_MTK_DEBUG
++ bool sr_enable:1;
++ bool enhanced_sr_enable:1;
++#endif
+ };
+
+ struct mt7996_dev {
+@@ -807,6 +811,8 @@ enum edcca_bw_id {
+ #ifdef CONFIG_MTK_DEBUG
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
++int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
++void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
+
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 053005dd..06dc794e 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2835,6 +2835,83 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
+ return 0;
+ }
+
++static int
++mt7996_sr_enable_get(void *data, u64 *val)
++{
++ struct mt7996_phy *phy = data;
++
++ *val = phy->sr_enable;
++
++ return 0;
++}
++
++static int
++mt7996_sr_enable_set(void *data, u64 val)
++{
++ struct mt7996_phy *phy = data;
++ int ret;
++
++ if (!!val == phy->sr_enable)
++ return 0;
++
++ ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, val, true);
++ if (ret)
++ return ret;
++
++ return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, 0, false);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, mt7996_sr_enable_get,
++ mt7996_sr_enable_set, "%lld\n");
++static int
++mt7996_sr_enhanced_enable_get(void *data, u64 *val)
++{
++ struct mt7996_phy *phy = data;
++
++ *val = phy->enhanced_sr_enable;
++
++ return 0;
++}
++
++static int
++mt7996_sr_enhanced_enable_set(void *data, u64 val)
++{
++ struct mt7996_phy *phy = data;
++ int ret;
++
++ if (!!val == phy->enhanced_sr_enable)
++ return 0;
++
++ ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, val, true);
++ if (ret)
++ return ret;
++
++ return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, 0, false);
++}
++DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enhanced_enable, mt7996_sr_enhanced_enable_get,
++ mt7996_sr_enhanced_enable_set, "%lld\n");
++
++static int
++mt7996_sr_stats_show(struct seq_file *file, void *data)
++{
++ struct mt7996_phy *phy = file->private;
++
++ mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_IND, 0, false);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(mt7996_sr_stats);
++
++static int
++mt7996_sr_scene_cond_show(struct seq_file *file, void *data)
++{
++ struct mt7996_phy *phy = file->private;
++
++ mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_SW_SD, 0, false);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(mt7996_sr_scene_cond);
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ struct mt7996_dev *dev = phy->dev;
+@@ -2915,6 +2992,11 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
+ debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
+
++ debugfs_create_file("sr_enable", 0600, dir, phy, &fops_sr_enable);
++ debugfs_create_file("sr_enhanced_enable", 0600, dir, phy, &fops_sr_enhanced_enable);
++ debugfs_create_file("sr_stats", 0400, dir, phy, &mt7996_sr_stats_fops);
++ debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7996_sr_scene_cond_fops);
++
+ return 0;
+ }
+
+diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
+index 5c54d02c..dbdf8d80 100644
+--- a/mt7996/mtk_mcu.c
++++ b/mt7996/mtk_mcu.c
+@@ -146,4 +146,115 @@ int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
+ return 0;
+ }
+
++int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set)
++{
++ struct {
++ u8 band_idx;
++ u8 _rsv[3];
++
++ __le16 tag;
++ __le16 len;
++
++ __le32 val;
++
++ } __packed req = {
++ .band_idx = phy->mt76->band_idx,
++
++ .tag = cpu_to_le16(action),
++ .len = cpu_to_le16(sizeof(req) - 4),
++
++ .val = cpu_to_le32((u32) val),
++ };
++
++ if (set)
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SR), &req,
++ sizeof(req), false);
++ else
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD_QUERY(SR), &req,
++ sizeof(req), false);
++}
++
++void mt7996_mcu_rx_sr_swsd(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++#define SR_SCENE_DETECTION_TIMER_PERIOD_MS 500
++ struct mt7996_mcu_sr_swsd_event *event;
++ static const char * const rules[] = {"1 - NO CONNECTED", "2 - NO CONGESTION",
++ "3 - NO INTERFERENCE", "4 - SR ON"};
++ u8 idx;
++
++ event = (struct mt7996_mcu_sr_swsd_event *)skb->data;
++ idx = event->basic.band_idx;
++
++ dev_info(dev->mt76.dev, "Band index = %u\n", le16_to_cpu(event->basic.band_idx));
++ dev_info(dev->mt76.dev, "Hit Rule = %s\n", rules[event->tlv[idx].rule]);
++ dev_info(dev->mt76.dev, "Timer Period = %d(us)\n"
++ "Congestion Ratio = %d.%1d%%\n",
++ SR_SCENE_DETECTION_TIMER_PERIOD_MS * 1000,
++ le32_to_cpu(event->tlv[idx].total_airtime_ratio) / 10,
++ le32_to_cpu(event->tlv[idx].total_airtime_ratio) % 10);
++ dev_info(dev->mt76.dev,
++ "Total Airtime = %d(us)\n"
++ "ChBusy = %d\n"
++ "SrTx = %d\n"
++ "OBSS = %d\n"
++ "MyTx = %d\n"
++ "MyRx = %d\n"
++ "Interference Ratio = %d.%1d%%\n",
++ le32_to_cpu(event->tlv[idx].total_airtime),
++ le32_to_cpu(event->tlv[idx].channel_busy_time),
++ le32_to_cpu(event->tlv[idx].sr_tx_airtime),
++ le32_to_cpu(event->tlv[idx].obss_airtime),
++ le32_to_cpu(event->tlv[idx].my_tx_airtime),
++ le32_to_cpu(event->tlv[idx].my_rx_airtime),
++ le32_to_cpu(event->tlv[idx].obss_airtime_ratio) / 10,
++ le32_to_cpu(event->tlv[idx].obss_airtime_ratio) % 10);
++}
++
++void mt7996_mcu_rx_sr_hw_indicator(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++ struct mt7996_mcu_sr_hw_ind_event *event;
++
++ event = (struct mt7996_mcu_sr_hw_ind_event *)skb->data;
++
++ dev_info(dev->mt76.dev, "Inter PPDU Count = %u\n",
++ le16_to_cpu(event->inter_bss_ppdu_cnt));
++ dev_info(dev->mt76.dev, "SR Valid Count = %u\n",
++ le16_to_cpu(event->non_srg_valid_cnt));
++ dev_info(dev->mt76.dev, "SR Tx Count = %u\n",
++ le32_to_cpu(event->sr_ampdu_mpdu_cnt));
++ dev_info(dev->mt76.dev, "SR Tx Acked Count = %u\n",
++ le32_to_cpu(event->sr_ampdu_mpdu_acked_cnt));
++}
++
++void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++ struct mt76_phy *mphy = &dev->mt76.phy;
++ struct mt7996_phy *phy;
++ struct mt7996_mcu_sr_common_event *event;
++
++ event = (struct mt7996_mcu_sr_common_event *)skb->data;
++ mphy = dev->mt76.phys[event->basic.band_idx];
++ if (!mphy)
++ return;
++
++ phy = (struct mt7996_phy *)mphy->priv;
++
++ switch (le16_to_cpu(event->basic.tag)) {
++ case UNI_EVENT_SR_CFG_SR_ENABLE:
++ phy->sr_enable = le32_to_cpu(event->value) ? true : false;
++ break;
++ case UNI_EVENT_SR_HW_ESR_ENABLE:
++ phy->enhanced_sr_enable = le32_to_cpu(event->value) ? true : false;
++ break;
++ case UNI_EVENT_SR_SW_SD:
++ mt7996_mcu_rx_sr_swsd(dev, skb);
++ break;
++ case UNI_EVENT_SR_HW_IND:
++ mt7996_mcu_rx_sr_hw_indicator(dev, skb);
++ break;
++ default:
++ dev_info(dev->mt76.dev, "Unknown SR event tag %d\n",
++ le16_to_cpu(event->basic.tag));
++ }
++}
+ #endif
+diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
+index 36a58ad6..098e63ae 100644
+--- a/mt7996/mtk_mcu.h
++++ b/mt7996/mtk_mcu.h
+@@ -121,6 +121,62 @@ enum {
+ EDCCA_JAPAN = 3
+ };
+
++enum {
++ UNI_EVENT_SR_CFG_SR_ENABLE = 0x1,
++ UNI_EVENT_SR_SW_SD = 0x83,
++ UNI_EVENT_SR_HW_IND = 0xC9,
++ UNI_EVENT_SR_HW_ESR_ENABLE = 0xD8,
++};
++enum {
++ UNI_CMD_SR_CFG_SR_ENABLE = 0x1,
++ UNI_CMD_SR_SW_SD = 0x84,
++ UNI_CMD_SR_HW_IND = 0xCB,
++ UNI_CMD_SR_HW_ENHANCE_SR_ENABLE = 0xDA,
++};
++
++struct mt7996_mcu_sr_basic_event {
++ struct mt7996_mcu_rxd rxd;
++
++ u8 band_idx;
++ u8 _rsv[3];
++
++ __le16 tag;
++ __le16 len;
++};
++
++struct sr_sd_tlv {
++ u8 _rsv[16];
++ __le32 sr_tx_airtime;
++ __le32 obss_airtime;
++ __le32 my_tx_airtime;
++ __le32 my_rx_airtime;
++ __le32 channel_busy_time;
++ __le32 total_airtime;
++ __le32 total_airtime_ratio;
++ __le32 obss_airtime_ratio;
++ u8 rule;
++ u8 _rsv2[59];
++} __packed;
++
++struct mt7996_mcu_sr_swsd_event {
++ struct mt7996_mcu_sr_basic_event basic;
++ struct sr_sd_tlv tlv[3];
++} __packed;
++
++struct mt7996_mcu_sr_common_event {
++ struct mt7996_mcu_sr_basic_event basic;
++ __le32 value;
++};
++
++struct mt7996_mcu_sr_hw_ind_event {
++ struct mt7996_mcu_sr_basic_event basic;
++ __le16 non_srg_valid_cnt;
++ u8 _rsv[4];
++ __le16 inter_bss_ppdu_cnt;
++ u8 _rsv2[4];
++ __le32 sr_ampdu_mpdu_cnt;
++ __le32 sr_ampdu_mpdu_acked_cnt;
++};
+ #endif
+
+ #endif
+--
+2.18.0
+