[][MAC80211][wifi7][Misc][Sync Internal patches to External Release Folder]
[Description]
Add 20231011 MT7996 firmware and sync patches to External Release Folder
[Release-log]
N/A
Change-Id: I8971c21f494c3947f2ac7f19b8c398488356ca59
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8101977
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
new file mode 100644
index 0000000..a581775
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
@@ -0,0 +1,528 @@
+From dda3205c68ab3b38945f0066be5fc95ba067f3af Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Mon, 11 Sep 2023 16:35:15 +0800
+Subject: [PATCH 78/98] wifi: mt76: mt7996: add support for HW-ATF
+ initialization
+
+---
+ mt7996/init.c | 43 ++++++++
+ mt7996/mcu.c | 263 +++++++++++++++++++++++++++++++++++++++++++-----
+ mt7996/mcu.h | 1 +
+ mt7996/mt7996.h | 94 +++++++++++++++++
+ 4 files changed, 376 insertions(+), 25 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index d539af0..d1db1d7 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -553,6 +553,37 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
+ return mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
+ }
+
++static int mt7996_vow_init(struct mt7996_phy *phy)
++{
++ struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++ int ret;
++
++ vow->atf_enable = true;
++ vow->watf_enable = false;
++ vow->max_deficit = 64;
++ vow->sch_type = VOW_SCH_TYPE_FOLLOW_POLICY;
++ vow->sch_policy = VOW_SCH_POLICY_SRR;
++
++ vow->drr_quantum[0] = VOW_DRR_QUANTUM_L0;
++ vow->drr_quantum[1] = VOW_DRR_QUANTUM_L1;
++ vow->drr_quantum[2] = VOW_DRR_QUANTUM_L2;
++ vow->drr_quantum[3] = VOW_DRR_QUANTUM_L3;
++ vow->drr_quantum[4] = VOW_DRR_QUANTUM_L4;
++ vow->drr_quantum[5] = VOW_DRR_QUANTUM_L5;
++ vow->drr_quantum[6] = VOW_DRR_QUANTUM_L6;
++ vow->drr_quantum[7] = VOW_DRR_QUANTUM_L7;
++
++ ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND);
++ if (ret)
++ return ret;
++
++ ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL);
++ if (ret)
++ return ret;
++
++ return mt7996_mcu_set_vow_feature_ctrl(phy);
++}
++
+ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ enum mt76_band_id band)
+ {
+@@ -626,6 +657,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ if (ret)
+ goto error;
+
++ if (mt7996_vow_should_enable(dev)) {
++ ret = mt7996_vow_init(phy);
++ if (ret)
++ goto error;
++ }
++
+ ret = mt7996_init_debugfs(phy);
+ if (ret)
+ goto error;
+@@ -1315,6 +1352,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
+
+ dev->recovery.hw_init_done = true;
+
++ if (mt7996_vow_should_enable(dev)) {
++ ret = mt7996_vow_init(&dev->phy);
++ if (ret)
++ goto error;
++ }
++
+ ret = mt7996_init_debugfs(&dev->phy);
+ if (ret)
+ goto error;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index b2cb627..1915a22 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2147,34 +2147,35 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ }
+
+ static int
+-mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+- struct ieee80211_sta *sta)
++mt7996_mcu_sta_init_vow(struct mt7996_phy *phy, struct mt7996_sta *msta)
+ {
+-#define MT_STA_BSS_GROUP 1
+- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+- struct mt7996_sta *msta;
+- struct {
+- u8 __rsv1[4];
++ struct mt7996_vow_sta_ctrl *vow = &msta->vow;
++ u8 omac_idx = msta->vif->mt76.omac_idx;
++ int ret;
+
+- __le16 tag;
+- __le16 len;
+- __le16 wlan_idx;
+- u8 __rsv2[2];
+- __le32 action;
+- __le32 val;
+- u8 __rsv3[8];
+- } __packed req = {
+- .tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
+- .len = cpu_to_le16(sizeof(req) - 4),
+- .action = cpu_to_le32(MT_STA_BSS_GROUP),
+- .val = cpu_to_le32(mvif->mt76.idx % 16),
+- };
++ /* Assignment of STA BSS group index aligns FW.
++ * Each band has its own BSS group bitmap space.
++ * 0: BSS 0
++ * 4..18: BSS 0x11..0x1f
++ */
++ vow->bss_grp_idx = (omac_idx <= HW_BSSID_MAX)
++ ? omac_idx
++ : HW_BSSID_MAX + omac_idx - EXT_BSSID_START;
++ vow->paused = false;
++ vow->drr_quantum[IEEE80211_AC_VO] = VOW_DRR_QUANTUM_IDX0;
++ vow->drr_quantum[IEEE80211_AC_VI] = VOW_DRR_QUANTUM_IDX1;
++ vow->drr_quantum[IEEE80211_AC_BE] = VOW_DRR_QUANTUM_IDX2;
++ vow->drr_quantum[IEEE80211_AC_BK] = VOW_DRR_QUANTUM_IDX2;
++
++ ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP);
++ if (ret)
++ return ret;
+
+- msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;
+- req.wlan_idx = cpu_to_le16(msta->wcid.idx);
++ ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_PAUSE);
++ if (ret)
++ return ret;
+
+- return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
+- sizeof(req), true);
++ return mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_ALL);
+ }
+
+ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2228,7 +2229,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+ }
+
+- ret = mt7996_mcu_add_group(dev, vif, sta);
++ ret = mt7996_mcu_sta_init_vow(mvif->phy, msta);
+ if (ret) {
+ dev_kfree_skb(skb);
+ return ret;
+@@ -5027,6 +5028,218 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ MCU_WM_UNI_CMD(TXPOWER), true);
+ }
+
++int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
++ enum vow_drr_ctrl_id id)
++{
++ struct mt7996_vow_sta_ctrl *vow = msta ? &msta->vow : NULL;
++ u32 val = 0;
++ struct {
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++ __le16 wlan_idx;
++ u8 band_idx;
++ u8 wmm_idx;
++ __le32 ctrl_id;
++
++ union {
++ __le32 val;
++ u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++ };
++
++ u8 __rsv2[3];
++ u8 omac_idx;
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .wlan_idx = cpu_to_le16(msta ? msta->wcid.idx : 0),
++ .band_idx = phy->mt76->band_idx,
++ .wmm_idx = msta ? msta->vif->mt76.wmm_idx : 0,
++ .ctrl_id = cpu_to_le32(id),
++ .omac_idx = msta ? msta->vif->mt76.omac_idx : 0
++ };
++
++ switch (id) {
++ case VOW_DRR_CTRL_STA_ALL:
++ val |= FIELD_PREP(MT7996_DRR_STA_BSS_GRP_MASK, vow->bss_grp_idx);
++ val |= FIELD_PREP(MT7996_DRR_STA_AC0_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BK]);
++ val |= FIELD_PREP(MT7996_DRR_STA_AC1_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BE]);
++ val |= FIELD_PREP(MT7996_DRR_STA_AC2_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VI]);
++ val |= FIELD_PREP(MT7996_DRR_STA_AC3_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VO]);
++ req.val = cpu_to_le32(val);
++ break;
++ case VOW_DRR_CTRL_STA_BSS_GROUP:
++ req.val = cpu_to_le32(vow->bss_grp_idx);
++ break;
++ case VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND:
++ req.val = cpu_to_le32(phy->dev->vow.max_deficit);
++ break;
++ case VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL:
++ memcpy(req.drr_quantum, phy->dev->vow.drr_quantum, VOW_DRR_QUANTUM_NUM);
++ break;
++ case VOW_DRR_CTRL_STA_PAUSE:
++ req.val = cpu_to_le32(vow->paused);
++ break;
++ default:
++ dev_err(phy->dev->mt76.dev, "Unknown VoW DRR Control ID: %u\n", id);
++ return -EINVAL;
++ }
++
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++ &req, sizeof(req), true);
++}
++
++int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy)
++{
++ struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++ struct {
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++
++ /* DW0 */
++ __le16 apply_bwc_enable_per_grp;
++ __le16 apply_bwc_refill_period : 1;
++ __le16 __rsv2 : 3;
++ __le16 apply_band1_search_rule : 1;
++ __le16 apply_band0_search_rule : 1;
++ __le16 __rsv3 : 3;
++ __le16 apply_watf_enable : 1;
++ __le16 __rsv4 : 2;
++ __le16 apply_grp_no_change_in_txop : 1;
++ __le16 apply_atf_enable : 1;
++ __le16 apply_bwc_token_refill_enable : 1;
++ __le16 apply_bwc_enable : 1;
++
++ /* DW1 */
++ __le16 apply_bwc_check_time_token_per_grp;
++ __le16 __rsv5;
++
++ /* DW2 */
++ __le16 apply_bwc_check_len_token_per_grp;
++ __le16 __rsv6;
++
++ /* DW3 */
++ u8 band_idx;
++ u8 __rsv7[3];
++
++ /* DW4 */
++ __le32 __rsv8;
++
++ /* DW5 */
++ __le16 bwc_enable_per_grp;
++ __le16 bwc_refill_period : 3;
++ __le16 __rsv9 : 1;
++ __le16 band1_search_rule : 1;
++ __le16 band0_search_rule : 1;
++ __le16 __rsv10 : 3;
++ __le16 watf_enable : 1;
++ __le16 __rsv11 : 2;
++ __le16 grp_no_change_in_txop : 1;
++ __le16 atf_enable : 1;
++ __le16 bwc_token_refill_enable : 1;
++ __le16 bwc_enable : 1;
++
++ /* DW6 */
++ __le16 bwc_check_time_token_per_grp;
++ __le16 __rsv12;
++
++ /* DW7 */
++ __le16 bwc_check_len_token_per_grp;
++ __le16 __rsv13;
++
++ /* DW8 */
++ __le32 apply_atf_rts_sta_lock : 1;
++ __le32 atf_rts_sta_lock : 1;
++ __le32 apply_atf_keep_quantum : 1;
++ __le32 atf_keep_quantum : 1;
++ __le32 apply_tx_cnt_mode_ctrl : 1;
++ __le32 tx_cnt_mode_ctrl : 4;
++ __le32 apply_tx_measure_mode_enable : 1;
++ __le32 tx_measure_mode_enable : 1;
++ __le32 apply_backoff_ctrl : 1;
++ __le32 backoff_bound_enable : 1;
++ __le32 backoff_bound : 5;
++ __le32 apply_atf_rts_fail_charge : 1;
++ __le32 atf_rts_fail_charge : 1;
++ __le32 apply_zero_eifs : 1;
++ __le32 zero_eifs : 1;
++ __le32 apply_rx_rifs_enable : 1;
++ __le32 rx_rifs_enable : 1;
++ __le32 apply_vow_ctrl : 1;
++ __le32 vow_ctrl_val : 1;
++ __le32 vow_ctrl_bit : 5;
++ __le32 __rsv14 : 1;
++
++ /* DW9 */
++ __le32 apply_spl_sta_num : 1;
++ __le32 spl_sta_num : 3;
++ __le32 dbg_lvl : 2;
++ __le32 apply_atf_sch_ctrl : 1;
++ __le32 atf_sch_type : 2;
++ __le32 atf_sch_policy : 2;
++ __le32 __rsv15 : 21;
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_VOW_FEATURE_CTRL),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ /* DW0 */
++ .apply_bwc_enable_per_grp = cpu_to_le16(0xffff),
++ .apply_bwc_refill_period = true,
++ .apply_band1_search_rule = true,
++ .apply_band0_search_rule = true,
++ .apply_watf_enable = true,
++ .apply_grp_no_change_in_txop = true,
++ .apply_atf_enable = true,
++ .apply_bwc_token_refill_enable = true,
++ .apply_bwc_enable = true,
++ /* DW1 */
++ .apply_bwc_check_time_token_per_grp = cpu_to_le16(0xffff),
++ /* DW2 */
++ .apply_bwc_check_len_token_per_grp = cpu_to_le16(0xffff),
++ /* DW3 */
++ .band_idx = phy->mt76->band_idx,
++ /* DW5 */
++ .bwc_enable_per_grp = cpu_to_le16(0xffff),
++ .bwc_refill_period = VOW_REFILL_PERIOD_32US,
++ .band1_search_rule = VOW_SEARCH_WMM_FIRST,
++ .band0_search_rule = VOW_SEARCH_WMM_FIRST,
++ .watf_enable = vow->watf_enable,
++ .grp_no_change_in_txop = true,
++ .atf_enable = vow->atf_enable,
++ .bwc_token_refill_enable = true,
++ .bwc_enable = false,
++ /* DW6 */
++ .bwc_check_time_token_per_grp = cpu_to_le16(0x0),
++ /* DW7 */
++ .bwc_check_len_token_per_grp = cpu_to_le16(0x0),
++ /* DW8 */
++ .apply_atf_rts_sta_lock = false,
++ .apply_atf_keep_quantum = true,
++ .atf_keep_quantum = true,
++ .apply_tx_cnt_mode_ctrl = false,
++ .apply_tx_measure_mode_enable = false,
++ .apply_backoff_ctrl = false,
++ .apply_atf_rts_fail_charge = false,
++ .apply_zero_eifs = false,
++ .apply_rx_rifs_enable = false,
++ .apply_vow_ctrl = true,
++ .vow_ctrl_val = true,
++ /* Reset DRR table when SER occurs. */
++ .vow_ctrl_bit = 26,
++ /* DW9 */
++ .apply_spl_sta_num = false,
++ .dbg_lvl = 0,
++ .apply_atf_sch_ctrl = true,
++ .atf_sch_type = vow->sch_type,
++ .atf_sch_policy = vow->sch_policy
++ };
++
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++ &req, sizeof(req), true);
++}
++
+ #ifdef CONFIG_MTK_VENDOR
+ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 0aa68f7..fb81645 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -860,6 +860,7 @@ enum {
+
+ enum {
+ UNI_VOW_DRR_CTRL,
++ UNI_VOW_FEATURE_CTRL,
+ UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
+ UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
+ UNI_VOW_RED_ENABLE = 0x18,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 4333d51..ba73520 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -107,6 +107,12 @@
+ #define MT7996_RX_MSDU_PAGE_SIZE (128 + \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
++#define MT7996_DRR_STA_BSS_GRP_MASK GENMASK(5, 0)
++#define MT7996_DRR_STA_AC0_QNTM_MASK GENMASK(10, 8)
++#define MT7996_DRR_STA_AC1_QNTM_MASK GENMASK(14, 12)
++#define MT7996_DRR_STA_AC2_QNTM_MASK GENMASK(18, 16)
++#define MT7996_DRR_STA_AC3_QNTM_MASK GENMASK(22, 20)
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -187,6 +193,79 @@ struct mt7996_twt_flow {
+
+ DECLARE_EWMA(avg_signal, 10, 8)
+
++enum {
++ VOW_SEARCH_AC_FIRST,
++ VOW_SEARCH_WMM_FIRST
++};
++
++enum {
++ VOW_REFILL_PERIOD_1US,
++ VOW_REFILL_PERIOD_2US,
++ VOW_REFILL_PERIOD_4US,
++ VOW_REFILL_PERIOD_8US,
++ VOW_REFILL_PERIOD_16US,
++ VOW_REFILL_PERIOD_32US,
++ VOW_REFILL_PERIOD_64US,
++ VOW_REFILL_PERIOD_128US
++};
++
++/* Default DRR airtime quantum of each level */
++enum {
++ VOW_DRR_QUANTUM_L0 = 6,
++ VOW_DRR_QUANTUM_L1 = 12,
++ VOW_DRR_QUANTUM_L2 = 16,
++ VOW_DRR_QUANTUM_L3 = 20,
++ VOW_DRR_QUANTUM_L4 = 24,
++ VOW_DRR_QUANTUM_L5 = 28,
++ VOW_DRR_QUANTUM_L6 = 32,
++ VOW_DRR_QUANTUM_L7 = 36
++};
++
++enum {
++ VOW_DRR_QUANTUM_IDX0,
++ VOW_DRR_QUANTUM_IDX1,
++ VOW_DRR_QUANTUM_IDX2,
++ VOW_DRR_QUANTUM_IDX3,
++ VOW_DRR_QUANTUM_IDX4,
++ VOW_DRR_QUANTUM_IDX5,
++ VOW_DRR_QUANTUM_IDX6,
++ VOW_DRR_QUANTUM_IDX7,
++ VOW_DRR_QUANTUM_NUM
++};
++
++enum {
++ VOW_SCH_TYPE_FOLLOW_POLICY,
++ VOW_SCH_TYPE_FOLLOW_HW
++};
++
++enum {
++ VOW_SCH_POLICY_SRR, /* Shared Round-Robin */
++ VOW_SCH_POLICY_WRR /* Weighted Round-Robin */
++};
++
++enum vow_drr_ctrl_id {
++ VOW_DRR_CTRL_STA_ALL,
++ VOW_DRR_CTRL_STA_BSS_GROUP,
++ VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND = 0x10,
++ VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL = 0x28,
++ VOW_DRR_CTRL_STA_PAUSE = 0x30
++};
++
++struct mt7996_vow_ctrl {
++ bool atf_enable;
++ bool watf_enable;
++ u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++ u8 max_deficit;
++ u8 sch_type;
++ u8 sch_policy;
++};
++
++struct mt7996_vow_sta_ctrl {
++ bool paused;
++ u8 bss_grp_idx;
++ u8 drr_quantum[IEEE80211_NUM_ACS];
++};
++
+ struct mt7996_sta {
+ struct mt76_wcid wcid; /* must be first */
+
+@@ -206,6 +285,8 @@ struct mt7996_sta {
+ u8 flowid_mask;
+ struct mt7996_twt_flow flow[MT7996_MAX_STA_TWT_AGRT];
+ } twt;
++
++ struct mt7996_vow_sta_ctrl vow;
+ };
+
+ struct mt7996_vif {
+@@ -470,6 +551,7 @@ struct mt7996_dev {
+
+ u8 wtbl_size_group;
+
++ struct mt7996_vow_ctrl vow;
+ #ifdef CONFIG_MTK_DEBUG
+ u16 wlan_idx;
+ struct {
+@@ -697,6 +779,10 @@ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
+
++int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
++ enum vow_drr_ctrl_id id);
++int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy);
++
+ static inline u16 mt7996_eeprom_size(struct mt7996_dev *dev)
+ {
+ return is_mt7996(&dev->mt76) ? MT7996_EEPROM_SIZE : MT7992_EEPROM_SIZE;
+@@ -749,6 +835,14 @@ static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
+ return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
+ }
+
++static inline bool
++mt7996_vow_should_enable(struct mt7996_dev *dev)
++{
++ return !wiphy_ext_feature_isset(mt76_hw(dev)->wiphy,
++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS) ||
++ mtk_wed_device_active(&dev->mt76.mmio.wed);
++}
++
+ void mt7996_mac_init(struct mt7996_dev *dev);
+ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
+ bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
+--
+2.18.0
+