WCNCR00165815][rdk-b][common][bsp][Refactor and sync kernel/wifi from Openwrt]
[Description]
Refactor and sync kernel/wifi from Openwrt
[Release-log]
N/A
diff --git a/recipes-wifi/linux-mt76/files/patches/3002-mt76-mt7915-wed-add-wds-support-when-wed-is-enabled.patch b/recipes-wifi/linux-mt76/files/patches/3002-mt76-mt7915-wed-add-wds-support-when-wed-is-enabled.patch
new file mode 100755
index 0000000..b3442f4
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/3002-mt76-mt7915-wed-add-wds-support-when-wed-is-enabled.patch
@@ -0,0 +1,207 @@
+From 2d158600e7c9b18069111d5935e9dbaf8c9277f3 Mon Sep 17 00:00:00 2001
+From: Sujuan Chen <sujuan.chen@mediatek.com>
+Date: Tue, 13 Dec 2022 17:51:26 +0800
+Subject: [PATCH 3002/3012] mt76: mt7915: wed: add wds support when wed is
+ enabled
+
+Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
+---
+ mt76.h | 6 ++++++
+ mt7915/main.c | 22 ++++++++++++++++++++--
+ mt7915/mcu.c | 13 +++++++++++--
+ mt7915/mcu.h | 1 +
+ util.c | 40 +++++++++++++++++++++++++++++++++++++---
+ util.h | 7 ++++++-
+ 6 files changed, 81 insertions(+), 8 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index 01baceaf..7b222e73 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -60,6 +60,12 @@ enum mt76_wed_type {
+ MT76_WED_Q_RX,
+ };
+
++enum mt76_wed_state {
++ MT76_WED_DEFAULT,
++ MT76_WED_ACTIVE,
++ MT76_WED_WDS_ACTIVE,
++};
++
+ struct mt76_bus_ops {
+ u32 (*rr)(struct mt76_dev *dev, u32 offset);
+ void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 370bfad7..75c78b8e 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -675,8 +675,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ #endif
+ int ret, idx;
+ u32 addr;
++ u8 flags = MT76_WED_DEFAULT;
+
+- idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ !is_mt7915(&dev->mt76)) {
++ flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ?
++ MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE;
++ }
++
++ idx = __mt76_wcid_alloc(mdev->wcid_mask, MT7915_WTBL_STA, flags);
+ if (idx < 0)
+ return -ENOSPC;
+
+@@ -1148,6 +1155,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
+ else
+ clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
+
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ !is_mt7915(&dev->mt76)) {
++ mt7915_sta_remove(hw, vif, sta);
++ mt76_sta_pre_rcu_remove(hw, vif, sta);
++ mt7915_sta_add(hw, vif, sta);
++ }
++
+ mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
+ }
+
+@@ -1519,8 +1533,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+ path->dev = ctx->dev;
+ path->mtk_wdma.wdma_idx = wed->wdma_idx;
+ path->mtk_wdma.bss = mvif->mt76.idx;
+- path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? 0xff : 0x3ff;
+ path->mtk_wdma.queue = phy != &dev->phy;
++ if (test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ||
++ is_mt7915(&dev->mt76))
++ path->mtk_wdma.wcid = msta->wcid.idx;
++ else
++ path->mtk_wdma.wcid = 0x3ff;
+
+ ctx->dev = NULL;
+
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 4b7ad450..bdfb71e2 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -2350,8 +2350,17 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
+ if (ret)
+ return ret;
+
+- if (mtk_wed_device_active(&dev->mt76.mmio.wed) && is_mt7915(&dev->mt76))
+- mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
++ if (is_mt7915(&dev->mt76))
++ ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY),
++ 0, 0, 0);
++ else
++ ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
++ MCU_WA_PARAM_WED_VERSION,
++ dev->mt76.mmio.wed.rev_id, 0);
++ if (ret)
++ return ret;
++ }
+
+ ret = mt7915_mcu_set_mwds(dev, 1);
+ if (ret)
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index d110e210..edb8b510 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -284,6 +284,7 @@ enum {
+ MCU_WA_PARAM_PDMA_RX = 0x04,
+ MCU_WA_PARAM_CPU_UTIL = 0x0b,
+ MCU_WA_PARAM_RED = 0x0e,
++ MCU_WA_PARAM_WED_VERSION = 0x32,
+ #ifdef MTK_DEBUG
+ MCU_WA_PARAM_RED_SHOW_STA = 0xf,
+ MCU_WA_PARAM_RED_TARGET_DELAY = 0x10,
+diff --git a/util.c b/util.c
+index 58196442..5cd5ede0 100644
+--- a/util.c
++++ b/util.c
+@@ -42,9 +42,14 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+ }
+ EXPORT_SYMBOL_GPL(__mt76_poll_msec);
+
+-int mt76_wcid_alloc(u32 *mask, int size)
++int __mt76_wcid_alloc(u32 *mask, int size, u8 flag)
+ {
++#define MT76_WED_WDS_MIN 256
++#define MT76_WED_WDS_CNT 16
++
+ int i, idx = 0, cur;
++ int min = MT76_WED_WDS_MIN;
++ int max = min + MT76_WED_WDS_CNT;
+
+ for (i = 0; i < DIV_ROUND_UP(size, 32); i++) {
+ idx = ffs(~mask[i]);
+@@ -53,16 +58,45 @@ int mt76_wcid_alloc(u32 *mask, int size)
+
+ idx--;
+ cur = i * 32 + idx;
+- if (cur >= size)
++
++ switch (flag) {
++ case MT76_WED_ACTIVE:
++ if (cur >= min && cur < max)
++ continue;
++
++ if (cur >= size) {
++ u32 end = MT76_WED_WDS_CNT - 1;
++
++ i = min / 32;
++ idx = ffs(~mask[i] & GENMASK(end, 0));
++ if (!idx)
++ goto error;
++ idx--;
++ cur = min + idx;
++ }
++
+ break;
++ case MT76_WED_WDS_ACTIVE:
++ if (cur < min)
++ continue;
++ if (cur >= max)
++ goto error;
++
++ break;
++ default:
++ if (cur >= size)
++ goto error;
++ break;
++ }
+
+ mask[i] |= BIT(idx);
+ return cur;
+ }
+
++error:
+ return -1;
+ }
+-EXPORT_SYMBOL_GPL(mt76_wcid_alloc);
++EXPORT_SYMBOL_GPL(__mt76_wcid_alloc);
+
+ int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy)
+ {
+diff --git a/util.h b/util.h
+index 260965dd..99b7263c 100644
+--- a/util.h
++++ b/util.h
+@@ -27,7 +27,12 @@ enum {
+ #define MT76_INCR(_var, _size) \
+ (_var = (((_var) + 1) % (_size)))
+
+-int mt76_wcid_alloc(u32 *mask, int size);
++int __mt76_wcid_alloc(u32 *mask, int size, u8 flags);
++
++static inline int mt76_wcid_alloc(u32 *mask, int size)
++{
++ return __mt76_wcid_alloc(mask, size, 0);
++}
+
+ static inline void
+ mt76_wcid_mask_set(u32 *mask, int idx)
+--
+2.18.0
+