Skip to content

Commit 4d401c5

Browse files
author
Paolo Abeni
committed
Johannes Berg says: ==================== Couple of quick fixes: - iwlwifi/iwlmld crash on certain error paths - iwlwifi/iwlmld regulatory data mixup - iwlwifi/iwlmld suspend/resume fix - iwlwifi MSI (without -X) fix - cfg80211/mac80211 S1G parsing fixes * tag 'wireless-2025-06-05' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: cfg80211/mac80211: correctly parse S1G beacon optional elements wifi: iwlwifi: mld: Move regulatory domain initialization wifi: iwlwifi: pcie: fix non-MSIX handshake register wifi: iwlwifi: mld: avoid panic on init failure wifi: iwlwifi: mvm: fix assert on suspend ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents edafd34 + 787fe16 commit 4d401c5

File tree

8 files changed

+92
-40
lines changed

8 files changed

+92
-40
lines changed

drivers/net/wireless/intel/iwlwifi/mld/fw.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,6 @@ int iwl_mld_load_fw(struct iwl_mld *mld)
349349
if (ret)
350350
goto err;
351351

352-
ret = iwl_mld_init_mcc(mld);
353-
if (ret)
354-
goto err;
355-
356352
mld->fw_status.running = true;
357353

358354
return 0;
@@ -546,6 +542,10 @@ int iwl_mld_start_fw(struct iwl_mld *mld)
546542
if (ret)
547543
goto error;
548544

545+
ret = iwl_mld_init_mcc(mld);
546+
if (ret)
547+
goto error;
548+
549549
return 0;
550550

551551
error:

drivers/net/wireless/intel/iwlwifi/mld/mld.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,8 @@ iwl_mld_nic_error(struct iwl_op_mode *op_mode,
653653
* It might not actually be true that we'll restart, but the
654654
* setting doesn't matter if we're going to be unbound either.
655655
*/
656-
if (type != IWL_ERR_TYPE_RESET_HS_TIMEOUT)
656+
if (type != IWL_ERR_TYPE_RESET_HS_TIMEOUT &&
657+
mld->fw_status.running)
657658
mld->fw_status.in_hw_restart = true;
658659
}
659660

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6360,8 +6360,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
63606360
(struct iwl_mvm_internal_rxq_notif *)cmd->payload;
63616361
struct iwl_host_cmd hcmd = {
63626362
.id = WIDE_ID(DATA_PATH_GROUP, TRIGGER_RX_QUEUES_NOTIF_CMD),
6363-
.data[0] = &cmd,
6364-
.len[0] = sizeof(cmd),
6363+
.data[0] = cmd,
6364+
.len[0] = __struct_size(cmd),
63656365
.data[1] = data,
63666366
.len[1] = size,
63676367
.flags = CMD_SEND_IN_RFKILL | (sync ? 0 : CMD_ASYNC),

drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
125125
reset_done =
126126
inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE;
127127
} else {
128-
inta_hw = iwl_read32(trans, CSR_INT_MASK);
128+
inta_hw = iwl_read32(trans, CSR_INT);
129129
reset_done = inta_hw & CSR_INT_BIT_RESET_DONE;
130130
}
131131

include/linux/ieee80211.h

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@
111111

112112
/* bits unique to S1G beacon */
113113
#define IEEE80211_S1G_BCN_NEXT_TBTT 0x100
114+
#define IEEE80211_S1G_BCN_CSSID 0x200
115+
#define IEEE80211_S1G_BCN_ANO 0x400
114116

115117
/* see 802.11ah-2016 9.9 NDP CMAC frames */
116118
#define IEEE80211_S1G_1MHZ_NDP_BITS 25
@@ -153,9 +155,6 @@
153155

154156
#define IEEE80211_ANO_NETTYPE_WILD 15
155157

156-
/* bits unique to S1G beacon */
157-
#define IEEE80211_S1G_BCN_NEXT_TBTT 0x100
158-
159158
/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */
160159
#define IEEE80211_CTL_EXT_POLL 0x2000
161160
#define IEEE80211_CTL_EXT_SPR 0x3000
@@ -627,6 +626,42 @@ static inline bool ieee80211_is_s1g_beacon(__le16 fc)
627626
cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON);
628627
}
629628

