| From a6b57c4e7197d09fb0e546e057e96c0a94634d2d 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 2001/2012] wifi: 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 | 16 ++++++++++++---- |
| mt7915/mcu.h | 1 + |
| util.c | 40 +++++++++++++++++++++++++++++++++++++--- |
| util.h | 7 ++++++- |
| 6 files changed, 82 insertions(+), 10 deletions(-) |
| |
| diff --git a/mt76.h b/mt76.h |
| index fb50d88b..d3c6ac0f 100644 |
| --- a/mt76.h |
| +++ b/mt76.h |
| @@ -78,6 +78,12 @@ enum mt76_wed_type { |
| MT76_WED_RRO_Q_IND, |
| }; |
| |
| +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 2ad95f43..1a259bd0 100644 |
| --- a/mt7915/main.c |
| +++ b/mt7915/main.c |
| @@ -804,8 +804,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; |
| |
| @@ -1296,6 +1303,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); |
| } |
| |
| @@ -1735,8 +1749,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 2f57b1d8..c92d6d9c 100644 |
| --- a/mt7915/mcu.c |
| +++ b/mt7915/mcu.c |
| @@ -2587,10 +2587,18 @@ 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)) || |
| - !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) |
| - 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) || |
| + !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) |
| + 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 f4767671..52baaa73 100644 |
| --- a/mt7915/mcu.h |
| +++ b/mt7915/mcu.h |
| @@ -392,6 +392,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 fc76c66f..61b2d30a 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 |
| |