[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
+