[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/0176-mtk-mt76-Add-dynamic-pp-vendor-and-debug-pp-algo-cmd.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0176-mtk-mt76-Add-dynamic-pp-vendor-and-debug-pp-algo-cmd.patch
new file mode 100644
index 0000000..7b2b8de
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0176-mtk-mt76-Add-dynamic-pp-vendor-and-debug-pp-algo-cmd.patch
@@ -0,0 +1,425 @@
+From a2ca9b9f2be2bd336db4c3e6a2f6693d6e2236b4 Mon Sep 17 00:00:00 2001
+From: Allen Ye <allen.ye@mediatek.com>
+Date: Tue, 28 May 2024 15:39:06 +0800
+Subject: [PATCH 176/199] mtk: mt76: Add dynamic pp vendor and debug pp algo
+ cmd support
+
+Add dynamic pp vendor and debug pp algo cmd support.
+1. Add support channel switch with a punct bitmap.
+2. Add pp event for fw mode and trigger a channel switch by hostapd.
+3. Add pp algo dump cmd to get current fw punct bitmap and mode.
+
+When extender sta have not connected to root ap and the chandef is null.
+mt76 just ignore the event. Once the sta connect to ap, the sta part would
+send a new fw cmd to update the pp bitmap.
+
+Signed-off-by: Allen Ye <allen.ye@mediatek.com>
+---
+ mt7996/mcu.c | 70 ++++++++++++++++++++++++++++-
+ mt7996/mcu.h | 38 ++++++++++++++++
+ mt7996/mt7996.h | 2 +
+ mt7996/mtk_debugfs.c | 14 ++++++
+ mt7996/vendor.c | 103 +++++++++++++++++++++++++++++++------------
+ mt7996/vendor.h | 8 +++-
+ 6 files changed, 205 insertions(+), 30 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index adb71bf5..00bc675e 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1280,6 +1280,39 @@ mt7996_mcu_wed_rro_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ }
+ }
+
++void
++mt7996_dump_pp_statistic_event(struct mt7996_dev *dev,
++ struct mt7996_mcu_pp_alg_ctrl_event *event)
++{
++ u32 unit_time = le32_to_cpu(event->pp_timer_intv);
++
++ dev_info(dev->mt76.dev, "band idx = %u\n", le32_to_cpu(event->band_idx));
++ dev_info(dev->mt76.dev, "x2 value = %u\n", le32_to_cpu(event->thr_x2_value));
++ dev_info(dev->mt76.dev, "x2 shift = %u\n", le32_to_cpu(event->thr_x2_shift));
++ dev_info(dev->mt76.dev, "x3 value = %u\n", le32_to_cpu(event->thr_x3_value));
++ dev_info(dev->mt76.dev, "x3 shift = %u\n", le32_to_cpu(event->thr_x3_shift));
++ dev_info(dev->mt76.dev, "x4 value = %u\n", le32_to_cpu(event->thr_x4_value));
++ dev_info(dev->mt76.dev, "x4 shift = %u\n", le32_to_cpu(event->thr_x4_shift));
++ dev_info(dev->mt76.dev, "x5 value = %u\n", le32_to_cpu(event->thr_x5_value));
++ dev_info(dev->mt76.dev, "x5 shift = %u\n", le32_to_cpu(event->thr_x5_shift));
++ dev_info(dev->mt76.dev, "x6 value = %u\n", le32_to_cpu(event->thr_x6_value));
++ dev_info(dev->mt76.dev, "x6 shift = %u\n", le32_to_cpu(event->thr_x6_shift));
++ dev_info(dev->mt76.dev, "x7 value = %u\n", le32_to_cpu(event->thr_x7_value));
++ dev_info(dev->mt76.dev, "x7 shift = %u\n", le32_to_cpu(event->thr_x7_shift));
++ dev_info(dev->mt76.dev, "x8 value = %u\n", le32_to_cpu(event->thr_x8_value));
++ dev_info(dev->mt76.dev, "x8 shift = %u\n", le32_to_cpu(event->thr_x8_shift));
++ dev_info(dev->mt76.dev, "sw_pp_time = %u (Unit: %u ms)\n",
++ le32_to_cpu(event->sw_pp_time), unit_time);
++ dev_info(dev->mt76.dev, "hw_pp_time = %u (Unit: %u ms)\n",
++ le32_to_cpu(event->hw_pp_time), unit_time);
++ dev_info(dev->mt76.dev, "no_pp_time = %u (Unit: %u ms)\n",
++ le32_to_cpu(event->no_pp_time), unit_time);
++ dev_info(dev->mt76.dev, "auto_bw_time = %u (Unit: %u ms)\n",
++ le32_to_cpu(event->auto_bw_time), unit_time);
++ dev_info(dev->mt76.dev, "punct_bitmap = 0x%04x\n",
++ le16_to_cpu(event->punct_bitmap));
++}
++
+ static void
+ mt7996_mcu_pp_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ {
+@@ -1306,9 +1339,13 @@ mt7996_mcu_pp_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ if (phy->punct_bitmap == report_bitmap)
+ return;
+
+- if (phy->pp_mode == PP_FW_MODE)
++ if (phy->pp_mode == PP_FW_MODE) {
+ phy->punct_bitmap = report_bitmap;
+-
++ mt7996_vendor_pp_bitmap_update(phy, report_bitmap);
++ }
++ break;
++ case UNI_EVENT_PP_TAG_ALG_CTRL:
++ mt7996_dump_pp_statistic_event(dev, (struct mt7996_mcu_pp_alg_ctrl_event *)event);
+ break;
+ }
+ }
+@@ -6405,6 +6442,35 @@ int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy,
+ &req, sizeof(req), false);
+ }
+
++int mt7996_mcu_set_pp_alg_ctrl(struct mt7996_phy *phy, u8 action)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct {
++ u8 _rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++
++ __le32 pp_timer_intv;
++ __le32 rsv2[14];
++ u8 band_idx;
++ u8 pp_action;
++ u8 reset;
++ u8 _rsv3;
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_CMD_PP_ALG_CTRL),
++ .len = cpu_to_le16(sizeof(req) - 4),
++
++ .pp_timer_intv = action == PP_ALG_SET_TIMER ? 2000 : 0,
++ .band_idx = phy->mt76->band_idx,
++ .pp_action = action,
++ .reset = 0,
++ };
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
++ &req, sizeof(req), false);
++}
++
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
+ {
+ struct mt7996_dev *dev = phy->dev;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 011b6c7a..01eb0ea1 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -1162,6 +1162,7 @@ enum {
+
+ enum {
+ UNI_CMD_PP_EN_CTRL,
++ UNI_CMD_PP_ALG_CTRL,
+ UNI_CMD_PP_DSCB_CTRL,
+ };
+
+@@ -1171,6 +1172,11 @@ enum pp_mode {
+ PP_USR_MODE,
+ };
+
++enum pp_alg_action {
++ PP_ALG_SET_TIMER,
++ PP_ALG_GET_STATISTICS = 2,
++};
++
+ enum {
+ UNI_EVENT_PP_TAG_ALG_CTRL = 1,
+ UNI_EVENT_STATIC_PP_TAG_DSCB_IE,
+@@ -1204,6 +1210,38 @@ struct mt7996_mcu_pp_dscb_event {
+ u8 __rsv3[2];
+ } __packed;
+
++struct mt7996_mcu_pp_alg_ctrl_event {
++ struct mt7996_mcu_rxd rxd;
++
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++
++ __le32 pp_timer_intv;
++ __le32 thr_x2_value;
++ __le32 thr_x2_shift;
++ __le32 thr_x3_value;
++ __le32 thr_x3_shift;
++ __le32 thr_x4_value;
++ __le32 thr_x4_shift;
++ __le32 thr_x5_value;
++ __le32 thr_x5_shift;
++ __le32 thr_x6_value;
++ __le32 thr_x6_shift;
++ __le32 thr_x7_value;
++ __le32 thr_x7_shift;
++ __le32 thr_x8_value;
++ __le32 thr_x8_shift;
++ __le32 sw_pp_time;
++ __le32 hw_pp_time;
++ __le32 no_pp_time;
++ __le32 auto_bw_time;
++ u8 band_idx;
++ u8 __rsv2;
++ __le16 punct_bitmap;
++} __packed;
++
+ enum {
+ UNI_CMD_SCS_SEND_DATA,
+ UNI_CMD_SCS_SET_PD_THR_RANGE = 2,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index f31d3f36..74c32827 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -1278,6 +1278,7 @@ int mt7996_mcu_cp_support(struct mt7996_dev *dev, u8 mode);
+ int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, u8 mode, u16 bitmap);
+ int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef,
+ u8 omac_idx);
++int mt7996_mcu_set_pp_alg_ctrl(struct mt7996_phy *phy, u8 action);
+ int mt7996_mcu_set_eml_omn(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 link_id,
+ struct ieee80211_sta *sta, struct mt7996_eml_omn *eml_omn);
+ #ifdef CONFIG_MAC80211_DEBUGFS
+@@ -1307,6 +1308,7 @@ int mt7996_mcu_set_muru_cfg(struct mt7996_dev *dev, void *data);
+ void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
+ int mt7996_mcu_set_csi(struct mt7996_phy *phy, u8 mode,
+ u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
++int mt7996_vendor_pp_bitmap_update(struct mt7996_phy *phy, u16 bitmap);
+ #endif
+
+ int mt7996_mcu_edcca_enable(struct mt7996_phy *phy, bool enable);
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index b698c68a..093f3c69 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -4368,6 +4368,18 @@ static const struct file_operations fops_muru_dbg_info = {
+ .llseek = default_llseek,
+ };
+
++static int mt7996_pp_alg_show(struct seq_file *s, void *data)
++{
++ struct mt7996_phy *phy = s->private;
++ struct mt7996_dev *dev = phy->dev;
++
++ dev_info(dev->mt76.dev, "pp_mode = %d\n", phy->pp_mode);
++ mt7996_mcu_set_pp_alg_ctrl(phy, PP_ALG_GET_STATISTICS);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(mt7996_pp_alg);
++
+ void mt7996_mtk_init_band_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ /* agg */
+@@ -4390,6 +4402,8 @@ void mt7996_mtk_init_band_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+
+ debugfs_create_file("thermal_enable", 0600, dir, phy, &fops_thermal_enable);
+ debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
++
++ debugfs_create_file("pp_alg", 0200, dir, phy, &mt7996_pp_alg_fops);
+ }
+
+ void mt7996_mtk_init_dev_debugfs(struct mt7996_dev *dev, struct dentry *dir)
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 33c682c0..d7973c5e 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -96,7 +96,9 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
+ static struct nla_policy
+ pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
+ [MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
+- [MTK_VENDOR_ATTR_PP_BAND_IDX] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_PP_LINK_ID] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_PP_BITMAP] = { .type = NLA_U16 },
++ [MTK_VENDOR_ATTR_PP_CURR_FREQ] = { .type = NLA_U32 },
+ };
+
+ static const struct nla_policy
+@@ -805,31 +807,44 @@ static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
+ const void *data, int data_len)
+ {
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct ieee80211_vif *vif = wdev_to_ieee80211_vif(wdev);
+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_PP_CTRL];
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy;
+- struct mt76_phy *mphy;
+ struct cfg80211_chan_def *chandef;
++ struct mt7996_bss_conf *mconf;
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ int err;
+- u8 val8, band_idx = 0;
++ u8 mode = 0, link_id = 0;
++ u16 punct_bitmap = 0;
+
+ err = nla_parse(tb, MTK_VENDOR_ATTR_PP_CTRL_MAX, data, data_len,
+ pp_ctrl_policy, NULL);
+
+- if (tb[MTK_VENDOR_ATTR_PP_BAND_IDX]) {
+- band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_BAND_IDX]);
+- }
++ if (tb[MTK_VENDOR_ATTR_PP_MODE])
++ mode = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_MODE]);
++ else
++ return -EINVAL;
+
+- if (!mt7996_band_valid(dev, band_idx))
+- goto error;
++ if (ieee80211_vif_is_mld(vif) && tb[MTK_VENDOR_ATTR_PP_LINK_ID]) {
++ link_id = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_LINK_ID]);
++ if (link_id >= IEEE80211_LINK_UNSPECIFIED)
++ return -EINVAL;
++ }
+
+- mphy = dev->mt76.phys[band_idx];
+- if (!mphy)
++ rcu_read_lock();
++ mconf = rcu_dereference(mvif->link[link_id]);
++ if (!mconf) {
++ rcu_read_unlock();
+ goto error;
++ }
+
+- phy = (struct mt7996_phy *)mphy->priv;
+- if (!phy)
++ phy = mconf->phy;
++ if (!phy) {
++ rcu_read_unlock();
+ goto error;
++ }
++ rcu_read_unlock();
+
+ chandef = &phy->chanctx->chandef;
+ if (!chandef)
+@@ -838,28 +853,53 @@ static int mt7996_vendor_pp_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
+ if (chandef->chan->band == NL80211_BAND_2GHZ)
+ return 0;
+
+- if (tb[MTK_VENDOR_ATTR_PP_MODE]) {
+- val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_PP_MODE]);
+- switch (val8) {
+- case PP_DISABLE:
+- case PP_FW_MODE:
+- err = mt7996_mcu_set_pp_en(phy, val8, 0);
+- break;
+- case PP_USR_MODE:
+- /* handled by add_chanctx */
+- err = 0;
+- break;
+- default:
+- err = -EINVAL;
+- }
++ switch (mode) {
++ case PP_USR_MODE:
++ if (tb[MTK_VENDOR_ATTR_PP_BITMAP])
++ punct_bitmap = nla_get_u16(tb[MTK_VENDOR_ATTR_PP_BITMAP]);
++ fallthrough;
++ case PP_FW_MODE:
++ case PP_DISABLE:
++ err = mt7996_mcu_set_pp_en(phy, mode, punct_bitmap);
++ break;
++ default:
++ return -EINVAL;
+ }
+
+ return err;
+ error:
+- dev_err(dev->mt76.dev, "Invalid band idx: %d\n", band_idx);
++ dev_err(dev->mt76.dev, "Invalid link id: %d\n", link_id);
+ return -EINVAL;
+ }
+
++int mt7996_vendor_pp_bitmap_update(struct mt7996_phy *phy, u16 bitmap)
++{
++ struct sk_buff *skb;
++ struct mt76_phy *mphy = phy->mt76;
++ struct cfg80211_chan_def *chandef = &phy->chanctx->chandef;
++
++ if (!chandef)
++ return 0;
++
++ skb = cfg80211_vendor_event_alloc(mphy->hw->wiphy, NULL, 20,
++ MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE,
++ GFP_ATOMIC);
++
++ if (!skb)
++ return -ENOMEM;
++
++ if (nla_put_u16(skb, MTK_VENDOR_ATTR_PP_BITMAP, bitmap) ||
++ nla_put_u32(skb, MTK_VENDOR_ATTR_PP_CURR_FREQ,
++ chandef->chan->center_freq)) {
++ dev_kfree_skb(skb);
++ return -ENOMEM;
++ }
++
++ cfg80211_vendor_event(skb, GFP_ATOMIC);
++
++ return 0;
++}
++
+ static int mt7996_vendor_rfeature_ctrl(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+@@ -1490,10 +1530,19 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ },
+ };
+
++static const struct nl80211_vendor_cmd_info mt7996_vendor_events[] = {
++ [MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE] = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE,
++ },
++};
++
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+ {
+ phy->mt76->hw->wiphy->vendor_commands = mt7996_vendor_commands;
+ phy->mt76->hw->wiphy->n_vendor_commands = ARRAY_SIZE(mt7996_vendor_commands);
++ phy->mt76->hw->wiphy->vendor_events = mt7996_vendor_events;
++ phy->mt76->hw->wiphy->n_vendor_events = ARRAY_SIZE(mt7996_vendor_events);
+
+ INIT_LIST_HEAD(&phy->csi.list);
+ spin_lock_init(&phy->csi.lock);
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 714f0b3e..ca4f00ad 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -21,6 +21,10 @@ enum mtk_nl80211_vendor_subcmds {
+ MTK_NL80211_VENDOR_SUBCMD_EML_CTRL = 0xd3,
+ };
+
++enum mtk_nl80211_vendor_events {
++ MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE = 0x5,
++};
++
+ enum mtk_vendor_attr_edcca_ctrl {
+ MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0,
+
+@@ -222,7 +226,9 @@ enum mtk_vendor_attr_pp_ctrl {
+ MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
+
+ MTK_VENDOR_ATTR_PP_MODE,
+- MTK_VENDOR_ATTR_PP_BAND_IDX,
++ MTK_VENDOR_ATTR_PP_LINK_ID,
++ MTK_VENDOR_ATTR_PP_BITMAP,
++ MTK_VENDOR_ATTR_PP_CURR_FREQ,
+
+ /* keep last */
+ NUM_MTK_VENDOR_ATTRS_PP_CTRL,
+--
+2.18.0
+