629+
/**
630+
* ieee80211_s1g_has_next_tbtt - check if IEEE80211_S1G_BCN_NEXT_TBTT
631+
* @fc: frame control bytes in little-endian byteorder
632+
* Return: whether or not the frame contains the variable-length
633+
* next TBTT field
634+
*/
635+
static inline bool ieee80211_s1g_has_next_tbtt(__le16 fc)
636+
{
637+
return ieee80211_is_s1g_beacon(fc) &&
638+
(fc & cpu_to_le16(IEEE80211_S1G_BCN_NEXT_TBTT));
639+
}
640+
641+
/**
642+
* ieee80211_s1g_has_ano - check if IEEE80211_S1G_BCN_ANO
643+
* @fc: frame control bytes in little-endian byteorder
644+
* Return: whether or not the frame contains the variable-length
645+
* ANO field
646+
*/
647+
static inline bool ieee80211_s1g_has_ano(__le16 fc)
648+
{
649+
return ieee80211_is_s1g_beacon(fc) &&
650+
(fc & cpu_to_le16(IEEE80211_S1G_BCN_ANO));
651+
}
652+
653+
/**
654+
* ieee80211_s1g_has_cssid - check if IEEE80211_S1G_BCN_CSSID
655+
* @fc: frame control bytes in little-endian byteorder
656+
* Return: whether or not the frame contains the variable-length
657+
* compressed SSID field
658+
*/
659+
static inline bool ieee80211_s1g_has_cssid(__le16 fc)
660+
{
661+
return ieee80211_is_s1g_beacon(fc) &&
662+
(fc & cpu_to_le16(IEEE80211_S1G_BCN_CSSID));
663+
}
664+
630665
/**
631666
* ieee80211_is_s1g_short_beacon - check if frame is an S1G short beacon
632667
* @fc: frame control bytes in little-endian byteorder
@@ -1245,16 +1280,40 @@ struct ieee80211_ext {
12451280
u8 change_seq;
12461281
u8 variable[0];
12471282
} __packed s1g_beacon;
1248-
struct {
1249-
u8 sa[ETH_ALEN];
1250-
__le32 timestamp;
1251-
u8 change_seq;
1252-
u8 next_tbtt[3];
1253-
u8 variable[0];
1254-
} __packed s1g_short_beacon;
12551283
} u;
12561284
} __packed __aligned(2);
12571285

1286+
/**
1287+
* ieee80211_s1g_optional_len - determine length of optional S1G beacon fields
1288+
* @fc: frame control bytes in little-endian byteorder
1289+
* Return: total length in bytes of the optional fixed-length fields
1290+
*
1291+
* S1G beacons may contain up to three optional fixed-length fields that
1292+
* precede the variable-length elements. Whether these fields are present
1293+
* is indicated by flags in the frame control field.
1294+
*
1295+
* From IEEE 802.11-2024 section 9.3.4.3:
1296+
* - Next TBTT field may be 0 or 3 bytes
1297+
* - Short SSID field may be 0 or 4 bytes
1298+
* - Access Network Options (ANO) field may be 0 or 1 byte
1299+
*/
1300+
static inline size_t
1301+
ieee80211_s1g_optional_len(__le16 fc)
1302+
{
1303+
size_t len = 0;
1304+
1305+
if (ieee80211_s1g_has_next_tbtt(fc))
1306+
len += 3;
1307+
1308+
if (ieee80211_s1g_has_cssid(fc))
1309+
len += 4;
1310+
1311+
if (ieee80211_s1g_has_ano(fc))
1312+
len += 1;
1313+
1314+
return len;
1315+
}
1316+
12581317
#define IEEE80211_TWT_CONTROL_NDP BIT(0)
12591318
#define IEEE80211_TWT_CONTROL_RESP_MODE BIT(1)
12601319
#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3)

net/mac80211/mlme.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7220,11 +7220,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
72207220
bssid = ieee80211_get_bssid(hdr, len, sdata->vif.type);
72217221
if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
72227222
struct ieee80211_ext *ext = (void *) mgmt;
7223-
7224-
if (ieee80211_is_s1g_short_beacon(ext->frame_control))
7225-
variable = ext->u.s1g_short_beacon.variable;
7226-
else
7227-
variable = ext->u.s1g_beacon.variable;
7223+
variable = ext->u.s1g_beacon.variable +
7224+
ieee80211_s1g_optional_len(ext->frame_control);
72287225
}
72297226

72307227
baselen = (u8 *) variable - (u8 *) mgmt;

net/mac80211/scan.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
276276
struct ieee80211_mgmt *mgmt = (void *)skb->data;
277277
struct ieee80211_bss *bss;
278278
struct ieee80211_channel *channel;
279+
struct ieee80211_ext *ext;
279280
size_t min_hdr_len = offsetof(struct ieee80211_mgmt,
280281
u.probe_resp.variable);
281282

@@ -285,12 +286,10 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
285286
return;
286287

287288
if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
288-
if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
289-
min_hdr_len = offsetof(struct ieee80211_ext,
290-
u.s1g_short_beacon.variable);
291-
else
292-
min_hdr_len = offsetof(struct ieee80211_ext,
293-
u.s1g_beacon);
289+
ext = (struct ieee80211_ext *)mgmt;
290+
min_hdr_len =
291+
offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
292+
ieee80211_s1g_optional_len(ext->frame_control);
294293
}
295294

296295
if (skb->len < min_hdr_len)

net/wireless/scan.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,6 +3250,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
32503250
const u8 *ie;
32513251
size_t ielen;
32523252
u64 tsf;
3253+
size_t s1g_optional_len;
32533254

32543255
if (WARN_ON(!mgmt))
32553256
return NULL;
@@ -3264,12 +3265,11 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
32643265

32653266
if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
32663267
ext = (void *) mgmt;
3267-
if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
3268-
min_hdr_len = offsetof(struct ieee80211_ext,
3269-
u.s1g_short_beacon.variable);
3270-
else
3271-
min_hdr_len = offsetof(struct ieee80211_ext,
3272-
u.s1g_beacon.variable);
3268+
s1g_optional_len =
3269+
ieee80211_s1g_optional_len(ext->frame_control);
3270+
min_hdr_len =
3271+
offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
3272+
s1g_optional_len;
32733273
} else {
32743274
/* same for beacons */
32753275
min_hdr_len = offsetof(struct ieee80211_mgmt,
@@ -3285,11 +3285,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
32853285
const struct ieee80211_s1g_bcn_compat_ie *compat;
32863286
const struct element *elem;
32873287

3288-
if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
3289-
ie = ext->u.s1g_short_beacon.variable;
3290-
else
3291-
ie = ext->u.s1g_beacon.variable;
3292-
3288+
ie = ext->u.s1g_beacon.variable + s1g_optional_len;
32933289
elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen);
32943290
if (!elem)
32953291
return NULL;

0 commit comments

Comments
 (0)