From e016239fcb9802e58dc059b85e0fb25ac1777df4 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 9 Sep 2024 14:12:37 -0700 Subject: [PATCH 01/16] wifi: mt76: mt7996: Add eht radiotap tlv This duplicates what the 7925 driver is doing, wireshark seems to at least mostly decode it as expected. Signed-off-by: Ben Greear Link: https://patch.msgid.link/20240909211238.3237111-1-greearb@candelatech.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 0d21414e2c88..4706ddefea9e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -679,14 +679,25 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q, if (ieee80211_has_a4(fc) && is_mesh && status->amsdu) *qos &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; } + skb_set_mac_header(skb, (unsigned char *)hdr - skb->data); } else { status->flag |= RX_FLAG_8023; mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb, *info); } - if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) - mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode); + if (rxv && !(status->flag & RX_FLAG_8023)) { + switch (status->encoding) { + case RX_ENC_EHT: + mt76_connac3_mac_decode_eht_radiotap(skb, rxv, mode); + break; + case RX_ENC_HE: + mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode); + break; + default: + break; + } + } if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr) return 0; -- 2.51.0 From 512e26db3565b310052dc2b8975ac7c973bf8ab6 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 9 Sep 2024 14:12:38 -0700 Subject: [PATCH 02/16] wifi: mt76: Fix EHT NSS radiotap reporting. Wireshark and iwlwifi use zero-based NSS reporting, adjust mt76 to do the same. Signed-off-by: Ben Greear Link: https://patch.msgid.link/20240909211238.3237111-2-greearb@candelatech.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c index 92ad1ecf6c9d..2d300948308d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c @@ -231,7 +231,8 @@ void mt76_connac3_mac_decode_eht_radiotap(struct sk_buff *skb, __le32 *rxv, EHT_PREP(DATA0_PE_DISAMBIGUITY_OM, PE_DISAMBIG, rxv[5]) | EHT_PREP(DATA0_LDPC_EXTRA_SYM_OM, LDPC_EXT_SYM, rxv[4]); - eht->data[7] |= le32_encode_bits(status->nss, IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); + /* iwlwifi and wireshark expect radiotap to report zero-based NSS, so subtract 1. */ + eht->data[7] |= le32_encode_bits(status->nss - 1, IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); eht->user_info[0] |= EHT_BITS(USER_INFO_MCS_KNOWN) | @@ -240,7 +241,7 @@ void mt76_connac3_mac_decode_eht_radiotap(struct sk_buff *skb, __le32 *rxv, EHT_BITS(USER_INFO_BEAMFORMING_KNOWN_O) | EHT_BITS(USER_INFO_DATA_FOR_USER) | le32_encode_bits(status->rate_idx, IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - le32_encode_bits(status->nss, IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O); + le32_encode_bits(status->nss - 1, IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O); if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) eht->user_info[0] |= EHT_BITS(USER_INFO_BEAMFORMING_O); -- 2.51.0 From 5ed54896b6bd444223092cab361b0785932119ab Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Thu, 18 Jul 2024 21:49:09 +0800 Subject: [PATCH 03/16] wifi: mt76: mt7921: fix a potential scan no APs In multi-channel scenarios, the granted channel must be aborted before station remove. Otherwise, the firmware will be put into a wrong state, resulting in have chance to make subsequence scan no APs. With this patch, the granted channel will be always aborted before station remove. Signed-off-by: Quan Zhou Reviewed-by: Sean Wang Tested-by: David Ruth Reviewed-by: David Ruth Link: https://patch.msgid.link/1ac1ae779db86d4012199a24ea2ca74050ed4af6.1721300411.git.quan.zhou@mediatek.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index a7f5bfbc02ed..2ef8dbfc4a95 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -360,9 +360,9 @@ void mt7921_roc_abort_sync(struct mt792x_dev *dev) del_timer_sync(&phy->roc_timer); cancel_work_sync(&phy->roc_work); if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) - ieee80211_iterate_active_interfaces(mt76_hw(dev), - IEEE80211_IFACE_ITER_RESUME_ALL, - mt7921_roc_iter, (void *)phy); + ieee80211_iterate_interfaces(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt7921_roc_iter, (void *)phy); } EXPORT_SYMBOL_GPL(mt7921_roc_abort_sync); @@ -858,6 +858,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + mt7921_roc_abort_sync(dev); mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->deflink.wcid); mt76_connac_pm_wake(&dev->mphy, &dev->pm); -- 2.51.0 From f1b1e133a770fcdbd89551651232b034d2f7a27a Mon Sep 17 00:00:00 2001 From: WangYuli Date: Mon, 13 Jan 2025 15:02:41 +0800 Subject: [PATCH 04/16] wifi: mt76: mt76u_vendor_request: Do not print error messages when -EPROTO MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When initializing the network card, unplugging the device will trigger an -EPROTO error, resulting in a flood of error messages being printed frantically. The exception is printed as follows: mt76x2u 2-2.4:1.0: vendor request req:47 off:9018 failed:-71 mt76x2u 2-2.4:1.0: vendor request req:47 off:9018 failed:-71 ... It will continue to print more than 2000 times for about 5 minutes, causing the usb device to be unable to be disconnected. During this period, the usb port cannot recognize the new device because the old device has not disconnected. There may be other operating methods that cause -EPROTO, but -EPROTO is a low-level hardware error. It is unwise to repeat vendor requests expecting to read correct data. It is a better choice to treat -EPROTO and -ENODEV the same way. Similar to commit 9b0f100c1970 ("mt76: usb: process URBs with status EPROTO properly") do no schedule rx_worker for urb marked with status set -EPROTO. I also reproduced this situation when plugging and unplugging the device, and this patch is effective. Just do not vendor request again for urb marked with status set -EPROTO. Link: https://lore.kernel.org/all/531681bd-30f5-4a70-a156-bf8754b8e072@intel.com/ Link: https://lore.kernel.org/all/D4B9CC1FFC0CBAC3+20250105040607.154706-1-wangyuli@uniontech.com/ Fixes: b40b15e1521f ("mt76: add usb support to mt76 layer") Co-developed-by: Xu Rao Signed-off-by: Xu Rao Signed-off-by: WangYuli Link: https://patch.msgid.link/9DD7DE7AAB497CB7+20250113070241.63590-1-wangyuli@uniontech.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 58ff06823389..f9e67b8c3b3c 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -33,9 +33,9 @@ int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, ret = usb_control_msg(udev, pipe, req, req_type, val, offset, buf, len, MT_VEND_REQ_TOUT_MS); - if (ret == -ENODEV) + if (ret == -ENODEV || ret == -EPROTO) set_bit(MT76_REMOVED, &dev->phy.state); - if (ret >= 0 || ret == -ENODEV) + if (ret >= 0 || ret == -ENODEV || ret == -EPROTO) return ret; usleep_range(5000, 10000); } -- 2.51.0 From aa566ac6b7272e7ea5359cb682bdca36d2fc7e73 Mon Sep 17 00:00:00 2001 From: Michael Lo Date: Thu, 1 Aug 2024 10:43:35 +0800 Subject: [PATCH 05/16] wifi: mt76: mt7921: fix using incorrect group cipher after disconnection. To avoid incorrect cipher after disconnection, we should do the key deletion process in this case. Fixes: e6db67fa871d ("wifi: mt76: ignore key disable commands") Signed-off-by: Michael Lo Signed-off-by: Ming Yen Hsieh Tested-by: David Ruth Reviewed-by: David Ruth Link: https://patch.msgid.link/20240801024335.12981-1-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 2ef8dbfc4a95..573a2cd7fe45 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -531,7 +531,13 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } else { if (idx == *wcid_keyidx) *wcid_keyidx = -1; - goto out; + + /* For security issue we don't trigger the key deletion when + * reassociating. But we should trigger the deletion process + * to avoid using incorrect cipher after disconnection, + */ + if (vif->type != NL80211_IFTYPE_STATION || vif->cfg.assoc) + goto out; } mt76_wcid_key_setup(&dev->mt76, wcid, key); -- 2.51.0 From 126a516fe30639708e759678bcb10178938cc718 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 29 Sep 2024 21:53:40 +0200 Subject: [PATCH 06/16] wifi: mt76: mt7915: Fix an error handling path in mt7915_add_interface() If mt76_wcid_alloc() fails, the "mt76.mutex" mutex needs to be released as done in the other error handling paths of mt7915_add_interface(). Fixes: f3049b88b2b3 ("wifi: mt76: mt7915: allocate vif wcid in the same range as stations") Signed-off-by: Christophe JAILLET Link: https://patch.msgid.link/b9d8fbfc19360bfe60b9cea1cb0f735ab3b4bc26.1727639596.git.christophe.jaillet@wanadoo.fr Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 8183708a9b35..351285daac99 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -246,8 +246,10 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); idx = mt76_wcid_alloc(dev->mt76.wcid_mask, mt7915_wtbl_size(dev)); - if (idx < 0) - return -ENOSPC; + if (idx < 0) { + ret = -ENOSPC; + goto out; + } INIT_LIST_HEAD(&mvif->sta.rc_list); INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); -- 2.51.0 From 57af267d2b8f5d88485c6372761386d79c5e6a1a Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Thu, 10 Oct 2024 10:38:16 +0200 Subject: [PATCH 07/16] wifi: mt76: mt7915: add module param to select 5 GHz or 6 GHz on MT7916 Due to a limitation in available memory, the MT7916 firmware can only handle either 5 GHz or 6 GHz at a time. It does not support runtime switching without a full restart. On older firmware, this accidentally worked to some degree due to missing checks, but couldn't be supported properly, because it left the 6 GHz channels uncalibrated. Newer firmware refuses to start on either band if the passed EEPROM data indicates support for both. Deal with this limitation by using a module parameter to specify the preferred band in case both are supported. Fixes: b4d093e321bd ("mt76: mt7915: add 6 GHz support") Cc: stable@vger.kernel.org Signed-off-by: Shayne Chen Link: https://patch.msgid.link/20241010083816.51880-1-nbd@nbd.name Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7915/eeprom.c | 21 +++++++++++++++++-- .../net/wireless/mediatek/mt76/mt7915/init.c | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index bfdbc15abaa9..928e0b07a9bf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -2,9 +2,14 @@ /* Copyright (C) 2020 MediaTek Inc. */ #include +#include #include "mt7915.h" #include "eeprom.h" +static bool enable_6ghz; +module_param(enable_6ghz, bool, 0644); +MODULE_PARM_DESC(enable_6ghz, "Enable 6 GHz instead of 5 GHz on hardware that supports both"); + static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) { struct mt76_dev *mdev = &dev->mt76; @@ -170,8 +175,20 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) phy->mt76->cap.has_6ghz = true; return; case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: - phy->mt76->cap.has_5ghz = true; - phy->mt76->cap.has_6ghz = true; + if (enable_6ghz) { + phy->mt76->cap.has_6ghz = true; + u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], + MT_EE_V2_BAND_SEL_6GHZ, + MT_EE_WIFI_CONF0_BAND_SEL); + } else { + phy->mt76->cap.has_5ghz = true; + u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band], + MT_EE_V2_BAND_SEL_5GHZ, + MT_EE_WIFI_CONF0_BAND_SEL); + } + /* force to buffer mode */ + dev->flash_mode = true; + return; default: phy->mt76->cap.has_2ghz = true; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index 6bef96e3d2a3..f82216d1bda0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -1239,14 +1239,14 @@ int mt7915_register_device(struct mt7915_dev *dev) if (ret) goto unreg_dev; - ieee80211_queue_work(mt76_hw(dev), &dev->init_work); - if (phy2) { ret = mt7915_register_ext_phy(dev, phy2); if (ret) goto unreg_thermal; } + ieee80211_queue_work(mt76_hw(dev), &dev->init_work); + dev->recovery.hw_init_done = true; ret = mt7915_init_debugfs(&dev->phy); -- 2.51.0 From 6d18b668301e0a7d924a6c821b84516bc08bdafe Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 16 Oct 2024 18:10:17 +0800 Subject: [PATCH 08/16] wifi: mt76: introduce mt792x_config_mac_addr_list routine Add mt792x_config_mac_addr_list routine in order to set the mac address list supported by the driver. Initialize wiphy->addresses/n_addresses for mt792x driver Signed-off-by: Hao Zhang Signed-off-by: Leon Yen Signed-off-by: Allan Wang Link: https://patch.msgid.link/20241016101017.19598-1-allan.wang@mediatek.com Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7921/init.c | 1 + .../net/wireless/mediatek/mt76/mt7925/init.c | 1 + drivers/net/wireless/mediatek/mt76/mt792x.h | 3 +++ .../net/wireless/mediatek/mt76/mt792x_core.c | 22 +++++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index d1d64fa7d35d..cdcb002b3094 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -227,6 +227,7 @@ static void mt7921_init_work(struct work_struct *work) mt76_set_stream_caps(&dev->mphy, true); mt7921_set_stream_he_caps(&dev->phy); + mt792x_config_mac_addr_list(dev); ret = mt76_register_device(&dev->mt76, true, mt76_rates, ARRAY_SIZE(mt76_rates)); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index 039949b344b9..ddc654b9ea5e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -178,6 +178,7 @@ static void mt7925_init_work(struct work_struct *work) mt76_set_stream_caps(&dev->mphy, true); mt7925_set_stream_he_eht_caps(&dev->phy); + mt792x_config_mac_addr_list(dev); ret = mt7925_init_mlo_caps(&dev->phy); if (ret) { diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index ab12616ec2b8..10e1eaa52706 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -206,6 +206,8 @@ struct mt792x_dev { struct mt76_phy mphy; }; + struct mac_address macaddr_list[8]; + const struct mt76_bus_ops *bus_ops; struct mt792x_phy phy; @@ -414,6 +416,7 @@ int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev); void mt792x_mac_link_bss_remove(struct mt792x_dev *dev, struct mt792x_bss_conf *mconf, struct mt792x_link_sta *mlink); +void mt792x_config_mac_addr_list(struct mt792x_dev *dev); static inline char *mt792x_ram_name(struct mt792x_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c index 042aa8d1b6e7..868cb97fa2ff 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -916,6 +916,28 @@ int mt792x_load_firmware(struct mt792x_dev *dev) } EXPORT_SYMBOL_GPL(mt792x_load_firmware); +void mt792x_config_mac_addr_list(struct mt792x_dev *dev) +{ + struct ieee80211_hw *hw = mt76_hw(dev); + struct wiphy *wiphy = hw->wiphy; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) { + u8 *addr = dev->macaddr_list[i].addr; + + memcpy(addr, dev->mphy.macaddr, ETH_ALEN); + + if (!i) + continue; + + addr[0] |= BIT(1); + addr[0] ^= ((i - 1) << 2); + } + wiphy->addresses = dev->macaddr_list; + wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list); +} +EXPORT_SYMBOL_GPL(mt792x_config_mac_addr_list); + MODULE_DESCRIPTION("MediaTek MT792x core driver"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Lorenzo Bianconi "); -- 2.51.0 From 5cd0bd815c8a48862a296df9b30e0ea0da14acd3 Mon Sep 17 00:00:00 2001 From: Charles Han Date: Fri, 25 Oct 2024 15:55:54 +0800 Subject: [PATCH 09/16] wifi: mt76: mt7925: fix NULL deref check in mt7925_change_vif_links In mt7925_change_vif_links() devm_kzalloc() may return NULL but this returned value is not checked. Fixes: 69acd6d910b0 ("wifi: mt76: mt7925: add mt7925_change_vif_links") Signed-off-by: Charles Han Link: https://patch.msgid.link/20241025075554.181572-1-hanchunchao@inspur.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 791c8b00e112..a5110f8485e5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1946,6 +1946,8 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, GFP_KERNEL); mlink = devm_kzalloc(dev->mt76.dev, sizeof(*mlink), GFP_KERNEL); + if (!mconf || !mlink) + return -ENOMEM; } mconfs[link_id] = mconf; -- 2.51.0 From 85bb7c10c1a013ab29d4be07559105dd843c6f7d Mon Sep 17 00:00:00 2001 From: Eric-SY Chang Date: Fri, 1 Nov 2024 15:43:40 +0800 Subject: [PATCH 10/16] wifi: mt76: mt7925: fix wrong band_idx setting when enable sniffer mode Currently, sniffer mode does not support band auto, so set band_idx to the default 0. Fixes: 0cb349d742d1 ("wifi: mt76: mt7925: update mt7925_mac_link_bss_add for MLO") Signed-off-by: Eric-SY Chang Signed-off-by: Ming Yen Hsieh Link: https://patch.msgid.link/20241101074340.26176-1-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 0c2a2337c313..a78883d4d6df 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -1976,8 +1976,6 @@ int mt7925_get_txpwr_info(struct mt792x_dev *dev, u8 band_idx, struct mt7925_txp int mt7925_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { - struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; - struct { struct { u8 band_idx; @@ -1991,7 +1989,7 @@ int mt7925_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, } __packed enable; } __packed req = { .hdr = { - .band_idx = mvif->bss_conf.mt76.band_idx, + .band_idx = 0, }, .enable = { .tag = cpu_to_le16(UNI_SNIFFER_ENABLE), @@ -2050,7 +2048,7 @@ int mt7925_mcu_config_sniffer(struct mt792x_vif *vif, } __packed tlv; } __packed req = { .hdr = { - .band_idx = vif->bss_conf.mt76.band_idx, + .band_idx = 0, }, .tlv = { .tag = cpu_to_le16(UNI_SNIFFER_CONFIG), -- 2.51.0 From 4d264f31b3074d361f65702dd7969861bcf1c158 Mon Sep 17 00:00:00 2001 From: Ming Yen Hsieh Date: Mon, 4 Nov 2024 13:14:47 +0800 Subject: [PATCH 11/16] wifi: mt76: mt7925: fix get wrong chip cap from incorrect pointer Use tlv instead of skb, because using skb will get valid data with wrong offset. Fixes: 86c051f2c418 ("wifi: mt76: mt7925: enabling MLO when the firmware supports it") Signed-off-by: Ming Yen Hsieh Link: https://patch.msgid.link/20241104051447.4286-1-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index a78883d4d6df..b43617dbd5fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -823,7 +823,7 @@ mt7925_mcu_get_nic_capability(struct mt792x_dev *dev) mt7925_mcu_parse_phy_cap(dev, tlv->data); break; case MT_NIC_CAP_CHIP_CAP: - memcpy(&dev->phy.chip_cap, (void *)skb->data, sizeof(u64)); + dev->phy.chip_cap = le64_to_cpu(*(__le64 *)tlv->data); break; case MT_NIC_CAP_EML_CAP: mt7925_mcu_parse_eml_cap(dev, tlv->data); -- 2.51.0 From 113d469e7e23579a64b0fbb2eadf9228763092be Mon Sep 17 00:00:00 2001 From: Ming Yen Hsieh Date: Thu, 7 Nov 2024 13:30:05 +0800 Subject: [PATCH 12/16] wifi: mt76: mt7925: fix the invalid ip address for arp offload The wrong ieee80211_vif will lead to get invalid ip address and the correct ieee80211_vif can be obtained from ieee80211_bss_conf. Fixes: 147324292979 ("wifi: mt76: mt7925: add link handling in the BSS_CHANGED_ARP_FILTER handler") Signed-off-by: Ming Yen Hsieh Link: https://patch.msgid.link/20241107053005.10558-1-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index b43617dbd5fd..123a585098e3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -123,10 +123,8 @@ EXPORT_SYMBOL_GPL(mt7925_mcu_regval); int mt7925_mcu_update_arp_filter(struct mt76_dev *dev, struct ieee80211_bss_conf *link_conf) { - struct ieee80211_vif *mvif = container_of((void *)link_conf->vif, - struct ieee80211_vif, - drv_priv); struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf); + struct ieee80211_vif *mvif = link_conf->vif; struct sk_buff *skb; int i, len = min_t(int, mvif->cfg.arp_addr_cnt, IEEE80211_BSS_ARP_ADDR_LIST_LEN); -- 2.51.0 From 5adbc8ce5bbe7e311e2600b7d7d998a958873e98 Mon Sep 17 00:00:00 2001 From: xueqin Luo Date: Mon, 2 Dec 2024 11:19:16 +0800 Subject: [PATCH 13/16] wifi: mt76: mt7996: fix overflows seen when writing limit attributes DIV_ROUND_CLOSEST() after kstrtoul() results in an overflow if a large number such as 18446744073709551615 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations. This commit was inspired by commit: 57ee12b6c514. Fixes: 6879b2e94172 ("wifi: mt76: mt7996: add thermal sensor device support") Signed-off-by: xueqin Luo Link: https://patch.msgid.link/20241202031917.23741-2-luoxueqin@kylinos.cn Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 2d36c7325137..8cfb122b48ac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -82,7 +82,7 @@ static ssize_t mt7996_thermal_temp_store(struct device *dev, return ret; mutex_lock(&phy->dev->mt76.mutex); - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130); + val = DIV_ROUND_CLOSEST(clamp_val(val, 40 * 1000, 130 * 1000), 1000); /* add a safety margin ~10 */ if ((i - 1 == MT7996_CRIT_TEMP_IDX && -- 2.51.0 From 64d571742b0ae44eee5efd51e2d4a09d7f6782fc Mon Sep 17 00:00:00 2001 From: xueqin Luo Date: Mon, 2 Dec 2024 11:19:17 +0800 Subject: [PATCH 14/16] wifi: mt76: mt7915: fix overflows seen when writing limit attributes DIV_ROUND_CLOSEST() after kstrtoul() results in an overflow if a large number such as 18446744073709551615 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations. This commit was inspired by commit: 57ee12b6c514. Fixes: 02ee68b95d81 ("mt76: mt7915: add control knobs for thermal throttling") Signed-off-by: xueqin Luo Link: https://patch.msgid.link/20241202031917.23741-3-luoxueqin@kylinos.cn Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index f82216d1bda0..bc983ab10b0c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -82,7 +82,7 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev, return ret; mutex_lock(&phy->dev->mt76.mutex); - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 60, 130); + val = DIV_ROUND_CLOSEST(clamp_val(val, 60 * 1000, 130 * 1000), 1000); if ((i - 1 == MT7915_CRIT_TEMP_IDX && val > phy->throttle_temp[MT7915_MAX_TEMP_IDX]) || -- 2.51.0 From c693723bb5dba0f04c3e75703c91f733a0a637c8 Mon Sep 17 00:00:00 2001 From: Chad Monroe Date: Tue, 26 Nov 2024 04:52:58 +0000 Subject: [PATCH 15/16] wifi: mt76: mt7915: exclude tx backoff time from airtime This helps to make STA airtime counters more accurate. Signed-off-by: Chad Monroe Suggested-by: Ryder Lee Link: https://patch.msgid.link/026380cec180261956b983cbdb009605867bcd8d.1732596478.git.chad@monroe.io Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 9 +++++++++ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 9 +++++++-- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 7 +++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index bc983ab10b0c..4282857d8ce9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -512,6 +512,15 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME4(band), MT_WF_RMAC_MIB_QOS23_BACKOFF); + /* clear backoff time for Tx duration */ + mt76_clear(dev, MT_WTBLOFF_TOP_ACR(band), + MT_WTBLOFF_TOP_ADM_BACKOFFTIME); + + /* exclude estimated backoff time for Tx duration on MT7915 */ + if (is_mt7915(&dev->mt76)) + mt76_set(dev, MT_AGG_ATCR0(band), + MT_AGG_ATCR_MAC_BFF_TIME_EN); + /* clear backoff time and set software compensation for OBSS time */ mask = MT_WF_RMAC_MIB_OBSS_BACKOFF | MT_WF_RMAC_MIB_ED_OFFSET; set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) | diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 87d0dd040001..35af41b5bad6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3150,8 +3150,13 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch) res = (struct mt7915_mcu_mib *)(skb->data + offs_cc); #define __res_u64(s) le64_to_cpu(res[s].data) - /* subtract Tx backoff time from Tx duration */ - cc_tx = is_mt7915(&dev->mt76) ? __res_u64(1) - __res_u64(4) : __res_u64(1); + /* subtract Tx backoff time from Tx duration for MT7915 */ + if (is_mt7915(&dev->mt76)) { + u64 backoff = (__res_u64(4) & 0xffff) * 79; /* 16us + 9us * 7 */ + cc_tx = __res_u64(1) - backoff; + } else { + cc_tx = __res_u64(1); + } if (chan_switch) goto out; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 44e112b8b5b3..530182e20ce2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -138,6 +138,7 @@ static const u32 mt7915_offs[] = { [AGG_ACR0] = 0x084, [AGG_ACR4] = 0x08c, [AGG_MRCR] = 0x098, + [AGG_ATCR0] = 0x0ec, [AGG_ATCR1] = 0x0f0, [AGG_ATCR3] = 0x0f4, [LPON_UTTR0] = 0x080, @@ -212,6 +213,7 @@ static const u32 mt7916_offs[] = { [AGG_ACR0] = 0x054, [AGG_ACR4] = 0x05c, [AGG_MRCR] = 0x068, + [AGG_ATCR0] = 0x1a4, [AGG_ATCR1] = 0x1a8, [AGG_ATCR3] = 0x080, [LPON_UTTR0] = 0x360, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index 89ac8e6707b8..c5ec63a25a42 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -66,6 +66,7 @@ enum offs_rev { AGG_ACR0, AGG_ACR4, AGG_MRCR, + AGG_ATCR0, AGG_ATCR1, AGG_ATCR3, LPON_UTTR0, @@ -254,6 +255,9 @@ enum offs_rev { #define MT_WTBLOFF_TOP_RSCR_RCPI_MODE GENMASK(31, 30) #define MT_WTBLOFF_TOP_RSCR_RCPI_PARAM GENMASK(25, 24) +#define MT_WTBLOFF_TOP_ACR(_band) MT_WTBLOFF_TOP(_band, 0x010) +#define MT_WTBLOFF_TOP_ADM_BACKOFFTIME BIT(29) + /* ETBF: band 0(0x820ea000), band 1(0x820fa000) */ #define MT_WF_ETBF_BASE(_band) ((_band) ? 0x820fa000 : 0x820ea000) #define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs)) @@ -505,6 +509,9 @@ enum offs_rev { #define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7) #define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24) +#define MT_AGG_ATCR0(_band) MT_WF_AGG(_band, __OFFS(AGG_ATCR0)) +#define MT_AGG_ATCR_MAC_BFF_TIME_EN BIT(30) + #define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, __OFFS(AGG_ATCR1)) #define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, __OFFS(AGG_ATCR3)) -- 2.51.0 From 1e232a9fb1937f6f8d6846845f34f7d0bb799084 Mon Sep 17 00:00:00 2001 From: Chad Monroe Date: Tue, 26 Nov 2024 20:40:49 +0000 Subject: [PATCH 16/16] wifi: mt76: mt7996: exclude tx backoff time from airtime This helps to make STA airtime counters more accurate. Signed-off-by: Chad Monroe Suggested-by: Ryder Lee Link: https://patch.msgid.link/88821d8f08e2715927939b35e630a06171962636.1732653612.git.chad@monroe.io Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 4 ++++ drivers/net/wireless/mediatek/mt76/mt7996/regs.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 8cfb122b48ac..260cd1c34c64 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -457,6 +457,10 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band) mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME4(band), MT_WF_RMAC_MIB_QOS23_BACKOFF); + /* clear backoff time for Tx duration */ + mt76_clear(dev, MT_WTBLOFF_ACR(band), + MT_WTBLOFF_ADM_BACKOFFTIME); + /* clear backoff time and set software compensation for OBSS time */ mask = MT_WF_RMAC_MIB_OBSS_BACKOFF | MT_WF_RMAC_MIB_ED_OFFSET; set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) | diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h index 06e307b5b02e..1876a968c92d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h @@ -175,6 +175,9 @@ enum offs_rev { #define MT_WTBLOFF_RSCR_RCPI_MODE GENMASK(31, 30) #define MT_WTBLOFF_RSCR_RCPI_PARAM GENMASK(25, 24) +#define MT_WTBLOFF_ACR(_band) MT_WTBLOFF(_band, 0x010) +#define MT_WTBLOFF_ADM_BACKOFFTIME BIT(29) + /* ETBF: band 0(0x820ea000), band 1(0x820fa000), band 2(0x830ea000) */ #define MT_WF_ETBF_BASE(_band) __BASE(WF_ETBF_BASE, (_band)) #define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs)) -- 2.51.0