wifi: mt76: mt7925: fix incorrect scan probe IE handling for hw_scan

The IEs should be processed and filled into the command tlv separately
according to each band.

Cc: [email protected]
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Ming Yen Hsieh <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Ming Yen Hsieh
2025-06-18 16:47:24 +02:00
committed by Felix Fietkau
parent 63f18baa5b
commit 4bdc4c5f26
3 changed files with 63 additions and 19 deletions
+1 -1
View File
@@ -1481,7 +1481,7 @@ mt7925_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mt792x_mutex_acquire(dev);
err = mt7925_mcu_sched_scan_req(mphy, vif, req);
err = mt7925_mcu_sched_scan_req(mphy, vif, req, ies);
if (err < 0)
goto out;
+59 -16
View File
@@ -164,6 +164,7 @@ mt7925_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
bool suspend, struct cfg80211_wowlan *wowlan)
{
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
struct ieee80211_scan_ies ies = {};
struct mt76_dev *dev = phy->dev;
struct {
struct {
@@ -194,7 +195,7 @@ mt7925_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
UNI_WOW_DETECT_TYPE_BCN_LOST);
if (wowlan->nd_config) {
mt7925_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
mt7925_mcu_sched_scan_req(phy, vif, wowlan->nd_config, &ies);
req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
mt7925_mcu_sched_scan_enable(phy, vif, suspend);
}
@@ -2818,6 +2819,54 @@ int mt7925_mcu_set_dbdc(struct mt76_phy *phy, bool enable)
return err;
}
static void
mt7925_mcu_build_scan_ie_tlv(struct mt76_dev *mdev,
struct sk_buff *skb,
struct ieee80211_scan_ies *scan_ies)
{
u32 max_len = sizeof(struct scan_ie_tlv) + MT76_CONNAC_SCAN_IE_LEN;
struct scan_ie_tlv *ie;
enum nl80211_band i;
struct tlv *tlv;
const u8 *ies;
u16 ies_len;
for (i = 0; i <= NL80211_BAND_6GHZ; i++) {
if (i == NL80211_BAND_60GHZ)
continue;
ies = scan_ies->ies[i];
ies_len = scan_ies->len[i];
if (!ies || !ies_len)
continue;
if (ies_len > max_len)
return;
tlv = mt76_connac_mcu_add_tlv(skb, UNI_SCAN_IE,
sizeof(*ie) + ies_len);
ie = (struct scan_ie_tlv *)tlv;
memcpy(ie->ies, ies, ies_len);
ie->ies_len = cpu_to_le16(ies_len);
switch (i) {
case NL80211_BAND_2GHZ:
ie->band = 1;
break;
case NL80211_BAND_6GHZ:
ie->band = 3;
break;
default:
ie->band = 2;
break;
}
max_len -= (sizeof(*ie) + ies_len);
}
}
int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_scan_request *scan_req)
{
@@ -2845,7 +2894,8 @@ int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
max_len = sizeof(*hdr) + sizeof(*req) + sizeof(*ssid) +
sizeof(*bssid) * MT7925_RNR_SCAN_MAX_BSSIDS +
sizeof(*chan_info) + sizeof(*misc) + sizeof(*ie);
sizeof(*chan_info) + sizeof(*misc) + sizeof(*ie) +
MT76_CONNAC_SCAN_IE_LEN;
skb = mt76_mcu_msg_alloc(mdev, NULL, max_len);
if (!skb)
@@ -2929,13 +2979,6 @@ int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
}
chan_info->channel_type = sreq->n_channels ? 4 : 0;
tlv = mt76_connac_mcu_add_tlv(skb, UNI_SCAN_IE, sizeof(*ie));
ie = (struct scan_ie_tlv *)tlv;
if (sreq->ie_len > 0) {
memcpy(ie->ies, sreq->ie, sreq->ie_len);
ie->ies_len = cpu_to_le16(sreq->ie_len);
}
req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
tlv = mt76_connac_mcu_add_tlv(skb, UNI_SCAN_MISC, sizeof(*misc));
@@ -2946,6 +2989,9 @@ int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
req->scan_func |= SCAN_FUNC_RANDOM_MAC;
}
/* Append scan probe IEs as the last tlv */
mt7925_mcu_build_scan_ie_tlv(mdev, skb, &scan_req->ies);
err = mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SCAN_REQ),
true);
if (err < 0)
@@ -2957,7 +3003,8 @@ EXPORT_SYMBOL_GPL(mt7925_mcu_hw_scan);
int mt7925_mcu_sched_scan_req(struct mt76_phy *phy,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *sreq)
struct cfg80211_sched_scan_request *sreq,
struct ieee80211_scan_ies *ies)
{
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
struct ieee80211_channel **scan_list = sreq->channels;
@@ -3045,12 +3092,8 @@ int mt7925_mcu_sched_scan_req(struct mt76_phy *phy,
}
chan_info->channel_type = sreq->n_channels ? 4 : 0;
tlv = mt76_connac_mcu_add_tlv(skb, UNI_SCAN_IE, sizeof(*ie));
ie = (struct scan_ie_tlv *)tlv;
if (sreq->ie_len > 0) {
memcpy(ie->ies, sreq->ie, sreq->ie_len);
ie->ies_len = cpu_to_le16(sreq->ie_len);
}
/* Append scan probe IEs as the last tlv */
mt7925_mcu_build_scan_ie_tlv(mdev, skb, ies);
return mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SCAN_REQ),
true);
+3 -2
View File
@@ -269,7 +269,7 @@ struct scan_ie_tlv {
__le16 ies_len;
u8 band;
u8 pad;
u8 ies[MT76_CONNAC_SCAN_IE_LEN];
u8 ies[];
};
struct scan_misc_tlv {
@@ -673,7 +673,8 @@ int mt7925_mcu_cancel_hw_scan(struct mt76_phy *phy,
struct ieee80211_vif *vif);
int mt7925_mcu_sched_scan_req(struct mt76_phy *phy,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *sreq);
struct cfg80211_sched_scan_request *sreq,
struct ieee80211_scan_ies *ies);
int mt7925_mcu_sched_scan_enable(struct mt76_phy *phy,
struct ieee80211_vif *vif,
bool enable);