Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'wireless-next-2025-11-05' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
More changes from drivers are coming in, notably:

- ath10k: factory test support
- ath11k: TX power insertion support
- ath12k: BSS color change support
- iwlwifi: new sniffer API support

* tag 'wireless-next-2025-11-05' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (63 commits)
wifi: ath10k: use = {} to initialize bmi_target_info instead of memset
wifi: ath10k: use = {} to initialize pm_qos_request instead of memset
wifi: ath12k: unassign arvif on scan vdev create failure
wifi: ath12k: enforce vdev limit in ath12k_mac_vdev_create()
wifi: ath12k: Set EHT fixed rates for associated STAs
wifi: ath12k: add EHT rates to ath12k_mac_op_set_bitrate_mask()
wifi: ath12k: Add EHT fixed GI/LTF
wifi: ath12k: Add EHT MCS/NSS rates to Peer Assoc
wifi: ath12k: add EHT rate handling to existing set rate functions
wifi: ath12k: generalize GI and LTF fixed rate functions
wifi: ath12k: fix error handling in creating hardware group
wifi: ath12k: fix reusing m3 memory
wifi: ath12k: fix potential memory leak in ath12k_wow_arp_ns_offload()
wifi: iwlwifi: mld: add null check for kzalloc() in iwl_mld_send_proto_offload()
wifi: iwlwifi: mld: check for NULL pointer after kmalloc
wifi: iwlwifi: cfg: fix a few device names
wifi: iwlwifi: mld: Move EMLSR prints to IWL_DL_EHT
wifi: iwlwifi: disable EHT if the device doesn't allow it
wifi: iwlwifi: bump core version for BZ/SC/DR
wifi: iwlwifi: mld: use FW_CHECK on bad ROC notification
...
====================

Link: https://patch.msgid.link/20251105153537.54096-38-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+3437 -1975
+11 -17
drivers/net/wireless/ath/ath10k/core.c
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 6 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 8 7 */ 9 8 ··· 1186 1187 u32 address, data_len; 1187 1188 const void *data; 1188 1189 int ret; 1189 - struct pm_qos_request latency_qos; 1190 + struct pm_qos_request latency_qos = {}; 1190 1191 1191 1192 address = ar->hw_params.patch_load_addr; 1192 1193 ··· 1220 1221 ret); 1221 1222 } 1222 1223 1223 - memset(&latency_qos, 0, sizeof(latency_qos)); 1224 1224 cpu_latency_qos_add_request(&latency_qos, 0); 1225 1225 1226 1226 ret = ath10k_bmi_fast_download(ar, address, data, data_len); ··· 2491 2493 return 0; 2492 2494 } 2493 2495 2494 - static bool ath10k_core_needs_recovery(struct ath10k *ar) 2496 + static void ath10k_core_recovery_check_work(struct work_struct *work) 2495 2497 { 2498 + struct ath10k *ar = container_of(work, struct ath10k, recovery_check_work); 2496 2499 long time_left; 2497 2500 2498 2501 /* Sometimes the recovery will fail and then the next all recovery fail, ··· 2503 2504 ath10k_err(ar, "consecutive fail %d times, will shutdown driver!", 2504 2505 atomic_read(&ar->fail_cont_count)); 2505 2506 ar->state = ATH10K_STATE_WEDGED; 2506 - return false; 2507 + return; 2507 2508 } 2508 2509 2509 2510 ath10k_dbg(ar, ATH10K_DBG_BOOT, "total recovery count: %d", ++ar->recovery_count); ··· 2517 2518 ATH10K_RECOVERY_TIMEOUT_HZ); 2518 2519 if (time_left) { 2519 2520 ath10k_warn(ar, "previous recovery succeeded, skip this!\n"); 2520 - return false; 2521 + return; 2521 2522 } 2522 2523 2523 2524 /* Record the continuous recovery fail count when recovery failed. */ 2524 2525 atomic_inc(&ar->fail_cont_count); 2525 2526 2526 2527 /* Avoid having multiple recoveries at the same time. */ 2527 - return false; 2528 + return; 2528 2529 } 2529 2530 2530 2531 atomic_inc(&ar->pending_recovery); 2531 - 2532 - return true; 2532 + queue_work(ar->workqueue, &ar->restart_work); 2533 2533 } 2534 2534 2535 2535 void ath10k_core_start_recovery(struct ath10k *ar) 2536 2536 { 2537 - if (!ath10k_core_needs_recovery(ar)) 2538 - return; 2539 - 2540 - queue_work(ar->workqueue, &ar->restart_work); 2537 + /* Use workqueue_aux to avoid blocking recovery tracking */ 2538 + queue_work(ar->workqueue_aux, &ar->recovery_check_work); 2541 2539 } 2542 2540 EXPORT_SYMBOL(ath10k_core_start_recovery); 2543 2541 ··· 3352 3356 */ 3353 3357 static int ath10k_core_probe_fw(struct ath10k *ar) 3354 3358 { 3355 - struct bmi_target_info target_info; 3359 + struct bmi_target_info target_info = {}; 3356 3360 int ret = 0; 3357 3361 3358 3362 ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL); ··· 3363 3367 3364 3368 switch (ar->hif.bus) { 3365 3369 case ATH10K_BUS_SDIO: 3366 - memset(&target_info, 0, sizeof(target_info)); 3367 3370 ret = ath10k_bmi_get_target_info_sdio(ar, &target_info); 3368 3371 if (ret) { 3369 3372 ath10k_err(ar, "could not get target info (%d)\n", ret); ··· 3374 3379 case ATH10K_BUS_PCI: 3375 3380 case ATH10K_BUS_AHB: 3376 3381 case ATH10K_BUS_USB: 3377 - memset(&target_info, 0, sizeof(target_info)); 3378 3382 ret = ath10k_bmi_get_target_info(ar, &target_info); 3379 3383 if (ret) { 3380 3384 ath10k_err(ar, "could not get target info (%d)\n", ret); ··· 3383 3389 ar->hw->wiphy->hw_version = target_info.version; 3384 3390 break; 3385 3391 case ATH10K_BUS_SNOC: 3386 - memset(&target_info, 0, sizeof(target_info)); 3387 3392 ret = ath10k_hif_get_target_info(ar, &target_info); 3388 3393 if (ret) { 3389 3394 ath10k_err(ar, "could not get target info (%d)\n", ret); ··· 3727 3734 3728 3735 INIT_WORK(&ar->register_work, ath10k_core_register_work); 3729 3736 INIT_WORK(&ar->restart_work, ath10k_core_restart); 3737 + INIT_WORK(&ar->recovery_check_work, ath10k_core_recovery_check_work); 3730 3738 INIT_WORK(&ar->set_coverage_class_work, 3731 3739 ath10k_core_set_coverage_class_work); 3732 3740
+5 -1
drivers/net/wireless/ath/ath10k/core.h
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 7 6 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 8 7 */ 9 8 ··· 1207 1208 1208 1209 struct work_struct register_work; 1209 1210 struct work_struct restart_work; 1211 + struct work_struct recovery_check_work; 1210 1212 struct work_struct bundle_tx_work; 1211 1213 struct work_struct tx_complete_work; 1212 1214 ··· 1259 1259 struct { 1260 1260 /* protected by conf_mutex */ 1261 1261 struct ath10k_fw_components utf_mode_fw; 1262 + u8 ftm_msgref; 1262 1263 1263 1264 /* protected by data_lock */ 1264 1265 bool utf_monitor; 1266 + u32 data_pos; 1267 + u32 expected_seq; 1268 + u8 *eventdata; 1265 1269 } testmode; 1266 1270 1267 1271 struct {
+1 -1
drivers/net/wireless/ath/ath10k/mac.c
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 6 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 8 7 */ 9 8 ··· 5427 5428 cancel_work_sync(&ar->set_coverage_class_work); 5428 5429 cancel_delayed_work_sync(&ar->scan.timeout); 5429 5430 cancel_work_sync(&ar->restart_work); 5431 + cancel_work_sync(&ar->recovery_check_work); 5430 5432 } 5431 5433 5432 5434 static int ath10k_config_ps(struct ath10k *ar)
+234 -41
drivers/net/wireless/ath/ath10k/testmode.c
··· 1 1 // SPDX-License-Identifier: ISC 2 2 /* 3 3 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 6 7 #include "testmode.h" ··· 11 10 12 11 #include "debug.h" 13 12 #include "wmi.h" 13 + #include "wmi-tlv.h" 14 14 #include "hif.h" 15 15 #include "hw.h" 16 16 #include "core.h" 17 17 18 18 #include "testmode_i.h" 19 + 20 + #define ATH10K_FTM_SEG_NONE ((u32)-1) 21 + #define ATH10K_FTM_SEGHDR_CURRENT_SEQ GENMASK(3, 0) 22 + #define ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS GENMASK(7, 4) 19 23 20 24 static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = { 21 25 [ATH10K_TM_ATTR_CMD] = { .type = NLA_U32 }, ··· 31 25 [ATH10K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, 32 26 }; 33 27 28 + static void ath10k_tm_event_unsegmented(struct ath10k *ar, u32 cmd_id, 29 + struct sk_buff *skb) 30 + { 31 + struct sk_buff *nl_skb; 32 + int ret; 33 + 34 + nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, 35 + 2 * sizeof(u32) + skb->len, 36 + GFP_ATOMIC); 37 + if (!nl_skb) { 38 + ath10k_warn(ar, 39 + "failed to allocate skb for testmode wmi event\n"); 40 + return; 41 + } 42 + 43 + ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI); 44 + if (ret) { 45 + ath10k_warn(ar, 46 + "failed to put testmode wmi event cmd attribute: %d\n", 47 + ret); 48 + kfree_skb(nl_skb); 49 + return; 50 + } 51 + 52 + ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id); 53 + if (ret) { 54 + ath10k_warn(ar, 55 + "failed to put testmode wmi event cmd_id: %d\n", 56 + ret); 57 + kfree_skb(nl_skb); 58 + return; 59 + } 60 + 61 + ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data); 62 + if (ret) { 63 + ath10k_warn(ar, 64 + "failed to copy skb to testmode wmi event: %d\n", 65 + ret); 66 + kfree_skb(nl_skb); 67 + return; 68 + } 69 + 70 + cfg80211_testmode_event(nl_skb, GFP_ATOMIC); 71 + } 72 + 73 + static void ath10k_tm_event_segmented(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb) 74 + { 75 + struct wmi_ftm_cmd *ftm = (struct wmi_ftm_cmd *)skb->data; 76 + u8 total_segments, current_seq; 77 + struct sk_buff *nl_skb; 78 + u8 const *buf_pos; 79 + u16 datalen; 80 + u32 data_pos; 81 + int ret; 82 + 83 + if (skb->len < sizeof(*ftm)) { 84 + ath10k_warn(ar, "Invalid ftm event length: %d\n", skb->len); 85 + return; 86 + } 87 + 88 + current_seq = FIELD_GET(ATH10K_FTM_SEGHDR_CURRENT_SEQ, 89 + __le32_to_cpu(ftm->seg_hdr.segmentinfo)); 90 + total_segments = FIELD_GET(ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS, 91 + __le32_to_cpu(ftm->seg_hdr.segmentinfo)); 92 + datalen = skb->len - sizeof(*ftm); 93 + buf_pos = ftm->data; 94 + 95 + if (current_seq == 0) { 96 + ar->testmode.expected_seq = 0; 97 + ar->testmode.data_pos = 0; 98 + } 99 + 100 + data_pos = ar->testmode.data_pos; 101 + 102 + if ((data_pos + datalen) > ATH_FTM_EVENT_MAX_BUF_LENGTH) { 103 + ath10k_warn(ar, "Invalid ftm event length at %u: %u\n", 104 + data_pos, datalen); 105 + ret = -EINVAL; 106 + return; 107 + } 108 + 109 + memcpy(&ar->testmode.eventdata[data_pos], buf_pos, datalen); 110 + data_pos += datalen; 111 + 112 + if (++ar->testmode.expected_seq != total_segments) { 113 + ar->testmode.data_pos = data_pos; 114 + ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "partial data received %u/%u\n", 115 + current_seq + 1, total_segments); 116 + return; 117 + } 118 + 119 + ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "total data length %u\n", data_pos); 120 + 121 + nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, 122 + 2 * sizeof(u32) + data_pos, 123 + GFP_ATOMIC); 124 + if (!nl_skb) { 125 + ath10k_warn(ar, "failed to allocate skb for testmode wmi event\n"); 126 + return; 127 + } 128 + 129 + ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_TLV); 130 + if (ret) { 131 + ath10k_warn(ar, "failed to put testmode wmi event attribute: %d\n", ret); 132 + kfree_skb(nl_skb); 133 + return; 134 + } 135 + 136 + ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id); 137 + if (ret) { 138 + ath10k_warn(ar, "failed to put testmode wmi event cmd_id: %d\n", ret); 139 + kfree_skb(nl_skb); 140 + return; 141 + } 142 + 143 + ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, data_pos, &ar->testmode.eventdata[0]); 144 + if (ret) { 145 + ath10k_warn(ar, "failed to copy skb to testmode wmi event: %d\n", ret); 146 + kfree_skb(nl_skb); 147 + return; 148 + } 149 + 150 + cfg80211_testmode_event(nl_skb, GFP_ATOMIC); 151 + } 152 + 34 153 /* Returns true if callee consumes the skb and the skb should be discarded. 35 154 * Returns false if skb is not used. Does not sleep. 36 155 */ 37 156 bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb) 38 157 { 39 - struct sk_buff *nl_skb; 40 158 bool consumed; 41 - int ret; 42 159 43 160 ath10k_dbg(ar, ATH10K_DBG_TESTMODE, 44 161 "testmode event wmi cmd_id %d skb %p skb->len %d\n", ··· 182 53 */ 183 54 consumed = true; 184 55 185 - nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, 186 - 2 * sizeof(u32) + skb->len, 187 - GFP_ATOMIC); 188 - if (!nl_skb) { 189 - ath10k_warn(ar, 190 - "failed to allocate skb for testmode wmi event\n"); 191 - goto out; 192 - } 193 - 194 - ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI); 195 - if (ret) { 196 - ath10k_warn(ar, 197 - "failed to put testmode wmi event cmd attribute: %d\n", 198 - ret); 199 - kfree_skb(nl_skb); 200 - goto out; 201 - } 202 - 203 - ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id); 204 - if (ret) { 205 - ath10k_warn(ar, 206 - "failed to put testmode wmi event cmd_id: %d\n", 207 - ret); 208 - kfree_skb(nl_skb); 209 - goto out; 210 - } 211 - 212 - ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data); 213 - if (ret) { 214 - ath10k_warn(ar, 215 - "failed to copy skb to testmode wmi event: %d\n", 216 - ret); 217 - kfree_skb(nl_skb); 218 - goto out; 219 - } 220 - 221 - cfg80211_testmode_event(nl_skb, GFP_ATOMIC); 56 + if (ar->testmode.expected_seq != ATH10K_FTM_SEG_NONE) 57 + ath10k_tm_event_segmented(ar, cmd_id, skb); 58 + else 59 + ath10k_tm_event_unsegmented(ar, cmd_id, skb); 222 60 223 61 out: 224 62 spin_unlock_bh(&ar->data_lock); ··· 377 281 goto err_release_utf_mode_fw; 378 282 } 379 283 284 + ar->testmode.eventdata = kzalloc(ATH_FTM_EVENT_MAX_BUF_LENGTH, GFP_KERNEL); 285 + if (!ar->testmode.eventdata) { 286 + ret = -ENOMEM; 287 + goto err_power_down; 288 + } 289 + 380 290 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_UTF, 381 291 &ar->testmode.utf_mode_fw); 382 292 if (ret) { 383 293 ath10k_err(ar, "failed to start core (testmode): %d\n", ret); 384 294 ar->state = ATH10K_STATE_OFF; 385 - goto err_power_down; 295 + goto err_release_eventdata; 386 296 } 387 297 388 298 ar->state = ATH10K_STATE_UTF; ··· 403 301 mutex_unlock(&ar->conf_mutex); 404 302 405 303 return 0; 304 + 305 + err_release_eventdata: 306 + kfree(ar->testmode.eventdata); 307 + ar->testmode.eventdata = NULL; 406 308 407 309 err_power_down: 408 310 ath10k_hif_power_down(ar); ··· 446 340 447 341 release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware); 448 342 ar->testmode.utf_mode_fw.fw_file.firmware = NULL; 343 + 344 + kfree(ar->testmode.eventdata); 345 + ar->testmode.eventdata = NULL; 449 346 450 347 ar->state = ATH10K_STATE_OFF; 451 348 } ··· 533 424 return ret; 534 425 } 535 426 427 + static int ath10k_tm_cmd_tlv(struct ath10k *ar, struct nlattr *tb[]) 428 + { 429 + u16 total_bytes, num_segments; 430 + u32 cmd_id, buf_len; 431 + u8 segnumber = 0; 432 + u8 *bufpos; 433 + void *buf; 434 + int ret; 435 + 436 + mutex_lock(&ar->conf_mutex); 437 + 438 + if (ar->state != ATH10K_STATE_UTF) { 439 + ret = -ENETDOWN; 440 + goto out; 441 + } 442 + 443 + buf = nla_data(tb[ATH10K_TM_ATTR_DATA]); 444 + buf_len = nla_len(tb[ATH10K_TM_ATTR_DATA]); 445 + cmd_id = WMI_PDEV_UTF_CMDID; 446 + 447 + ath10k_dbg(ar, ATH10K_DBG_TESTMODE, 448 + "cmd wmi ftm cmd_id %d buffer length %d\n", 449 + cmd_id, buf_len); 450 + ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len); 451 + 452 + bufpos = buf; 453 + total_bytes = buf_len; 454 + num_segments = total_bytes / MAX_WMI_UTF_LEN; 455 + ar->testmode.expected_seq = 0; 456 + 457 + if (buf_len - (num_segments * MAX_WMI_UTF_LEN)) 458 + num_segments++; 459 + 460 + while (buf_len) { 461 + u16 chunk_len = min_t(u16, buf_len, MAX_WMI_UTF_LEN); 462 + struct wmi_ftm_cmd *ftm_cmd; 463 + struct sk_buff *skb; 464 + u32 hdr_info; 465 + u8 seginfo; 466 + 467 + skb = ath10k_wmi_alloc_skb(ar, (chunk_len + 468 + sizeof(struct wmi_ftm_cmd))); 469 + if (!skb) { 470 + ret = -ENOMEM; 471 + goto out; 472 + } 473 + 474 + ftm_cmd = (struct wmi_ftm_cmd *)skb->data; 475 + hdr_info = FIELD_PREP(WMI_TLV_TAG, WMI_TLV_TAG_ARRAY_BYTE) | 476 + FIELD_PREP(WMI_TLV_LEN, (chunk_len + 477 + sizeof(struct wmi_ftm_seg_hdr))); 478 + ftm_cmd->tlv_header = __cpu_to_le32(hdr_info); 479 + ftm_cmd->seg_hdr.len = __cpu_to_le32(total_bytes); 480 + ftm_cmd->seg_hdr.msgref = __cpu_to_le32(ar->testmode.ftm_msgref); 481 + seginfo = FIELD_PREP(ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS, num_segments) | 482 + FIELD_PREP(ATH10K_FTM_SEGHDR_CURRENT_SEQ, segnumber); 483 + ftm_cmd->seg_hdr.segmentinfo = __cpu_to_le32(seginfo); 484 + segnumber++; 485 + 486 + memcpy(&ftm_cmd->data, bufpos, chunk_len); 487 + 488 + ret = ath10k_wmi_cmd_send(ar, skb, cmd_id); 489 + if (ret) { 490 + ath10k_warn(ar, "failed to send wmi ftm command: %d\n", ret); 491 + goto out; 492 + } 493 + 494 + buf_len -= chunk_len; 495 + bufpos += chunk_len; 496 + } 497 + 498 + ar->testmode.ftm_msgref++; 499 + ret = 0; 500 + 501 + out: 502 + mutex_unlock(&ar->conf_mutex); 503 + return ret; 504 + } 505 + 536 506 int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 537 507 void *data, int len) 538 508 { ··· 627 439 if (!tb[ATH10K_TM_ATTR_CMD]) 628 440 return -EINVAL; 629 441 442 + ar->testmode.expected_seq = ATH10K_FTM_SEG_NONE; 443 + 630 444 switch (nla_get_u32(tb[ATH10K_TM_ATTR_CMD])) { 631 445 case ATH10K_TM_CMD_GET_VERSION: 632 - return ath10k_tm_cmd_get_version(ar, tb); 446 + if (!tb[ATH10K_TM_ATTR_DATA]) 447 + return ath10k_tm_cmd_get_version(ar, tb); 448 + else /* ATH10K_TM_CMD_TLV */ 449 + return ath10k_tm_cmd_tlv(ar, tb); 633 450 case ATH10K_TM_CMD_UTF_START: 634 451 return ath10k_tm_cmd_utf_start(ar, tb); 635 452 case ATH10K_TM_CMD_UTF_STOP:
+15
drivers/net/wireless/ath/ath10k/testmode_i.h
··· 1 1 /* SPDX-License-Identifier: ISC */ 2 2 /* 3 3 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 5 */ 5 6 6 7 /* "API" level of the ath10k testmode interface. Bump it after every ··· 15 14 #define ATH10K_TESTMODE_VERSION_MINOR 0 16 15 17 16 #define ATH10K_TM_DATA_MAX_LEN 5000 17 + #define ATH_FTM_EVENT_MAX_BUF_LENGTH 2048 18 18 19 19 enum ath10k_tm_attr { 20 20 __ATH10K_TM_ATTR_INVALID = 0, ··· 59 57 * ATH10K_TM_ATTR_DATA. 60 58 */ 61 59 ATH10K_TM_CMD_WMI = 3, 60 + 61 + /* The command used to transmit a test command to the firmware 62 + * and the event to receive test events from the firmware. The data 63 + * received only contain the TLV payload, need to add the tlv header 64 + * and send the cmd to firmware with command id WMI_PDEV_UTF_CMDID. 65 + * The data payload size could be large and the driver needs to 66 + * send segmented data to firmware. 67 + * 68 + * This legacy testmode command shares the same value as the get-version 69 + * command. To distinguish between them, we check whether the data attribute 70 + * is present. 71 + */ 72 + ATH10K_TM_CMD_TLV = ATH10K_TM_CMD_GET_VERSION, 62 73 };
+18 -1
drivers/net/wireless/ath/ath10k/wmi.h
··· 3 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 6 - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 6 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 7 */ 8 8 9 9 #ifndef _WMI_H_ ··· 7417 7417 /* Tx_end to external pa off timing */ 7418 7418 __le32 bb_xpa_timing; 7419 7419 } __packed; 7420 + 7421 + struct wmi_ftm_seg_hdr { 7422 + __le32 len; 7423 + __le32 msgref; 7424 + __le32 segmentinfo; 7425 + __le32 pdev_id; 7426 + } __packed; 7427 + 7428 + struct wmi_ftm_cmd { 7429 + __le32 tlv_header; 7430 + struct wmi_ftm_seg_hdr seg_hdr; 7431 + u8 data[]; 7432 + } __packed; 7433 + 7434 + #define WMI_TLV_LEN GENMASK(15, 0) 7435 + #define WMI_TLV_TAG GENMASK(31, 16) 7436 + #define MAX_WMI_UTF_LEN 252 7420 7437 7421 7438 struct ath10k; 7422 7439 struct ath10k_vif;
+19 -19
drivers/net/wireless/ath/ath11k/hal.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #ifndef ATH11K_HAL_H ··· 43 43 #define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 44 44 #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 45 45 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 46 - #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(x) \ 47 - (ab->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg) 48 - #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(x) \ 49 - (ab->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg) 50 - #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(x) \ 51 - (ab->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg) 52 - #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(x) \ 53 - (ab->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg) 46 + #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \ 47 + ((ab)->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg) 48 + #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \ 49 + ((ab)->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg) 50 + #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \ 51 + ((ab)->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg) 52 + #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \ 53 + ((ab)->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg) 54 54 #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 55 55 56 56 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 ··· 209 209 #define HAL_REO_STATUS_HP(ab) ab->hw_params.regs->hal_reo_status_hp 210 210 211 211 /* WBM Idle R0 address */ 212 - #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(x) \ 213 - (ab->hw_params.regs->hal_wbm_idle_link_ring_base_lsb) 214 - #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(x) \ 215 - (ab->hw_params.regs->hal_wbm_idle_link_ring_misc) 212 + #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \ 213 + ((ab)->hw_params.regs->hal_wbm_idle_link_ring_base_lsb) 214 + #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \ 215 + ((ab)->hw_params.regs->hal_wbm_idle_link_ring_misc) 216 216 #define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR 0x00000048 217 217 #define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR 0x0000004c 218 218 #define HAL_WBM_SCATTERED_RING_BASE_LSB 0x00000058 ··· 227 227 #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b0 228 228 229 229 /* SW2WBM R0 release address */ 230 - #define HAL_WBM_RELEASE_RING_BASE_LSB(x) \ 231 - (ab->hw_params.regs->hal_wbm_release_ring_base_lsb) 230 + #define HAL_WBM_RELEASE_RING_BASE_LSB(ab) \ 231 + ((ab)->hw_params.regs->hal_wbm_release_ring_base_lsb) 232 232 233 233 /* SW2WBM R2 release address */ 234 234 #define HAL_WBM_RELEASE_RING_HP 0x00003018 235 235 236 236 /* WBM2SW R0 release address */ 237 - #define HAL_WBM0_RELEASE_RING_BASE_LSB(x) \ 238 - (ab->hw_params.regs->hal_wbm0_release_ring_base_lsb) 239 - #define HAL_WBM1_RELEASE_RING_BASE_LSB(x) \ 240 - (ab->hw_params.regs->hal_wbm1_release_ring_base_lsb) 237 + #define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \ 238 + ((ab)->hw_params.regs->hal_wbm0_release_ring_base_lsb) 239 + #define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \ 240 + ((ab)->hw_params.regs->hal_wbm1_release_ring_base_lsb) 241 241 242 242 /* WBM2SW R2 release address */ 243 243 #define HAL_WBM0_RELEASE_RING_HP 0x000030c0
+316 -139
drivers/net/wireless/ath/ath11k/mac.c
··· 2235 2235 arg->peer_nss = min(sta->deflink.rx_nss, max_nss); 2236 2236 arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); 2237 2237 arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); 2238 + arg->rx_mcs_set = ath11k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); 2238 2239 arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); 2239 - arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit( 2240 - __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); 2240 + arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); 2241 2241 2242 2242 /* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default. 2243 2243 * VHT mcs rate 10 and 11 is not supported in 11ac standard. ··· 2522 2522 he_tx_mcs = v; 2523 2523 } 2524 2524 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 2525 + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); 2525 2526 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 2526 2527 2527 2528 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); 2528 - v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); 2529 2529 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 2530 2530 2531 2531 arg->peer_he_mcs_count++; ··· 2535 2535 2536 2536 default: 2537 2537 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 2538 + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); 2538 2539 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 2539 2540 2540 2541 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); 2541 - v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); 2542 2542 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 2543 2543 2544 2544 arg->peer_he_mcs_count++; ··· 4026 4026 spin_unlock_bh(&ar->data_lock); 4027 4027 4028 4028 return 0; 4029 + } 4030 + 4031 + static void ath11k_mac_fw_stats_reset(struct ath11k *ar) 4032 + { 4033 + spin_lock_bh(&ar->data_lock); 4034 + ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); 4035 + ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs); 4036 + ar->fw_stats.num_vdev_recvd = 0; 4037 + ar->fw_stats.num_bcn_recvd = 0; 4038 + spin_unlock_bh(&ar->data_lock); 4039 + } 4040 + 4041 + int ath11k_mac_fw_stats_request(struct ath11k *ar, 4042 + struct stats_request_params *req_param) 4043 + { 4044 + struct ath11k_base *ab = ar->ab; 4045 + unsigned long time_left; 4046 + int ret; 4047 + 4048 + lockdep_assert_held(&ar->conf_mutex); 4049 + 4050 + ath11k_mac_fw_stats_reset(ar); 4051 + 4052 + reinit_completion(&ar->fw_stats_complete); 4053 + reinit_completion(&ar->fw_stats_done); 4054 + 4055 + ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); 4056 + 4057 + if (ret) { 4058 + ath11k_warn(ab, "could not request fw stats (%d)\n", 4059 + ret); 4060 + return ret; 4061 + } 4062 + 4063 + time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ); 4064 + if (!time_left) 4065 + return -ETIMEDOUT; 4066 + 4067 + /* FW stats can get split when exceeding the stats data buffer limit. 4068 + * In that case, since there is no end marking for the back-to-back 4069 + * received 'update stats' event, we keep a 3 seconds timeout in case, 4070 + * fw_stats_done is not marked yet 4071 + */ 4072 + time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ); 4073 + if (!time_left) 4074 + return -ETIMEDOUT; 4075 + 4076 + return 0; 4077 + } 4078 + 4079 + static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id, 4080 + u32 vdev_id, u32 stats_id) 4081 + { 4082 + struct ath11k_base *ab = ar->ab; 4083 + struct stats_request_params req_param; 4084 + int ret; 4085 + 4086 + lockdep_assert_held(&ar->conf_mutex); 4087 + 4088 + if (ar->state != ATH11K_STATE_ON) 4089 + return -ENETDOWN; 4090 + 4091 + req_param.pdev_id = pdev_id; 4092 + req_param.vdev_id = vdev_id; 4093 + req_param.stats_id = stats_id; 4094 + 4095 + ret = ath11k_mac_fw_stats_request(ar, &req_param); 4096 + if (ret) 4097 + ath11k_warn(ab, "failed to request fw stats: %d\n", ret); 4098 + 4099 + ath11k_dbg(ab, ATH11K_DBG_WMI, 4100 + "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n", 4101 + pdev_id, vdev_id, stats_id); 4102 + 4103 + return ret; 4104 + } 4105 + 4106 + static int ath11k_mac_handle_get_txpower(struct ath11k *ar, 4107 + struct ieee80211_vif *vif, 4108 + int *dbm) 4109 + { 4110 + struct ath11k_base *ab = ar->ab; 4111 + struct ath11k_fw_stats_pdev *pdev; 4112 + int ret; 4113 + 4114 + /* Final Tx power is minimum of Target Power, CTL power, Regulatory 4115 + * Power, PSD EIRP Power. We just know the Regulatory power from the 4116 + * regulatory rules obtained. FW knows all these power and sets the min 4117 + * of these. Hence, we request the FW pdev stats in which FW reports 4118 + * the minimum of all vdev's channel Tx power. 4119 + */ 4120 + lockdep_assert_held(&ar->conf_mutex); 4121 + 4122 + /* Firmware doesn't provide Tx power during CAC hence no need to fetch 4123 + * the stats. 4124 + */ 4125 + if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) 4126 + return -EAGAIN; 4127 + 4128 + ret = ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0, 4129 + WMI_REQUEST_PDEV_STAT); 4130 + if (ret) { 4131 + ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret); 4132 + goto err_fallback; 4133 + } 4134 + 4135 + spin_lock_bh(&ar->data_lock); 4136 + pdev = list_first_entry_or_null(&ar->fw_stats.pdevs, 4137 + struct ath11k_fw_stats_pdev, list); 4138 + if (!pdev) { 4139 + spin_unlock_bh(&ar->data_lock); 4140 + goto err_fallback; 4141 + } 4142 + 4143 + /* tx power is set as 2 units per dBm in FW. */ 4144 + *dbm = pdev->chan_tx_power / 2; 4145 + 4146 + spin_unlock_bh(&ar->data_lock); 4147 + 4148 + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware %d, reported %d dBm\n", 4149 + pdev->chan_tx_power, *dbm); 4150 + return 0; 4151 + 4152 + err_fallback: 4153 + /* We didn't get txpower from FW. Hence, relying on vif->bss_conf.txpower */ 4154 + *dbm = vif->bss_conf.txpower; 4155 + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware NaN, reported %d dBm\n", 4156 + *dbm); 4157 + return 0; 4158 + } 4159 + 4160 + static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw, 4161 + struct ieee80211_vif *vif, 4162 + unsigned int link_id, 4163 + int *dbm) 4164 + { 4165 + struct ath11k *ar = hw->priv; 4166 + int ret; 4167 + 4168 + mutex_lock(&ar->conf_mutex); 4169 + ret = ath11k_mac_handle_get_txpower(ar, vif, dbm); 4170 + mutex_unlock(&ar->conf_mutex); 4171 + 4172 + return ret; 4029 4173 } 4030 4174 4031 4175 static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, ··· 6251 6107 ath11k_mgmt_over_wmi_tx_drop(ar, skb); 6252 6108 } 6253 6109 6110 + static int ath11k_mac_mgmt_action_frame_fill_elem_data(struct ath11k_vif *arvif, 6111 + struct sk_buff *skb) 6112 + { 6113 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 6114 + u8 category, *buf, iv_len, action_code, dialog_token; 6115 + int cur_tx_power, max_tx_power; 6116 + struct ath11k *ar = arvif->ar; 6117 + struct cfg80211_chan_def def; 6118 + struct ath11k_skb_cb *skb_cb; 6119 + struct ieee80211_mgmt *mgmt; 6120 + unsigned int remaining_len; 6121 + bool has_protected; 6122 + 6123 + lockdep_assert_held(&ar->conf_mutex); 6124 + 6125 + /* make sure category field is present */ 6126 + if (skb->len < IEEE80211_MIN_ACTION_SIZE) 6127 + return -EINVAL; 6128 + 6129 + remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE; 6130 + has_protected = ieee80211_has_protected(hdr->frame_control); 6131 + 6132 + /* In case of SW crypto and hdr protected (PMF), packet will already be encrypted, 6133 + * we can't put in data in this case 6134 + */ 6135 + if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && 6136 + has_protected) 6137 + return 0; 6138 + 6139 + mgmt = (struct ieee80211_mgmt *)hdr; 6140 + buf = (u8 *)&mgmt->u.action; 6141 + 6142 + /* FCTL_PROTECTED frame might have extra space added for HDR_LEN. Offset that 6143 + * many bytes if it is there 6144 + */ 6145 + if (has_protected) { 6146 + skb_cb = ATH11K_SKB_CB(skb); 6147 + 6148 + switch (skb_cb->cipher) { 6149 + /* Cipher suite having flag %IEEE80211_KEY_FLAG_GENERATE_IV_MGMT set in 6150 + * key needs to be processed. See ath11k_install_key() 6151 + */ 6152 + case WLAN_CIPHER_SUITE_CCMP: 6153 + case WLAN_CIPHER_SUITE_CCMP_256: 6154 + case WLAN_CIPHER_SUITE_GCMP: 6155 + case WLAN_CIPHER_SUITE_GCMP_256: 6156 + iv_len = IEEE80211_CCMP_HDR_LEN; 6157 + break; 6158 + case WLAN_CIPHER_SUITE_TKIP: 6159 + iv_len = 0; 6160 + break; 6161 + default: 6162 + return -EINVAL; 6163 + } 6164 + 6165 + if (remaining_len < iv_len) 6166 + return -EINVAL; 6167 + 6168 + buf += iv_len; 6169 + remaining_len -= iv_len; 6170 + } 6171 + 6172 + category = *buf++; 6173 + /* category code is already taken care in %IEEE80211_MIN_ACTION_SIZE hence 6174 + * no need to adjust remaining_len 6175 + */ 6176 + 6177 + switch (category) { 6178 + case WLAN_CATEGORY_RADIO_MEASUREMENT: 6179 + /* need action code and dialog token */ 6180 + if (remaining_len < 2) 6181 + return -EINVAL; 6182 + 6183 + /* Packet Format: 6184 + * Action Code | Dialog Token | Variable Len (based on Action Code) 6185 + */ 6186 + action_code = *buf++; 6187 + dialog_token = *buf++; 6188 + remaining_len -= 2; 6189 + 6190 + if (ath11k_mac_vif_chan(arvif->vif, &def)) 6191 + return -ENOENT; 6192 + 6193 + cur_tx_power = arvif->vif->bss_conf.txpower; 6194 + max_tx_power = min(def.chan->max_reg_power, (int)ar->max_tx_power / 2); 6195 + ath11k_mac_handle_get_txpower(ar, arvif->vif, &cur_tx_power); 6196 + 6197 + switch (action_code) { 6198 + case WLAN_RM_ACTION_LINK_MEASUREMENT_REQUEST: 6199 + /* need variable fields to be present in len */ 6200 + if (remaining_len < 2) 6201 + return -EINVAL; 6202 + 6203 + /* Variable length format as defined in IEEE 802.11-2024, 6204 + * Figure 9-1187-Link Measurement Request frame Action field 6205 + * format. 6206 + * Transmit Power | Max Tx Power 6207 + * We fill both of these. 6208 + */ 6209 + *buf++ = cur_tx_power; 6210 + *buf = max_tx_power; 6211 + 6212 + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, 6213 + "RRM: Link Measurement Req dialog_token %u cur_tx_power %d max_tx_power %d\n", 6214 + dialog_token, cur_tx_power, max_tx_power); 6215 + break; 6216 + case WLAN_RM_ACTION_LINK_MEASUREMENT_REPORT: 6217 + /* need variable fields to be present in len */ 6218 + if (remaining_len < 3) 6219 + return -EINVAL; 6220 + 6221 + /* Variable length format as defined in IEEE 802.11-2024, 6222 + * Figure 9-1188-Link Measurement Report frame Action field format 6223 + * TPC Report | Variable Fields 6224 + * 6225 + * TPC Report Format: 6226 + * Element ID | Len | Tx Power | Link Margin 6227 + * 6228 + * We fill Tx power in the TPC Report (2nd index) 6229 + */ 6230 + buf[2] = cur_tx_power; 6231 + 6232 + /* TODO: At present, Link margin data is not present so can't 6233 + * really fill it now. Once it is available, it can be added 6234 + * here 6235 + */ 6236 + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, 6237 + "RRM: Link Measurement Report dialog_token %u cur_tx_power %d\n", 6238 + dialog_token, cur_tx_power); 6239 + break; 6240 + default: 6241 + return -EINVAL; 6242 + } 6243 + break; 6244 + default: 6245 + /* nothing to fill */ 6246 + return 0; 6247 + } 6248 + 6249 + return 0; 6250 + } 6251 + 6252 + static int ath11k_mac_mgmt_frame_fill_elem_data(struct ath11k_vif *arvif, 6253 + struct sk_buff *skb) 6254 + { 6255 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 6256 + 6257 + if (!ieee80211_is_action(hdr->frame_control)) 6258 + return 0; 6259 + 6260 + return ath11k_mac_mgmt_action_frame_fill_elem_data(arvif, skb); 6261 + } 6262 + 6254 6263 static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work) 6255 6264 { 6256 6265 struct ath11k *ar = container_of(work, struct ath11k, wmi_mgmt_tx_work); ··· 6423 6126 arvif = ath11k_vif_to_arvif(skb_cb->vif); 6424 6127 mutex_lock(&ar->conf_mutex); 6425 6128 if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) { 6129 + /* Fill in the data which is required to be filled by the driver 6130 + * For example: Max Tx power in Link Measurement Request/Report 6131 + */ 6132 + ret = ath11k_mac_mgmt_frame_fill_elem_data(arvif, skb); 6133 + if (ret) { 6134 + /* If we couldn't fill the data due to any reason, 6135 + * let's not discard transmitting the packet. 6136 + */ 6137 + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, 6138 + "Failed to fill the required data for the mgmt packet err %d\n", 6139 + ret); 6140 + } 6141 + 6426 6142 ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb); 6427 6143 if (ret) { 6428 6144 ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n", ··· 9389 9079 } 9390 9080 } 9391 9081 9392 - static void ath11k_mac_fw_stats_reset(struct ath11k *ar) 9393 - { 9394 - spin_lock_bh(&ar->data_lock); 9395 - ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs); 9396 - ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs); 9397 - ar->fw_stats.num_vdev_recvd = 0; 9398 - ar->fw_stats.num_bcn_recvd = 0; 9399 - spin_unlock_bh(&ar->data_lock); 9400 - } 9401 - 9402 - int ath11k_mac_fw_stats_request(struct ath11k *ar, 9403 - struct stats_request_params *req_param) 9404 - { 9405 - struct ath11k_base *ab = ar->ab; 9406 - unsigned long time_left; 9407 - int ret; 9408 - 9409 - lockdep_assert_held(&ar->conf_mutex); 9410 - 9411 - ath11k_mac_fw_stats_reset(ar); 9412 - 9413 - reinit_completion(&ar->fw_stats_complete); 9414 - reinit_completion(&ar->fw_stats_done); 9415 - 9416 - ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); 9417 - 9418 - if (ret) { 9419 - ath11k_warn(ab, "could not request fw stats (%d)\n", 9420 - ret); 9421 - return ret; 9422 - } 9423 - 9424 - time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ); 9425 - if (!time_left) 9426 - return -ETIMEDOUT; 9427 - 9428 - /* FW stats can get split when exceeding the stats data buffer limit. 9429 - * In that case, since there is no end marking for the back-to-back 9430 - * received 'update stats' event, we keep a 3 seconds timeout in case, 9431 - * fw_stats_done is not marked yet 9432 - */ 9433 - time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ); 9434 - if (!time_left) 9435 - return -ETIMEDOUT; 9436 - 9437 - return 0; 9438 - } 9439 - 9440 - static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id, 9441 - u32 vdev_id, u32 stats_id) 9442 - { 9443 - struct ath11k_base *ab = ar->ab; 9444 - struct stats_request_params req_param; 9445 - int ret; 9446 - 9447 - lockdep_assert_held(&ar->conf_mutex); 9448 - 9449 - if (ar->state != ATH11K_STATE_ON) 9450 - return -ENETDOWN; 9451 - 9452 - req_param.pdev_id = pdev_id; 9453 - req_param.vdev_id = vdev_id; 9454 - req_param.stats_id = stats_id; 9455 - 9456 - ret = ath11k_mac_fw_stats_request(ar, &req_param); 9457 - if (ret) 9458 - ath11k_warn(ab, "failed to request fw stats: %d\n", ret); 9459 - 9460 - ath11k_dbg(ab, ATH11K_DBG_WMI, 9461 - "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n", 9462 - pdev_id, vdev_id, stats_id); 9463 - 9464 - return ret; 9465 - } 9466 - 9467 9082 static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, 9468 9083 struct ieee80211_vif *vif, 9469 9084 struct ieee80211_sta *sta, ··· 9772 9537 exit: 9773 9538 mutex_unlock(&ar->conf_mutex); 9774 9539 return ret; 9775 - } 9776 - 9777 - static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw, 9778 - struct ieee80211_vif *vif, 9779 - unsigned int link_id, 9780 - int *dbm) 9781 - { 9782 - struct ath11k *ar = hw->priv; 9783 - struct ath11k_base *ab = ar->ab; 9784 - struct ath11k_fw_stats_pdev *pdev; 9785 - int ret; 9786 - 9787 - /* Final Tx power is minimum of Target Power, CTL power, Regulatory 9788 - * Power, PSD EIRP Power. We just know the Regulatory power from the 9789 - * regulatory rules obtained. FW knows all these power and sets the min 9790 - * of these. Hence, we request the FW pdev stats in which FW reports 9791 - * the minimum of all vdev's channel Tx power. 9792 - */ 9793 - mutex_lock(&ar->conf_mutex); 9794 - 9795 - /* Firmware doesn't provide Tx power during CAC hence no need to fetch 9796 - * the stats. 9797 - */ 9798 - if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) { 9799 - mutex_unlock(&ar->conf_mutex); 9800 - return -EAGAIN; 9801 - } 9802 - 9803 - ret = ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0, 9804 - WMI_REQUEST_PDEV_STAT); 9805 - if (ret) { 9806 - ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret); 9807 - goto err_fallback; 9808 - } 9809 - 9810 - spin_lock_bh(&ar->data_lock); 9811 - pdev = list_first_entry_or_null(&ar->fw_stats.pdevs, 9812 - struct ath11k_fw_stats_pdev, list); 9813 - if (!pdev) { 9814 - spin_unlock_bh(&ar->data_lock); 9815 - goto err_fallback; 9816 - } 9817 - 9818 - /* tx power is set as 2 units per dBm in FW. */ 9819 - *dbm = pdev->chan_tx_power / 2; 9820 - 9821 - spin_unlock_bh(&ar->data_lock); 9822 - mutex_unlock(&ar->conf_mutex); 9823 - 9824 - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware %d, reported %d dBm\n", 9825 - pdev->chan_tx_power, *dbm); 9826 - return 0; 9827 - 9828 - err_fallback: 9829 - mutex_unlock(&ar->conf_mutex); 9830 - /* We didn't get txpower from FW. Hence, relying on vif->bss_conf.txpower */ 9831 - *dbm = vif->bss_conf.txpower; 9832 - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware NaN, reported %d dBm\n", 9833 - *dbm); 9834 - return 0; 9835 9540 } 9836 9541 9837 9542 static int ath11k_mac_station_add(struct ath11k *ar, ··· 10542 10367 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 10543 10368 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | 10544 10369 NL80211_FEATURE_AP_SCAN; 10370 + 10371 + ar->hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION; 10545 10372 10546 10373 ar->max_num_stations = TARGET_NUM_STATIONS(ab); 10547 10374 ar->max_num_peers = TARGET_NUM_PEERS_PDEV(ab);
+19 -1
drivers/net/wireless/ath/ath11k/pci.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include <linux/module.h> ··· 177 177 ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); 178 178 } 179 179 180 + static void ath11k_pci_restore_window(struct ath11k_base *ab) 181 + { 182 + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); 183 + 184 + spin_lock_bh(&ab_pci->window_lock); 185 + 186 + iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | ab_pci->register_window, 187 + ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); 188 + ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); 189 + 190 + spin_unlock_bh(&ab_pci->window_lock); 191 + } 192 + 180 193 static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) 181 194 { 182 195 u32 val, delay; ··· 214 201 val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); 215 202 if (val == 0xffffffff) 216 203 ath11k_warn(ab, "link down error during global reset\n"); 204 + 205 + /* Restore window register as its content is cleared during 206 + * hardware global reset, such that it aligns with host cache. 207 + */ 208 + ath11k_pci_restore_window(ab); 217 209 } 218 210 219 211 static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab)
+9 -9
drivers/net/wireless/ath/ath11k/pci.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 #ifndef _ATH11K_PCI_H 7 7 #define _ATH11K_PCI_H ··· 35 35 #define PCIE_SMLH_REQ_RST_LINK_DOWN 0x2 36 36 #define PCIE_INT_CLEAR_ALL 0xffffffff 37 37 38 - #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(x) \ 39 - (ab->hw_params.regs->pcie_qserdes_sysclk_en_sel) 38 + #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab) \ 39 + ((ab)->hw_params.regs->pcie_qserdes_sysclk_en_sel) 40 40 #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL 0x10 41 41 #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK 0xffffffff 42 - #define PCIE_PCS_OSC_DTCT_CONFIG1_REG(x) \ 43 - (ab->hw_params.regs->pcie_pcs_osc_dtct_config_base) 42 + #define PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab) \ 43 + ((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base) 44 44 #define PCIE_PCS_OSC_DTCT_CONFIG1_VAL 0x02 45 - #define PCIE_PCS_OSC_DTCT_CONFIG2_REG(x) \ 46 - (ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0x4) 45 + #define PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab) \ 46 + ((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0x4) 47 47 #define PCIE_PCS_OSC_DTCT_CONFIG2_VAL 0x52 48 - #define PCIE_PCS_OSC_DTCT_CONFIG4_REG(x) \ 49 - (ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0xc) 48 + #define PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab) \ 49 + ((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0xc) 50 50 #define PCIE_PCS_OSC_DTCT_CONFIG4_VAL 0xff 51 51 #define PCIE_PCS_OSC_DTCT_CONFIG_MSK 0x000000ff 52 52
+13 -7
drivers/net/wireless/ath/ath11k/wmi.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 #include <linux/skbuff.h> 7 7 #include <linux/ctype.h> ··· 2061 2061 cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; 2062 2062 2063 2063 if (param->vht_capable) { 2064 - mcs->rx_max_rate = param->rx_max_rate; 2065 - mcs->rx_mcs_set = param->rx_mcs_set; 2066 - mcs->tx_max_rate = param->tx_max_rate; 2067 - mcs->tx_mcs_set = param->tx_mcs_set; 2064 + /* firmware interprets mcs->tx_mcs_set field as peer's 2065 + * RX capability 2066 + */ 2067 + mcs->tx_max_rate = param->rx_max_rate; 2068 + mcs->tx_mcs_set = param->rx_mcs_set; 2069 + mcs->rx_max_rate = param->tx_max_rate; 2070 + mcs->rx_mcs_set = param->tx_mcs_set; 2068 2071 } 2069 2072 2070 2073 /* HE Rates */ ··· 2091 2088 FIELD_PREP(WMI_TLV_LEN, 2092 2089 sizeof(*he_mcs) - TLV_HDR_SIZE); 2093 2090 2094 - he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; 2095 - he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; 2091 + /* firmware interprets mcs->rx_mcs_set field as peer's 2092 + * RX capability 2093 + */ 2094 + he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; 2095 + he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; 2096 2096 ptr += sizeof(*he_mcs); 2097 2097 } 2098 2098
+3 -15
drivers/net/wireless/ath/ath11k/wmi.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #ifndef ATH11K_WMI_H ··· 3463 3463 u32 pdev_id; 3464 3464 }; 3465 3465 3466 - struct wmi_bcn_send_from_host_cmd { 3467 - u32 tlv_header; 3468 - u32 vdev_id; 3469 - u32 data_len; 3470 - union { 3471 - u32 frag_ptr; 3472 - u32 frag_ptr_lo; 3473 - }; 3474 - u32 frame_ctrl; 3475 - u32 dtim_flag; 3476 - u32 bcn_antenna; 3477 - u32 frag_ptr_hi; 3478 - }; 3479 - 3480 3466 #define WMI_CHAN_INFO_MODE GENMASK(5, 0) 3481 3467 #define WMI_CHAN_INFO_HT40_PLUS BIT(6) 3482 3468 #define WMI_CHAN_INFO_PASSIVE BIT(7) ··· 4119 4133 struct wmi_vht_rate_set { 4120 4134 u32 tlv_header; 4121 4135 u32 rx_max_rate; 4136 + /* MCS at which the peer can transmit */ 4122 4137 u32 rx_mcs_set; 4123 4138 u32 tx_max_rate; 4139 + /* MCS at which the peer can receive */ 4124 4140 u32 tx_mcs_set; 4125 4141 u32 tx_max_mcs_nss; 4126 4142 } __packed;
+17 -5
drivers/net/wireless/ath/ath12k/core.c
··· 2106 2106 ret = ath12k_core_soc_create(ab); 2107 2107 if (ret) { 2108 2108 mutex_unlock(&ab->core_lock); 2109 - ath12k_err(ab, "failed to create soc core: %d\n", ret); 2110 - return ret; 2109 + ath12k_err(ab, "failed to create soc %d core: %d\n", i, ret); 2110 + goto destroy; 2111 2111 } 2112 2112 2113 2113 mutex_unlock(&ab->core_lock); 2114 2114 } 2115 2115 2116 2116 return 0; 2117 + 2118 + destroy: 2119 + for (i--; i >= 0; i--) { 2120 + ab = ag->ab[i]; 2121 + if (!ab) 2122 + continue; 2123 + 2124 + mutex_lock(&ab->core_lock); 2125 + ath12k_core_soc_destroy(ab); 2126 + mutex_unlock(&ab->core_lock); 2127 + } 2128 + 2129 + return ret; 2117 2130 } 2118 2131 2119 2132 void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag) ··· 2201 2188 if (ret) { 2202 2189 mutex_unlock(&ag->mutex); 2203 2190 ath12k_warn(ab, "unable to create hw group\n"); 2204 - goto err_destroy_hw_group; 2191 + goto err_unassign_hw_group; 2205 2192 } 2206 2193 } 2207 2194 ··· 2209 2196 2210 2197 return 0; 2211 2198 2212 - err_destroy_hw_group: 2213 - ath12k_core_hw_group_destroy(ab->ag); 2199 + err_unassign_hw_group: 2214 2200 ath12k_core_hw_group_unassign(ab); 2215 2201 err_unregister_notifier: 2216 2202 ath12k_core_panic_notifier_unregister(ab);
+3
drivers/net/wireless/ath/ath12k/core.h
··· 355 355 struct wmi_vdev_install_key_arg group_key; 356 356 bool pairwise_key_done; 357 357 u16 num_stations; 358 + bool is_csa_in_progress; 359 + struct wiphy_work bcn_tx_work; 358 360 }; 359 361 360 362 struct ath12k_vif { ··· 965 963 u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; 966 964 u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; 967 965 u32 tx_completed[DP_TCL_NUM_RING_MAX]; 966 + u32 reo_excep_msdu_buf_type; 968 967 }; 969 968 970 969 struct ath12k_reg_freq {
+4 -1
drivers/net/wireless/ath/ath12k/debugfs.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include "core.h" ··· 1177 1177 1178 1178 len += scnprintf(buf + len, size - len, "\n"); 1179 1179 } 1180 + 1181 + len += scnprintf(buf + len, size - len, "\nREO excep MSDU buf type:%u\n", 1182 + device_stats->reo_excep_msdu_buf_type); 1180 1183 1181 1184 len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n"); 1182 1185
+12 -7
drivers/net/wireless/ath/ath12k/dp_mon.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include "dp_mon.h" ··· 105 105 if (ppdu_info->is_stbc && nsts > 0) 106 106 nsts = ((nsts + 1) >> 1) - 1; 107 107 108 - ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); 108 + ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1; 109 109 ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); 110 110 ppdu_info->beamformed = u32_get_bits(info1, 111 111 HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); ··· 129 129 ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); 130 130 ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); 131 131 ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); 132 - ppdu_info->nss = (ppdu_info->mcs >> 3); 132 + ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; 133 133 } 134 134 135 135 static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, ··· 233 233 value = value << HE_STA_ID_SHIFT; 234 234 ppdu_info->he_data4 |= value; 235 235 236 - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); 236 + ppdu_info->nss = 237 + u32_get_bits(info0, 238 + HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1; 237 239 ppdu_info->beamformed = u32_get_bits(info0, 238 240 HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); 239 241 } ··· 263 261 value = value << HE_STA_ID_SHIFT; 264 262 ppdu_info->he_data4 |= value; 265 263 266 - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); 264 + ppdu_info->nss = 265 + u32_get_bits(info0, 266 + HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; 267 267 } 268 268 269 269 static void ··· 557 553 ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); 558 554 ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); 559 555 dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); 560 - ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); 556 + ppdu_info->nss = u32_get_bits(info0, 557 + HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; 561 558 ppdu_info->dcm = dcm; 562 559 } 563 560 ··· 2184 2179 spin_unlock_bh(&ar->data_lock); 2185 2180 2186 2181 rxs->flag |= RX_FLAG_MACTIME_START; 2187 - rxs->nss = ppduinfo->nss + 1; 2182 + rxs->nss = ppduinfo->nss; 2188 2183 if (test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, 2189 2184 ar->ab->wmi_ab.svc_map)) 2190 2185 rxs->signal = ppduinfo->rssi_comb;
+68 -6
drivers/net/wireless/ath/ath12k/dp_rx.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include <linux/ieee80211.h> ··· 1088 1088 struct ath12k_dp_rx_tid *rx_tid) 1089 1089 { 1090 1090 struct dp_reo_update_rx_queue_elem *elem; 1091 + 1092 + lockdep_assert_held(&dp->ab->base_lock); 1091 1093 1092 1094 elem = kzalloc(sizeof(*elem), GFP_ATOMIC); 1093 1095 if (!elem) ··· 3783 3781 return 0; 3784 3782 } 3785 3783 3784 + static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, 3785 + struct list_head *list, 3786 + struct hal_reo_dest_ring *desc) 3787 + { 3788 + struct ath12k_rx_desc_info *desc_info; 3789 + struct ath12k_skb_rxcb *rxcb; 3790 + struct sk_buff *msdu; 3791 + u64 desc_va; 3792 + 3793 + ab->device_stats.reo_excep_msdu_buf_type++; 3794 + 3795 + desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | 3796 + le32_to_cpu(desc->buf_va_lo); 3797 + desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; 3798 + if (!desc_info) { 3799 + u32 cookie; 3800 + 3801 + cookie = le32_get_bits(desc->buf_addr_info.info1, 3802 + BUFFER_ADDR_INFO1_SW_COOKIE); 3803 + desc_info = ath12k_dp_get_rx_desc(ab, cookie); 3804 + if (!desc_info) { 3805 + ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", 3806 + cookie); 3807 + return -EINVAL; 3808 + } 3809 + } 3810 + 3811 + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { 3812 + ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", 3813 + desc_info->magic); 3814 + return -EINVAL; 3815 + } 3816 + 3817 + msdu = desc_info->skb; 3818 + desc_info->skb = NULL; 3819 + list_add_tail(&desc_info->list, list); 3820 + rxcb = ATH12K_SKB_RXCB(msdu); 3821 + dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), 3822 + DMA_FROM_DEVICE); 3823 + dev_kfree_skb_any(msdu); 3824 + 3825 + return 0; 3826 + } 3827 + 3786 3828 int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, 3787 3829 int budget) 3788 3830 { ··· 3871 3825 drop = false; 3872 3826 ab->device_stats.err_ring_pkts++; 3873 3827 3828 + hw_link_id = le32_get_bits(reo_desc->info0, 3829 + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); 3830 + device_id = hw_links[hw_link_id].device_id; 3831 + partner_ab = ath12k_ag_to_ab(ag, device_id); 3832 + 3833 + /* Below case is added to handle data packet from un-associated clients. 3834 + * As it is expected that AST lookup will fail for 3835 + * un-associated station's data packets. 3836 + */ 3837 + if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == 3838 + HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { 3839 + if (!ath12k_dp_h_msdu_buffer_type(partner_ab, 3840 + &rx_desc_used_list[device_id], 3841 + reo_desc)) { 3842 + num_buffs_reaped[device_id]++; 3843 + tot_n_bufs_reaped++; 3844 + } 3845 + goto next_desc; 3846 + } 3847 + 3874 3848 ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, 3875 3849 &desc_bank); 3876 3850 if (ret) { ··· 3898 3832 ret); 3899 3833 continue; 3900 3834 } 3901 - 3902 - hw_link_id = le32_get_bits(reo_desc->info0, 3903 - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); 3904 - device_id = hw_links[hw_link_id].device_id; 3905 - partner_ab = ath12k_ag_to_ab(ag, device_id); 3906 3835 3907 3836 pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, 3908 3837 hw_links[hw_link_id].pdev_idx); ··· 3947 3886 } 3948 3887 } 3949 3888 3889 + next_desc: 3950 3890 if (tot_n_bufs_reaped >= quota) { 3951 3891 tot_n_bufs_reaped = quota; 3952 3892 goto exit;
+2 -8
drivers/net/wireless/ath/ath12k/hal_rx.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include "debug.h" ··· 323 323 { 324 324 enum hal_reo_dest_ring_push_reason push_reason; 325 325 enum hal_reo_dest_ring_error_code err_code; 326 - u32 cookie, val; 326 + u32 cookie; 327 327 328 328 push_reason = le32_get_bits(desc->info0, 329 329 HAL_REO_DEST_RING_INFO0_PUSH_REASON); ··· 335 335 push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { 336 336 ath12k_warn(ab, "expected error push reason code, received %d\n", 337 337 push_reason); 338 - return -EINVAL; 339 - } 340 - 341 - val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); 342 - if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { 343 - ath12k_warn(ab, "expected buffer type link_desc"); 344 338 return -EINVAL; 345 339 } 346 340
+632 -119
drivers/net/wireless/ath/ath12k/mac.c
··· 533 533 return 1; 534 534 } 535 535 536 + static u32 537 + ath12k_mac_max_eht_nss(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX]) 538 + { 539 + int nss; 540 + 541 + for (nss = NL80211_EHT_NSS_MAX - 1; nss >= 0; nss--) 542 + if (eht_mcs_mask[nss]) 543 + return nss + 1; 544 + 545 + return 1; 546 + } 547 + 548 + static u32 549 + ath12k_mac_max_eht_mcs_nss(const u8 *eht_mcs, int eht_mcs_set_size) 550 + { 551 + int i; 552 + u8 nss = 0; 553 + 554 + for (i = 0; i < eht_mcs_set_size; i++) 555 + nss = max(nss, u8_get_bits(eht_mcs[i], IEEE80211_EHT_MCS_NSS_RX)); 556 + 557 + return nss; 558 + } 559 + 536 560 static u8 ath12k_parse_mpdudensity(u8 mpdudensity) 537 561 { 538 562 /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing": ··· 2273 2249 struct cfg80211_chan_def def; 2274 2250 enum nl80211_band band; 2275 2251 u16 *vht_mcs_mask; 2276 - u16 tx_mcs_map; 2277 2252 u8 ampdu_factor; 2278 2253 u8 max_nss, vht_mcs; 2279 2254 int i, vht_nss, nss_idx; ··· 2363 2340 arg->peer_nss = min(link_sta->rx_nss, max_nss); 2364 2341 arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); 2365 2342 arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); 2366 - arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); 2343 + arg->rx_mcs_set = ath12k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); 2367 2344 2368 - tx_mcs_map = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); 2369 - arg->tx_mcs_set = ath12k_peer_assoc_h_vht_limit(tx_mcs_map, vht_mcs_mask); 2345 + arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); 2346 + arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); 2370 2347 2371 2348 /* In QCN9274 platform, VHT MCS rate 10 and 11 is enabled by default. 2372 2349 * VHT MCS rate 10 and 11 is not supported in 11ac standard. ··· 2648 2625 switch (link_sta->bandwidth) { 2649 2626 case IEEE80211_STA_RX_BW_160: 2650 2627 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 2628 + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); 2651 2629 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 2652 2630 2653 - v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); 2631 + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); 2654 2632 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 2655 2633 2656 2634 arg->peer_he_mcs_count++; ··· 2661 2637 2662 2638 default: 2663 2639 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 2640 + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); 2664 2641 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 2665 2642 2666 2643 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); 2667 - v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); 2668 2644 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 2669 2645 2670 2646 arg->peer_he_mcs_count++; ··· 3028 3004 return MODE_UNKNOWN; 3029 3005 } 3030 3006 3007 + static bool 3008 + ath12k_peer_assoc_h_eht_masked(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX]) 3009 + { 3010 + int nss; 3011 + 3012 + for (nss = 0; nss < NL80211_EHT_NSS_MAX; nss++) 3013 + if (eht_mcs_mask[nss]) 3014 + return false; 3015 + 3016 + return true; 3017 + } 3018 + 3031 3019 static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, 3032 3020 struct ath12k_link_vif *arvif, 3033 3021 struct ath12k_link_sta *arsta, ··· 3051 3015 const u8 *ht_mcs_mask; 3052 3016 const u16 *vht_mcs_mask; 3053 3017 const u16 *he_mcs_mask; 3018 + const u16 *eht_mcs_mask; 3054 3019 enum wmi_phy_mode phymode = MODE_UNKNOWN; 3055 3020 3056 3021 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); ··· 3066 3029 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; 3067 3030 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; 3068 3031 he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; 3032 + eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs; 3069 3033 3070 3034 link_sta = ath12k_mac_get_link_sta(arsta); 3071 3035 if (!link_sta) { ··· 3077 3039 3078 3040 switch (band) { 3079 3041 case NL80211_BAND_2GHZ: 3080 - if (link_sta->eht_cap.has_eht) { 3042 + if (link_sta->eht_cap.has_eht && 3043 + !ath12k_peer_assoc_h_eht_masked(eht_mcs_mask)) { 3081 3044 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_40) 3082 3045 phymode = MODE_11BE_EHT40_2G; 3083 3046 else ··· 3141 3102 WARN_ON(phymode == MODE_UNKNOWN); 3142 3103 } 3143 3104 3105 + #define ATH12K_EHT_MCS_7_ENABLED 0x00FF 3106 + #define ATH12K_EHT_MCS_9_ENABLED 0x0300 3107 + #define ATH12K_EHT_MCS_11_ENABLED 0x0C00 3108 + #define ATH12K_EHT_MCS_13_ENABLED 0x3000 3109 + 3144 3110 static void ath12k_mac_set_eht_mcs(u8 rx_tx_mcs7, u8 rx_tx_mcs9, 3145 3111 u8 rx_tx_mcs11, u8 rx_tx_mcs13, 3146 - u32 *rx_mcs, u32 *tx_mcs) 3112 + u32 *rx_mcs, u32 *tx_mcs, 3113 + const u16 eht_mcs_limit[NL80211_EHT_NSS_MAX]) 3147 3114 { 3148 - *rx_mcs = 0; 3149 - u32p_replace_bits(rx_mcs, 3150 - u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_RX), 3151 - WMI_EHT_MCS_NSS_0_7); 3152 - u32p_replace_bits(rx_mcs, 3153 - u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_RX), 3154 - WMI_EHT_MCS_NSS_8_9); 3155 - u32p_replace_bits(rx_mcs, 3156 - u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_RX), 3157 - WMI_EHT_MCS_NSS_10_11); 3158 - u32p_replace_bits(rx_mcs, 3159 - u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_RX), 3160 - WMI_EHT_MCS_NSS_12_13); 3115 + int nss; 3116 + u8 mcs_7 = 0, mcs_9 = 0, mcs_11 = 0, mcs_13 = 0; 3117 + u8 peer_mcs_7, peer_mcs_9, peer_mcs_11, peer_mcs_13; 3161 3118 3162 - *tx_mcs = 0; 3163 - u32p_replace_bits(tx_mcs, 3164 - u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_TX), 3165 - WMI_EHT_MCS_NSS_0_7); 3166 - u32p_replace_bits(tx_mcs, 3167 - u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_TX), 3168 - WMI_EHT_MCS_NSS_8_9); 3169 - u32p_replace_bits(tx_mcs, 3170 - u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_TX), 3171 - WMI_EHT_MCS_NSS_10_11); 3172 - u32p_replace_bits(tx_mcs, 3173 - u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_TX), 3174 - WMI_EHT_MCS_NSS_12_13); 3119 + for (nss = 0; nss < NL80211_EHT_NSS_MAX; nss++) { 3120 + if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_7_ENABLED) 3121 + mcs_7++; 3122 + if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_9_ENABLED) 3123 + mcs_9++; 3124 + if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_11_ENABLED) 3125 + mcs_11++; 3126 + if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_13_ENABLED) 3127 + mcs_13++; 3128 + } 3129 + 3130 + peer_mcs_7 = u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_RX); 3131 + peer_mcs_9 = u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_RX); 3132 + peer_mcs_11 = u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_RX); 3133 + peer_mcs_13 = u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_RX); 3134 + 3135 + *rx_mcs = u32_encode_bits(min(peer_mcs_7, mcs_7), WMI_EHT_MCS_NSS_0_7) | 3136 + u32_encode_bits(min(peer_mcs_9, mcs_9), WMI_EHT_MCS_NSS_8_9) | 3137 + u32_encode_bits(min(peer_mcs_11, mcs_11), WMI_EHT_MCS_NSS_10_11) | 3138 + u32_encode_bits(min(peer_mcs_13, mcs_13), WMI_EHT_MCS_NSS_12_13); 3139 + 3140 + peer_mcs_7 = u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_TX); 3141 + peer_mcs_9 = u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_TX); 3142 + peer_mcs_11 = u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_TX); 3143 + peer_mcs_13 = u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_TX); 3144 + 3145 + *tx_mcs = u32_encode_bits(min(peer_mcs_7, mcs_7), WMI_EHT_MCS_NSS_0_7) | 3146 + u32_encode_bits(min(peer_mcs_9, mcs_9), WMI_EHT_MCS_NSS_8_9) | 3147 + u32_encode_bits(min(peer_mcs_11, mcs_11), WMI_EHT_MCS_NSS_10_11) | 3148 + u32_encode_bits(min(peer_mcs_13, mcs_13), WMI_EHT_MCS_NSS_12_13); 3175 3149 } 3176 3150 3177 3151 static void ath12k_mac_set_eht_ppe_threshold(const u8 *ppe_thres, ··· 3223 3171 struct ath12k_wmi_peer_assoc_arg *arg) 3224 3172 { 3225 3173 struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); 3174 + struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); 3175 + const struct ieee80211_eht_mcs_nss_supp *own_eht_mcs_nss_supp; 3226 3176 const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20; 3177 + const struct ieee80211_sta_eht_cap *eht_cap, *own_eht_cap; 3178 + const struct ieee80211_sband_iftype_data *iftd; 3227 3179 const struct ieee80211_eht_mcs_nss_supp_bw *bw; 3228 - const struct ieee80211_sta_eht_cap *eht_cap; 3229 3180 const struct ieee80211_sta_he_cap *he_cap; 3230 3181 struct ieee80211_link_sta *link_sta; 3231 3182 struct ieee80211_bss_conf *link_conf; 3183 + struct cfg80211_chan_def def; 3184 + bool user_rate_valid = true; 3185 + enum nl80211_band band; 3186 + int eht_nss, nss_idx; 3232 3187 u32 *rx_mcs, *tx_mcs; 3188 + u16 *eht_mcs_mask; 3189 + u8 max_nss = 0; 3233 3190 3234 3191 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 3235 3192 ··· 3260 3199 if (!he_cap->has_he || !eht_cap->has_eht) 3261 3200 return; 3262 3201 3202 + if (WARN_ON(ath12k_mac_vif_link_chan(vif, arvif->link_id, &def))) 3203 + return; 3204 + 3205 + band = def.chan->band; 3206 + eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs; 3207 + 3208 + iftd = ieee80211_get_sband_iftype_data(&ar->mac.sbands[band], vif->type); 3209 + if (!iftd) { 3210 + ath12k_warn(ar->ab, 3211 + "unable to access iftype_data in struct ieee80211_supported_band\n"); 3212 + return; 3213 + } 3214 + 3215 + own_eht_cap = &iftd->eht_cap; 3216 + own_eht_mcs_nss_supp = &own_eht_cap->eht_mcs_nss_supp; 3217 + 3263 3218 arg->eht_flag = true; 3264 3219 3265 3220 if ((eht_cap->eht_cap_elem.phy_cap_info[5] & ··· 3292 3215 rx_mcs = arg->peer_eht_rx_mcs_set; 3293 3216 tx_mcs = arg->peer_eht_tx_mcs_set; 3294 3217 3218 + eht_nss = ath12k_mac_max_eht_mcs_nss((void *)own_eht_mcs_nss_supp, 3219 + sizeof(*own_eht_mcs_nss_supp)); 3220 + if (eht_nss > link_sta->rx_nss) { 3221 + user_rate_valid = false; 3222 + for (nss_idx = (link_sta->rx_nss - 1); nss_idx >= 0; nss_idx--) { 3223 + if (eht_mcs_mask[nss_idx]) { 3224 + user_rate_valid = true; 3225 + break; 3226 + } 3227 + } 3228 + } 3229 + 3230 + if (!user_rate_valid) { 3231 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 3232 + "Setting eht range MCS value to peer supported nss %d for peer %pM\n", 3233 + link_sta->rx_nss, arsta->addr); 3234 + eht_mcs_mask[link_sta->rx_nss - 1] = eht_mcs_mask[eht_nss - 1]; 3235 + } 3236 + 3237 + bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz; 3238 + bw = &eht_cap->eht_mcs_nss_supp.bw._80; 3239 + 3295 3240 switch (link_sta->bandwidth) { 3296 3241 case IEEE80211_STA_RX_BW_320: 3297 3242 bw = &eht_cap->eht_mcs_nss_supp.bw._320; ··· 3322 3223 bw->rx_tx_mcs11_max_nss, 3323 3224 bw->rx_tx_mcs13_max_nss, 3324 3225 &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320], 3325 - &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320]); 3226 + &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320], 3227 + eht_mcs_mask); 3326 3228 arg->peer_eht_mcs_count++; 3327 3229 fallthrough; 3328 3230 case IEEE80211_STA_RX_BW_160: ··· 3333 3233 bw->rx_tx_mcs11_max_nss, 3334 3234 bw->rx_tx_mcs13_max_nss, 3335 3235 &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160], 3336 - &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160]); 3236 + &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160], 3237 + eht_mcs_mask); 3337 3238 arg->peer_eht_mcs_count++; 3338 3239 fallthrough; 3339 3240 default: 3340 - if ((he_cap->he_cap_elem.phy_cap_info[0] & 3341 - (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | 3342 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | 3343 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | 3344 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0) { 3241 + if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] & 3242 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 3345 3243 bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz; 3346 3244 3347 3245 ath12k_mac_set_eht_mcs(bw_20->rx_tx_mcs7_max_nss, ··· 3347 3249 bw_20->rx_tx_mcs11_max_nss, 3348 3250 bw_20->rx_tx_mcs13_max_nss, 3349 3251 &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80], 3350 - &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80]); 3252 + &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80], 3253 + eht_mcs_mask); 3351 3254 } else { 3352 3255 bw = &eht_cap->eht_mcs_nss_supp.bw._80; 3353 3256 ath12k_mac_set_eht_mcs(bw->rx_tx_mcs9_max_nss, ··· 3356 3257 bw->rx_tx_mcs11_max_nss, 3357 3258 bw->rx_tx_mcs13_max_nss, 3358 3259 &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80], 3359 - &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80]); 3260 + &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80], 3261 + eht_mcs_mask); 3360 3262 } 3361 3263 3362 3264 arg->peer_eht_mcs_count++; ··· 3366 3266 3367 3267 arg->punct_bitmap = ~arvif->punct_bitmap; 3368 3268 arg->eht_disable_mcs15 = link_conf->eht_disable_mcs15; 3269 + 3270 + if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] & 3271 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 3272 + if (bw_20->rx_tx_mcs13_max_nss) 3273 + max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs13_max_nss, 3274 + IEEE80211_EHT_MCS_NSS_RX)); 3275 + if (bw_20->rx_tx_mcs11_max_nss) 3276 + max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs11_max_nss, 3277 + IEEE80211_EHT_MCS_NSS_RX)); 3278 + if (bw_20->rx_tx_mcs9_max_nss) 3279 + max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs9_max_nss, 3280 + IEEE80211_EHT_MCS_NSS_RX)); 3281 + if (bw_20->rx_tx_mcs7_max_nss) 3282 + max_nss = max(max_nss, u8_get_bits(bw_20->rx_tx_mcs7_max_nss, 3283 + IEEE80211_EHT_MCS_NSS_RX)); 3284 + } else { 3285 + if (bw->rx_tx_mcs13_max_nss) 3286 + max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs13_max_nss, 3287 + IEEE80211_EHT_MCS_NSS_RX)); 3288 + if (bw->rx_tx_mcs11_max_nss) 3289 + max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs11_max_nss, 3290 + IEEE80211_EHT_MCS_NSS_RX)); 3291 + if (bw->rx_tx_mcs9_max_nss) 3292 + max_nss = max(max_nss, u8_get_bits(bw->rx_tx_mcs9_max_nss, 3293 + IEEE80211_EHT_MCS_NSS_RX)); 3294 + } 3295 + 3296 + max_nss = min(max_nss, (uint8_t)eht_nss); 3297 + 3298 + arg->peer_nss = min(link_sta->rx_nss, max_nss); 3299 + 3300 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 3301 + "mac eht peer %pM nss %d mcs cnt %d ru_punct_bitmap 0x%x\n", 3302 + arsta->addr, arg->peer_nss, arg->peer_eht_mcs_count, 3303 + arg->punct_bitmap); 3369 3304 } 3370 3305 3371 3306 static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta, ··· 3969 3834 ath12k_warn(ar->ab, "failed to set beacon tx rate %d\n", ret); 3970 3835 } 3971 3836 3837 + static void ath12k_mac_bcn_tx_event(struct ath12k_link_vif *arvif) 3838 + { 3839 + struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); 3840 + struct ieee80211_bss_conf *link_conf; 3841 + 3842 + link_conf = ath12k_mac_get_link_bss_conf(arvif); 3843 + if (!link_conf) { 3844 + ath12k_warn(arvif->ar->ab, "failed to get link conf for vdev %u\n", 3845 + arvif->vdev_id); 3846 + return; 3847 + } 3848 + 3849 + if (link_conf->color_change_active) { 3850 + if (ieee80211_beacon_cntdwn_is_complete(vif, arvif->link_id)) { 3851 + ieee80211_color_change_finish(vif, arvif->link_id); 3852 + return; 3853 + } 3854 + 3855 + ieee80211_beacon_update_cntdwn(vif, arvif->link_id); 3856 + ath12k_mac_setup_bcn_tmpl(arvif); 3857 + } 3858 + } 3859 + 3860 + static void ath12k_mac_bcn_tx_work(struct wiphy *wiphy, struct wiphy_work *work) 3861 + { 3862 + struct ath12k_link_vif *arvif = container_of(work, struct ath12k_link_vif, 3863 + bcn_tx_work); 3864 + 3865 + lockdep_assert_wiphy(wiphy); 3866 + ath12k_mac_bcn_tx_event(arvif); 3867 + } 3868 + 3972 3869 static void ath12k_mac_init_arvif(struct ath12k_vif *ahvif, 3973 3870 struct ath12k_link_vif *arvif, int link_id) 3974 3871 { ··· 4030 3863 INIT_LIST_HEAD(&arvif->list); 4031 3864 INIT_DELAYED_WORK(&arvif->connection_loss_work, 4032 3865 ath12k_mac_vif_sta_connection_loss_work); 3866 + wiphy_work_init(&arvif->bcn_tx_work, ath12k_mac_bcn_tx_work); 4033 3867 4034 3868 arvif->num_stations = 0; 4035 3869 ··· 4043 3875 sizeof(arvif->bitrate_mask.control[i].vht_mcs)); 4044 3876 memset(arvif->bitrate_mask.control[i].he_mcs, 0xff, 4045 3877 sizeof(arvif->bitrate_mask.control[i].he_mcs)); 3878 + memset(arvif->bitrate_mask.control[i].eht_mcs, 0xff, 3879 + sizeof(arvif->bitrate_mask.control[i].eht_mcs)); 4046 3880 } 4047 3881 4048 3882 /* Handle MLO related assignments */ ··· 4070 3900 lockdep_assert_wiphy(ah->hw->wiphy); 4071 3901 4072 3902 cancel_delayed_work_sync(&arvif->connection_loss_work); 3903 + wiphy_work_cancel(ath12k_ar_to_hw(ar)->wiphy, &arvif->bcn_tx_work); 4073 3904 4074 3905 ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac remove link interface (vdev %d link id %d)", 4075 3906 arvif->vdev_id, arvif->link_id); ··· 4392 4221 chandef->chan->band == NL80211_BAND_6GHZ; 4393 4222 } 4394 4223 4224 + static void ath12k_wmi_vdev_params_up(struct ath12k *ar, 4225 + struct ath12k_link_vif *arvif, 4226 + struct ath12k_link_vif *tx_arvif, 4227 + struct ieee80211_bss_conf *info, u16 aid) 4228 + { 4229 + struct ath12k_wmi_vdev_up_params params = { 4230 + .vdev_id = arvif->vdev_id, 4231 + .aid = aid, 4232 + .bssid = arvif->bssid 4233 + }; 4234 + int ret; 4235 + 4236 + if (tx_arvif) { 4237 + params.tx_bssid = tx_arvif->bssid; 4238 + params.nontx_profile_idx = info->bssid_index; 4239 + params.nontx_profile_cnt = 1 << info->bssid_indicator; 4240 + } 4241 + 4242 + ret = ath12k_wmi_vdev_up(arvif->ar, &params); 4243 + if (ret) 4244 + ath12k_warn(ar->ab, "failed to bring vdev up %d: %d\n", 4245 + arvif->vdev_id, ret); 4246 + } 4247 + 4395 4248 static void ath12k_mac_bss_info_changed(struct ath12k *ar, 4396 4249 struct ath12k_link_vif *arvif, 4397 4250 struct ieee80211_bss_conf *info, ··· 4423 4228 { 4424 4229 struct ath12k_vif *ahvif = arvif->ahvif; 4425 4230 struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); 4231 + struct ath12k_link_vif *tx_arvif; 4426 4232 struct cfg80211_chan_def def; 4427 4233 u32 param_id, param_value; 4428 4234 enum nl80211_band band; ··· 4432 4236 u32 preamble; 4433 4237 u16 hw_value; 4434 4238 u16 bitrate; 4435 - int ret; 4436 4239 u8 rateidx; 4437 4240 u32 rate; 4241 + int ret; 4438 4242 4439 4243 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 4440 4244 ··· 4467 4271 "Set burst beacon mode for VDEV: %d\n", 4468 4272 arvif->vdev_id); 4469 4273 4274 + /* In MBSSID case, need to install transmitting VIF's template first */ 4275 + 4470 4276 ret = ath12k_mac_setup_bcn_tmpl(arvif); 4471 4277 if (ret) 4472 4278 ath12k_warn(ar->ab, "failed to update bcn template: %d\n", 4473 4279 ret); 4280 + 4281 + if (!arvif->is_csa_in_progress) 4282 + goto skip_vdev_up; 4283 + 4284 + tx_arvif = ath12k_mac_get_tx_arvif(arvif, info); 4285 + if (tx_arvif && arvif != tx_arvif && tx_arvif->is_csa_in_progress) 4286 + /* skip non tx vif's */ 4287 + goto skip_vdev_up; 4288 + 4289 + ath12k_wmi_vdev_params_up(ar, arvif, tx_arvif, info, ahvif->aid); 4290 + 4291 + arvif->is_csa_in_progress = false; 4292 + 4293 + if (tx_arvif && arvif == tx_arvif) { 4294 + struct ath12k_link_vif *arvif_itr; 4295 + 4296 + list_for_each_entry(arvif_itr, &ar->arvifs, list) { 4297 + if (!arvif_itr->is_csa_in_progress) 4298 + continue; 4299 + 4300 + ath12k_wmi_vdev_params_up(ar, arvif, tx_arvif, 4301 + info, ahvif->aid); 4302 + arvif_itr->is_csa_in_progress = false; 4303 + } 4304 + } 4474 4305 } 4306 + 4307 + skip_vdev_up: 4475 4308 4476 4309 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) { 4477 4310 arvif->dtim_period = info->dtim_period; ··· 4718 4493 ATH12K_BSS_COLOR_AP_PERIODS, 4719 4494 info->he_bss_color.enabled); 4720 4495 if (ret) 4721 - ath12k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", 4496 + ath12k_warn(ar->ab, "failed to set bss color collision on vdev %u: %d\n", 4722 4497 arvif->vdev_id, ret); 4498 + 4499 + param_id = WMI_VDEV_PARAM_BSS_COLOR; 4500 + if (info->he_bss_color.enabled) 4501 + param_value = info->he_bss_color.color << 4502 + IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET; 4503 + else 4504 + param_value = IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED; 4505 + 4506 + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4507 + param_id, 4508 + param_value); 4509 + if (ret) 4510 + ath12k_warn(ar->ab, "failed to set bss color param on vdev %u: %d\n", 4511 + arvif->vdev_id, ret); 4512 + else 4513 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "bss color param 0x%x set on vdev %u\n", 4514 + param_value, arvif->vdev_id); 4723 4515 } else if (vif->type == NL80211_IFTYPE_STATION) { 4724 4516 ret = ath12k_wmi_send_bss_color_change_enable_cmd(ar, 4725 4517 arvif->vdev_id, ··· 5313 5071 ret = ath12k_mac_vdev_create(ar, arvif); 5314 5072 if (ret) { 5315 5073 ath12k_warn(ar->ab, "unable to create scan vdev %d\n", ret); 5316 - return -EINVAL; 5074 + ath12k_mac_unassign_link_vif(arvif); 5075 + return ret; 5317 5076 } 5318 5077 } 5319 5078 ··· 5974 5731 } 5975 5732 5976 5733 static int 5734 + ath12k_mac_bitrate_mask_num_eht_rates(struct ath12k *ar, 5735 + enum nl80211_band band, 5736 + const struct cfg80211_bitrate_mask *mask) 5737 + { 5738 + int num_rates = 0; 5739 + int i; 5740 + 5741 + for (i = 0; i < ARRAY_SIZE(mask->control[band].eht_mcs); i++) 5742 + num_rates += hweight16(mask->control[band].eht_mcs[i]); 5743 + 5744 + return num_rates; 5745 + } 5746 + 5747 + static int 5977 5748 ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_link_vif *arvif, 5978 5749 struct ath12k_link_sta *arsta, 5979 5750 const struct cfg80211_bitrate_mask *mask, ··· 6087 5830 return ret; 6088 5831 } 6089 5832 5833 + static int 5834 + ath12k_mac_set_peer_eht_fixed_rate(struct ath12k_link_vif *arvif, 5835 + struct ath12k_link_sta *arsta, 5836 + const struct cfg80211_bitrate_mask *mask, 5837 + enum nl80211_band band) 5838 + { 5839 + struct ath12k_sta *ahsta = arsta->ahsta; 5840 + struct ath12k *ar = arvif->ar; 5841 + struct ieee80211_sta *sta; 5842 + struct ieee80211_link_sta *link_sta; 5843 + u8 eht_rate, nss = 0; 5844 + u32 rate_code; 5845 + int ret, i; 5846 + 5847 + lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 5848 + 5849 + sta = ath12k_ahsta_to_sta(ahsta); 5850 + 5851 + for (i = 0; i < ARRAY_SIZE(mask->control[band].eht_mcs); i++) { 5852 + if (hweight16(mask->control[band].eht_mcs[i]) == 1) { 5853 + nss = i + 1; 5854 + eht_rate = ffs(mask->control[band].eht_mcs[i]) - 1; 5855 + } 5856 + } 5857 + 5858 + if (!nss) { 5859 + ath12k_warn(ar->ab, "No single EHT Fixed rate found to set for %pM\n", 5860 + arsta->addr); 5861 + return -EINVAL; 5862 + } 5863 + 5864 + /* Avoid updating invalid nss as fixed rate*/ 5865 + link_sta = ath12k_mac_get_link_sta(arsta); 5866 + if (!link_sta || nss > link_sta->rx_nss) { 5867 + ath12k_warn(ar->ab, 5868 + "unable to access link sta for sta %pM link %u or fixed nss of %u is not supported by sta\n", 5869 + sta->addr, arsta->link_id, nss); 5870 + return -EINVAL; 5871 + } 5872 + 5873 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 5874 + "Setting Fixed EHT Rate for peer %pM. Device will not switch to any other selected rates\n", 5875 + arsta->addr); 5876 + 5877 + rate_code = ATH12K_HW_RATE_CODE(eht_rate, nss - 1, 5878 + WMI_RATE_PREAMBLE_EHT); 5879 + 5880 + ret = ath12k_wmi_set_peer_param(ar, arsta->addr, 5881 + arvif->vdev_id, 5882 + WMI_PEER_PARAM_FIXED_RATE, 5883 + rate_code); 5884 + if (ret) 5885 + ath12k_warn(ar->ab, 5886 + "failed to update STA %pM Fixed Rate %d: %d\n", 5887 + arsta->addr, rate_code, ret); 5888 + 5889 + return ret; 5890 + } 5891 + 6090 5892 static int ath12k_mac_station_assoc(struct ath12k *ar, 6091 5893 struct ath12k_link_vif *arvif, 6092 5894 struct ath12k_link_sta *arsta, ··· 6158 5842 struct cfg80211_chan_def def; 6159 5843 enum nl80211_band band; 6160 5844 struct cfg80211_bitrate_mask *mask; 6161 - u8 num_vht_rates, num_he_rates; 5845 + u8 num_vht_rates, num_he_rates, num_eht_rates; 6162 5846 u8 link_id = arvif->link_id; 6163 5847 6164 5848 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); ··· 6201 5885 6202 5886 num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask); 6203 5887 num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask); 5888 + num_eht_rates = ath12k_mac_bitrate_mask_num_eht_rates(ar, band, mask); 6204 5889 6205 - /* If single VHT/HE rate is configured (by set_bitrate_mask()), 6206 - * peer_assoc will disable VHT/HE. This is now enabled by a peer specific 6207 - * fixed param. 5890 + /* If single VHT/HE/EHT rate is configured (by set_bitrate_mask()), 5891 + * peer_assoc will disable VHT/HE/EHT. This is now enabled by a peer 5892 + * specific fixed param. 6208 5893 * Note that all other rates and NSS will be disabled for this peer. 6209 5894 */ 6210 5895 link_sta = ath12k_mac_get_link_sta(arsta); ··· 6223 5906 ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, arsta, mask, band); 6224 5907 } else if (link_sta->he_cap.has_he && num_he_rates == 1) { 6225 5908 ret = ath12k_mac_set_peer_he_fixed_rate(arvif, arsta, mask, band); 5909 + if (ret) 5910 + return ret; 5911 + } else if (link_sta->eht_cap.has_eht && num_eht_rates == 1) { 5912 + ret = ath12k_mac_set_peer_eht_fixed_rate(arvif, arsta, mask, band); 6226 5913 if (ret) 6227 5914 return ret; 6228 5915 } ··· 6291 5970 const u8 *ht_mcs_mask; 6292 5971 const u16 *vht_mcs_mask; 6293 5972 const u16 *he_mcs_mask; 5973 + const u16 *eht_mcs_mask; 6294 5974 u32 changed, bw, nss, mac_nss, smps, bw_prev; 6295 - int err, num_vht_rates, num_he_rates; 5975 + int err, num_vht_rates, num_he_rates, num_eht_rates; 6296 5976 const struct cfg80211_bitrate_mask *mask; 6297 5977 enum wmi_phy_mode peer_phymode; 6298 5978 struct ath12k_link_sta *arsta; ··· 6314 5992 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; 6315 5993 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; 6316 5994 he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; 5995 + eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs; 6317 5996 6318 5997 spin_lock_bh(&ar->data_lock); 6319 5998 ··· 6332 6009 mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask), 6333 6010 ath12k_mac_max_vht_nss(vht_mcs_mask), 6334 6011 ath12k_mac_max_he_nss(he_mcs_mask)); 6012 + mac_nss = max(mac_nss, ath12k_mac_max_eht_nss(eht_mcs_mask)); 6335 6013 nss = min(nss, mac_nss); 6336 6014 6337 6015 struct ath12k_wmi_peer_assoc_arg *peer_arg __free(kfree) = ··· 6418 6094 mask); 6419 6095 num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, 6420 6096 mask); 6097 + num_eht_rates = ath12k_mac_bitrate_mask_num_eht_rates(ar, band, 6098 + mask); 6421 6099 6422 6100 /* Peer_assoc_prepare will reject vht rates in 6423 6101 * bitrate_mask if its not available in range format and ··· 6444 6118 band); 6445 6119 } else if (link_sta->he_cap.has_he && num_he_rates == 1) { 6446 6120 ath12k_mac_set_peer_he_fixed_rate(arvif, arsta, mask, band); 6121 + } else if (link_sta->eht_cap.has_eht && num_eht_rates == 1) { 6122 + err = ath12k_mac_set_peer_eht_fixed_rate(arvif, arsta, 6123 + mask, band); 6124 + if (err) { 6125 + ath12k_warn(ar->ab, 6126 + "failed to set peer EHT fixed rate for STA %pM ret %d\n", 6127 + arsta->addr, err); 6128 + return; 6129 + } 6447 6130 } else { 6448 - /* If the peer is non-VHT/HE or no fixed VHT/HE rate 6449 - * is provided in the new bitrate mask we set the 6131 + /* If the peer is non-VHT/HE/EHT or no fixed VHT/HE/EHT 6132 + * rate is provided in the new bitrate mask we set the 6450 6133 * other rates using peer_assoc command. Also clear 6451 6134 * the peer fixed rate settings as it has higher proprity 6452 6135 * than peer assoc ··· 10034 9699 if (vif->type == NL80211_IFTYPE_MONITOR && ar->monitor_vdev_created) 10035 9700 return -EINVAL; 10036 9701 9702 + if (ar->num_created_vdevs >= TARGET_NUM_VDEVS(ab)) { 9703 + ath12k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", 9704 + TARGET_NUM_VDEVS(ab)); 9705 + return -ENOSPC; 9706 + } 9707 + 10037 9708 link_id = arvif->link_id; 10038 9709 10039 9710 if (link_id < IEEE80211_MLD_MAX_NUM_LINKS) { ··· 10398 10057 10399 10058 if (arvif->is_created) 10400 10059 goto flush; 10401 - 10402 - if (ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { 10403 - ath12k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", 10404 - TARGET_NUM_VDEVS(ab)); 10405 - goto unlock; 10406 - } 10407 10060 10408 10061 ret = ath12k_mac_vdev_create(ar, arvif); 10409 10062 if (ret) { ··· 11199 10864 int n_vifs) 11200 10865 { 11201 10866 struct ath12k_wmi_vdev_up_params params = {}; 11202 - struct ath12k_link_vif *arvif; 11203 10867 struct ieee80211_bss_conf *link_conf; 11204 10868 struct ath12k_base *ab = ar->ab; 10869 + struct ath12k_link_vif *arvif; 11205 10870 struct ieee80211_vif *vif; 11206 10871 struct ath12k_vif *ahvif; 11207 10872 u8 link_id; ··· 11262 10927 continue; 11263 10928 } 11264 10929 10930 + ret = ath12k_mac_update_peer_puncturing_width(arvif->ar, arvif, 10931 + vifs[i].new_ctx->def); 10932 + if (ret) { 10933 + ath12k_warn(ar->ab, 10934 + "failed to update puncturing bitmap %02x and width %d: %d\n", 10935 + vifs[i].new_ctx->def.punctured, 10936 + vifs[i].new_ctx->def.width, ret); 10937 + continue; 10938 + } 10939 + 10940 + /* Defer VDEV bring-up during CSA to avoid installing stale 10941 + * beacon templates. The beacon content is updated only 10942 + * after CSA finalize, so we mark CSA in progress and skip 10943 + * VDEV_UP for now. It will be handled later in 10944 + * bss_info_changed(). 10945 + */ 10946 + if (link_conf->csa_active && 10947 + arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) { 10948 + arvif->is_csa_in_progress = true; 10949 + continue; 10950 + } 10951 + 11265 10952 ret = ath12k_mac_setup_bcn_tmpl(arvif); 11266 10953 if (ret) 11267 10954 ath12k_warn(ab, "failed to update bcn tmpl during csa: %d\n", ··· 11302 10945 if (ret) { 11303 10946 ath12k_warn(ab, "failed to bring vdev up %d: %d\n", 11304 10947 arvif->vdev_id, ret); 11305 - continue; 11306 - } 11307 - 11308 - ret = ath12k_mac_update_peer_puncturing_width(arvif->ar, arvif, 11309 - vifs[i].new_ctx->def); 11310 - if (ret) { 11311 - ath12k_warn(ar->ab, 11312 - "failed to update puncturing bitmap %02x and width %d: %d\n", 11313 - vifs[i].new_ctx->def.punctured, 11314 - vifs[i].new_ctx->def.width, ret); 11315 10948 continue; 11316 10949 } 11317 10950 } ··· 12208 11861 if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask)) 12209 11862 return false; 12210 11863 11864 + if (ath12k_mac_bitrate_mask_num_eht_rates(ar, band, mask)) 11865 + return false; 11866 + 12211 11867 return num_rates == 1; 12212 11868 } 12213 11869 ··· 12233 11883 { 12234 11884 struct ieee80211_supported_band *sband = &ar->mac.sbands[band]; 12235 11885 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map); 11886 + const struct ieee80211_sband_iftype_data *data; 12236 11887 const struct ieee80211_sta_he_cap *he_cap; 12237 11888 u16 he_mcs_map = 0; 11889 + u16 eht_mcs_map = 0; 12238 11890 u8 ht_nss_mask = 0; 12239 11891 u8 vht_nss_mask = 0; 12240 11892 u8 he_nss_mask = 0; 11893 + u8 eht_nss_mask = 0; 11894 + u8 mcs_nss_len; 12241 11895 int i; 12242 11896 12243 11897 /* No need to consider legacy here. Basic rates are always present ··· 12285 11931 return false; 12286 11932 } 12287 11933 12288 - if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask) 11934 + data = ieee80211_get_sband_iftype_data(sband, vif->type); 11935 + 11936 + mcs_nss_len = ieee80211_eht_mcs_nss_size(&data->he_cap.he_cap_elem, 11937 + &data->eht_cap.eht_cap_elem, 11938 + false); 11939 + if (mcs_nss_len == 4) { 11940 + /* 20 MHz only STA case */ 11941 + const struct ieee80211_eht_mcs_nss_supp_20mhz_only *eht_mcs_nss = 11942 + &data->eht_cap.eht_mcs_nss_supp.only_20mhz; 11943 + if (eht_mcs_nss->rx_tx_mcs13_max_nss) 11944 + eht_mcs_map = 0x1fff; 11945 + else if (eht_mcs_nss->rx_tx_mcs11_max_nss) 11946 + eht_mcs_map = 0x07ff; 11947 + else if (eht_mcs_nss->rx_tx_mcs9_max_nss) 11948 + eht_mcs_map = 0x01ff; 11949 + else 11950 + eht_mcs_map = 0x007f; 11951 + } else { 11952 + const struct ieee80211_eht_mcs_nss_supp_bw *eht_mcs_nss; 11953 + 11954 + switch (mcs_nss_len) { 11955 + case 9: 11956 + eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._320; 11957 + break; 11958 + case 6: 11959 + eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._160; 11960 + break; 11961 + case 3: 11962 + eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._80; 11963 + break; 11964 + default: 11965 + return false; 11966 + } 11967 + 11968 + if (eht_mcs_nss->rx_tx_mcs13_max_nss) 11969 + eht_mcs_map = 0x1fff; 11970 + else if (eht_mcs_nss->rx_tx_mcs11_max_nss) 11971 + eht_mcs_map = 0x7ff; 11972 + else 11973 + eht_mcs_map = 0x1ff; 11974 + } 11975 + 11976 + for (i = 0; i < ARRAY_SIZE(mask->control[band].eht_mcs); i++) { 11977 + if (mask->control[band].eht_mcs[i] == 0) 11978 + continue; 11979 + 11980 + if (mask->control[band].eht_mcs[i] < eht_mcs_map) 11981 + eht_nss_mask |= BIT(i); 11982 + else 11983 + return false; 11984 + } 11985 + 11986 + if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask || 11987 + ht_nss_mask != eht_nss_mask) 12289 11988 return false; 12290 11989 12291 11990 if (ht_nss_mask == 0) ··· 12386 11979 } 12387 11980 12388 11981 static int 12389 - ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 he_gi, u8 he_ltf) 11982 + ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf, 11983 + u32 param) 12390 11984 { 12391 11985 struct ath12k *ar = arvif->ar; 12392 11986 int ret; ··· 12395 11987 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 12396 11988 12397 11989 /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */ 12398 - if (he_gi && he_gi != 0xFF) 12399 - he_gi += 1; 11990 + if (gi && gi != 0xFF) 11991 + gi += 1; 12400 11992 12401 11993 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 12402 - WMI_VDEV_PARAM_SGI, he_gi); 11994 + WMI_VDEV_PARAM_SGI, gi); 12403 11995 if (ret) { 12404 - ath12k_warn(ar->ab, "failed to set HE GI:%d, error:%d\n", 12405 - he_gi, ret); 11996 + ath12k_warn(ar->ab, "failed to set GI:%d, error:%d\n", 11997 + gi, ret); 12406 11998 return ret; 12407 11999 } 12408 - /* start from 1 */ 12409 - if (he_ltf != 0xFF) 12410 - he_ltf += 1; 12000 + 12001 + if (param == WMI_VDEV_PARAM_HE_LTF) { 12002 + /* HE values start from 1 */ 12003 + if (ltf != 0xFF) 12004 + ltf += 1; 12005 + } else { 12006 + /* EHT values start from 5 */ 12007 + if (ltf != 0xFF) 12008 + ltf += 4; 12009 + } 12411 12010 12412 12011 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 12413 - WMI_VDEV_PARAM_HE_LTF, he_ltf); 12012 + param, ltf); 12414 12013 if (ret) { 12415 - ath12k_warn(ar->ab, "failed to set HE LTF:%d, error:%d\n", 12416 - he_ltf, ret); 12014 + ath12k_warn(ar->ab, "failed to set LTF:%d, error:%d\n", 12015 + ltf, ret); 12417 12016 return ret; 12418 12017 } 12419 12018 return 0; 12420 12019 } 12421 12020 12422 12021 static int 12423 - ath12k_mac_set_auto_rate_gi_ltf(struct ath12k_link_vif *arvif, u16 he_gi, u8 he_ltf) 12022 + ath12k_mac_set_auto_rate_gi_ltf(struct ath12k_link_vif *arvif, u16 gi, u8 ltf) 12424 12023 { 12425 12024 struct ath12k *ar = arvif->ar; 12426 12025 int ret; 12427 - u32 he_ar_gi_ltf; 12026 + u32 ar_gi_ltf; 12428 12027 12429 - if (he_gi != 0xFF) { 12430 - switch (he_gi) { 12431 - case NL80211_RATE_INFO_HE_GI_0_8: 12432 - he_gi = WMI_AUTORATE_800NS_GI; 12028 + if (gi != 0xFF) { 12029 + switch (gi) { 12030 + case ATH12K_RATE_INFO_GI_0_8: 12031 + gi = WMI_AUTORATE_800NS_GI; 12433 12032 break; 12434 - case NL80211_RATE_INFO_HE_GI_1_6: 12435 - he_gi = WMI_AUTORATE_1600NS_GI; 12033 + case ATH12K_RATE_INFO_GI_1_6: 12034 + gi = WMI_AUTORATE_1600NS_GI; 12436 12035 break; 12437 - case NL80211_RATE_INFO_HE_GI_3_2: 12438 - he_gi = WMI_AUTORATE_3200NS_GI; 12036 + case ATH12K_RATE_INFO_GI_3_2: 12037 + gi = WMI_AUTORATE_3200NS_GI; 12439 12038 break; 12440 12039 default: 12441 12040 ath12k_warn(ar->ab, "Invalid GI\n"); ··· 12450 12035 } 12451 12036 } 12452 12037 12453 - if (he_ltf != 0xFF) { 12454 - switch (he_ltf) { 12455 - case NL80211_RATE_INFO_HE_1XLTF: 12456 - he_ltf = WMI_HE_AUTORATE_LTF_1X; 12038 + if (ltf != 0xFF) { 12039 + switch (ltf) { 12040 + case ATH12K_RATE_INFO_1XLTF: 12041 + ltf = WMI_AUTORATE_LTF_1X; 12457 12042 break; 12458 - case NL80211_RATE_INFO_HE_2XLTF: 12459 - he_ltf = WMI_HE_AUTORATE_LTF_2X; 12043 + case ATH12K_RATE_INFO_2XLTF: 12044 + ltf = WMI_AUTORATE_LTF_2X; 12460 12045 break; 12461 - case NL80211_RATE_INFO_HE_4XLTF: 12462 - he_ltf = WMI_HE_AUTORATE_LTF_4X; 12046 + case ATH12K_RATE_INFO_4XLTF: 12047 + ltf = WMI_AUTORATE_LTF_4X; 12463 12048 break; 12464 12049 default: 12465 12050 ath12k_warn(ar->ab, "Invalid LTF\n"); ··· 12467 12052 } 12468 12053 } 12469 12054 12470 - he_ar_gi_ltf = he_gi | he_ltf; 12055 + ar_gi_ltf = gi | ltf; 12471 12056 12472 12057 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 12473 12058 WMI_VDEV_PARAM_AUTORATE_MISC_CFG, 12474 - he_ar_gi_ltf); 12059 + ar_gi_ltf); 12475 12060 if (ret) { 12476 12061 ath12k_warn(ar->ab, 12477 - "failed to set HE autorate GI:%u, LTF:%u params, error:%d\n", 12478 - he_gi, he_ltf, ret); 12062 + "failed to set autorate GI:%u, LTF:%u params, error:%d\n", 12063 + gi, ltf, ret); 12479 12064 return ret; 12480 12065 } 12481 12066 ··· 12496 12081 12497 12082 static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, 12498 12083 u32 rate, u8 nss, u8 sgi, u8 ldpc, 12499 - u8 he_gi, u8 he_ltf, bool he_fixed_rate) 12084 + u8 he_gi, u8 he_ltf, bool he_fixed_rate, 12085 + u8 eht_gi, u8 eht_ltf, 12086 + bool eht_fixed_rate) 12500 12087 { 12501 12088 struct ieee80211_bss_conf *link_conf; 12502 12089 struct ath12k *ar = arvif->ar; 12090 + bool he_support, eht_support, gi_ltf_set = false; 12503 12091 u32 vdev_param; 12504 12092 u32 param_value; 12505 12093 int ret; 12506 - bool he_support; 12507 12094 12508 12095 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 12509 12096 ··· 12514 12097 return -EINVAL; 12515 12098 12516 12099 he_support = link_conf->he_support; 12100 + eht_support = link_conf->eht_support; 12517 12101 12518 12102 ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 12519 12103 "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x\n", ··· 12524 12106 "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi, 12525 12107 he_ltf, he_fixed_rate); 12526 12108 12527 - if (!he_support) { 12109 + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 12110 + "eht_gi 0x%02x eht_ltf 0x%02x eht_fixed_rate %d\n", 12111 + eht_gi, eht_ltf, eht_fixed_rate); 12112 + 12113 + if (!he_support && !eht_support) { 12528 12114 vdev_param = WMI_VDEV_PARAM_FIXED_RATE; 12529 12115 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 12530 12116 vdev_param, rate); ··· 12557 12135 return ret; 12558 12136 } 12559 12137 12138 + if (eht_support) { 12139 + if (eht_fixed_rate) 12140 + ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, eht_gi, eht_ltf, 12141 + WMI_VDEV_PARAM_EHT_LTF); 12142 + else 12143 + ret = ath12k_mac_set_auto_rate_gi_ltf(arvif, eht_gi, eht_ltf); 12144 + 12145 + if (ret) { 12146 + ath12k_warn(ar->ab, 12147 + "failed to set EHT LTF/GI params %d/%d: %d\n", 12148 + eht_gi, eht_ltf, ret); 12149 + return ret; 12150 + } 12151 + gi_ltf_set = true; 12152 + } 12153 + 12560 12154 if (he_support) { 12561 12155 if (he_fixed_rate) 12562 - ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, he_ltf); 12156 + ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, he_ltf, 12157 + WMI_VDEV_PARAM_HE_LTF); 12563 12158 else 12564 12159 ret = ath12k_mac_set_auto_rate_gi_ltf(arvif, he_gi, he_ltf); 12565 12160 if (ret) 12566 12161 return ret; 12567 - } else { 12162 + gi_ltf_set = true; 12163 + } 12164 + 12165 + if (!gi_ltf_set) { 12568 12166 vdev_param = WMI_VDEV_PARAM_SGI; 12569 12167 param_value = ath12k_mac_nlgi_to_wmigi(sgi); 12570 12168 ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ··· 12649 12207 return true; 12650 12208 } 12651 12209 12210 + static bool 12211 + ath12k_mac_eht_mcs_range_present(struct ath12k *ar, 12212 + enum nl80211_band band, 12213 + const struct cfg80211_bitrate_mask *mask) 12214 + { 12215 + u16 eht_mcs; 12216 + int i; 12217 + 12218 + for (i = 0; i < NL80211_EHT_NSS_MAX; i++) { 12219 + eht_mcs = mask->control[band].eht_mcs[i]; 12220 + 12221 + switch (eht_mcs) { 12222 + case 0: 12223 + case BIT(8) - 1: 12224 + case BIT(10) - 1: 12225 + case BIT(12) - 1: 12226 + case BIT(14) - 1: 12227 + break; 12228 + case BIT(15) - 1: 12229 + case BIT(16) - 1: 12230 + case BIT(16) - BIT(14) - 1: 12231 + if (i != 0) 12232 + return false; 12233 + break; 12234 + default: 12235 + return false; 12236 + } 12237 + } 12238 + 12239 + return true; 12240 + } 12241 + 12652 12242 static void ath12k_mac_set_bitrate_mask_iter(void *data, 12653 12243 struct ieee80211_sta *sta) 12654 12244 { ··· 12735 12261 const struct cfg80211_bitrate_mask *mask, 12736 12262 unsigned int link_id) 12737 12263 { 12738 - bool he_fixed_rate = false, vht_fixed_rate = false; 12739 - const u16 *vht_mcs_mask, *he_mcs_mask; 12264 + bool eht_fixed_rate = false, he_fixed_rate = false, vht_fixed_rate = false; 12265 + const u16 *vht_mcs_mask, *he_mcs_mask, *eht_mcs_mask; 12740 12266 struct ieee80211_link_sta *link_sta; 12741 12267 struct ath12k_peer *peer, *tmp; 12742 - u8 vht_nss, he_nss; 12268 + u8 vht_nss, he_nss, eht_nss; 12743 12269 int ret = true; 12744 12270 12745 12271 vht_mcs_mask = mask->control[band].vht_mcs; 12746 12272 he_mcs_mask = mask->control[band].he_mcs; 12273 + eht_mcs_mask = mask->control[band].eht_mcs; 12747 12274 12748 12275 if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1) 12749 12276 vht_fixed_rate = true; ··· 12752 12277 if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1) 12753 12278 he_fixed_rate = true; 12754 12279 12755 - if (!vht_fixed_rate && !he_fixed_rate) 12280 + if (ath12k_mac_bitrate_mask_num_eht_rates(ar, band, mask) == 1) 12281 + eht_fixed_rate = true; 12282 + 12283 + if (!vht_fixed_rate && !he_fixed_rate && !eht_fixed_rate) 12756 12284 return true; 12757 12285 12758 12286 vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask); 12759 12287 he_nss = ath12k_mac_max_he_nss(he_mcs_mask); 12288 + eht_nss = ath12k_mac_max_eht_nss(eht_mcs_mask); 12760 12289 12761 12290 rcu_read_lock(); 12762 12291 spin_lock_bh(&ar->ab->base_lock); ··· 12779 12300 } 12780 12301 if (he_fixed_rate && (!link_sta->he_cap.has_he || 12781 12302 link_sta->rx_nss < he_nss)) { 12303 + ret = false; 12304 + goto exit; 12305 + } 12306 + if (eht_fixed_rate && (!link_sta->eht_cap.has_eht || 12307 + link_sta->rx_nss < eht_nss)) { 12782 12308 ret = false; 12783 12309 goto exit; 12784 12310 } ··· 12808 12324 const u8 *ht_mcs_mask; 12809 12325 const u16 *vht_mcs_mask; 12810 12326 const u16 *he_mcs_mask; 12327 + const u16 *eht_mcs_mask; 12811 12328 u8 he_ltf = 0; 12812 12329 u8 he_gi = 0; 12330 + u8 eht_ltf = 0, eht_gi = 0; 12813 12331 u32 rate; 12814 12332 u8 nss, mac_nss; 12815 12333 u8 sgi; ··· 12820 12334 int ret; 12821 12335 int num_rates; 12822 12336 bool he_fixed_rate = false; 12337 + bool eht_fixed_rate = false; 12823 12338 12824 12339 lockdep_assert_wiphy(hw->wiphy); 12825 12340 ··· 12836 12349 ht_mcs_mask = mask->control[band].ht_mcs; 12837 12350 vht_mcs_mask = mask->control[band].vht_mcs; 12838 12351 he_mcs_mask = mask->control[band].he_mcs; 12352 + eht_mcs_mask = mask->control[band].eht_mcs; 12839 12353 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); 12840 12354 12841 12355 sgi = mask->control[band].gi; ··· 12847 12359 12848 12360 he_gi = mask->control[band].he_gi; 12849 12361 he_ltf = mask->control[band].he_ltf; 12362 + 12363 + eht_gi = mask->control[band].eht_gi; 12364 + eht_ltf = mask->control[band].eht_ltf; 12850 12365 12851 12366 /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it 12852 12367 * requires passing at least one of used basic rates along with them. ··· 12888 12397 ath12k_warn(ar->ab, 12889 12398 "failed to update fixed rate settings due to mcs/nss incompatibility\n"); 12890 12399 12891 - mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask), 12892 - ath12k_mac_max_vht_nss(vht_mcs_mask), 12893 - ath12k_mac_max_he_nss(he_mcs_mask)); 12400 + mac_nss = max(max3(ath12k_mac_max_ht_nss(ht_mcs_mask), 12401 + ath12k_mac_max_vht_nss(vht_mcs_mask), 12402 + ath12k_mac_max_he_nss(he_mcs_mask)), 12403 + ath12k_mac_max_eht_nss(eht_mcs_mask)); 12894 12404 nss = min_t(u32, ar->num_tx_chains, mac_nss); 12895 12405 12896 12406 /* If multiple rates across different preambles are given ··· 12939 12447 ret = -EINVAL; 12940 12448 goto out; 12941 12449 } 12450 + 12451 + num_rates = ath12k_mac_bitrate_mask_num_eht_rates(ar, band, 12452 + mask); 12453 + if (num_rates == 1) 12454 + eht_fixed_rate = true; 12455 + 12456 + if (!ath12k_mac_eht_mcs_range_present(ar, band, mask) && 12457 + num_rates > 1) { 12458 + ath12k_warn(ar->ab, 12459 + "Setting more than one EHT MCS Value in bitrate mask not supported\n"); 12460 + ret = -EINVAL; 12461 + goto out; 12462 + } 12463 + 12942 12464 ieee80211_iterate_stations_mtx(hw, 12943 12465 ath12k_mac_disable_peer_fixed_rate, 12944 12466 arvif); ··· 12964 12458 } 12965 12459 12966 12460 ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, 12967 - he_ltf, he_fixed_rate); 12461 + he_ltf, he_fixed_rate, eht_gi, eht_ltf, 12462 + eht_fixed_rate); 12968 12463 if (ret) { 12969 12464 ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", 12970 12465 arvif->vdev_id, ret); ··· 13414 12907 if (ret) { 13415 12908 ath12k_warn(ar->ab, "unable to create scan vdev for roc: %d\n", 13416 12909 ret); 12910 + ath12k_mac_unassign_link_vif(arvif); 13417 12911 return ret; 13418 12912 } 13419 12913 } ··· 14414 13906 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); 14415 13907 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); 14416 13908 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 13909 + if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD, 13910 + ab->wmi_ab.svc_map)) { 13911 + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR); 13912 + ieee80211_hw_set(hw, DETECTS_COLOR_COLLISION); 13913 + } 14417 13914 14418 13915 wiphy->cipher_suites = cipher_suites; 14419 13916 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+13 -1
drivers/net/wireless/ath/ath12k/mac.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #ifndef ATH12K_MAC_H ··· 82 82 ATH12K_BW_80 = 2, 83 83 ATH12K_BW_160 = 3, 84 84 ATH12K_BW_320 = 4, 85 + }; 86 + 87 + enum ath12k_gi { 88 + ATH12K_RATE_INFO_GI_0_8, 89 + ATH12K_RATE_INFO_GI_1_6, 90 + ATH12K_RATE_INFO_GI_3_2, 91 + }; 92 + 93 + enum ath12k_ltf { 94 + ATH12K_RATE_INFO_1XLTF, 95 + ATH12K_RATE_INFO_2XLTF, 96 + ATH12K_RATE_INFO_4XLTF, 85 97 }; 86 98 87 99 struct ath12k_mac_get_any_chanctx_conf_arg {
+23 -1
drivers/net/wireless/ath/ath12k/pci.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include <linux/module.h> ··· 218 218 return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END); 219 219 } 220 220 221 + static void ath12k_pci_restore_window(struct ath12k_base *ab) 222 + { 223 + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); 224 + 225 + spin_lock_bh(&ab_pci->window_lock); 226 + 227 + iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window, 228 + ab->mem + WINDOW_REG_ADDRESS); 229 + ioread32(ab->mem + WINDOW_REG_ADDRESS); 230 + 231 + spin_unlock_bh(&ab_pci->window_lock); 232 + } 233 + 221 234 static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) 222 235 { 223 236 u32 val, delay; ··· 255 242 val = ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET); 256 243 if (val == 0xffffffff) 257 244 ath12k_warn(ab, "link down error during global reset\n"); 245 + 246 + /* Restore window register as its content is cleared during 247 + * hardware global reset, such that it aligns with host cache. 248 + */ 249 + ath12k_pci_restore_window(ab); 258 250 } 259 251 260 252 static void ath12k_pci_clear_dbg_registers(struct ath12k_base *ab) ··· 1889 1871 { 1890 1872 pci_unregister_driver(&ath12k_pci_driver); 1891 1873 } 1874 + 1875 + /* firmware files */ 1876 + MODULE_FIRMWARE(ATH12K_FW_DIR "/QCN9274/hw2.0/*"); 1877 + MODULE_FIRMWARE(ATH12K_FW_DIR "/WCN7850/hw2.0/*");
+7 -4
drivers/net/wireless/ath/ath12k/qmi.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #include <linux/elf.h> ··· 3114 3114 if (!m3_mem->vaddr) 3115 3115 return; 3116 3116 3117 - dma_free_coherent(ab->dev, m3_mem->size, 3117 + dma_free_coherent(ab->dev, m3_mem->total_size, 3118 3118 m3_mem->vaddr, m3_mem->paddr); 3119 3119 m3_mem->vaddr = NULL; 3120 + m3_mem->total_size = 0; 3120 3121 m3_mem->size = 0; 3121 3122 } 3122 3123 ··· 3153 3152 3154 3153 /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */ 3155 3154 if (m3_mem->vaddr) { 3156 - if (m3_mem->size >= m3_len) 3155 + if (m3_mem->total_size >= m3_len) 3157 3156 goto skip_m3_alloc; 3158 3157 3159 3158 /* Old buffer is too small, free and reallocate */ ··· 3165 3164 GFP_KERNEL); 3166 3165 if (!m3_mem->vaddr) { 3167 3166 ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n", 3168 - fw->size); 3167 + m3_len); 3169 3168 ret = -ENOMEM; 3170 3169 goto out; 3171 3170 } 3171 + 3172 + m3_mem->total_size = m3_len; 3172 3173 3173 3174 skip_m3_alloc: 3174 3175 memcpy(m3_mem->vaddr, m3_data, m3_len);
+4 -1
drivers/net/wireless/ath/ath12k/qmi.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #ifndef ATH12K_QMI_H ··· 120 120 }; 121 121 122 122 struct m3_mem_region { 123 + /* total memory allocated */ 124 + u32 total_size; 125 + /* actual memory being used */ 123 126 u32 size; 124 127 dma_addr_t paddr; 125 128 void *vaddr;
+80 -6
drivers/net/wireless/ath/ath12k/wmi.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 #include <linux/skbuff.h> 7 7 #include <linux/ctype.h> ··· 14 14 #include <linux/uuid.h> 15 15 #include <linux/time.h> 16 16 #include <linux/of.h> 17 + #include <linux/cleanup.h> 17 18 #include "core.h" 18 19 #include "debugfs.h" 19 20 #include "debug.h" ··· 191 190 .min_len = sizeof(struct wmi_11d_new_cc_event) }, 192 191 [WMI_TAG_PER_CHAIN_RSSI_STATS] = { 193 192 .min_len = sizeof(struct wmi_per_chain_rssi_stat_params) }, 193 + [WMI_TAG_OBSS_COLOR_COLLISION_EVT] = { 194 + .min_len = sizeof(struct wmi_obss_color_collision_event) }, 194 195 }; 195 196 196 197 __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len) ··· 2370 2367 cmd->peer_bw_rxnss_override |= cpu_to_le32(arg->peer_bw_rxnss_override); 2371 2368 2372 2369 if (arg->vht_capable) { 2373 - mcs->rx_max_rate = cpu_to_le32(arg->rx_max_rate); 2374 - mcs->rx_mcs_set = cpu_to_le32(arg->rx_mcs_set); 2375 - mcs->tx_max_rate = cpu_to_le32(arg->tx_max_rate); 2376 - mcs->tx_mcs_set = cpu_to_le32(arg->tx_mcs_set); 2370 + /* Firmware interprets mcs->tx_mcs_set field as peer's 2371 + * RX capability 2372 + */ 2373 + mcs->rx_max_rate = cpu_to_le32(arg->tx_max_rate); 2374 + mcs->rx_mcs_set = cpu_to_le32(arg->tx_mcs_set); 2375 + mcs->tx_max_rate = cpu_to_le32(arg->rx_max_rate); 2376 + mcs->tx_mcs_set = cpu_to_le32(arg->rx_mcs_set); 2377 2377 } 2378 2378 2379 2379 /* HE Rates */ ··· 3851 3845 dev_kfree_skb(skb); 3852 3846 } 3853 3847 return ret; 3848 + } 3849 + 3850 + static void 3851 + ath12k_wmi_obss_color_collision_event(struct ath12k_base *ab, struct sk_buff *skb) 3852 + { 3853 + const struct wmi_obss_color_collision_event *ev; 3854 + struct ath12k_link_vif *arvif; 3855 + u32 vdev_id, evt_type; 3856 + u64 bitmap; 3857 + 3858 + const void **tb __free(kfree) = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); 3859 + if (IS_ERR(tb)) { 3860 + ath12k_warn(ab, "failed to parse OBSS color collision tlv %ld\n", 3861 + PTR_ERR(tb)); 3862 + return; 3863 + } 3864 + 3865 + ev = tb[WMI_TAG_OBSS_COLOR_COLLISION_EVT]; 3866 + if (!ev) { 3867 + ath12k_warn(ab, "failed to fetch OBSS color collision event\n"); 3868 + return; 3869 + } 3870 + 3871 + vdev_id = le32_to_cpu(ev->vdev_id); 3872 + evt_type = le32_to_cpu(ev->evt_type); 3873 + bitmap = le64_to_cpu(ev->obss_color_bitmap); 3874 + 3875 + guard(rcu)(); 3876 + 3877 + arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_id); 3878 + if (!arvif) { 3879 + ath12k_warn(ab, "no arvif found for vdev %u in OBSS color collision event\n", 3880 + vdev_id); 3881 + return; 3882 + } 3883 + 3884 + switch (evt_type) { 3885 + case WMI_BSS_COLOR_COLLISION_DETECTION: 3886 + ieee80211_obss_color_collision_notify(arvif->ahvif->vif, 3887 + bitmap, 3888 + arvif->link_id); 3889 + ath12k_dbg(ab, ATH12K_DBG_WMI, 3890 + "obss color collision detected vdev %u event %d bitmap %016llx\n", 3891 + vdev_id, evt_type, bitmap); 3892 + break; 3893 + case WMI_BSS_COLOR_COLLISION_DISABLE: 3894 + case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: 3895 + case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: 3896 + break; 3897 + default: 3898 + ath12k_warn(ab, "unknown OBSS color collision event type %d\n", evt_type); 3899 + } 3854 3900 } 3855 3901 3856 3902 static void ··· 7069 7011 7070 7012 static void ath12k_bcn_tx_status_event(struct ath12k_base *ab, struct sk_buff *skb) 7071 7013 { 7014 + struct ath12k_link_vif *arvif; 7015 + struct ath12k *ar; 7072 7016 u32 vdev_id, tx_status; 7073 7017 7074 7018 if (ath12k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) { 7075 7019 ath12k_warn(ab, "failed to extract bcn tx status"); 7076 7020 return; 7077 7021 } 7022 + 7023 + guard(rcu)(); 7024 + 7025 + arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_id); 7026 + if (!arvif) { 7027 + ath12k_warn(ab, "invalid vdev %u in bcn tx status\n", 7028 + vdev_id); 7029 + return; 7030 + } 7031 + 7032 + ar = arvif->ar; 7033 + wiphy_work_queue(ath12k_ar_to_hw(ar)->wiphy, &arvif->bcn_tx_work); 7078 7034 } 7079 7035 7080 7036 static void ath12k_vdev_stopped_event(struct ath12k_base *ab, struct sk_buff *skb) ··· 9946 9874 case WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID: 9947 9875 ath12k_wmi_rssi_dbm_conversion_params_info_event(ab, skb); 9948 9876 break; 9877 + case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID: 9878 + ath12k_wmi_obss_color_collision_event(ab, skb); 9879 + break; 9949 9880 /* add Unsupported events (rare) here */ 9950 9881 case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID: 9951 9882 case WMI_PEER_OPER_MODE_CHANGE_EVENTID: ··· 9959 9884 /* add Unsupported events (frequent) here */ 9960 9885 case WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID: 9961 9886 case WMI_MGMT_RX_FW_CONSUMED_EVENTID: 9962 - case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID: 9963 9887 /* debug might flood hence silently ignore (no-op) */ 9964 9888 break; 9965 9889 case WMI_PDEV_UTF_EVENTID:
+34 -21
drivers/net/wireless/ath/ath12k/wmi.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 5 */ 6 6 7 7 #ifndef ATH12K_WMI_H ··· 223 223 }; 224 224 225 225 /* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command. 226 - * Used only for HE auto rate mode. 226 + * Used for HE and EHT auto rate mode. 227 227 */ 228 228 enum { 229 - /* HE LTF related configuration */ 230 - WMI_HE_AUTORATE_LTF_1X = BIT(0), 231 - WMI_HE_AUTORATE_LTF_2X = BIT(1), 232 - WMI_HE_AUTORATE_LTF_4X = BIT(2), 229 + /* LTF related configuration */ 230 + WMI_AUTORATE_LTF_1X = BIT(0), 231 + WMI_AUTORATE_LTF_2X = BIT(1), 232 + WMI_AUTORATE_LTF_4X = BIT(2), 233 233 234 - /* HE GI related configuration */ 234 + /* GI related configuration */ 235 235 WMI_AUTORATE_400NS_GI = BIT(8), 236 236 WMI_AUTORATE_800NS_GI = BIT(9), 237 237 WMI_AUTORATE_1600NS_GI = BIT(10), ··· 1197 1197 WMI_VDEV_PARAM_SET_HEMU_MODE, 1198 1198 WMI_VDEV_PARAM_HEOPS_0_31 = 0x8003, 1199 1199 WMI_VDEV_PARAM_SET_EHT_MU_MODE = 0x8005, 1200 + WMI_VDEV_PARAM_EHT_LTF, 1200 1201 }; 1201 1202 1202 1203 enum wmi_tlv_peer_flags { ··· 3610 3609 u32 pdev_id; 3611 3610 }; 3612 3611 3613 - struct wmi_bcn_send_from_host_cmd { 3614 - __le32 tlv_header; 3615 - __le32 vdev_id; 3616 - __le32 data_len; 3617 - union { 3618 - __le32 frag_ptr; 3619 - __le32 frag_ptr_lo; 3620 - }; 3621 - __le32 frame_ctrl; 3622 - __le32 dtim_flag; 3623 - __le32 bcn_antenna; 3624 - __le32 frag_ptr_hi; 3625 - }; 3626 - 3627 3612 #define WMI_CHAN_INFO_MODE GENMASK(5, 0) 3628 3613 #define WMI_CHAN_INFO_HT40_PLUS BIT(6) 3629 3614 #define WMI_CHAN_INFO_PASSIVE BIT(7) ··· 4205 4218 struct ath12k_wmi_vht_rate_set_params { 4206 4219 __le32 tlv_header; 4207 4220 __le32 rx_max_rate; 4221 + /* MCS at which the peer can transmit */ 4208 4222 __le32 rx_mcs_set; 4209 4223 __le32 tx_max_rate; 4224 + /* MCS at which the peer can receive */ 4210 4225 __le32 tx_mcs_set; 4211 4226 __le32 tx_max_mcs_nss; 4212 4227 } __packed; ··· 4929 4940 #define ATH12K_BSS_COLOR_STA_PERIODS 10000 4930 4941 #define ATH12K_BSS_COLOR_AP_PERIODS 5000 4931 4942 4943 + /** 4944 + * enum wmi_bss_color_collision - Event types for BSS color collision handling 4945 + * @WMI_BSS_COLOR_COLLISION_DISABLE: Indicates that BSS color collision detection 4946 + * is disabled. 4947 + * @WMI_BSS_COLOR_COLLISION_DETECTION: Event triggered when a BSS color collision 4948 + * is detected. 4949 + * @WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: Event indicating that the timer for waiting 4950 + * on a free BSS color slot has expired. 4951 + * @WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: Event indicating that a free BSS color slot 4952 + * has become available. 4953 + */ 4954 + enum wmi_bss_color_collision { 4955 + WMI_BSS_COLOR_COLLISION_DISABLE = 0, 4956 + WMI_BSS_COLOR_COLLISION_DETECTION, 4957 + WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY, 4958 + WMI_BSS_COLOR_FREE_SLOT_AVAILABLE, 4959 + }; 4960 + 4932 4961 struct wmi_obss_color_collision_cfg_params_cmd { 4933 4962 __le32 tlv_header; 4934 4963 __le32 vdev_id; ··· 4962 4955 __le32 tlv_header; 4963 4956 __le32 vdev_id; 4964 4957 __le32 enable; 4958 + } __packed; 4959 + 4960 + struct wmi_obss_color_collision_event { 4961 + __le32 vdev_id; 4962 + __le32 evt_type; 4963 + __le64 obss_color_bitmap; 4965 4964 } __packed; 4966 4965 4967 4966 #define ATH12K_IPV4_TH_SEED_SIZE 5
+1
drivers/net/wireless/ath/ath12k/wow.c
··· 758 758 if (ret) { 759 759 ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n", 760 760 arvif->vdev_id, enable, ret); 761 + kfree(offload); 761 762 return ret; 762 763 } 763 764 }
-74
drivers/net/wireless/ath/wcn36xx/hal.h
··· 4484 4484 u32 status; 4485 4485 }; 4486 4486 4487 - /* Update scan params - sent from host to PNO to be used during PNO 4488 - * scanningx */ 4489 - struct wcn36xx_hal_update_scan_params_req { 4490 - 4491 - struct wcn36xx_hal_msg_header header; 4492 - 4493 - /* Host setting for 11d */ 4494 - u8 dot11d_enabled; 4495 - 4496 - /* Lets PNO know that host has determined the regulatory domain */ 4497 - u8 dot11d_resolved; 4498 - 4499 - /* Channels on which PNO is allowed to scan */ 4500 - u8 channel_count; 4501 - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS]; 4502 - 4503 - /* Minimum channel time */ 4504 - u16 active_min_ch_time; 4505 - 4506 - /* Maximum channel time */ 4507 - u16 active_max_ch_time; 4508 - 4509 - /* Minimum channel time */ 4510 - u16 passive_min_ch_time; 4511 - 4512 - /* Maximum channel time */ 4513 - u16 passive_max_ch_time; 4514 - 4515 - /* Cb State */ 4516 - enum phy_chan_bond_state state; 4517 - } __packed; 4518 - 4519 - /* Update scan params - sent from host to PNO to be used during PNO 4520 - * scanningx */ 4521 - struct wcn36xx_hal_update_scan_params_req_ex { 4522 - 4523 - struct wcn36xx_hal_msg_header header; 4524 - 4525 - /* Host setting for 11d */ 4526 - u8 dot11d_enabled; 4527 - 4528 - /* Lets PNO know that host has determined the regulatory domain */ 4529 - u8 dot11d_resolved; 4530 - 4531 - /* Channels on which PNO is allowed to scan */ 4532 - u8 channel_count; 4533 - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX]; 4534 - 4535 - /* Minimum channel time */ 4536 - u16 active_min_ch_time; 4537 - 4538 - /* Maximum channel time */ 4539 - u16 active_max_ch_time; 4540 - 4541 - /* Minimum channel time */ 4542 - u16 passive_min_ch_time; 4543 - 4544 - /* Maximum channel time */ 4545 - u16 passive_max_ch_time; 4546 - 4547 - /* Cb State */ 4548 - enum phy_chan_bond_state state; 4549 - } __packed; 4550 - 4551 - /* Update scan params - sent from host to PNO to be used during PNO 4552 - * scanningx */ 4553 - struct wcn36xx_hal_update_scan_params_resp { 4554 - 4555 - struct wcn36xx_hal_msg_header header; 4556 - 4557 - /* status of the request */ 4558 - u32 status; 4559 - } __packed; 4560 - 4561 4487 struct wcn36xx_hal_set_tx_per_tracking_req_msg { 4562 4488 struct wcn36xx_hal_msg_header header; 4563 4489
-60
drivers/net/wireless/ath/wcn36xx/smd.c
··· 1127 1127 return ret; 1128 1128 } 1129 1129 1130 - static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len) 1131 - { 1132 - struct wcn36xx_hal_update_scan_params_resp *rsp; 1133 - 1134 - rsp = buf; 1135 - 1136 - /* Remove the PNO version bit */ 1137 - rsp->status &= (~(WCN36XX_FW_MSG_PNO_VERSION_MASK)); 1138 - 1139 - if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) { 1140 - wcn36xx_warn("error response from update scan\n"); 1141 - return rsp->status; 1142 - } 1143 - 1144 - return 0; 1145 - } 1146 - 1147 - int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, 1148 - u8 *channels, size_t channel_count) 1149 - { 1150 - struct wcn36xx_hal_update_scan_params_req_ex msg_body; 1151 - int ret; 1152 - 1153 - mutex_lock(&wcn->hal_mutex); 1154 - INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ); 1155 - 1156 - msg_body.dot11d_enabled = false; 1157 - msg_body.dot11d_resolved = true; 1158 - 1159 - msg_body.channel_count = channel_count; 1160 - memcpy(msg_body.channels, channels, channel_count); 1161 - msg_body.active_min_ch_time = 60; 1162 - msg_body.active_max_ch_time = 120; 1163 - msg_body.passive_min_ch_time = 60; 1164 - msg_body.passive_max_ch_time = 110; 1165 - msg_body.state = PHY_SINGLE_CHANNEL_CENTERED; 1166 - 1167 - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 1168 - 1169 - wcn36xx_dbg(WCN36XX_DBG_HAL, 1170 - "hal update scan params channel_count %d\n", 1171 - msg_body.channel_count); 1172 - 1173 - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); 1174 - if (ret) { 1175 - wcn36xx_err("Sending hal_update_scan_params failed\n"); 1176 - goto out; 1177 - } 1178 - ret = wcn36xx_smd_update_scan_params_rsp(wcn->hal_buf, 1179 - wcn->hal_rsp_len); 1180 - if (ret) { 1181 - wcn36xx_err("hal_update_scan_params response failed err=%d\n", 1182 - ret); 1183 - goto out; 1184 - } 1185 - out: 1186 - mutex_unlock(&wcn->hal_mutex); 1187 - return ret; 1188 - } 1189 - 1190 1130 static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn, 1191 1131 struct ieee80211_vif *vif, 1192 1132 void *buf,
-1
drivers/net/wireless/ath/wcn36xx/smd.h
··· 66 66 int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode, 67 67 struct ieee80211_vif *vif); 68 68 69 - int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count); 70 69 int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, 71 70 struct cfg80211_scan_request *req); 72 71 int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn);
-1
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
··· 38 38 .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, 39 39 .apmg_not_supported = true, 40 40 .mac_addr_from_csr = 0x380, 41 - .min_umac_error_event_table = 0x400000, 42 41 .d3_debug_data_base_addr = 0x401000, 43 42 .d3_debug_data_length = 60 * 1024, 44 43 .mon_smem_regs = {
-1
drivers/net/wireless/intel/iwlwifi/cfg/8000.c
··· 50 50 .smem_offset = IWL8260_SMEM_OFFSET, 51 51 .smem_len = IWL8260_SMEM_LEN, 52 52 .apmg_not_supported = true, 53 - .min_umac_error_event_table = 0x800000, 54 53 }; 55 54 56 55 static const struct iwl_tt_params iwl8000_tt_params = {
-1
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
··· 41 41 .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, 42 42 .apmg_not_supported = true, 43 43 .mac_addr_from_csr = 0x380, 44 - .min_umac_error_event_table = 0x800000, 45 44 .d3_debug_data_base_addr = 0x401000, 46 45 .d3_debug_data_length = 92 * 1024, 47 46 .nvm_hw_section_num = 10,
-1
drivers/net/wireless/intel/iwlwifi/cfg/ax210.c
··· 33 33 .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, 34 34 .apmg_not_supported = true, 35 35 .mac_addr_from_csr = 0x380, 36 - .min_umac_error_event_table = 0x400000, 37 36 .d3_debug_data_base_addr = 0x401000, 38 37 .d3_debug_data_length = 60 * 1024, 39 38 .mon_smem_regs = {
+2 -2
drivers/net/wireless/intel/iwlwifi/cfg/bz.c
··· 10 10 #include "fw/api/txq.h" 11 11 12 12 /* Highest firmware core release supported */ 13 - #define IWL_BZ_UCODE_CORE_MAX 99 13 + #define IWL_BZ_UCODE_CORE_MAX 101 14 14 15 15 /* Lowest firmware API version supported */ 16 16 #define IWL_BZ_UCODE_API_MIN 100 ··· 38 38 .smem_len = IWL_BZ_SMEM_LEN, 39 39 .apmg_not_supported = true, 40 40 .mac_addr_from_csr = 0x30, 41 - .min_umac_error_event_table = 0xD0000, 42 41 .d3_debug_data_base_addr = 0x401000, 43 42 .d3_debug_data_length = 60 * 1024, 44 43 .mon_smem_regs = { ··· 89 90 .low_latency_xtal = true, 90 91 .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, 91 92 }; 93 + EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_bz_mac_cfg); 92 94 93 95 const struct iwl_mac_cfg iwl_gl_mac_cfg = { 94 96 .device_family = IWL_DEVICE_FAMILY_BZ,
+1 -2
drivers/net/wireless/intel/iwlwifi/cfg/dr.c
··· 9 9 #include "fw/api/txq.h" 10 10 11 11 /* Highest firmware core release supported */ 12 - #define IWL_DR_UCODE_CORE_MAX 99 12 + #define IWL_DR_UCODE_CORE_MAX 101 13 13 14 14 /* Lowest firmware API version supported */ 15 15 #define IWL_DR_UCODE_API_MIN 100 ··· 33 33 .smem_len = IWL_DR_SMEM_LEN, 34 34 .apmg_not_supported = true, 35 35 .mac_addr_from_csr = 0x30, 36 - .min_umac_error_event_table = 0xD0000, 37 36 .d3_debug_data_base_addr = 0x401000, 38 37 .d3_debug_data_length = 60 * 1024, 39 38 .mon_smem_regs = {
+1
drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
··· 19 19 .non_shared_ant = ANT_B, \ 20 20 .vht_mu_mimo_supported = true, \ 21 21 .uhb_supported = true, \ 22 + .eht_supported = true, \ 22 23 .num_rbds = IWL_NUM_RBDS_EHT, \ 23 24 .nvm_ver = IWL_FM_NVM_VERSION, \ 24 25 .nvm_type = IWL_NVM_EXT
+1
drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
··· 12 12 "Killer(R) Wi-Fi 8 BN1850i 320MHz Wireless Network Adapter (BN201.NGW)"; 13 13 14 14 const char iwl_bn201_name[] = "Intel(R) Wi-Fi 8 BN201"; 15 + const char iwl_bn203_name[] = "Intel(R) Wi-Fi 8 BN203"; 15 16 const char iwl_be221_name[] = "Intel(R) Wi-Fi 7 BE221"; 16 17 const char iwl_be223_name[] = "Intel(R) Wi-Fi 7 BE223";
+24
drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
··· 4 4 */ 5 5 #include "iwl-config.h" 6 6 7 + /* NVM versions */ 8 + #define IWL_WH_NVM_VERSION 0x0a1d 9 + 10 + #define IWL_DEVICE_WH \ 11 + .ht_params = { \ 12 + .stbc = true, \ 13 + .ldpc = true, \ 14 + .ht40_bands = BIT(NL80211_BAND_2GHZ) | \ 15 + BIT(NL80211_BAND_5GHZ), \ 16 + }, \ 17 + .led_mode = IWL_LED_RF_STATE, \ 18 + .non_shared_ant = ANT_B, \ 19 + .vht_mu_mimo_supported = true, \ 20 + .uhb_supported = true, \ 21 + .num_rbds = IWL_NUM_RBDS_EHT, \ 22 + .nvm_ver = IWL_WH_NVM_VERSION, \ 23 + .nvm_type = IWL_NVM_EXT 24 + 7 25 /* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */ 26 + 27 + const struct iwl_rf_cfg iwl_rf_wh_non_eht = { 28 + IWL_DEVICE_WH, 29 + .eht_supported = false, 30 + }; 8 31 9 32 const char iwl_killer_be1775s_name[] = 10 33 "Killer(R) Wi-Fi 7 BE1775s 320MHz Wireless Network Adapter (BE211D2W)"; ··· 36 13 37 14 const char iwl_be211_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz"; 38 15 const char iwl_be213_name[] = "Intel(R) Wi-Fi 7 BE213 160MHz"; 16 + const char iwl_ax221_name[] = "Intel(R) Wi-Fi 6E AX221 160MHz";
+1 -2
drivers/net/wireless/intel/iwlwifi/cfg/sc.c
··· 10 10 #include "fw/api/txq.h" 11 11 12 12 /* Highest firmware core release supported */ 13 - #define IWL_SC_UCODE_CORE_MAX 99 13 + #define IWL_SC_UCODE_CORE_MAX 101 14 14 15 15 /* Lowest firmware API version supported */ 16 16 #define IWL_SC_UCODE_API_MIN 100 ··· 41 41 .smem_len = IWL_SC_SMEM_LEN, 42 42 .apmg_not_supported = true, 43 43 .mac_addr_from_csr = 0x30, 44 - .min_umac_error_event_table = 0xD0000, 45 44 .d3_debug_data_base_addr = 0x401000, 46 45 .d3_debug_data_length = 60 * 1024, 47 46 .mon_smem_regs = {
+1
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
··· 151 151 * @mcc: output buffer (3 bytes) that will get the MCC 152 152 * 153 153 * This function tries to read the current MCC from ACPI if available. 154 + * Return: 0 on success, or a negative error code 154 155 */ 155 156 int iwl_acpi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc); 156 157
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
··· 88 88 __le32 enabled; 89 89 } __packed; /* IMR_ALIVE_INFO_API_S_VER_1 */ 90 90 91 - struct iwl_alive_ntf_v6 { 91 + struct iwl_alive_ntf_v7 { 92 92 __le16 status; 93 93 __le16 flags; 94 94 struct iwl_lmac_alive lmac_data[2];
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/api/cmdhdr.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014 Intel Corporation 3 + * Copyright (C) 2005-2014, 2025 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 98 98 } __packed; 99 99 100 100 /** 101 - * struct iwl_cmd_header_wide 101 + * struct iwl_cmd_header_wide - wide command header 102 102 * 103 103 * This header format appears in the beginning of each command sent from the 104 104 * driver, and each response/notification received from uCode.
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2023-2024 Intel Corporation 3 + * Copyright (C) 2023-2025 Intel Corporation 4 4 * Copyright (C) 2013-2014, 2018-2019 Intel Corporation 5 5 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 6 6 * Copyright (C) 2017 Intel Deutschland GmbH ··· 52 52 } __packed; /* BT_COEX_CMD_API_S_VER_6 */ 53 53 54 54 /** 55 - * struct iwl_bt_coex_reduced_txp_update_cmd 55 + * struct iwl_bt_coex_reduced_txp_update_cmd - reduced TX power command 56 56 * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the 57 57 * bits are the sta_id (value) 58 58 */
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
··· 60 60 * @UCODE_ALIVE_NTFY: 61 61 * Alive data from the firmware, as described in 62 62 * &struct iwl_alive_ntf_v3 or &struct iwl_alive_ntf_v4 or 63 - * &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v6. 63 + * &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v7. 64 64 */ 65 65 UCODE_ALIVE_NTFY = 0x1, 66 66
+5
drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
··· 124 124 BEACON_FILTER_IN_NOTIF = 0xF8, 125 125 126 126 /** 127 + * @PHY_AIR_SNIFFER_NOTIF: &struct iwl_rx_phy_air_sniffer_ntfy 128 + */ 129 + PHY_AIR_SNIFFER_NOTIF = 0xF9, 130 + 131 + /** 127 132 * @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification 128 133 */ 129 134 STA_PM_NOTIF = 0xFD,
+7 -7
drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
··· 16 16 #define IWL_FW_INI_PRESET_DISABLE 0xff 17 17 18 18 /** 19 - * struct iwl_fw_ini_hcmd 19 + * struct iwl_fw_ini_hcmd - debug configuration host command 20 20 * 21 21 * @id: the debug configuration command type for instance: 0xf6 / 0xf5 / DHC 22 22 * @group: the desired cmd group ··· 199 199 } __packed; /* FW_TLV_DEBUG_REGION_API_S_VER_1 */ 200 200 201 201 /** 202 - * struct iwl_fw_ini_debug_info_tlv 202 + * struct iwl_fw_ini_debug_info_tlv - debug info TLV 203 203 * 204 204 * debug configuration name for a specific image 205 205 * ··· 311 311 } __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */ 312 312 313 313 /** 314 - * enum iwl_fw_ini_config_set_type 314 + * enum iwl_fw_ini_config_set_type - configuration set type 315 315 * 316 316 * @IWL_FW_INI_CONFIG_SET_TYPE_INVALID: invalid config set 317 317 * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: for PERIPHERY MAC configuration ··· 337 337 } __packed; 338 338 339 339 /** 340 - * enum iwl_fw_ini_allocation_id 340 + * enum iwl_fw_ini_allocation_id - allocation ID 341 341 * 342 342 * @IWL_FW_INI_ALLOCATION_INVALID: invalid 343 343 * @IWL_FW_INI_ALLOCATION_ID_DBGC1: allocation meant for DBGC1 configuration ··· 356 356 }; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */ 357 357 358 358 /** 359 - * enum iwl_fw_ini_buffer_location 359 + * enum iwl_fw_ini_buffer_location - buffer location 360 360 * 361 361 * @IWL_FW_INI_LOCATION_INVALID: invalid 362 362 * @IWL_FW_INI_LOCATION_SRAM_PATH: SRAM location ··· 373 373 }; /* FW_DEBUG_TLV_BUFFER_LOCATION_E_VER_1 */ 374 374 375 375 /** 376 - * enum iwl_fw_ini_region_type 376 + * enum iwl_fw_ini_region_type - region type 377 377 * 378 378 * @IWL_FW_INI_REGION_INVALID: invalid 379 379 * @IWL_FW_INI_REGION_TLV: uCode and debug TLVs ··· 437 437 }; /* FW_TLV_DEBUG_REGION_DEVICE_MEMORY_SUBTYPE_API_E */ 438 438 439 439 /** 440 - * enum iwl_fw_ini_time_point 440 + * enum iwl_fw_ini_time_point - time point type 441 441 * 442 442 * Hard coded time points in which the driver can send hcmd or perform dump 443 443 * collection
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
··· 421 421 } __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */ 422 422 423 423 /** 424 - * struct iwl_dbg_host_event_cfg_cmd 424 + * struct iwl_dbg_host_event_cfg_cmd - host event config command 425 425 * @enabled_severities: enabled severities 426 426 */ 427 427 struct iwl_dbg_host_event_cfg_cmd {
+4 -4
drivers/net/wireless/intel/iwlwifi/fw/api/location.h
··· 1092 1092 } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_9 */ 1093 1093 1094 1094 /** 1095 - * enum iwl_tof_response_mode 1095 + * enum iwl_tof_response_mode - TOF response mode 1096 1096 * @IWL_MVM_TOF_RESPONSE_ASAP: report each AP measurement separately as soon as 1097 1097 * possible (not supported for this release) 1098 1098 * @IWL_MVM_TOF_RESPONSE_TIMEOUT: report all AP measurements as a batch upon ··· 1108 1108 }; 1109 1109 1110 1110 /** 1111 - * enum iwl_tof_initiator_flags 1111 + * enum iwl_tof_initiator_flags - TOF initiator flags 1112 1112 * 1113 1113 * @IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED: disable fast algo, meaning run 1114 1114 * the algo on ant A+B, instead of only one of them. ··· 1409 1409 }; 1410 1410 1411 1411 /** 1412 - * enum iwl_tof_entry_status 1412 + * enum iwl_tof_entry_status - TOF entry status 1413 1413 * 1414 1414 * @IWL_TOF_ENTRY_SUCCESS: successful measurement. 1415 1415 * @IWL_TOF_ENTRY_GENERAL_FAILURE: General failure. ··· 1856 1856 } __packed; 1857 1857 1858 1858 /** 1859 - * struct iwl_tof_range_abort_cmd 1859 + * struct iwl_tof_range_abort_cmd - TOF range abort command 1860 1860 * @request_id: corresponds to a range request 1861 1861 * @reserved: reserved 1862 1862 */
+7 -127
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
··· 18 18 19 19 /** 20 20 * @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd_v1, 21 - * &struct iwl_lari_config_change_cmd_v2, 22 - * &struct iwl_lari_config_change_cmd_v3, 23 - * &struct iwl_lari_config_change_cmd_v4, 24 - * &struct iwl_lari_config_change_cmd_v5, 25 21 * &struct iwl_lari_config_change_cmd_v6, 26 - * &struct iwl_lari_config_change_cmd_v7, 27 - * &struct iwl_lari_config_change_cmd_v10 or 22 + * &struct iwl_lari_config_change_cmd_v8, 28 23 * &struct iwl_lari_config_change_cmd 29 24 */ 30 25 LARI_CONFIG_CHANGE = 0x1, ··· 560 565 } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_1 */ 561 566 562 567 /** 563 - * struct iwl_lari_config_change_cmd_v2 - change LARI configuration 564 - * @config_bitmap: bit map of the config commands. each bit will trigger a 565 - * different predefined FW config operation 566 - * @oem_uhb_allow_bitmap: bitmap of UHB enabled MCC sets 567 - */ 568 - struct iwl_lari_config_change_cmd_v2 { 569 - __le32 config_bitmap; 570 - __le32 oem_uhb_allow_bitmap; 571 - } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_2 */ 572 - 573 - /** 574 - * struct iwl_lari_config_change_cmd_v3 - change LARI configuration 575 - * @config_bitmap: bit map of the config commands. each bit will trigger a 576 - * different predefined FW config operation 577 - * @oem_uhb_allow_bitmap: bitmap of UHB enabled MCC sets 578 - * @oem_11ax_allow_bitmap: bitmap of 11ax allowed MCCs. 579 - * For each supported country, a pair of regulatory override bit and 11ax mode exist 580 - * in the bit field. 581 - */ 582 - struct iwl_lari_config_change_cmd_v3 { 583 - __le32 config_bitmap; 584 - __le32 oem_uhb_allow_bitmap; 585 - __le32 oem_11ax_allow_bitmap; 586 - } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_3 */ 587 - 588 - /** 589 - * struct iwl_lari_config_change_cmd_v4 - change LARI configuration 590 - * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 591 - * different predefined FW config operation. 592 - * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. 593 - * @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits 594 - * per country, one to indicate whether to override and the other to 595 - * indicate the value to use. 596 - * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 597 - * per country, one to indicate whether to override and the other to 598 - * indicate allow/disallow unii4 channels. 599 - */ 600 - struct iwl_lari_config_change_cmd_v4 { 601 - __le32 config_bitmap; 602 - __le32 oem_uhb_allow_bitmap; 603 - __le32 oem_11ax_allow_bitmap; 604 - __le32 oem_unii4_allow_bitmap; 605 - } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_4 */ 606 - 607 - /** 608 - * struct iwl_lari_config_change_cmd_v5 - change LARI configuration 609 - * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 610 - * different predefined FW config operation. 611 - * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. 612 - * @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits 613 - * per country, one to indicate whether to override and the other to 614 - * indicate the value to use. 615 - * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 616 - * per country, one to indicate whether to override and the other to 617 - * indicate allow/disallow unii4 channels. 618 - * @chan_state_active_bitmap: Bitmap for overriding channel state to active. 619 - * Each bit represents a country or region to activate, according to the BIOS 620 - * definitions. 621 - */ 622 - struct iwl_lari_config_change_cmd_v5 { 623 - __le32 config_bitmap; 624 - __le32 oem_uhb_allow_bitmap; 625 - __le32 oem_11ax_allow_bitmap; 626 - __le32 oem_unii4_allow_bitmap; 627 - __le32 chan_state_active_bitmap; 628 - } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_5 */ 629 - 630 - /** 631 568 * struct iwl_lari_config_change_cmd_v6 - change LARI configuration 632 569 * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 633 570 * different predefined FW config operation. ··· 586 659 } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_6 */ 587 660 588 661 /** 589 - * struct iwl_lari_config_change_cmd_v7 - change LARI configuration 590 - * This structure is used also for lari cmd version 8 and 9. 662 + * struct iwl_lari_config_change_cmd_v8 - change LARI configuration 591 663 * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 592 664 * different predefined FW config operation. 593 665 * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. ··· 596 670 * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 597 671 * per country, one to indicate whether to override and the other to 598 672 * indicate allow/disallow unii4 channels. 599 - * For LARI cmd version 4 to 8 - bits 0:3 are supported. 600 - * For LARI cmd version 9 - bits 0:5 are supported. 673 + * bit 0 - 3: supported. 601 674 * @chan_state_active_bitmap: Bitmap to enable different bands per country 602 675 * or region. 603 676 * Each bit represents a country or region, and a band to activate 604 677 * according to the BIOS definitions. 605 - * For LARI cmd version 7 - bits 0:3 are supported. 606 - * For LARI cmd version 8 - bits 0:4 are supported. 678 + * bit 0 - 4: supported. 607 679 * @force_disable_channels_bitmap: Bitmap of disabled bands/channels. 608 680 * Each bit represents a set of channels in a specific band that should be 609 681 * disabled 610 682 * @edt_bitmap: Bitmap of energy detection threshold table. 611 683 * Disable/enable the EDT optimization method for different band. 612 684 */ 613 - struct iwl_lari_config_change_cmd_v7 { 685 + struct iwl_lari_config_change_cmd_v8 { 614 686 __le32 config_bitmap; 615 687 __le32 oem_uhb_allow_bitmap; 616 688 __le32 oem_11ax_allow_bitmap; ··· 617 693 __le32 force_disable_channels_bitmap; 618 694 __le32 edt_bitmap; 619 695 } __packed; 620 - /* LARI_CHANGE_CONF_CMD_S_VER_7 */ 621 696 /* LARI_CHANGE_CONF_CMD_S_VER_8 */ 622 - /* LARI_CHANGE_CONF_CMD_S_VER_9 */ 623 697 624 - /** 625 - * struct iwl_lari_config_change_cmd_v10 - change LARI configuration 626 - * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 627 - * different predefined FW config operation. 628 - * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. 629 - * @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits 630 - * per country, one to indicate whether to override and the other to 631 - * indicate the value to use. 632 - * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 633 - * per country, one to indicate whether to override and the other to 634 - * indicate allow/disallow unii4 channels. 635 - * For LARI cmd version 10 - bits 0:5 are supported. 636 - * @chan_state_active_bitmap: Bitmap to enable different bands per country 637 - * or region. 638 - * Each bit represents a country or region, and a band to activate 639 - * according to the BIOS definitions. 640 - * For LARI cmd version 10 - bits 0:4 are supported. 641 - * @force_disable_channels_bitmap: Bitmap of disabled bands/channels. 642 - * Each bit represents a set of channels in a specific band that should be 643 - * disabled 644 - * @edt_bitmap: Bitmap of energy detection threshold table. 645 - * Disable/enable the EDT optimization method for different band. 646 - * @oem_320mhz_allow_bitmap: 320Mhz bandwidth enablement bitmap per MCC. 647 - * bit0: enable 320Mhz in Japan. 648 - * bit1: enable 320Mhz in South Korea. 649 - * bit 2 - 31: reserved. 650 - */ 651 - struct iwl_lari_config_change_cmd_v10 { 652 - __le32 config_bitmap; 653 - __le32 oem_uhb_allow_bitmap; 654 - __le32 oem_11ax_allow_bitmap; 655 - __le32 oem_unii4_allow_bitmap; 656 - __le32 chan_state_active_bitmap; 657 - __le32 force_disable_channels_bitmap; 658 - __le32 edt_bitmap; 659 - __le32 oem_320mhz_allow_bitmap; 660 - } __packed; 661 - /* LARI_CHANGE_CONF_CMD_S_VER_10 */ 662 698 663 699 /** 664 700 * struct iwl_lari_config_change_cmd - change LARI configuration ··· 631 747 * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 632 748 * per country, one to indicate whether to override and the other to 633 749 * indicate allow/disallow unii4 channels. 634 - * For LARI cmd version 11 - bits 0:5 are supported. 635 750 * @chan_state_active_bitmap: Bitmap to enable different bands per country 636 751 * or region. 637 752 * Each bit represents a country or region, and a band to activate 638 753 * according to the BIOS definitions. 639 - * For LARI cmd version 11 - bits 0:4 are supported. 640 - * For LARI cmd version 12 - bits 0:6 are supported and bits 7:31 are 641 - * reserved. 754 + * bit 0 - 6: supported. 642 755 * @force_disable_channels_bitmap: Bitmap of disabled bands/channels. 643 756 * Each bit represents a set of channels in a specific band that should be 644 757 * disabled ··· 662 781 __le32 oem_320mhz_allow_bitmap; 663 782 __le32 oem_11be_allow_bitmap; 664 783 } __packed; 665 - /* LARI_CHANGE_CONF_CMD_S_VER_11 */ 666 784 /* LARI_CHANGE_CONF_CMD_S_VER_12 */ 667 785 668 786 /* Activate UNII-1 (5.2GHz) for World Wide */ 669 787 #define ACTIVATE_5G2_IN_WW_MASK BIT(4) 670 - #define CHAN_STATE_ACTIVE_BITMAP_CMD_V11 0x1F 788 + #define CHAN_STATE_ACTIVE_BITMAP_CMD_V8 0x1F 671 789 #define CHAN_STATE_ACTIVE_BITMAP_CMD_V12 0x7F 672 790 673 791 /**
+3 -2
drivers/net/wireless/intel/iwlwifi/fw/api/power.h
··· 620 620 } __packed; /*SAR_OFFSET_MAPPING_TABLE_CMD_API_S*/ 621 621 622 622 /** 623 - * struct iwl_beacon_filter_cmd 623 + * struct iwl_beacon_filter_cmd - beacon filter command 624 624 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) 625 625 * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon 626 626 * to driver if delta in Energy values calculated for this and last ··· 762 762 }; /* PHY_AP_TYPE_API_E_VER_1 */ 763 763 764 764 /** 765 - * struct iwl_txpower_constraints_cmd 765 + * struct iwl_txpower_constraints_cmd - TX power constraints command 766 766 * AP_TX_POWER_CONSTRAINTS_CMD 767 767 * Used for VLP/LPI/AFC Access Point power constraints for 6GHz channels 768 768 * @link_id: linkId ··· 786 786 __s8 psd_pwr[IWL_MAX_TX_EIRP_PSD_PWR_MAX_SIZE]; 787 787 u8 reserved[3]; 788 788 } __packed; /* PHY_AP_TX_POWER_CONSTRAINTS_CMD_API_S_VER_1 */ 789 + 789 790 #endif /* __iwl_fw_api_power_h__ */
+286
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
··· 262 262 }; 263 263 264 264 enum iwl_rx_mpdu_phy_info { 265 + IWL_RX_MPDU_PHY_EOF_INDICATION = BIT(0), 265 266 IWL_RX_MPDU_PHY_AMPDU = BIT(5), 266 267 IWL_RX_MPDU_PHY_AMPDU_TOGGLE = BIT(6), 267 268 IWL_RX_MPDU_PHY_SHORT_PREAMBLE = BIT(7), ··· 1041 1040 __le32 average_energy; 1042 1041 __le32 link_id; 1043 1042 } __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_2 */ 1043 + 1044 + union iwl_legacy_sig { 1045 + #define OFDM_RX_LEGACY_LENGTH 0x00000fff 1046 + #define OFDM_RX_RATE 0x0000f000 1047 + __le32 ofdm; 1048 + #define CCK_CRFR_SHORT_PREAMBLE 0x00000040 1049 + __le32 cck; 1050 + }; 1051 + 1052 + struct iwl_ht_sigs { 1053 + #define OFDM_RX_FRAME_HT_MCS 0x0000007f 1054 + #define OFDM_RX_FRAME_HT_BANDWIDTH 0x00000080 1055 + #define OFDM_RX_FRAME_HT_LENGTH 0x03ffff00 1056 + __le32 a1; 1057 + __le32 a2; 1058 + }; 1059 + 1060 + struct iwl_vht_sigs { 1061 + #define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM 0x000007ff 1062 + #define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM_VALID 0x80000000 1063 + __le32 a0; 1064 + __le32 a1, a2; 1065 + }; 1066 + 1067 + struct iwl_he_sigs { 1068 + #define OFDM_RX_FRAME_HE_BEAM_CHANGE 0x00000001 1069 + #define OFDM_RX_FRAME_HE_UL_FLAG 0x00000002 1070 + #define OFDM_RX_FRAME_HE_MCS 0x0000003c 1071 + #define OFDM_RX_FRAME_HE_DCM 0x00000040 1072 + #define OFDM_RX_FRAME_HE_BSS_COLOR 0x00001f80 1073 + #define OFDM_RX_FRAME_HE_SPATIAL_REUSE 0x0001e000 1074 + #define OFDM_RX_FRAME_HE_BANDWIDTH 0x00060000 1075 + #define OFDM_RX_FRAME_HE_SU_EXT_BW10 0x00080000 1076 + #define OFDM_RX_FRAME_HE_GI_LTF_TYPE 0x00700000 1077 + #define OFDM_RX_FRAME_HE_NSTS 0x03800000 1078 + #define OFDM_RX_FRAME_HE_PRMBL_PUNC_TYPE 0x0c000000 1079 + __le32 a1; 1080 + #define OFDM_RX_FRAME_HE_TXOP_DURATION 0x0000007f 1081 + #define OFDM_RX_FRAME_HE_CODING 0x00000080 1082 + #define OFDM_RX_FRAME_HE_CODING_EXTRA_SYM 0x00000100 1083 + #define OFDM_RX_FRAME_HE_STBC 0x00000200 1084 + #define OFDM_RX_FRAME_HE_BF 0x00000400 1085 + #define OFDM_RX_FRAME_HE_PRE_FEC_PAD_FACTOR 0x00001800 1086 + #define OFDM_RX_FRAME_HE_PE_DISAMBIG 0x00002000 1087 + #define OFDM_RX_FRAME_HE_DOPPLER 0x00004000 1088 + #define OFDM_RX_FRAME_HE_TYPE 0x00038000 1089 + #define OFDM_RX_FRAME_HE_MU_NUM_OF_SIGB_SYM_OR_USER_NUM 0x003c0000 1090 + #define OFDM_RX_FRAME_HE_MU_SIGB_COMP 0x00400000 1091 + #define OFDM_RX_FRAME_HE_MU_NUM_OF_LTF_SYM 0x03800000 1092 + __le32 a2; 1093 + #define OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM 0x000007ff 1094 + #define OFDM_RX_FRAME_HE_PE_DURATION 0x00003800 1095 + #define OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM_VALID 0x80000000 1096 + __le32 a3; 1097 + #define OFDM_RX_FRAME_HE_SIGB_STA_ID_FOUND 0x00000001 1098 + #define OFDM_RX_FRAME_HE_SIGB_STA_ID_INDX 0x0000000e 1099 + #define OFDM_RX_FRAME_HE_SIGB_NSTS 0x00000070 1100 + #define OFDM_RX_FRAME_HE_SIGB_BF 0x00000080 1101 + #define OFDM_RX_FRAME_HE_SIGB_MCS 0x00000f00 1102 + #define OFDM_RX_FRAME_HE_SIGB_DCM 0x00001000 1103 + #define OFDM_RX_FRAME_HE_SIGB_CODING 0x00002000 1104 + #define OFDM_RX_FRAME_HE_SIGB_SPATIAL_CONFIG 0x0003c000 1105 + #define OFDM_RX_FRAME_HE_SIGB_STA_RU 0x03fc0000 1106 + #define OFDM_RX_FRAME_HE_SIGB_NUM_OF_SYM 0x3c000000 1107 + #define OFDM_RX_FRAME_HE_SIGB_CRC_OK 0x40000000 1108 + __le32 b; 1109 + /* index 0 */ 1110 + #define OFDM_RX_FRAME_HE_RU_ALLOC_0_A1 0x000000ff 1111 + #define OFDM_RX_FRAME_HE_RU_ALLOC_0_A2 0x0000ff00 1112 + #define OFDM_RX_FRAME_HE_RU_ALLOC_0_B1 0x00ff0000 1113 + #define OFDM_RX_FRAME_HE_RU_ALLOC_0_B2 0xff000000 1114 + /* index 1 */ 1115 + #define OFDM_RX_FRAME_HE_RU_ALLOC_1_C1 0x000000ff 1116 + #define OFDM_RX_FRAME_HE_RU_ALLOC_1_C2 0x0000ff00 1117 + #define OFDM_RX_FRAME_HE_RU_ALLOC_1_D1 0x00ff0000 1118 + #define OFDM_RX_FRAME_HE_RU_ALLOC_1_D2 0xff000000 1119 + /* index 2 */ 1120 + #define OFDM_RX_FRAME_HE_CENTER_RU_CC1 0x00000001 1121 + #define OFDM_RX_FRAME_HE_CENTER_RU_CC2 0x00000002 1122 + #define OFDM_RX_FRAME_HE_COMMON_CC1_CRC_OK 0x00000004 1123 + #define OFDM_RX_FRAME_HE_COMMON_CC2_CRC_OK 0x00000008 1124 + __le32 cmn[3]; 1125 + }; 1126 + 1127 + struct iwl_he_tb_sigs { 1128 + #define OFDM_RX_HE_TRIG_FORMAT 0x00000001 1129 + #define OFDM_RX_HE_TRIG_BSS_COLOR 0x0000007e 1130 + #define OFDM_RX_HE_TRIG_SPATIAL_REUSE_1 0x00000780 1131 + #define OFDM_RX_HE_TRIG_SPATIAL_REUSE_2 0x00007800 1132 + #define OFDM_RX_HE_TRIG_SPATIAL_REUSE_3 0x00078000 1133 + #define OFDM_RX_HE_TRIG_SPATIAL_REUSE_4 0x00780000 1134 + #define OFDM_RX_HE_TRIG_BANDWIDTH 0x03000000 1135 + __le32 a1; 1136 + #define OFDM_RX_HE_TRIG_TXOP_DURATION 0x0000007f 1137 + #define OFDM_RX_HE_TRIG_SIG2_RESERVED 0x0000ff80 1138 + #define OFDM_RX_HE_TRIG_FORMAT_ERR 0x08000000 1139 + #define OFDM_RX_HE_TRIG_BW_ERR 0x10000000 1140 + #define OFDM_RX_HE_TRIG_LEGACY_LENGTH_ERR 0x20000000 1141 + #define OFDM_RX_HE_TRIG_CRC_OK 0x40000000 1142 + __le32 a2; 1143 + #define OFDM_UCODE_TRIG_BASE_RX_LGCY_LENGTH 0x00000fff 1144 + #define OFDM_UCODE_TRIG_BASE_RX_BANDWIDTH 0x00007000 1145 + #define OFDM_UCODE_TRIG_BASE_PS160 0x00008000 1146 + #define OFDM_UCODE_EHT_TRIG_CONTROL_CHANNEL 0x000f0000 1147 + __le32 tb_rx0; 1148 + #define OFDM_UCODE_TRIG_BASE_RX_MCS 0x0000000f 1149 + #define OFDM_UCODE_TRIG_BASE_RX_DCM 0x00000010 1150 + #define OFDM_UCODE_TRIG_BASE_RX_GI_LTF_TYPE 0x00000060 1151 + #define OFDM_UCODE_TRIG_BASE_RX_NSTS 0x00000380 1152 + #define OFDM_UCODE_TRIG_BASE_RX_CODING 0x00000400 1153 + #define OFDM_UCODE_TRIG_BASE_RX_CODING_EXTRA_SYM 0x00000800 1154 + #define OFDM_UCODE_TRIG_BASE_RX_STBC 0x00001000 1155 + #define OFDM_UCODE_TRIG_BASE_RX_PRE_FEC_PAD_FACTOR 0x00006000 1156 + #define OFDM_UCODE_TRIG_BASE_RX_PE_DISAMBIG 0x00008000 1157 + #define OFDM_UCODE_TRIG_BASE_RX_DOPPLER 0x00010000 1158 + #define OFDM_UCODE_TRIG_BASE_RX_RU 0x01fe0000 1159 + #define OFDM_UCODE_TRIG_BASE_RX_RU_P80 0x00020000 1160 + #define OFDM_UCODE_TRIG_BASE_RX_NUM_OF_LTF_SYM 0x0e000000 1161 + #define OFDM_UCODE_TRIG_BASE_RX_LTF_PILOT_TYPE 0x10000000 1162 + #define OFDM_UCODE_TRIG_BASE_RX_LOWEST_SS_ALLOCATION 0xe0000000 1163 + __le32 tb_rx1; 1164 + }; 1165 + 1166 + struct iwl_eht_sigs { 1167 + #define OFDM_RX_FRAME_ENHANCED_WIFI_VER_ID 0x00000007 1168 + #define OFDM_RX_FRAME_ENHANCED_WIFI_BANDWIDTH 0x00000038 1169 + #define OFDM_RX_FRAME_ENHANCED_WIFI_UL_FLAG 0x00000040 1170 + #define OFDM_RX_FRAME_ENHANCED_WIFI_BSS_COLOR 0x00001f80 1171 + #define OFDM_RX_FRAME_ENHANCED_WIFI_TXOP_DURATION 0x000fe000 1172 + #define OFDM_RX_FRAME_EHT_USIG1_DISREGARD 0x01f00000 1173 + #define OFDM_RX_FRAME_EHT_USIG1_VALIDATE 0x02000000 1174 + #define OFDM_RX_FRAME_EHT_BW320_SLOT 0x04000000 1175 + #define OFDM_RX_FRAME_EHT_TYPE 0x18000000 1176 + #define OFDM_RX_FRAME_ENHANCED_ER_NO_STREAMS 0x20000000 1177 + __le32 usig_a1; 1178 + #define OFDM_RX_FRAME_EHT_PPDU_TYPE 0x00000003 1179 + #define OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B2 0x00000004 1180 + #define OFDM_RX_FRAME_EHT_PUNC_CHANNEL 0x000000f8 1181 + #define OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B8 0x00000100 1182 + #define OFDM_RX_FRAME_EHT_SIG_MCS 0x00000600 1183 + #define OFDM_RX_FRAME_EHT_SIG_SYM_NUM 0x0000f800 1184 + #define OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_1 0x000f0000 1185 + #define OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_2 0x00f00000 1186 + #define OFDM_RX_FRAME_EHT_TRIG_USIG2_DISREGARD 0x1f000000 1187 + #define OFDM_RX_FRAME_EHT_TRIG_NO_STREAMS 0x20000000 1188 + #define OFDM_RX_USIG_CRC_OK 0x40000000 1189 + __le32 usig_a2_eht; 1190 + #define OFDM_RX_FRAME_EHT_SPATIAL_REUSE 0x0000000f 1191 + #define OFDM_RX_FRAME_EHT_GI_LTF_TYPE 0x00000030 1192 + #define OFDM_RX_FRAME_EHT_NUM_OF_LTF_SYM 0x000001c0 1193 + #define OFDM_RX_FRAME_EHT_CODING_EXTRA_SYM 0x00000200 1194 + #define OFDM_RX_FRAME_EHT_PRE_FEC_PAD_FACTOR 0x00000c00 1195 + #define OFDM_RX_FRAME_EHT_PE_DISAMBIG 0x00001000 1196 + #define OFDM_RX_FRAME_EHT_USIG_OVF_DISREGARD 0x0001e000 1197 + #define OFDM_RX_FRAME_EHT_NUM_OF_USERS 0x000e0000 1198 + #define OFDM_RX_FRAME_EHT_NSTS 0x00f00000 1199 + #define OFDM_RX_FRAME_EHT_BF 0x01000000 1200 + #define OFDM_RX_FRAME_EHT_USIG_OVF_NDP_DISREGARD 0x06000000 1201 + #define OFDM_RX_FRAME_EHTSIG_COMM_CC1_CRC_OK 0x08000000 1202 + #define OFDM_RX_FRAME_EHTSIG_COMM_CC2_CRC_OK 0x10000000 1203 + #define OFDM_RX_FRAME_EHT_NON_VALID_RU_ALLOC 0x20000000 1204 + #define OFDM_RX_FRAME_EHT_NO_STREAMS 0x40000000 1205 + __le32 b1; 1206 + #define OFDM_RX_FRAME_EHT_MATCH_ID_FOUND 0x00000001 1207 + #define OFDM_RX_FRAME_EHT_ID_INDX 0x0000000e 1208 + #define OFDM_RX_FRAME_EHT_MCS 0x000000f0 1209 + #define OFDM_RX_FRAME_EHT_CODING 0x00000100 1210 + #define OFDM_RX_FRAME_EHT_SPATIAL_CONFIG 0x00007e00 1211 + #define OFDM_RX_FRAME_EHT_STA_RU 0x007f8000 1212 + #define OFDM_RX_FRAME_EHT_STA_RU_P80 0x00008000 1213 + #define OFDM_RX_FRAME_EHT_STA_RU_PS160 0x00800000 1214 + #define OFDM_RX_FRAME_EHT_USER_FIELD_CRC_OK 0x40000000 1215 + __le32 b2; 1216 + #define OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM 0x000007ff 1217 + #define OFDM_RX_FRAME_EHT_PE_DURATION 0x00003800 1218 + #define OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM_VALID 0x80000000 1219 + __le32 sig2; 1220 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A1 0x000001ff 1221 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A2 0x0003fe00 1222 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A3 0x07fc0000 1223 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B1 0x000001ff 1224 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B2 0x0003fe00 1225 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B3 0x07fc0000 1226 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C1 0x000001ff 1227 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C2 0x0003fe00 1228 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C3 0x07fc0000 1229 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D1 0x000001ff 1230 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D2 0x0003fe00 1231 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D3 0x07fc0000 1232 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_4_A4 0x000001ff 1233 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_4_B4 0x0003fe00 1234 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_5_C4 0x000001ff 1235 + #define OFDM_RX_FRAME_EHT_RU_ALLOC_5_D4 0x0003fe00 1236 + __le32 cmn[6]; 1237 + #define OFDM_RX_FRAME_EHT_USER_FIELD_ID 0x000007ff 1238 + __le32 user_id; 1239 + }; 1240 + 1241 + struct iwl_eht_tb_sigs { 1242 + /* same as non-TB above */ 1243 + __le32 usig_a1, usig_a2_eht; 1244 + /* same as HE TB above */ 1245 + __le32 tb_rx0, tb_rx1; 1246 + }; 1247 + 1248 + struct iwl_uhr_sigs { 1249 + __le32 usig_a1, usig_a1_uhr, usig_a2_uhr, b1, b2; 1250 + __le32 sig2; 1251 + __le32 cmn[6]; 1252 + __le32 user_id; 1253 + }; 1254 + 1255 + struct iwl_uhr_tb_sigs { 1256 + __le32 usig_a1, usig_a2_uhr, tb_rx0, tb_rx1; 1257 + }; 1258 + 1259 + struct iwl_uhr_elr_sigs { 1260 + __le32 usig_a1, usig_a2_uhr; 1261 + __le32 uhr_sig_elr1, uhr_sig_elr2; 1262 + }; 1263 + 1264 + union iwl_sigs { 1265 + struct iwl_ht_sigs ht; 1266 + struct iwl_vht_sigs vht; 1267 + struct iwl_he_sigs he; 1268 + struct iwl_he_tb_sigs he_tb; 1269 + struct iwl_eht_sigs eht; 1270 + struct iwl_eht_tb_sigs eht_tb; 1271 + struct iwl_uhr_sigs uhr; 1272 + struct iwl_uhr_tb_sigs uhr_tb; 1273 + struct iwl_uhr_elr_sigs uhr_elr; 1274 + }; 1275 + 1276 + enum iwl_sniffer_status { 1277 + IWL_SNIF_STAT_PLCP_RX_OK = 0, 1278 + IWL_SNIF_STAT_AID_NOT_FOR_US = 1, 1279 + IWL_SNIF_STAT_PLCP_RX_LSIG_ERR = 2, 1280 + IWL_SNIF_STAT_PLCP_RX_SIGA_ERR = 3, 1281 + IWL_SNIF_STAT_PLCP_RX_SIGB_ERR = 4, 1282 + IWL_SNIF_STAT_UNEXPECTED_TB = 5, 1283 + IWL_SNIF_STAT_UNSUPPORTED_RATE = 6, 1284 + IWL_SNIF_STAT_UNKNOWN_ERROR = 7, 1285 + }; /* AIR_SNIFFER_STATUS_E_VER_1 */ 1286 + 1287 + enum iwl_sniffer_flags { 1288 + IWL_SNIF_FLAG_VALID_TB_RX = BIT(0), 1289 + IWL_SNIF_FLAG_VALID_RU = BIT(1), 1290 + }; /* AIR_SNIFFER_FLAGS_E_VER_1 */ 1291 + 1292 + /** 1293 + * struct iwl_rx_phy_air_sniffer_ntfy - air sniffer notification 1294 + * 1295 + * @status: &enum iwl_sniffer_status 1296 + * @flags: &enum iwl_sniffer_flags 1297 + * @reserved1: reserved 1298 + * @rssi_a: energy chain-A in negative dBm, measured at FINA time 1299 + * @rssi_b: energy chain-B in negative dBm, measured at FINA time 1300 + * @channel: channel number 1301 + * @band: band information, PHY_BAND_* 1302 + * @on_air_rise_time: GP2 at on air rise 1303 + * @frame_time: frame time in us 1304 + * @rate: RATE_MCS_* 1305 + * @bytecount: byte count for legay and HT, otherwise number of symbols 1306 + * @legacy_sig: CCK signal information if %RATE_MCS_MOD_TYPE_MSK in @rate is 1307 + * %RATE_MCS_MOD_TYPE_CCK, otherwise OFDM signal information 1308 + * @sigs: PHY signal information, depending on %RATE_MCS_MOD_TYPE_MSK in @rate 1309 + * @reserved2: reserved 1310 + * 1311 + * Sent for every frame and before the normal RX command if data is included. 1312 + */ 1313 + struct iwl_rx_phy_air_sniffer_ntfy { 1314 + u8 status; 1315 + u8 flags; 1316 + u8 reserved1[2]; 1317 + u8 rssi_a, rssi_b; 1318 + u8 channel, band; 1319 + __le32 on_air_rise_time; 1320 + __le32 frame_time; 1321 + /* note: MCS in rate is not valid for MU-VHT */ 1322 + __le32 rate; 1323 + __le32 bytecount; 1324 + union iwl_legacy_sig legacy_sig; 1325 + union iwl_sigs sigs; 1326 + __le32 reserved2; 1327 + }; /* RX_PHY_AIR_SNIFFER_NTFY_API_S_VER_1 */ 1044 1328 1045 1329 #endif /* __iwl_fw_api_rx_h__ */
+41 -37
drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 129 129 } __packed; 130 130 131 131 /** 132 - * struct iwl_scan_offload_profile_cfg_data 132 + * struct iwl_scan_offload_profile_cfg_data - scan offload profile configs 133 133 * @blocklist_len: length of blocklist 134 134 * @num_profiles: num of profiles in the list 135 135 * @match_notify: clients waiting for match found notification ··· 159 159 } __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1-2*/ 160 160 161 161 /** 162 - * struct iwl_scan_offload_profile_cfg 162 + * struct iwl_scan_offload_profile_cfg - scan offload profile config 163 163 * @profiles: profiles to search for match 164 164 * @data: the rest of the data for profile_cfg 165 165 */ ··· 507 507 IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE = BIT(26), 508 508 }; 509 509 /** 510 - * struct iwl_scan_dwell 510 + * struct iwl_scan_dwell - scan dwell configuration 511 511 * @active: default dwell time for active scan 512 512 * @passive: default dwell time for passive scan 513 513 * @fragmented: default dwell time for fragmented scan ··· 728 728 }; 729 729 730 730 /** 731 - * struct iwl_scan_channel_cfg_umac 731 + * struct iwl_scan_channel_cfg_umac - scan channel config 732 732 * @flags: bitmap - 0-19: directed scan to i'th ssid. 733 733 * @channel_num: channel number 1-13 etc. 734 734 * @v1: command version 1 ··· 774 774 } __packed; 775 775 776 776 /** 777 - * struct iwl_scan_umac_schedule 777 + * struct iwl_scan_umac_schedule - scan schedule parameters 778 778 * @interval: interval in seconds between scan iterations 779 779 * @iter_count: num of scan iterations for schedule plan, 0xff for infinite loop 780 780 * @reserved: for alignment and future use ··· 815 815 } __packed; 816 816 817 817 /** 818 - * struct iwl_scan_umac_chan_param 818 + * struct iwl_scan_umac_chan_param - scan channel parameters 819 819 * @flags: channel flags &enum iwl_scan_channel_flags 820 820 * @count: num of channels in scan request 821 821 * @reserved: for future use and alignment ··· 827 827 } __packed; /*SCAN_CHANNEL_PARAMS_API_S_VER_1 */ 828 828 829 829 /** 830 - * struct iwl_scan_req_umac 830 + * struct iwl_scan_req_umac - scan request command 831 831 * @flags: &enum iwl_umac_scan_flags 832 832 * @uid: scan id, &enum iwl_umac_scan_uid_offsets 833 833 * @ooc_priority: out of channel priority - &enum iwl_scan_priority 834 834 * @general_flags: &enum iwl_umac_scan_general_flags 835 + * @reserved: reserved 835 836 * @scan_start_mac_id: report the scan start TSF time according to this mac TSF 836 - * @extended_dwell: dwell time for channels 1, 6 and 11 837 - * @active_dwell: dwell time for active scan per LMAC 838 - * @passive_dwell: dwell time for passive scan per LMAC 839 - * @fragmented_dwell: dwell time for fragmented passive scan 840 - * @adwell_default_n_aps: for adaptive dwell the default number of APs 837 + * @v1: version 1 command data 838 + * @v6: version 6 command data 839 + * @v7: version 7 command data 840 + * @v8: version 8 command data 841 + * @v9: version 9 command data 842 + * @v1.extended_dwell: dwell time for channels 1, 6 and 11 843 + * @v1.active_dwell: dwell time for active scan per LMAC 844 + * @v1.passive_dwell: dwell time for passive scan per LMAC 845 + * @v1.fragmented_dwell: dwell time for fragmented passive scan 846 + * @v7.adwell_default_n_aps: for adaptive dwell the default number of APs 841 847 * per channel 842 - * @adwell_default_n_aps_social: for adaptive dwell the default 848 + * @v7.adwell_default_n_aps_social: for adaptive dwell the default 843 849 * number of APs per social (1,6,11) channel 844 - * @general_flags2: &enum iwl_umac_scan_general_flags2 845 - * @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added 846 - * to total scan time 847 - * @max_out_time: max out of serving channel time, per LMAC - for CDB there 848 - * are 2 LMACs 849 - * @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs 850 - * @scan_priority: scan internal prioritization &enum iwl_scan_priority 851 - * @num_of_fragments: Number of fragments needed for full coverage per band. 850 + * @v8.general_flags2: &enum iwl_umac_scan_general_flags2 851 + * @v7.adwell_max_budget: for adaptive dwell the maximal budget of TU to be 852 + * added to total scan time 853 + * @v1.max_out_time: max out of serving channel time, per LMAC - for CDB 854 + * there are 2 LMACs 855 + * @v1.suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs 856 + * @v1.scan_priority: scan internal prioritization &enum iwl_scan_priority 857 + * @v8.num_of_fragments: Number of fragments needed for full coverage per band. 852 858 * Relevant only for fragmented scan. 853 - * @channel: &struct iwl_scan_umac_chan_param 854 - * @reserved: for future use and alignment 855 - * @reserved3: for future use and alignment 856 - * @data: &struct iwl_scan_channel_cfg_umac and 859 + * @v1.channel: &struct iwl_scan_umac_chan_param 860 + * @v1.data: &struct iwl_scan_channel_cfg_umac and 857 861 * &struct iwl_scan_req_umac_tail 858 862 */ 859 863 struct iwl_scan_req_umac { ··· 943 939 #define IWL_SCAN_REQ_UMAC_SIZE_V1 36 944 940 945 941 /** 946 - * struct iwl_scan_probe_params_v3 942 + * struct iwl_scan_probe_params_v3 - scan probe parameters 947 943 * @preq: scan probe request params 948 944 * @ssid_num: number of valid SSIDs in direct scan array 949 945 * @short_ssid_num: number of valid short SSIDs in short ssid array ··· 965 961 } __packed; /* SCAN_PROBE_PARAMS_API_S_VER_3 */ 966 962 967 963 /** 968 - * struct iwl_scan_probe_params_v4 964 + * struct iwl_scan_probe_params_v4 - scan probe parameters 969 965 * @preq: scan probe request params 970 966 * @short_ssid_num: number of valid short SSIDs in short ssid array 971 967 * @bssid_num: number of valid bssid in bssids array ··· 987 983 #define SCAN_MAX_NUM_CHANS_V3 67 988 984 989 985 /** 990 - * struct iwl_scan_channel_params_v4 986 + * struct iwl_scan_channel_params_v4 - channel params 991 987 * @flags: channel flags &enum iwl_scan_channel_flags 992 988 * @count: num of channels in scan request 993 989 * @num_of_aps_override: override the number of APs the FW uses to calculate ··· 1010 1006 SCAN_CHANNEL_PARAMS_API_S_VER_5 */ 1011 1007 1012 1008 /** 1013 - * struct iwl_scan_channel_params_v7 1009 + * struct iwl_scan_channel_params_v7 - channel params 1014 1010 * @flags: channel flags &enum iwl_scan_channel_flags 1015 1011 * @count: num of channels in scan request 1016 1012 * @n_aps_override: override the number of APs the FW uses to calculate dwell ··· 1028 1024 } __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */ 1029 1025 1030 1026 /** 1031 - * struct iwl_scan_general_params_v11 1027 + * struct iwl_scan_general_params_v11 - channel params 1032 1028 * @flags: &enum iwl_umac_scan_general_flags_v2 1033 1029 * @reserved: reserved for future 1034 1030 * @scan_start_mac_or_link_id: report the scan start TSF time according to this ··· 1070 1066 } __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_12, *_VER_11 and *_VER_10 */ 1071 1067 1072 1068 /** 1073 - * struct iwl_scan_periodic_parms_v1 1069 + * struct iwl_scan_periodic_parms_v1 - periodicity parameters 1074 1070 * @schedule: can scheduling parameter 1075 1071 * @delay: initial delay of the periodic scan in seconds 1076 1072 * @reserved: reserved for future ··· 1082 1078 } __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ 1083 1079 1084 1080 /** 1085 - * struct iwl_scan_req_params_v12 1081 + * struct iwl_scan_req_params_v12 - scan request parameters (v12) 1086 1082 * @general_params: &struct iwl_scan_general_params_v11 1087 1083 * @channel_params: &struct iwl_scan_channel_params_v4 1088 1084 * @periodic_params: &struct iwl_scan_periodic_parms_v1 ··· 1110 1106 } __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_17 - 14 */ 1111 1107 1112 1108 /** 1113 - * struct iwl_scan_req_umac_v12 1109 + * struct iwl_scan_req_umac_v12 - scan request command (v12) 1114 1110 * @uid: scan id, &enum iwl_umac_scan_uid_offsets 1115 1111 * @ooc_priority: out of channel priority - &enum iwl_scan_priority 1116 1112 * @scan_params: scan parameters ··· 1134 1130 } __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_17 - 14 */ 1135 1131 1136 1132 /** 1137 - * struct iwl_umac_scan_abort 1133 + * struct iwl_umac_scan_abort - scan abort command 1138 1134 * @uid: scan id, &enum iwl_umac_scan_uid_offsets 1139 1135 * @flags: reserved 1140 1136 */ ··· 1144 1140 } __packed; /* SCAN_ABORT_CMD_UMAC_API_S_VER_1 */ 1145 1141 1146 1142 /** 1147 - * enum iwl_umac_scan_abort_status 1143 + * enum iwl_umac_scan_abort_status - scan abort status 1148 1144 * 1149 1145 * @IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS: scan was successfully aborted 1150 1146 * @IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS: scan abort is in progress ··· 1157 1153 }; 1158 1154 1159 1155 /** 1160 - * struct iwl_umac_scan_complete 1156 + * struct iwl_umac_scan_complete - scan complete notification 1161 1157 * @uid: scan id, &enum iwl_umac_scan_uid_offsets 1162 1158 * @last_schedule: last scheduling line 1163 1159 * @last_iter: last scan iteration number
+3 -3
drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2021, 2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2021, 2023, 2025 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 6 */ ··· 428 428 } __packed; /* REMOVE_STA_CMD_API_S_VER_2 */ 429 429 430 430 /** 431 - * struct iwl_mvm_mgmt_mcast_key_cmd_v1 431 + * struct iwl_mvm_mgmt_mcast_key_cmd_v1 - IGTK command 432 432 * ( MGMT_MCAST_KEY = 0x1f ) 433 433 * @ctrl_flags: &enum iwl_sta_key_flag 434 434 * @igtk: IGTK key material ··· 449 449 } __packed; /* SEC_MGMT_MULTICAST_KEY_CMD_API_S_VER_1 */ 450 450 451 451 /** 452 - * struct iwl_mvm_mgmt_mcast_key_cmd 452 + * struct iwl_mvm_mgmt_mcast_key_cmd - IGTK command 453 453 * ( MGMT_MCAST_KEY = 0x1f ) 454 454 * @ctrl_flags: &enum iwl_sta_key_flag 455 455 * @igtk: IGTK master key
+20 -19
drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
··· 26 26 } __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */ 27 27 28 28 /** 29 - * struct mvm_statistics_rx_non_phy 29 + * struct mvm_statistics_rx_non_phy - non-PHY RX statistics 30 30 * @bogus_cts: CTS received when not expecting CTS 31 31 * @bogus_ack: ACK received when not expecting ACK 32 32 * @non_channel_beacons: beacons with our bss id but not on our serving channel ··· 456 456 } __packed; /* STATISTICS_FW_CMD_API_S_VER_1 */ 457 457 458 458 /** 459 - * enum iwl_fw_statistics_type 459 + * enum iwl_fw_statistics_type - statistics type 460 460 * 461 461 * @FW_STATISTICS_OPERATIONAL: operational statistics 462 462 * @FW_STATISTICS_PHY: phy statistics ··· 478 478 479 479 #define IWL_STATISTICS_TYPE_MSK 0x7f 480 480 /** 481 - * struct iwl_statistics_ntfy_hdr 481 + * struct iwl_statistics_ntfy_hdr - statistics notification header 482 482 * 483 483 * @type: struct type 484 484 * @version: version of the struct ··· 491 491 }; /* STATISTICS_NTFY_HDR_API_S_VER_1 */ 492 492 493 493 /** 494 - * struct iwl_stats_ntfy_per_link 494 + * struct iwl_stats_ntfy_per_link - per-link statistics 495 495 * 496 496 * @beacon_filter_average_energy: Average energy [-dBm] of the 2 497 497 * antennas. ··· 514 514 } __packed; /* STATISTICS_NTFY_PER_LINK_API_S_VER_1 */ 515 515 516 516 /** 517 - * struct iwl_stats_ntfy_part1_per_link 517 + * struct iwl_stats_ntfy_part1_per_link - part1 per link statistics 518 518 * 519 519 * @rx_time: rx time 520 520 * @tx_time: tx time ··· 533 533 } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_PER_LINK_API_S_VER_1 */ 534 534 535 535 /** 536 - * struct iwl_stats_ntfy_per_mac 536 + * struct iwl_stats_ntfy_per_mac - per MAC statistics 537 537 * 538 538 * @beacon_filter_average_energy: Average energy [-dBm] of the 2 539 539 * antennas. ··· 556 556 } __packed; /* STATISTICS_NTFY_PER_MAC_API_S_VER_1 */ 557 557 558 558 #define IWL_STATS_MAX_BW_INDEX 5 559 - /** struct iwl_stats_ntfy_per_phy 559 + /** 560 + * struct iwl_stats_ntfy_per_phy - per PHY statistics 560 561 * @channel_load: channel load 561 562 * @channel_load_by_us: device contribution to MCLM 562 563 * @channel_load_not_by_us: other devices' contribution to MCLM ··· 589 588 #define IWL_STATS_UNKNOWN_CHANNEL_LOAD 0xffffffff 590 589 591 590 /** 592 - * struct iwl_stats_ntfy_per_sta 591 + * struct iwl_stats_ntfy_per_sta - per STA statistics 593 592 * 594 593 * @average_energy: in fact it is minus the energy.. 595 594 */ ··· 601 600 #define IWL_STATS_MAX_FW_LINKS (IWL_FW_MAX_LINK_ID + 1) 602 601 603 602 /** 604 - * struct iwl_system_statistics_notif_oper 603 + * struct iwl_system_statistics_notif_oper - statistics notification 605 604 * 606 605 * @time_stamp: time when the notification is sent from firmware 607 606 * @per_link: per link statistics, &struct iwl_stats_ntfy_per_link ··· 616 615 } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */ 617 616 618 617 /** 619 - * struct iwl_system_statistics_part1_notif_oper 618 + * struct iwl_system_statistics_part1_notif_oper - part1 stats notification 620 619 * 621 620 * @time_stamp: time when the notification is sent from firmware 622 621 * @per_link: per link statistics &struct iwl_stats_ntfy_part1_per_link ··· 629 628 } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_API_S_VER_4 */ 630 629 631 630 /** 632 - * struct iwl_system_statistics_end_notif 631 + * struct iwl_system_statistics_end_notif - statistics end notification 633 632 * 634 633 * @time_stamp: time when the notification is sent from firmware 635 634 */ ··· 638 637 } __packed; /* STATISTICS_FW_NTFY_END_API_S_VER_1 */ 639 638 640 639 /** 641 - * struct iwl_statistics_operational_ntfy 640 + * struct iwl_statistics_operational_ntfy - operational stats notification 642 641 * 643 642 * @hdr: general statistics header 644 643 * @flags: bitmap of possible notification structures ··· 663 662 } __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_15 */ 664 663 665 664 /** 666 - * struct iwl_statistics_operational_ntfy_ver_14 665 + * struct iwl_statistics_operational_ntfy_ver_14 - operational stats notification 667 666 * 668 667 * @hdr: general statistics header 669 668 * @flags: bitmap of possible notification structures ··· 708 707 } __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_14 */ 709 708 710 709 /** 711 - * struct iwl_statistics_phy_ntfy 710 + * struct iwl_statistics_phy_ntfy - PHY statistics notification 712 711 * 713 712 * @hdr: general statistics header 714 713 * RX PHY related statistics ··· 809 808 } __packed; /* STATISTICS_PHY_NTFY_API_S_VER_1 */ 810 809 811 810 /** 812 - * struct iwl_statistics_mac_ntfy 811 + * struct iwl_statistics_mac_ntfy - MAC statistics notification 813 812 * 814 813 * @hdr: general statistics header 815 814 * @bcast_filter_passed_per_mac: bcast filter passed per mac ··· 828 827 } __packed; /* STATISTICS_MAC_NTFY_API_S_VER_1 */ 829 828 830 829 /** 831 - * struct iwl_statistics_rx_ntfy 830 + * struct iwl_statistics_rx_ntfy - RX statistics notification 832 831 * 833 832 * @hdr: general statistics header 834 833 * @rx_agg_mpdu_cnt: aggregation frame count (number of ··· 868 867 } __packed; /* STATISTICS_RX_NTFY_API_S_VER_1 */ 869 868 870 869 /** 871 - * struct iwl_statistics_tx_ntfy 870 + * struct iwl_statistics_tx_ntfy - TX statistics notification 872 871 * 873 872 * @hdr: general statistics header 874 873 * @cts_timeout: timeout when waiting for CTS ··· 977 976 } __packed; /* STATISTICS_TX_NTFY_API_S_VER_1 */ 978 977 979 978 /** 980 - * struct iwl_statistics_duration_ntfy 979 + * struct iwl_statistics_duration_ntfy - burst/duration statistics 981 980 * 982 981 * @hdr: general statistics header 983 982 * @cont_burst_chk_cnt: number of times continuation or ··· 996 995 } __packed; /* STATISTICS_DURATION_NTFY_API_S_VER_1 */ 997 996 998 997 /** 999 - * struct iwl_statistics_he_ntfy 998 + * struct iwl_statistics_he_ntfy - HE statistics 1000 999 * 1001 1000 * @hdr: general statistics header 1002 1001 * received HE frames
+1 -1
drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
··· 963 963 } __packed; /* SCD_QUEUE_CFG_CMD_API_S_VER_1 */ 964 964 965 965 /** 966 - * struct iwl_scd_txq_cfg_rsp 966 + * struct iwl_scd_txq_cfg_rsp - scheduler TXQ configuration response 967 967 * @token: taken from the command 968 968 * @sta_id: station id from the command 969 969 * @tid: tid from the command
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
··· 266 266 } __packed; 267 267 268 268 /** 269 - * struct iwl_fw_ini_dump_entry 269 + * struct iwl_fw_ini_dump_entry - dump entry descriptor 270 270 * @list: list of dump entries 271 271 * @size: size of the data 272 272 * @data: entry data ··· 305 305 * @dram_base_addr: base address of dram monitor range 306 306 * @page_num: page number of memory range 307 307 * @fifo_hdr: fifo header of memory range 308 - * @fw_pkt: FW packet header of memory range 308 + * @fw_pkt_hdr: FW packet header of memory range 309 309 * @data: the actual memory 310 310 */ 311 311 struct iwl_fw_ini_error_dump_range {
+55 -19
drivers/net/wireless/intel/iwlwifi/fw/file.h
··· 222 222 * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement. 223 223 * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2 224 224 * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL: support for adaptive dwell in scanning 225 + * @IWL_UCODE_TLV_API_OCE: support for OCE 226 + * @IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE: new beacon template 225 227 * @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used 228 + * @IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL: WoWLAN key material support 226 229 * @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field 227 230 * indicating low latency direction. 228 231 * @IWL_UCODE_TLV_API_DEPRECATE_TTAK: RX status flag TTAK ok (bit 7) is ··· 248 245 * SCAN_OFFLOAD_PROFILES_QUERY_RSP_S. 249 246 * @IWL_UCODE_TLV_API_MBSSID_HE: This ucode supports v2 of 250 247 * STA_CONTEXT_DOT11AX_API_S 248 + * @IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE: WoWLAN TCP-SYN wake support 251 249 * @IWL_UCODE_TLV_API_FTM_RTT_ACCURACY: version 7 of the range response API 252 250 * is supported by FW, this indicates the RTT confidence value 253 251 * @IWL_UCODE_TLV_API_SAR_TABLE_VER: This ucode supports different sar ··· 257 253 * SCAN_CONFIG_DB_CMD_API_S. 258 254 * @IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP: support for setting adaptive dwell 259 255 * number of APs in the 5 GHz band 256 + * @IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER: extended channel config in scan 260 257 * @IWL_UCODE_TLV_API_BAND_IN_RX_DATA: FW reports band number in RX notification 261 258 * @IWL_UCODE_TLV_API_NO_HOST_DISABLE_TX: Firmware offloaded the station disable tx 262 259 * logic. ··· 357 352 * @IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT: the firmware supports setting 358 353 * stabilization latency for SoCs. 359 354 * @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification 355 + * @IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT: binding CDB support 356 + * @IWL_UCODE_TLV_CAPA_CDB_SUPPORT: CDB support 357 + * @IWL_UCODE_TLV_CAPA_D0I3_END_FIRST: D0I3 end command comes first 360 358 * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm 361 359 * @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related 362 360 * @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2 363 - * IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command 361 + * @IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command 364 362 * @IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS: firmware supports ultra high band 365 363 * (6 GHz). 366 364 * @IWL_UCODE_TLV_CAPA_CS_MODIFY: firmware supports modify action CSA command 365 + * @IWL_UCODE_TLV_CAPA_SET_LTR_GEN2: LTR gen2 support 366 + * @IWL_UCODE_TLV_CAPA_TAS_CFG: TAS configuration support 367 + * @IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD: session protection command 368 + * @IWL_UCODE_TLV_CAPA_SET_PPAG: PPAG support 367 369 * @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement 368 370 * @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts 369 371 * @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT 372 + * @IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT: MQ RX support 370 373 * @IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD: the firmware supports CSA 371 374 * countdown offloading. Beacon notifications are not sent to the host. 372 375 * The fw also offloads TBTT alignment. ··· 396 383 * command size (command version 4) that supports toggling ACK TX 397 384 * power reduction. 398 385 * @IWL_UCODE_TLV_CAPA_D3_DEBUG: supports debug recording during D3 386 + * @IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT: LED command support 399 387 * @IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT: MCC response support 11ax 400 388 * capability. 401 389 * @IWL_UCODE_TLV_CAPA_CSI_REPORTING: firmware is capable of being configured 402 390 * to report the CSI information with (certain) RX frames 391 + * @IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP: suspend/resume command 392 + * @IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP: support for DBGC 393 + * buffer allocation command 403 394 * @IWL_UCODE_TLV_CAPA_FTM_CALIBRATED: has FTM calibrated and thus supports both 404 395 * initiator and responder 405 396 * @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA: supports (de)activating UNII-4 406 397 * for US/CA/WW from BIOS 398 + * @IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT: supports PSC channels 399 + * @IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT: BIGTK support 407 400 * @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames 408 401 * @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in 409 402 * reset flow 410 403 * @IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN: Support for passive scan on 6GHz PSC 411 404 * channels even when these are not enabled. 405 + * @IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN: hidden SSID 6 GHz scan support 406 + * @IWL_UCODE_TLV_CAPA_BROADCAST_TWT: broadcast TWT support 407 + * @IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO: support for BT-coex high 408 + * priority for 802.1X/4-way-HS 409 + * @IWL_UCODE_TLV_CAPA_BAID_ML_SUPPORT: multi-link BAID support 410 + * @IWL_UCODE_TLV_CAPA_SYNCED_TIME: synced time command support 411 + * @IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM: time sync support 412 + * @IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT: BIGTK TX support 413 + * @IWL_UCODE_TLV_CAPA_MLD_API_SUPPORT: MLD API support 414 + * @IWL_UCODE_TLV_CAPA_SCAN_DONT_TOGGLE_ANT: fixed antenna scan support 415 + * @IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT: PPAG China BIOS support 416 + * @IWL_UCODE_TLV_CAPA_OFFLOAD_BTM_SUPPORT: BTM protocol offload support 417 + * @IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT: STA command MFP support 418 + * @IWL_UCODE_TLV_CAPA_SNIFF_VALIDATE_SUPPORT: sniffer validate bits support 419 + * @IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT: China 2022 regulator support 412 420 * @IWL_UCODE_TLV_CAPA_DUMP_COMPLETE_SUPPORT: Support for indicating dump collection 413 421 * complete to FW. 414 422 * @IWL_UCODE_TLV_CAPA_SPP_AMSDU_SUPPORT: Support SPP (signaling and payload 415 423 * protected) A-MSDU. 424 + * @IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT: support for DBGC fragmented 425 + * DRAM buffers 416 426 * @IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT: Support secure LTF measurement. 417 427 * @IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS: Support monitor mode on otherwise 418 428 * passive channels ··· 443 407 * for CA from BIOS. 444 408 * @IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT: supports %TAS_UHB_ALLOWED_CANADA 445 409 * @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support 410 + * @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed 411 + * during assert handling even if the dump isn't split 446 412 * @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of 447 413 * handling raw DSM table data. 448 414 * ··· 525 487 526 488 /* set 3 */ 527 489 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA = (__force iwl_ucode_tlv_capa_t)96, 528 - 529 - /* 530 - * @IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT: supports PSC channels 531 - */ 532 490 IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)98, 533 - 534 491 IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100, 535 492 IWL_UCODE_TLV_CAPA_SPP_AMSDU_SUPPORT = (__force iwl_ucode_tlv_capa_t)103, 536 493 IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104, ··· 547 514 IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT = (__force iwl_ucode_tlv_capa_t)125, 548 515 549 516 /* set 4 */ 550 - /** 551 - * @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed 552 - * during assert handling even if the dump isn't split 553 - */ 554 - IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0), 517 + 518 + IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0), 555 519 IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 1), 556 520 NUM_IWL_UCODE_TLV_CAPA 557 521 /* ··· 882 852 * @start_assoc_denied: number of denied association to start recording 883 853 * @start_assoc_timeout: number of association timeout to start recording 884 854 * @start_connection_loss: number of connection loss to start recording 855 + * @reserved: reserved 856 + * @reserved2: reserved 885 857 */ 886 858 struct iwl_fw_dbg_trigger_mlme { 887 859 u8 stop_auth_denied; ··· 917 885 * @p2p_device: timeout for the queues of a P2P device in ms 918 886 * @ibss: timeout for the queues of an IBSS in ms 919 887 * @tdls: timeout for the queues of a TDLS station in ms 888 + * @reserved: reserved 920 889 */ 921 890 struct iwl_fw_dbg_trigger_txq_timer { 922 891 __le32 command_queue; ··· 933 900 934 901 /** 935 902 * struct iwl_fw_dbg_trigger_time_event - configures a time event trigger 936 - * time_Events: a list of tuples <id, action_bitmap>. The driver will issue a 903 + * @time_events: a list of tuples <id, action_bitmap>. The driver will issue a 937 904 * trigger each time a time event notification that relates to time event 938 905 * id with one of the actions in the bitmap is received and 939 906 * BIT(notif->status) is set in status_bitmap. ··· 949 916 950 917 /** 951 918 * struct iwl_fw_dbg_trigger_ba - configures BlockAck related trigger 952 - * rx_ba_start: tid bitmap to configure on what tid the trigger should occur 919 + * @rx_ba_start: tid bitmap to configure on what tid the trigger should occur 953 920 * when an Rx BlockAck session is started. 954 - * rx_ba_stop: tid bitmap to configure on what tid the trigger should occur 921 + * @rx_ba_stop: tid bitmap to configure on what tid the trigger should occur 955 922 * when an Rx BlockAck session is stopped. 956 - * tx_ba_start: tid bitmap to configure on what tid the trigger should occur 923 + * @tx_ba_start: tid bitmap to configure on what tid the trigger should occur 957 924 * when a Tx BlockAck session is started. 958 - * tx_ba_stop: tid bitmap to configure on what tid the trigger should occur 925 + * @tx_ba_stop: tid bitmap to configure on what tid the trigger should occur 959 926 * when a Tx BlockAck session is stopped. 960 - * rx_bar: tid bitmap to configure on what tid the trigger should occur 927 + * @rx_bar: tid bitmap to configure on what tid the trigger should occur 961 928 * when a BAR is received (for a Tx BlockAck session). 962 - * tx_bar: tid bitmap to configure on what tid the trigger should occur 929 + * @tx_bar: tid bitmap to configure on what tid the trigger should occur 963 930 * when a BAR is send (for an Rx BlocAck session). 964 - * frame_timeout: tid bitmap to configure on what tid the trigger should occur 931 + * @frame_timeout: tid bitmap to configure on what tid the trigger should occur 965 932 * when a frame times out in the reordering buffer. 966 933 */ 967 934 struct iwl_fw_dbg_trigger_ba { ··· 979 946 * @action_bitmap: the TDLS action to trigger the collection upon 980 947 * @peer_mode: trigger on specific peer or all 981 948 * @peer: the TDLS peer to trigger the collection on 949 + * @reserved: reserved 982 950 */ 983 951 struct iwl_fw_dbg_trigger_tdls { 984 952 u8 action_bitmap; ··· 992 958 * struct iwl_fw_dbg_trigger_tx_status - configures trigger for tx response 993 959 * status. 994 960 * @statuses: the list of statuses to trigger the collection on 961 + * @reserved: reserved 995 962 */ 996 963 struct iwl_fw_dbg_trigger_tx_status { 997 964 struct tx_status { ··· 1006 971 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. 1007 972 * @id: conf id 1008 973 * @usniffer: should the uSniffer image be used 974 + * @reserved: reserved 1009 975 * @num_of_hcmds: how many HCMDs to send are present here 1010 976 * @hcmd: a variable length host command to be sent to apply the configuration. 1011 977 * If there is more than one HCMD to send, they will appear one after the
+8 -4
drivers/net/wireless/intel/iwlwifi/fw/img.h
··· 14 14 #include "error-dump.h" 15 15 16 16 /** 17 - * enum iwl_ucode_type 18 - * 19 - * The type of ucode. 17 + * enum iwl_ucode_type - type of ucode 20 18 * 21 19 * @IWL_UCODE_REGULAR: Normal runtime ucode 22 20 * @IWL_UCODE_INIT: Initial ucode 23 21 * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode 24 22 * @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image 23 + * @IWL_UCODE_TYPE_MAX: (internal value) 25 24 */ 26 25 enum iwl_ucode_type { 27 26 IWL_UCODE_REGULAR, ··· 121 122 #define FW_ADDR_CACHE_CONTROL 0xC0000000UL 122 123 123 124 /** 124 - * struct iwl_fw_paging 125 + * struct iwl_fw_paging - FW paging descriptor 125 126 * @fw_paging_phys: page phy pointer 126 127 * @fw_paging_block: pointer to the allocated block 127 128 * @fw_paging_size: page size ··· 196 197 * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image 197 198 * @pnvm_data: PNVM data embedded in the .ucode file, if any 198 199 * @pnvm_size: size of the embedded PNVM data 200 + * @dbg: debug data, see &struct iwl_fw_dbg 201 + * @default_calib: default calibration data 202 + * @phy_config: PHY configuration flags 203 + * @valid_rx_ant: valid RX antenna bitmap 204 + * @valid_tx_ant: valid TX antenna bitmap 199 205 */ 200 206 struct iwl_fw { 201 207 u32 ucode_ver;
+4 -22
drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
··· 543 543 544 544 switch (cmd_ver) { 545 545 case 12: 546 - case 11: 547 546 cmd_size = sizeof(struct iwl_lari_config_change_cmd); 548 547 break; 549 - case 10: 550 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v10); 551 - break; 552 - case 9: 553 548 case 8: 554 - case 7: 555 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7); 549 + cmd_size = sizeof(struct iwl_lari_config_change_cmd_v8); 556 550 break; 557 551 case 6: 558 552 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6); 559 - break; 560 - case 5: 561 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5); 562 - break; 563 - case 4: 564 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4); 565 - break; 566 - case 3: 567 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3); 568 - break; 569 - case 2: 570 - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2); 571 553 break; 572 554 default: 573 555 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1); ··· 591 609 if (!has_raw_dsm_capa) 592 610 value &= DSM_UNII4_ALLOW_BITMAP; 593 611 594 - /* Since version 9, bits 4 and 5 are supported 612 + /* Since version 12, bits 4 and 5 are supported 595 613 * regardless of this capability, By pass this masking 596 614 * if firmware has capability of accepting raw DSM table. 597 615 */ 598 - if (!has_raw_dsm_capa && cmd_ver < 9 && 616 + if (!has_raw_dsm_capa && cmd_ver < 12 && 599 617 !fw_has_capa(&fwrt->fw->ucode_capa, 600 618 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA)) 601 619 value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | ··· 619 637 if (!has_raw_dsm_capa && cmd_ver < 12 && 620 638 !fw_has_capa(&fwrt->fw->ucode_capa, 621 639 IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA)) 622 - value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11; 640 + value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V8; 623 641 624 642 cmd->chan_state_active_bitmap = cpu_to_le32(value); 625 643 }
+21 -1
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
··· 45 45 * struct iwl_fwrt_dump_data - dump data 46 46 * @trig: trigger the worker was scheduled upon 47 47 * @fw_pkt: packet received from FW 48 + * @desc: dump descriptor 49 + * @monitor_only: only dump for monitor 48 50 * 49 51 * Note that the decision which part of the union is used 50 52 * is based on iwl_trans_dbg_ini_valid(): the 'trig' part ··· 70 68 * struct iwl_fwrt_wk_data - dump worker data struct 71 69 * @idx: index of the worker 72 70 * @wk: worker 71 + * @dump_data: dump data 73 72 */ 74 73 struct iwl_fwrt_wk_data { 75 74 u8 idx; ··· 94 91 95 92 /** 96 93 * struct iwl_fw_runtime - runtime data for firmware 94 + * @trans: transport pointer 97 95 * @fw: firmware image 98 - * @cfg: NIC configuration 99 96 * @dev: device pointer 100 97 * @ops: user ops 101 98 * @ops_ctx: user ops context ··· 120 117 * zero (default initialization) means it hasn't been read yet, 121 118 * and BIT(0) is set when it has since function 0 also has this 122 119 * bitmap and is always supported 120 + * @geo_enabled: WGDS table is present 121 + * @geo_num_profiles: number of geo profiles 122 + * @geo_rev: geo profiles table revision 123 + * @ppag_chains: PPAG table data 124 + * @ppag_flags: PPAG flags 125 + * @reduced_power_flags: reduced power flags 126 + * @sanitize_ctx: context for dump sanitizer 127 + * @sanitize_ops: dump sanitizer ops 128 + * @sar_chain_a_profile: SAR chain A profile 129 + * @sar_chain_b_profile: SAR chain B profile 130 + * @sgom_enabled: SGOM enabled 131 + * @sgom_table: SGOM table 132 + * @timestamp: timestamp marker data 133 + * @timestamp.wk: timestamp marking worker 134 + * @timestamp.seq: timestamp marking sequence 135 + * @timestamp.delay: timestamp marking worker delay 136 + * @tpc_enabled: TPC enabled 123 137 */ 124 138 struct iwl_fw_runtime { 125 139 struct iwl_trans *trans;
+7 -4
drivers/net/wireless/intel/iwlwifi/iwl-config.h
··· 170 170 * for aggregation 171 171 * @min_txq_size: minimum number of slots required in a TX queue 172 172 * @gp2_reg_addr: GP2 (timer) register address 173 - * @min_umac_error_event_table: minimum SMEM location of UMAC error table 174 173 * @mon_dbgi_regs: monitor DBGI registers 175 174 * @mon_dram_regs: monitor DRAM registers 176 175 * @mon_smem_regs: monitor SMEM registers ··· 202 203 netdev_features_t features; 203 204 u32 smem_offset; 204 205 u32 smem_len; 205 - u32 min_umac_error_event_table; 206 206 u32 d3_debug_data_base_addr; 207 207 u32 d3_debug_data_length; 208 208 u32 min_txq_size; ··· 383 385 #define IWL_NUM_RBDS_EHT (512 * 8) 384 386 385 387 /** 386 - * struct iwl_rf_cfg 388 + * struct iwl_rf_cfg - RF/CRF configuration data 387 389 * @fw_name_pre: Firmware filename prefix. The api version and extension 388 390 * (.ucode) will be added to filename before loading from disk. The 389 391 * filename is constructed as <fw_name_pre>-<api>.ucode. ··· 416 418 * @vht_mu_mimo_supported: VHT MU-MIMO support 417 419 * @nvm_type: see &enum iwl_nvm_type 418 420 * @uhb_supported: ultra high band channels supported 421 + * @eht_supported: EHT supported 419 422 * @num_rbds: number of receive buffer descriptors to use 420 423 * (only used for multi-queue capable devices) 421 424 * ··· 449 450 host_interrupt_operation_mode:1, 450 451 lp_xtal_workaround:1, 451 452 vht_mu_mimo_supported:1, 452 - uhb_supported:1; 453 + uhb_supported:1, 454 + eht_supported:1; 453 455 u8 valid_tx_ant; 454 456 u8 valid_rx_ant; 455 457 u8 non_shared_ant; ··· 686 686 extern const char iwl_killer_bn1850w2_name[]; 687 687 extern const char iwl_killer_bn1850i_name[]; 688 688 extern const char iwl_bn201_name[]; 689 + extern const char iwl_bn203_name[]; 689 690 extern const char iwl_be221_name[]; 690 691 extern const char iwl_be223_name[]; 692 + extern const char iwl_ax221_name[]; 691 693 #if IS_ENABLED(CONFIG_IWLDVM) 692 694 extern const struct iwl_rf_cfg iwl5300_agn_cfg; 693 695 extern const struct iwl_rf_cfg iwl5350_agn_cfg; ··· 745 743 extern const struct iwl_rf_cfg iwl_rf_fm_160mhz; 746 744 #define iwl_rf_wh iwl_rf_fm 747 745 #define iwl_rf_wh_160mhz iwl_rf_fm_160mhz 746 + extern const struct iwl_rf_cfg iwl_rf_wh_non_eht; 748 747 #define iwl_rf_pe iwl_rf_fm 749 748 #endif /* CONFIG_IWLMLD */ 750 749
+2 -2
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2018-2023 Intel Corporation 3 + * Copyright (C) 2018-2023, 2025 Intel Corporation 4 4 */ 5 5 #ifndef __iwl_dbg_tlv_h__ 6 6 #define __iwl_dbg_tlv_h__ ··· 32 32 }; 33 33 34 34 /** 35 - * struct iwl_dbg_tlv_time_point_data 35 + * struct iwl_dbg_tlv_time_point_data - debug time point data 36 36 * @trig_list: list of triggers 37 37 * @active_trig_list: list of active triggers 38 38 * @hcmd_list: list of host commands
+9 -20
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
··· 177 177 return 'a' + step; 178 178 } 179 179 180 - static bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans) 180 + bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans) 181 181 { 182 - return CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM; 182 + return trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ && 183 + CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM; 183 184 } 184 185 185 186 const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf) ··· 348 347 349 348 if (first) 350 349 drv->fw_index = ucode_api_max; 351 - else if (drv->fw_index == ENCODE_CORE_AS_API(99)) 352 - drv->fw_index = 101; /* last API-scheme number below core 99 */ 350 + else if (drv->fw_index == ENCODE_CORE_AS_API(100)) 351 + drv->fw_index = 102; /* last API-scheme number below core 100 */ 353 352 else 354 353 drv->fw_index--; 355 354 ··· 428 427 size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; 429 428 struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv; 430 429 size_t n_mem_tlv; 431 - u32 major; 432 430 }; 433 431 434 432 static void alloc_sec_data(struct iwl_firmware_pieces *pieces, ··· 1069 1069 break; 1070 1070 case IWL_UCODE_TLV_FW_VERSION: { 1071 1071 const __le32 *ptr = (const void *)tlv_data; 1072 - u32 minor; 1072 + u32 major, minor; 1073 1073 u8 local_comp; 1074 1074 1075 1075 if (tlv_len != sizeof(u32) * 3) 1076 1076 goto invalid_tlv_len; 1077 1077 1078 - pieces->major = le32_to_cpup(ptr++); 1078 + major = le32_to_cpup(ptr++); 1079 1079 minor = le32_to_cpup(ptr++); 1080 1080 local_comp = le32_to_cpup(ptr); 1081 1081 1082 1082 snprintf(drv->fw.fw_version, 1083 1083 sizeof(drv->fw.fw_version), 1084 - "%u.%08x.%u %s", pieces->major, minor, 1084 + "%u.%08x.%u %s", major, minor, 1085 1085 local_comp, iwl_reduced_fw_name(drv)); 1086 1086 break; 1087 1087 } ··· 1589 1589 } 1590 1590 } 1591 1591 1592 - #define IWL_MLD_SUPPORTED_FW_VERSION 97 1593 - 1594 1592 /* 1595 1593 * iwl_req_fw_callback - callback when firmware was loaded 1596 1594 * ··· 1857 1859 } 1858 1860 1859 1861 #if IS_ENABLED(CONFIG_IWLMLD) 1860 - if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION && 1861 - iwl_drv_is_wifi7_supported(drv->trans)) 1862 + if (iwl_drv_is_wifi7_supported(drv->trans)) 1862 1863 op = &iwlwifi_opmode_table[MLD_OP_MODE]; 1863 - #else 1864 - if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION && 1865 - iwl_drv_is_wifi7_supported(drv->trans)) { 1866 - IWL_ERR(drv, 1867 - "IWLMLD needs to be compiled to support this firmware\n"); 1868 - mutex_unlock(&iwlwifi_opmode_table_mtx); 1869 - goto out_unbind; 1870 - } 1871 1864 #endif 1872 1865 1873 1866 IWL_INFO(drv, "loaded firmware version %s op_mode %s\n",
+8 -1
drivers/net/wireless/intel/iwlwifi/iwl-drv.h
··· 62 62 * starts the driver: fetches the firmware. This should be called by bus 63 63 * specific system flows implementations. For example, the bus specific probe 64 64 * function should do bus related operations only, and then call to this 65 - * function. It returns the driver object or %NULL if an error occurred. 65 + * function. 66 + * Return: the driver object or %NULL if an error occurred. 66 67 */ 67 68 struct iwl_drv *iwl_drv_start(struct iwl_trans *trans); 68 69 ··· 77 76 * call this function and then do the bus related operations only. 78 77 */ 79 78 void iwl_drv_stop(struct iwl_drv *drv); 79 + 80 + /* 81 + * iwl_drv_is_wifi7_supported - returns if wifi7 is supported 82 + * If yes, iwlmld needs to be used to drive the device. 83 + */ 84 + bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans); 80 85 81 86 /* 82 87 * exported symbol management
+2 -2
drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014, 2018-2022, 2024 Intel Corporation 3 + * Copyright (C) 2005-2014, 2018-2022, 2024-2025 Intel Corporation 4 4 */ 5 5 #ifndef __iwl_modparams_h__ 6 6 #define __iwl_modparams_h__ ··· 42 42 }; 43 43 44 44 /** 45 - * struct iwl_mod_params 45 + * struct iwl_mod_params - module parameters for iwlwifi 46 46 * 47 47 * Holds the module parameters 48 48 *
+1 -1
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 2080 2080 !!(mac_flags & NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED); 2081 2081 nvm->sku_cap_mimo_disabled = 2082 2082 !!(mac_flags & NVM_MAC_SKU_FLAGS_MIMO_DISABLED); 2083 - if (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM) 2083 + if (trans->cfg->eht_supported) 2084 2084 nvm->sku_cap_11be_enable = true; 2085 2085 2086 2086 /* Initialize PHY sku data */
+12 -5
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
··· 115 115 * iwl_parse_nvm_mcc_info - parse MCC (mobile country code) info coming from FW 116 116 * 117 117 * This function parses the regulatory channel data received as a 118 - * MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain, 119 - * to be fed into the regulatory core. In case the geo_info is set handle 120 - * accordingly. An ERR_PTR is returned on error. 121 - * If not given to the regulatory core, the user is responsible for freeing 122 - * the regdomain returned here with kfree. 118 + * MCC_UPDATE_CMD command. 119 + * 120 + * Return: a newly allocation regulatory domain, to be given to the regulatory 121 + * core. In case the geo_info is set handle accordingly. An ERR_PTR is 122 + * returned on error. If not given to the regulatory core, the user is 123 + * responsible for freeing the regdomain returned here with kfree(). 123 124 * 124 125 * @trans: the transport 125 126 * @num_of_ch: the number of channels ··· 141 140 * This struct holds an NVM section read from the NIC using NVM_ACCESS_CMD, 142 141 * and saved for later use by the driver. Not all NVM sections are saved 143 142 * this way, only the needed ones. 143 + * @length: length of the section 144 + * @data: section data 144 145 */ 145 146 struct iwl_nvm_section { 146 147 u16 length; ··· 151 148 152 149 /** 153 150 * iwl_read_external_nvm - Reads external NVM from a file into nvm_sections 151 + * @trans: the transport 152 + * @nvm_file_name: the filename to request 153 + * @nvm_sections: sections data to fill 154 + * Return: 0 on success or an error code 154 155 */ 155 156 int iwl_read_external_nvm(struct iwl_trans *trans, 156 157 const char *nvm_file_name,
+1
drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
··· 185 185 /** 186 186 * struct iwl_op_mode - operational mode 187 187 * @ops: pointer to its own ops 188 + * @op_mode_specific: per-opmode data 188 189 * 189 190 * This holds an implementation of the mac80211 / fw API. 190 191 */
+3 -3
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
··· 121 121 #define DEF_CMD_PAYLOAD_SIZE 320 122 122 123 123 /** 124 - * struct iwl_device_cmd 124 + * struct iwl_device_cmd - device command structure 125 125 * 126 126 * For allocation of the command and tx queues, this establishes the overall 127 127 * size of the largest command we send to uCode, except for commands that ··· 516 516 */ 517 517 518 518 /** 519 - * enum iwl_ini_cfg_state 519 + * enum iwl_ini_cfg_state - debug config state 520 520 * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given 521 521 * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded 522 522 * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs ··· 532 532 #define IWL_TRANS_NMI_TIMEOUT (HZ / 4) 533 533 534 534 /** 535 - * struct iwl_dram_data 535 + * struct iwl_dram_data - DRAM data descriptor 536 536 * @physical: page phy pointer 537 537 * @block: pointer to the allocated block/page 538 538 * @size: size of the block/page
+2
drivers/net/wireless/intel/iwlwifi/mld/constants.h
··· 75 75 #define IWL_MLD_FTM_RESP_LMR_FEEDBACK_SUPPORT true 76 76 #define IWL_MLD_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 7 77 77 #define IWL_MLD_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000 78 + #define IWL_MLD_STA_EXT_CAPA_SIZE 9 79 + #define IWL_MLD_EXT_CAPA_NUM_IFTYPES 1 78 80 79 81 #endif /* __iwl_mld_constants_h__ */
+4
drivers/net/wireless/intel/iwlwifi/mld/d3.c
··· 1794 1794 u32 enabled = 0; 1795 1795 1796 1796 cmd = kzalloc(hcmd.len[0], GFP_KERNEL); 1797 + if (!cmd) { 1798 + IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n"); 1799 + return -ENOMEM; 1800 + } 1797 1801 1798 1802 #if IS_ENABLED(CONFIG_IPV6) 1799 1803 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
+4 -10
drivers/net/wireless/intel/iwlwifi/mld/fw.c
··· 124 124 u16 status; 125 125 126 126 switch (version) { 127 - case 6: 128 127 case 7: 129 - expected_sz = sizeof(struct iwl_alive_ntf_v6); 128 + expected_sz = sizeof(struct iwl_alive_ntf_v7); 130 129 break; 131 130 case 8: 132 131 expected_sz = sizeof(struct iwl_alive_ntf); ··· 167 168 umac_error_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr) & 168 169 ~FW_ADDR_CACHE_CONTROL; 169 170 170 - if (umac_error_table >= trans->mac_cfg->base->min_umac_error_event_table) 171 - iwl_fw_umac_set_alive_err_table(trans, umac_error_table); 172 - else 173 - IWL_ERR(mld, "Not valid error log pointer 0x%08X\n", 174 - umac_error_table); 171 + iwl_fw_umac_set_alive_err_table(trans, umac_error_table); 175 172 176 173 alive_data->valid = status == IWL_ALIVE_STATUS_OK; 177 174 ··· 183 188 le32_to_cpu(umac->umac_major), 184 189 le32_to_cpu(umac->umac_minor)); 185 190 186 - if (version >= 7) 187 - IWL_DEBUG_FW(mld, "FW alive flags 0x%x\n", 188 - le16_to_cpu(palive->flags)); 191 + IWL_DEBUG_FW(mld, "FW alive flags 0x%x\n", 192 + le16_to_cpu(palive->flags)); 189 193 190 194 if (version >= 8) 191 195 IWL_DEBUG_FW(mld, "platform_id 0x%llx\n",
+13
drivers/net/wireless/intel/iwlwifi/mld/iface.c
··· 528 528 529 529 mld_link = &iwl_mld_vif_from_mac80211(vif)->deflink; 530 530 531 + /* len_low should be 2 + n*13 (where n is the number of descriptors. 532 + * 13 is the size of a NoA descriptor). We can have either one or two 533 + * descriptors. 534 + */ 535 + if (IWL_FW_CHECK(mld, notif->noa_active && 536 + notif->noa_attr.len_low != 2 + 537 + sizeof(struct ieee80211_p2p_noa_desc) && 538 + notif->noa_attr.len_low != 2 + 539 + sizeof(struct ieee80211_p2p_noa_desc) * 2, 540 + "Invalid noa_attr.len_low (%d)\n", 541 + notif->noa_attr.len_low)) 542 + return; 543 + 531 544 new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); 532 545 if (!new_data) 533 546 return;
+12 -4
drivers/net/wireless/intel/iwlwifi/mld/link.c
··· 465 465 int ret; 466 466 467 467 if (!link) { 468 - if (is_deflink) 468 + if (is_deflink) { 469 469 link = &mld_vif->deflink; 470 - else 470 + } else { 471 471 link = kzalloc(sizeof(*link), GFP_KERNEL); 472 + if (!link) 473 + return -ENOMEM; 474 + } 472 475 } else { 473 476 WARN_ON(!mld->fw_status.in_hw_restart); 474 477 } ··· 575 572 /* Not in EMLSR and we can't hear the link. 576 573 * Try to switch to a better link. EMLSR case is handled below. 577 574 */ 578 - if (!iwl_mld_emlsr_active(vif)) 575 + if (!iwl_mld_emlsr_active(vif)) { 576 + IWL_DEBUG_EHT(mld, 577 + "missed beacons exceeds threshold. link_id=%u. Try to switch to a better link.\n", 578 + link_id); 579 579 iwl_mld_int_mlo_scan(mld, vif); 580 + } 580 581 } 581 582 582 583 /* no more logic if we're not in EMLSR */ ··· 599 592 return; 600 593 601 594 IWL_DEBUG_EHT(mld, 602 - "missed bcn on the other link (link_id=%u): %u\n", 595 + "missed bcn link_id=%u: %u consecutive=%u, other link_id=%u: %u\n", 596 + link_id, missed_bcon, missed_bcon_since_rx, 603 597 other_link->link_id, scnd_lnk_bcn_lost); 604 598 605 599 /* Exit EMLSR if we lost more than
+70 -33
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
··· 23 23 #include "roc.h" 24 24 #include "mlo.h" 25 25 #include "stats.h" 26 + #include "iwl-nvm-parse.h" 26 27 #include "ftm-initiator.h" 27 28 #include "low_latency.h" 28 29 #include "fw/api/scan.h" ··· 76 75 }, 77 76 }; 78 77 79 - static const u8 if_types_ext_capa_sta[] = { 80 - [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 81 - [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, 82 - [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF | 83 - WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB, 84 - [8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB, 85 - [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT, 78 + static const u8 ext_capa_base[IWL_MLD_STA_EXT_CAPA_SIZE] = { 79 + [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 80 + [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, 81 + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF | 82 + WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB, 83 + [8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB, 86 84 }; 87 85 88 86 #define IWL_MLD_EMLSR_CAPA (IEEE80211_EML_CAP_EMLSR_SUPP | \ ··· 93 93 IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP, \ 94 94 IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME) | \ 95 95 IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT) 96 - 97 - static const struct wiphy_iftype_ext_capab iftypes_ext_capa[] = { 98 - { 99 - .iftype = NL80211_IFTYPE_STATION, 100 - .extended_capabilities = if_types_ext_capa_sta, 101 - .extended_capabilities_mask = if_types_ext_capa_sta, 102 - .extended_capabilities_len = sizeof(if_types_ext_capa_sta), 103 - /* relevant only if EHT is supported */ 104 - .eml_capabilities = IWL_MLD_EMLSR_CAPA, 105 - .mld_capa_and_ops = IWL_MLD_CAPA_OPS, 106 - }, 107 - }; 108 96 109 97 static void iwl_mld_hw_set_addresses(struct iwl_mld *mld) 110 98 { ··· 323 335 if (fw_has_capa(ucode_capa, IWL_UCODE_TLV_CAPA_PROTECTED_TWT)) 324 336 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PROTECTED_TWT); 325 337 326 - wiphy->iftype_ext_capab = NULL; 327 - wiphy->num_iftype_ext_capab = 0; 328 - 329 - if (!iwlwifi_mod_params.disable_11ax) { 330 - wiphy->iftype_ext_capab = iftypes_ext_capa; 331 - wiphy->num_iftype_ext_capab = ARRAY_SIZE(iftypes_ext_capa); 332 - 333 - ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); 334 - ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); 335 - } 336 - 337 338 if (iwlmld_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 338 339 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 339 340 else 340 341 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 342 + 343 + /* We are done for non-HE */ 344 + if (iwlwifi_mod_params.disable_11ax) 345 + return; 346 + 347 + ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); 348 + ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); 349 + 350 + wiphy->iftype_ext_capab = mld->ext_capab; 351 + wiphy->num_iftype_ext_capab = ARRAY_SIZE(mld->ext_capab); 352 + 353 + BUILD_BUG_ON(sizeof(mld->sta_ext_capab) < sizeof(ext_capa_base)); 354 + 355 + memcpy(mld->sta_ext_capab, ext_capa_base, sizeof(ext_capa_base)); 356 + 357 + mld->ext_capab[0].iftype = NL80211_IFTYPE_STATION; 358 + mld->ext_capab[0].extended_capabilities = mld->sta_ext_capab; 359 + mld->ext_capab[0].extended_capabilities_mask = mld->sta_ext_capab; 360 + mld->ext_capab[0].extended_capabilities_len = sizeof(mld->sta_ext_capab); 361 + 362 + if (!mld->nvm_data->sku_cap_11be_enable || 363 + iwlwifi_mod_params.disable_11be) 364 + return; 365 + 366 + mld->ext_capab[0].eml_capabilities = IWL_MLD_EMLSR_CAPA; 367 + mld->ext_capab[0].mld_capa_and_ops = IWL_MLD_CAPA_OPS; 368 + 341 369 } 342 370 343 371 static void iwl_mac_hw_set_misc(struct iwl_mld *mld) ··· 397 393 TLC_MNG_UPDATE_NOTIF, 0) >= 4) + 398 394 (iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP, 399 395 REPLY_RX_MPDU_CMD, 0) >= 6) + 400 - (iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP, 401 - RX_NO_DATA_NOTIF, 0) >= 4) + 402 396 (iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP, TX_CMD, 0) >= 9); 403 397 404 - if (ratecheck != 0 && ratecheck != 5) { 398 + if (ratecheck != 0 && ratecheck != 4) { 405 399 IWL_ERR(mld, "Firmware has inconsistent rates\n"); 406 400 return -EINVAL; 407 401 } ··· 682 680 #endif 683 681 684 682 iwl_mld_rm_vif(mld, vif); 683 + 684 + mld->monitor.phy.valid = false; 685 685 } 686 686 687 687 struct iwl_mld_mc_iter_data { ··· 2595 2591 return NEG_TTLM_RES_ACCEPT; 2596 2592 } 2597 2593 2594 + static int iwl_mld_get_antenna(struct ieee80211_hw *hw, int radio_idx, 2595 + u32 *tx_ant, u32 *rx_ant) 2596 + { 2597 + struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2598 + 2599 + *tx_ant = iwl_mld_get_valid_tx_ant(mld); 2600 + *rx_ant = iwl_mld_get_valid_rx_ant(mld); 2601 + 2602 + return 0; 2603 + } 2604 + 2605 + static int iwl_mld_set_antenna(struct ieee80211_hw *hw, int radio_idx, 2606 + u32 tx_ant, u32 rx_ant) 2607 + { 2608 + struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2609 + 2610 + if (WARN_ON(!mld->nvm_data)) 2611 + return -EBUSY; 2612 + 2613 + /* mac80211 ensures the device is not started, 2614 + * so the firmware cannot be running 2615 + */ 2616 + 2617 + mld->set_tx_ant = tx_ant; 2618 + mld->set_rx_ant = rx_ant; 2619 + 2620 + iwl_reinit_cab(mld->trans, mld->nvm_data, tx_ant, rx_ant, mld->fw); 2621 + 2622 + return 0; 2623 + } 2624 + 2598 2625 const struct ieee80211_ops iwl_mld_hw_ops = { 2599 2626 .tx = iwl_mld_mac80211_tx, 2600 2627 .start = iwl_mld_mac80211_start, 2601 2628 .stop = iwl_mld_mac80211_stop, 2602 2629 .config = iwl_mld_mac80211_config, 2630 + .get_antenna = iwl_mld_get_antenna, 2631 + .set_antenna = iwl_mld_set_antenna, 2603 2632 .add_interface = iwl_mld_mac80211_add_interface, 2604 2633 .remove_interface = iwl_mld_mac80211_remove_interface, 2605 2634 .conf_tx = iwl_mld_mac80211_conf_tx,
+1
drivers/net/wireless/intel/iwlwifi/mld/mld.c
··· 259 259 HCMD_NAME(MONITOR_NOTIF), 260 260 HCMD_NAME(TLC_MNG_UPDATE_NOTIF), 261 261 HCMD_NAME(BEACON_FILTER_IN_NOTIF), 262 + HCMD_NAME(PHY_AIR_SNIFFER_NOTIF), 262 263 HCMD_NAME(MU_GROUP_MGMT_NOTIF), 263 264 }; 264 265
+24 -1
drivers/net/wireless/intel/iwlwifi/mld/mld.h
··· 118 118 * @monitor.cur_bssid: current bssid tracked by the sniffer 119 119 * @monitor.ptp_time: set the Rx mactime using the device's PTP clock time 120 120 * @monitor.p80: primary channel position relative to he whole bandwidth, in 121 - * steps of 80 MHz 121 + * steps of 80 MHz 122 + * @monitor.phy: PHY data information 123 + * @monitor.phy.data: PHY data (&struct iwl_rx_phy_air_sniffer_ntfy) received 124 + * @monitor.phy.valid: PHY data is valid (was received) 125 + * @monitor.phy.used: PHY data was used by an RX 122 126 * @fw_id_to_link_sta: maps a fw id of a sta to the corresponding 123 127 * ieee80211_link_sta. This is not cleaned up on restart since we want to 124 128 * preserve the fw sta ids during a restart (for SN/PN restoring). ··· 138 134 * @fw: a pointer to the fw object 139 135 * @hw: pointer to the hw object. 140 136 * @wiphy: a pointer to the wiphy struct, for easier access to it. 137 + * @ext_capab: extended capabilities that will be set to wiphy on registration. 138 + * @sta_ext_capab: extended capabilities for the station interface. 141 139 * @nvm_data: pointer to the nvm_data that includes all our capabilities 142 140 * @fwrt: fw runtime data 143 141 * @debugfs_dir: debugfs directory ··· 186 180 * @mcast_filter_cmd: pointer to the multicast filter command. 187 181 * @mgmt_tx_ant: stores the last TX antenna index; used for setting 188 182 * TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure). 183 + * @set_tx_ant: stores the last TX antenna bitmask set by user space (if any) 184 + * @set_rx_ant: stores the last RX antenna bitmask set by user space (if any) 189 185 * @fw_rates_ver_3: FW rates are in version 3 190 186 * @low_latency: low-latency manager. 191 187 * @tzone: thermal zone device's data ··· 213 205 u32 ampdu_ref; 214 206 bool ampdu_toggle; 215 207 u8 p80; 208 + struct { 209 + struct iwl_rx_phy_air_sniffer_ntfy data; 210 + u8 valid:1, used:1; 211 + } phy; 216 212 #ifdef CONFIG_IWLWIFI_DEBUGFS 217 213 __le16 cur_aid; 218 214 u8 cur_bssid[ETH_ALEN]; ··· 237 225 const struct iwl_fw *fw; 238 226 struct ieee80211_hw *hw; 239 227 struct wiphy *wiphy; 228 + struct wiphy_iftype_ext_capab ext_capab[IWL_MLD_EXT_CAPA_NUM_IFTYPES]; 229 + u8 sta_ext_capab[IWL_MLD_STA_EXT_CAPA_SIZE]; 240 230 struct iwl_nvm_data *nvm_data; 241 231 struct iwl_fw_runtime fwrt; 242 232 struct dentry *debugfs_dir; ··· 292 278 struct iwl_mcast_filter_cmd *mcast_filter_cmd; 293 279 294 280 u8 mgmt_tx_ant; 281 + 282 + u8 set_tx_ant; 283 + u8 set_rx_ant; 295 284 296 285 bool fw_rates_ver_3; 297 286 ··· 391 374 if (mld->nvm_data && mld->nvm_data->valid_tx_ant) 392 375 tx_ant &= mld->nvm_data->valid_tx_ant; 393 376 377 + if (mld->set_tx_ant) 378 + tx_ant &= mld->set_tx_ant; 379 + 394 380 return tx_ant; 395 381 } 396 382 ··· 403 383 404 384 if (mld->nvm_data && mld->nvm_data->valid_rx_ant) 405 385 rx_ant &= mld->nvm_data->valid_rx_ant; 386 + 387 + if (mld->set_rx_ant) 388 + rx_ant &= mld->set_rx_ant; 406 389 407 390 return rx_ant; 408 391 }
+46 -54
drivers/net/wireless/intel/iwlwifi/mld/mlo.c
··· 31 31 { 32 32 #define NAME_FMT(x) "%s" 33 33 #define NAME_PR(x) (mask & IWL_MLD_EMLSR_BLOCKED_##x) ? "[" #x "]" : "", 34 - IWL_DEBUG_INFO(mld, 35 - "EMLSR blocked = " HANDLE_EMLSR_BLOCKED_REASONS(NAME_FMT) 36 - " (0x%x)\n", 37 - HANDLE_EMLSR_BLOCKED_REASONS(NAME_PR) 38 - mask); 34 + IWL_DEBUG_EHT(mld, 35 + "EMLSR blocked = " HANDLE_EMLSR_BLOCKED_REASONS(NAME_FMT) 36 + " (0x%x)\n", HANDLE_EMLSR_BLOCKED_REASONS(NAME_PR) mask); 39 37 #undef NAME_FMT 40 38 #undef NAME_PR 41 39 } ··· 70 72 { 71 73 #define NAME_FMT(x) "%s" 72 74 #define NAME_PR(x) (mask & IWL_MLD_EMLSR_EXIT_##x) ? "[" #x "]" : "", 73 - IWL_DEBUG_INFO(mld, 74 - "EMLSR exit = " HANDLE_EMLSR_EXIT_REASONS(NAME_FMT) 75 - " (0x%x)\n", 76 - HANDLE_EMLSR_EXIT_REASONS(NAME_PR) 77 - mask); 75 + IWL_DEBUG_EHT(mld, 76 + "EMLSR exit = " HANDLE_EMLSR_EXIT_REASONS(NAME_FMT) 77 + " (0x%x)\n", HANDLE_EMLSR_EXIT_REASONS(NAME_PR) mask); 78 78 #undef NAME_FMT 79 79 #undef NAME_PR 80 80 } ··· 166 170 WARN_ON(mld_vif->emlsr.exit_repeat_count > 3); 167 171 } 168 172 169 - IWL_DEBUG_INFO(mld, 170 - "Preventing EMLSR for %ld seconds due to %u exits with the reason = %s (0x%x)\n", 171 - delay / HZ, mld_vif->emlsr.exit_repeat_count, 172 - iwl_mld_get_emlsr_exit_string(reason), reason); 173 + IWL_DEBUG_EHT(mld, 174 + "Preventing EMLSR for %ld seconds due to %u exits with the reason = %s (0x%x)\n", 175 + delay / HZ, mld_vif->emlsr.exit_repeat_count, 176 + iwl_mld_get_emlsr_exit_string(reason), reason); 173 177 174 178 wiphy_delayed_work_queue(mld->wiphy, 175 179 &mld_vif->emlsr.prevent_done_wk, delay); ··· 213 217 link_to_keep = __ffs(vif->active_links); 214 218 215 219 new_active_links = BIT(link_to_keep); 216 - IWL_DEBUG_INFO(mld, 217 - "Exiting EMLSR. reason = %s (0x%x). Current active links=0x%x, new active links = 0x%x\n", 218 - iwl_mld_get_emlsr_exit_string(exit), exit, 219 - vif->active_links, new_active_links); 220 + IWL_DEBUG_EHT(mld, 221 + "Exiting EMLSR. reason = %s (0x%x). Current active links=0x%x, new active links = 0x%x\n", 222 + iwl_mld_get_emlsr_exit_string(exit), exit, 223 + vif->active_links, new_active_links); 220 224 221 225 if (sync) 222 226 ret = ieee80211_set_active_links(vif, new_active_links); ··· 258 262 259 263 mld_vif->emlsr.blocked_reasons |= reason; 260 264 261 - IWL_DEBUG_INFO(mld, 262 - "Blocking EMLSR mode. reason = %s (0x%x)\n", 263 - iwl_mld_get_emlsr_blocked_string(reason), reason); 265 + IWL_DEBUG_EHT(mld, "Blocking EMLSR mode. reason = %s (0x%x)\n", 266 + iwl_mld_get_emlsr_blocked_string(reason), reason); 264 267 iwl_mld_print_emlsr_blocked(mld, mld_vif->emlsr.blocked_reasons); 265 268 266 269 if (reason == IWL_MLD_EMLSR_BLOCKED_TPT) ··· 330 335 331 336 mld_vif->emlsr.blocked_reasons &= ~reason; 332 337 333 - IWL_DEBUG_INFO(mld, 334 - "Unblocking EMLSR mode. reason = %s (0x%x)\n", 335 - iwl_mld_get_emlsr_blocked_string(reason), reason); 338 + IWL_DEBUG_EHT(mld, "Unblocking EMLSR mode. reason = %s (0x%x)\n", 339 + iwl_mld_get_emlsr_blocked_string(reason), reason); 336 340 iwl_mld_print_emlsr_blocked(mld, mld_vif->emlsr.blocked_reasons); 337 341 338 342 if (reason == IWL_MLD_EMLSR_BLOCKED_TPT) ··· 342 348 if (mld_vif->emlsr.blocked_reasons) 343 349 return; 344 350 345 - IWL_DEBUG_INFO(mld, "EMLSR is unblocked\n"); 351 + IWL_DEBUG_EHT(mld, "EMLSR is unblocked\n"); 346 352 iwl_mld_int_mlo_scan(mld, vif); 347 353 } 348 354 ··· 359 365 360 366 switch (action) { 361 367 case ESR_RECOMMEND_LEAVE: 362 - IWL_DEBUG_INFO(mld_vif->mld, 363 - "FW recommend leave reason = 0x%x\n", 364 - le32_to_cpu(notif->leave_reason_mask)); 368 + IWL_DEBUG_EHT(mld_vif->mld, 369 + "FW recommend leave reason = 0x%x\n", 370 + le32_to_cpu(notif->leave_reason_mask)); 365 371 366 372 iwl_mld_exit_emlsr(mld_vif->mld, vif, 367 373 IWL_MLD_EMLSR_EXIT_FW_REQUEST, 368 374 iwl_mld_get_primary_link(vif)); 369 375 break; 370 376 case ESR_FORCE_LEAVE: 371 - IWL_DEBUG_INFO(mld_vif->mld, 372 - "FW force leave reason = 0x%x\n", 373 - le32_to_cpu(notif->leave_reason_mask)); 377 + IWL_DEBUG_EHT(mld_vif->mld, "FW force leave reason = 0x%x\n", 378 + le32_to_cpu(notif->leave_reason_mask)); 374 379 fallthrough; 375 380 case ESR_RECOMMEND_ENTER: 376 381 default: ··· 405 412 struct ieee80211_bss_conf *bss_conf = 406 413 iwl_mld_fw_id_to_link_conf(mld, fw_link_id); 407 414 408 - IWL_DEBUG_INFO(mld, "Failed to %s EMLSR on link %d (FW: %d), reason %d\n", 409 - le32_to_cpu(notif->activation) ? "enter" : "exit", 410 - bss_conf ? bss_conf->link_id : -1, 411 - le32_to_cpu(notif->link_id), 412 - le32_to_cpu(notif->err_code)); 415 + IWL_DEBUG_EHT(mld, 416 + "Failed to %s EMLSR on link %d (FW: %d), reason %d\n", 417 + le32_to_cpu(notif->activation) ? "enter" : "exit", 418 + bss_conf ? bss_conf->link_id : -1, 419 + le32_to_cpu(notif->link_id), 420 + le32_to_cpu(notif->err_code)); 413 421 414 422 if (IWL_FW_CHECK(mld, !bss_conf, 415 423 "FW reported failure to %sactivate EMLSR on a non-existing link: %d\n", ··· 584 590 spin_unlock_bh(&queue_counter->lock); 585 591 } 586 592 587 - IWL_DEBUG_INFO(mld, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n", 588 - total_tx, total_rx); 593 + IWL_DEBUG_EHT(mld, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n", 594 + total_tx, total_rx); 589 595 590 596 /* If we don't have enough MPDUs - exit EMLSR */ 591 597 if (total_tx < IWL_MLD_ENTER_EMLSR_TPT_THRESH && ··· 597 603 598 604 /* EMLSR is not active */ 599 605 if (sec_link_id == -1) 600 - return; 606 + goto schedule; 601 607 602 - IWL_DEBUG_INFO(mld, "Secondary Link %d: Tx MPDUs: %ld. Rx MPDUs: %ld\n", 603 - sec_link_id, sec_link_tx, sec_link_rx); 608 + IWL_DEBUG_EHT(mld, "Secondary Link %d: Tx MPDUs: %ld. Rx MPDUs: %ld\n", 609 + sec_link_id, sec_link_tx, sec_link_rx); 604 610 605 611 /* Calculate the percentage of the secondary link TX/RX */ 606 612 sec_link_tx_perc = total_tx ? sec_link_tx * 100 / total_tx : 0; ··· 619 625 return; 620 626 } 621 627 628 + schedule: 622 629 /* Check again when the next window ends */ 623 630 wiphy_delayed_work_queue(mld_vif->mld->wiphy, 624 631 &mld_vif->emlsr.check_tpt_wk, ··· 697 702 ret |= IWL_MLD_EMLSR_EXIT_CSA; 698 703 699 704 if (ret) { 700 - IWL_DEBUG_INFO(mld, 701 - "Link %d is not allowed for EMLSR as %s\n", 702 - link->link_id, 703 - primary ? "primary" : "secondary"); 705 + IWL_DEBUG_EHT(mld, "Link %d is not allowed for EMLSR as %s\n", 706 + link->link_id, primary ? "primary" : "secondary"); 704 707 iwl_mld_print_emlsr_exit(mld, ret); 705 708 } 706 709 ··· 862 869 reason_mask |= IWL_MLD_EMLSR_EXIT_CHAN_LOAD; 863 870 864 871 if (reason_mask) { 865 - IWL_DEBUG_INFO(mld, 866 - "Links %d and %d are not a valid pair for EMLSR\n", 867 - a->link_id, b->link_id); 868 - IWL_DEBUG_INFO(mld, 869 - "Links bandwidth are: %d and %d\n", 870 - nl80211_chan_width_to_mhz(a->chandef->width), 871 - nl80211_chan_width_to_mhz(b->chandef->width)); 872 + IWL_DEBUG_EHT(mld, 873 + "Links %d and %d are not a valid pair for EMLSR\n", 874 + a->link_id, b->link_id); 875 + IWL_DEBUG_EHT(mld, "Links bandwidth are: %d and %d\n", 876 + nl80211_chan_width_to_mhz(a->chandef->width), 877 + nl80211_chan_width_to_mhz(b->chandef->width)); 872 878 iwl_mld_print_emlsr_exit(mld, reason_mask); 873 879 } 874 880 ··· 985 993 } 986 994 987 995 set_active: 988 - IWL_DEBUG_INFO(mld, "Link selection result: 0x%x. Primary = %d\n", 989 - new_active, new_primary); 996 + IWL_DEBUG_EHT(mld, "Link selection result: 0x%x. Primary = %d\n", 997 + new_active, new_primary); 990 998 991 999 mld_vif->emlsr.selected_primary = new_primary; 992 1000 mld_vif->emlsr.selected_links = new_active;
+2 -2
drivers/net/wireless/intel/iwlwifi/mld/notif.c
··· 589 589 else if (unlikely(cmd_id == WIDE_ID(DATA_PATH_GROUP, 590 590 RX_QUEUES_NOTIFICATION))) 591 591 iwl_mld_handle_rx_queues_sync_notif(mld, napi, pkt, 0); 592 - else if (cmd_id == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF)) 593 - iwl_mld_rx_monitor_no_data(mld, napi, pkt, 0); 592 + else if (cmd_id == WIDE_ID(DATA_PATH_GROUP, PHY_AIR_SNIFFER_NOTIF)) 593 + iwl_mld_handle_phy_air_sniffer_notif(mld, napi, pkt); 594 594 else 595 595 iwl_mld_rx_notif(mld, rxb, pkt); 596 596 }
+3 -1
drivers/net/wireless/intel/iwlwifi/mld/roc.c
··· 231 231 struct ieee80211_vif *vif; 232 232 233 233 vif = iwl_mld_find_roc_vif(mld, activity); 234 - if (WARN_ON(!vif)) 234 + if (IWL_FW_CHECK(mld, !vif, 235 + "unexpected ROC notif from FW for activity %d\n", 236 + activity)) 235 237 return; 236 238 237 239 mld_vif = iwl_mld_vif_from_mac80211(vif);
+913 -796
drivers/net/wireless/intel/iwlwifi/mld/rx.c
··· 18 18 19 19 /* stores relevant PHY data fields extracted from iwl_rx_mpdu_desc */ 20 20 struct iwl_mld_rx_phy_data { 21 - enum iwl_rx_phy_info_type info_type; 22 - __le32 data0; 23 - __le32 data1; 24 - __le32 data2; 25 - __le32 data3; 26 - __le32 eht_data4; 27 - __le32 data5; 28 - __le16 data4; 21 + struct iwl_rx_phy_air_sniffer_ntfy *ntfy; 29 22 bool first_subframe; 30 23 bool with_data; 31 - __le32 rx_vec[4]; 32 24 u32 rate_n_flags; 33 25 u32 gp2_on_air_rise; 26 + /* phy_info is only valid when we have a frame, i.e. with_data=true */ 34 27 u16 phy_info; 35 28 u8 energy_a, energy_b; 36 29 }; 37 30 38 31 static void 39 - iwl_mld_fill_phy_data(struct iwl_mld *mld, 40 - struct iwl_rx_mpdu_desc *desc, 41 - struct iwl_mld_rx_phy_data *phy_data) 32 + iwl_mld_fill_phy_data_from_mpdu(struct iwl_mld *mld, 33 + struct iwl_rx_mpdu_desc *desc, 34 + struct iwl_mld_rx_phy_data *phy_data) 42 35 { 36 + if (unlikely(mld->monitor.phy.valid)) { 37 + mld->monitor.phy.used = true; 38 + phy_data->ntfy = &mld->monitor.phy.data; 39 + } 40 + 43 41 phy_data->phy_info = le16_to_cpu(desc->phy_info); 44 42 phy_data->rate_n_flags = iwl_v3_rate_from_v2_v3(desc->v3.rate_n_flags, 45 43 mld->fw_rates_ver_3); 46 44 phy_data->gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); 47 45 phy_data->energy_a = desc->v3.energy_a; 48 46 phy_data->energy_b = desc->v3.energy_b; 49 - phy_data->data0 = desc->v3.phy_data0; 50 - phy_data->data1 = desc->v3.phy_data1; 51 - phy_data->data2 = desc->v3.phy_data2; 52 - phy_data->data3 = desc->v3.phy_data3; 53 - phy_data->data4 = desc->phy_data4; 54 - phy_data->eht_data4 = desc->phy_eht_data4; 55 - phy_data->data5 = desc->v3.phy_data5; 56 47 phy_data->with_data = true; 57 48 } 58 49 ··· 208 217 } 209 218 210 219 static void 211 - iwl_mld_decode_he_phy_ru_alloc(struct iwl_mld_rx_phy_data *phy_data, 212 - struct ieee80211_radiotap_he *he, 213 - struct ieee80211_radiotap_he_mu *he_mu, 214 - struct ieee80211_rx_status *rx_status) 220 + iwl_mld_he_set_ru_alloc(struct ieee80211_rx_status *rx_status, 221 + struct ieee80211_radiotap_he *he, 222 + u8 ru_with_p80) 215 223 { 216 - /* Unfortunately, we have to leave the mac80211 data 217 - * incorrect for the case that we receive an HE-MU 218 - * transmission and *don't* have the HE phy data (due 219 - * to the bits being used for TSF). This shouldn't 220 - * happen though as management frames where we need 221 - * the TSF/timers are not be transmitted in HE-MU. 222 - */ 223 - u8 ru = le32_get_bits(phy_data->data1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK); 224 - u32 rate_n_flags = phy_data->rate_n_flags; 225 - u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; 224 + u8 ru = ru_with_p80 >> 1; 225 + u8 p80 = ru_with_p80 & 1; 226 226 u8 offs = 0; 227 227 228 228 rx_status->bw = RATE_INFO_BW_HE_RU; 229 229 230 230 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); 231 + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN | 232 + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN); 231 233 232 234 switch (ru) { 233 235 case 0 ... 36: ··· 250 266 rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; 251 267 break; 252 268 } 269 + 253 270 he->data2 |= le16_encode_bits(offs, 254 271 IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); 255 - he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN | 256 - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN); 257 - if (phy_data->data1 & cpu_to_le32(IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80)) 258 - he->data2 |= 259 - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); 260 272 261 - #define CHECK_BW(bw) \ 262 - BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ 263 - RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS); \ 264 - BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_ ## bw ## MHZ != \ 265 - RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) 266 - CHECK_BW(20); 267 - CHECK_BW(40); 268 - CHECK_BW(80); 269 - CHECK_BW(160); 270 - 271 - if (he_mu) 272 - he_mu->flags2 |= 273 - le16_encode_bits(u32_get_bits(rate_n_flags, 274 - RATE_MCS_CHAN_WIDTH_MSK), 275 - IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); 276 - else if (he_type == RATE_MCS_HE_TYPE_TRIG) 277 - he->data6 |= 278 - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) | 279 - le16_encode_bits(u32_get_bits(rate_n_flags, 280 - RATE_MCS_CHAN_WIDTH_MSK), 281 - IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW); 273 + he->data2 |= le16_encode_bits(p80, IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); 282 274 } 283 275 276 + #define RTAP_ENC_HE(src, src_msk, dst_msk) \ 277 + le16_encode_bits(le32_get_bits(src, src_msk), dst_msk) 278 + 284 279 static void 285 - iwl_mld_decode_he_mu_ext(struct iwl_mld_rx_phy_data *phy_data, 286 - struct ieee80211_radiotap_he_mu *he_mu) 280 + iwl_mld_decode_he_mu(struct iwl_mld_rx_phy_data *phy_data, 281 + struct ieee80211_radiotap_he *he, 282 + struct ieee80211_radiotap_he_mu *he_mu, 283 + struct ieee80211_rx_status *rx_status) 287 284 { 288 - u32 phy_data2 = le32_to_cpu(phy_data->data2); 289 - u32 phy_data3 = le32_to_cpu(phy_data->data3); 290 - u16 phy_data4 = le16_to_cpu(phy_data->data4); 291 285 u32 rate_n_flags = phy_data->rate_n_flags; 292 286 293 - if (u32_get_bits(phy_data4, IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK)) { 287 + he_mu->flags1 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.b, 288 + OFDM_RX_FRAME_HE_SIGB_DCM, 289 + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); 290 + he_mu->flags1 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.b, 291 + OFDM_RX_FRAME_HE_SIGB_MCS, 292 + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); 293 + he_mu->flags2 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a1, 294 + OFDM_RX_FRAME_HE_PRMBL_PUNC_TYPE, 295 + IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); 296 + he_mu->flags2 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 297 + OFDM_RX_FRAME_HE_MU_NUM_OF_SIGB_SYM_OR_USER_NUM, 298 + IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); 299 + he_mu->flags2 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.b, 300 + OFDM_RX_FRAME_HE_MU_SIGB_COMP, 301 + IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); 302 + 303 + if (phy_data->ntfy->flags & IWL_SNIF_FLAG_VALID_RU && 304 + le32_get_bits(phy_data->ntfy->sigs.he.cmn[2], 305 + OFDM_RX_FRAME_HE_COMMON_CC1_CRC_OK)) { 294 306 he_mu->flags1 |= 295 307 cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN | 296 308 IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN); 297 309 298 310 he_mu->flags1 |= 299 - le16_encode_bits(u32_get_bits(phy_data4, 300 - IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CTR_RU), 301 - IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU); 311 + RTAP_ENC_HE(phy_data->ntfy->sigs.he.cmn[2], 312 + OFDM_RX_FRAME_HE_CENTER_RU_CC1, 313 + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU); 302 314 303 - he_mu->ru_ch1[0] = u32_get_bits(phy_data2, 304 - IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU0); 305 - he_mu->ru_ch1[1] = u32_get_bits(phy_data3, 306 - IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU1); 307 - he_mu->ru_ch1[2] = u32_get_bits(phy_data2, 308 - IWL_RX_PHY_DATA2_HE_MU_EXT_CH1_RU2); 309 - he_mu->ru_ch1[3] = u32_get_bits(phy_data3, 310 - IWL_RX_PHY_DATA3_HE_MU_EXT_CH1_RU3); 315 + he_mu->ru_ch1[0] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[0], 316 + OFDM_RX_FRAME_HE_RU_ALLOC_0_A1); 317 + he_mu->ru_ch1[1] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[1], 318 + OFDM_RX_FRAME_HE_RU_ALLOC_1_C1); 319 + he_mu->ru_ch1[2] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[0], 320 + OFDM_RX_FRAME_HE_RU_ALLOC_0_A2); 321 + he_mu->ru_ch1[3] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[1], 322 + OFDM_RX_FRAME_HE_RU_ALLOC_1_C2); 311 323 } 312 324 313 - if (u32_get_bits(phy_data4, IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK) && 325 + if (phy_data->ntfy->flags & IWL_SNIF_FLAG_VALID_RU && 326 + le32_get_bits(phy_data->ntfy->sigs.he.cmn[2], 327 + OFDM_RX_FRAME_HE_COMMON_CC2_CRC_OK) && 314 328 (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) { 315 329 he_mu->flags1 |= 316 330 cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | 317 331 IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); 318 332 319 333 he_mu->flags2 |= 320 - le16_encode_bits(u32_get_bits(phy_data4, 321 - IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CTR_RU), 322 - IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU); 334 + RTAP_ENC_HE(phy_data->ntfy->sigs.he.cmn[2], 335 + OFDM_RX_FRAME_HE_CENTER_RU_CC2, 336 + IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU); 323 337 324 - he_mu->ru_ch2[0] = u32_get_bits(phy_data2, 325 - IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU0); 326 - he_mu->ru_ch2[1] = u32_get_bits(phy_data3, 327 - IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU1); 328 - he_mu->ru_ch2[2] = u32_get_bits(phy_data2, 329 - IWL_RX_PHY_DATA2_HE_MU_EXT_CH2_RU2); 330 - he_mu->ru_ch2[3] = u32_get_bits(phy_data3, 331 - IWL_RX_PHY_DATA3_HE_MU_EXT_CH2_RU3); 338 + he_mu->ru_ch2[0] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[0], 339 + OFDM_RX_FRAME_HE_RU_ALLOC_0_B1); 340 + he_mu->ru_ch2[1] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[1], 341 + OFDM_RX_FRAME_HE_RU_ALLOC_1_D1); 342 + he_mu->ru_ch2[2] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[0], 343 + OFDM_RX_FRAME_HE_RU_ALLOC_0_B2); 344 + he_mu->ru_ch2[3] = le32_get_bits(phy_data->ntfy->sigs.he.cmn[1], 345 + OFDM_RX_FRAME_HE_RU_ALLOC_1_D2); 332 346 } 347 + 348 + #define CHECK_BW(bw) \ 349 + BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ 350 + RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) 351 + CHECK_BW(20); 352 + CHECK_BW(40); 353 + CHECK_BW(80); 354 + CHECK_BW(160); 355 + #undef CHECK_BW 356 + 357 + he_mu->flags2 |= 358 + le16_encode_bits(u32_get_bits(rate_n_flags, RATE_MCS_CHAN_WIDTH_MSK), 359 + IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); 360 + 361 + iwl_mld_he_set_ru_alloc(rx_status, he, 362 + le32_get_bits(phy_data->ntfy->sigs.he.b, 363 + OFDM_RX_FRAME_HE_SIGB_STA_RU)); 364 + } 365 + 366 + static void 367 + iwl_mld_decode_he_tb_phy_data(struct iwl_mld_rx_phy_data *phy_data, 368 + struct ieee80211_radiotap_he *he, 369 + struct ieee80211_rx_status *rx_status) 370 + { 371 + u32 rate_n_flags = phy_data->rate_n_flags; 372 + u32 nsts; 373 + 374 + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | 375 + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | 376 + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | 377 + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | 378 + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); 379 + 380 + he->data4 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a1, 381 + OFDM_RX_HE_TRIG_SPATIAL_REUSE_1, 382 + IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); 383 + he->data4 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a1, 384 + OFDM_RX_HE_TRIG_SPATIAL_REUSE_2, 385 + IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); 386 + he->data4 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a1, 387 + OFDM_RX_HE_TRIG_SPATIAL_REUSE_3, 388 + IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); 389 + he->data4 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a1, 390 + OFDM_RX_HE_TRIG_SPATIAL_REUSE_4, 391 + IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); 392 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a1, 393 + OFDM_RX_HE_TRIG_BSS_COLOR, 394 + IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); 395 + 396 + #define CHECK_BW(bw) \ 397 + BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_ ## bw ## MHZ != \ 398 + RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) 399 + CHECK_BW(20); 400 + CHECK_BW(40); 401 + CHECK_BW(80); 402 + CHECK_BW(160); 403 + #undef CHECK_BW 404 + 405 + he->data6 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) | 406 + le16_encode_bits(u32_get_bits(rate_n_flags, RATE_MCS_CHAN_WIDTH_MSK), 407 + IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW); 408 + 409 + if (!(phy_data->ntfy->flags & IWL_SNIF_FLAG_VALID_TB_RX)) 410 + return; 411 + 412 + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | 413 + IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN); 414 + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | 415 + IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | 416 + IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | 417 + IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); 418 + 419 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.tb_rx1, 420 + OFDM_UCODE_TRIG_BASE_RX_CODING_EXTRA_SYM, 421 + IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); 422 + he->data6 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.tb_rx1, 423 + OFDM_UCODE_TRIG_BASE_RX_DOPPLER, 424 + IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); 425 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.tb_rx1, 426 + OFDM_UCODE_TRIG_BASE_RX_PRE_FEC_PAD_FACTOR, 427 + IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); 428 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.tb_rx1, 429 + OFDM_UCODE_TRIG_BASE_RX_PE_DISAMBIG, 430 + IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); 431 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.tb_rx1, 432 + OFDM_UCODE_TRIG_BASE_RX_NUM_OF_LTF_SYM, 433 + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); 434 + he->data6 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he_tb.a2, 435 + OFDM_RX_HE_TRIG_TXOP_DURATION, 436 + IEEE80211_RADIOTAP_HE_DATA6_TXOP); 437 + 438 + iwl_mld_he_set_ru_alloc(rx_status, he, 439 + le32_get_bits(phy_data->ntfy->sigs.he_tb.tb_rx1, 440 + OFDM_UCODE_TRIG_BASE_RX_RU)); 441 + 442 + nsts = le32_get_bits(phy_data->ntfy->sigs.he_tb.tb_rx1, 443 + OFDM_UCODE_TRIG_BASE_RX_NSTS) + 1; 444 + rx_status->nss = nsts >> !!(rate_n_flags & RATE_MCS_STBC_MSK); 333 445 } 334 446 335 447 static void 336 448 iwl_mld_decode_he_phy_data(struct iwl_mld_rx_phy_data *phy_data, 337 449 struct ieee80211_radiotap_he *he, 338 450 struct ieee80211_radiotap_he_mu *he_mu, 339 - struct ieee80211_rx_status *rx_status, 340 - int queue) 451 + struct ieee80211_rx_status *rx_status) 341 452 { 342 - switch (phy_data->info_type) { 343 - case IWL_RX_PHY_INFO_TYPE_NONE: 344 - case IWL_RX_PHY_INFO_TYPE_CCK: 345 - case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY: 346 - case IWL_RX_PHY_INFO_TYPE_HT: 347 - case IWL_RX_PHY_INFO_TYPE_VHT_SU: 348 - case IWL_RX_PHY_INFO_TYPE_VHT_MU: 349 - case IWL_RX_PHY_INFO_TYPE_EHT_MU: 350 - case IWL_RX_PHY_INFO_TYPE_EHT_TB: 351 - case IWL_RX_PHY_INFO_TYPE_EHT_MU_EXT: 352 - case IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT: 453 + u32 rate_n_flags = phy_data->rate_n_flags; 454 + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; 455 + u32 nsts; 456 + 457 + switch (he_type) { 458 + case RATE_MCS_HE_TYPE_TRIG: 459 + iwl_mld_decode_he_tb_phy_data(phy_data, he, rx_status); 460 + /* that's it, below is only for SU/MU */ 353 461 return; 354 - case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: 355 - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN | 356 - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | 357 - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | 358 - IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); 359 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->data2, 360 - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1), 361 - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); 362 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->data2, 363 - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2), 364 - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); 365 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->data2, 366 - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3), 367 - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); 368 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->data2, 369 - IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4), 370 - IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); 371 - fallthrough; 372 - case IWL_RX_PHY_INFO_TYPE_HE_SU: 373 - case IWL_RX_PHY_INFO_TYPE_HE_MU: 374 - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 375 - case IWL_RX_PHY_INFO_TYPE_HE_TB: 376 - /* HE common */ 377 - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | 378 - IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | 379 - IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); 380 - he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | 381 - IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | 382 - IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | 383 - IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); 384 - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->data0, 385 - IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK), 386 - IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); 387 - if (phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB && 388 - phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB_EXT) { 389 - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN); 390 - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->data0, 391 - IWL_RX_PHY_DATA0_HE_UPLINK), 392 - IEEE80211_RADIOTAP_HE_DATA3_UL_DL); 393 - } 394 - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->data0, 395 - IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM), 396 - IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); 397 - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->data0, 398 - IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK), 399 - IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); 400 - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->data0, 401 - IWL_RX_PHY_DATA0_HE_PE_DISAMBIG), 402 - IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); 403 - he->data5 |= le16_encode_bits(le32_get_bits(phy_data->data1, 404 - IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK), 405 - IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); 406 - he->data6 |= le16_encode_bits(le32_get_bits(phy_data->data0, 407 - IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK), 408 - IEEE80211_RADIOTAP_HE_DATA6_TXOP); 409 - he->data6 |= le16_encode_bits(le32_get_bits(phy_data->data0, 410 - IWL_RX_PHY_DATA0_HE_DOPPLER), 411 - IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); 412 - break; 413 - } 462 + case RATE_MCS_HE_TYPE_MU: 463 + iwl_mld_decode_he_mu(phy_data, he, he_mu, rx_status); 414 464 415 - switch (phy_data->info_type) { 416 - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 417 - case IWL_RX_PHY_INFO_TYPE_HE_MU: 418 - case IWL_RX_PHY_INFO_TYPE_HE_SU: 419 - he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN); 420 - he->data4 |= le16_encode_bits(le32_get_bits(phy_data->data0, 421 - IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK), 422 - IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); 465 + nsts = le32_get_bits(phy_data->ntfy->sigs.he.b, 466 + OFDM_RX_FRAME_HE_SIGB_NSTS) + 1; 423 467 break; 424 - default: 425 - /* nothing here */ 426 - break; 427 - } 428 - 429 - switch (phy_data->info_type) { 430 - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 431 - he_mu->flags1 |= 432 - le16_encode_bits(le16_get_bits(phy_data->data4, 433 - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM), 434 - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); 435 - he_mu->flags1 |= 436 - le16_encode_bits(le16_get_bits(phy_data->data4, 437 - IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_MCS_MASK), 438 - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); 439 - he_mu->flags2 |= 440 - le16_encode_bits(le16_get_bits(phy_data->data4, 441 - IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK), 442 - IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); 443 - iwl_mld_decode_he_mu_ext(phy_data, he_mu); 444 - fallthrough; 445 - case IWL_RX_PHY_INFO_TYPE_HE_MU: 446 - he_mu->flags2 |= 447 - le16_encode_bits(le32_get_bits(phy_data->data1, 448 - IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK), 449 - IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); 450 - he_mu->flags2 |= 451 - le16_encode_bits(le32_get_bits(phy_data->data1, 452 - IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION), 453 - IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); 454 - fallthrough; 455 - case IWL_RX_PHY_INFO_TYPE_HE_TB: 456 - case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: 457 - iwl_mld_decode_he_phy_ru_alloc(phy_data, he, he_mu, rx_status); 458 - break; 459 - case IWL_RX_PHY_INFO_TYPE_HE_SU: 468 + case RATE_MCS_HE_TYPE_SU: 469 + case RATE_MCS_HE_TYPE_EXT_SU: 460 470 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN); 461 - he->data3 |= le16_encode_bits(le32_get_bits(phy_data->data0, 462 - IWL_RX_PHY_DATA0_HE_BEAM_CHNG), 463 - IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE); 464 - break; 465 - default: 466 - /* nothing */ 471 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a1, 472 + OFDM_RX_FRAME_HE_BEAM_CHANGE, 473 + IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE); 474 + 475 + nsts = le32_get_bits(phy_data->ntfy->sigs.he.a1, 476 + OFDM_RX_FRAME_HE_NSTS) + 1; 467 477 break; 468 478 } 479 + 480 + rx_status->nss = nsts >> !!(rate_n_flags & RATE_MCS_STBC_MSK); 481 + 482 + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | 483 + IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN); 484 + he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | 485 + IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | 486 + IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | 487 + IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); 488 + 489 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 490 + OFDM_RX_FRAME_HE_CODING_EXTRA_SYM, 491 + IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); 492 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 493 + OFDM_RX_FRAME_HE_PRE_FEC_PAD_FACTOR, 494 + IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); 495 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 496 + OFDM_RX_FRAME_HE_PE_DISAMBIG, 497 + IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG); 498 + he->data5 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 499 + OFDM_RX_FRAME_HE_MU_NUM_OF_LTF_SYM, 500 + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); 501 + he->data6 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 502 + OFDM_RX_FRAME_HE_TXOP_DURATION, 503 + IEEE80211_RADIOTAP_HE_DATA6_TXOP); 504 + he->data6 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a2, 505 + OFDM_RX_FRAME_HE_DOPPLER, 506 + IEEE80211_RADIOTAP_HE_DATA6_DOPPLER); 507 + 508 + he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | 509 + IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | 510 + IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN); 511 + 512 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a1, 513 + OFDM_RX_FRAME_HE_BSS_COLOR, 514 + IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); 515 + he->data3 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a1, 516 + OFDM_RX_FRAME_HE_UL_FLAG, 517 + IEEE80211_RADIOTAP_HE_DATA3_UL_DL); 518 + he->data4 |= RTAP_ENC_HE(phy_data->ntfy->sigs.he.a1, 519 + OFDM_RX_FRAME_HE_SPATIAL_REUSE, 520 + IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE); 469 521 } 470 522 471 - static void iwl_mld_rx_he(struct iwl_mld *mld, struct sk_buff *skb, 472 - struct iwl_mld_rx_phy_data *phy_data, 473 - int queue) 523 + static void iwl_mld_rx_he(struct sk_buff *skb, 524 + struct iwl_mld_rx_phy_data *phy_data) 474 525 { 475 526 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 476 527 struct ieee80211_radiotap_he *he = NULL; ··· 529 510 .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN | 530 511 IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), 531 512 }; 532 - u16 phy_info = phy_data->phy_info; 533 513 534 514 he = skb_put_data(skb, &known, sizeof(known)); 535 515 rx_status->flag |= RX_FLAG_RADIOTAP_HE; 536 516 537 - if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU || 538 - phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) { 539 - he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known)); 540 - rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; 541 - } 542 - 543 - /* report the AMPDU-EOF bit on single frames */ 544 - if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 545 - rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 546 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 547 - if (phy_data->data0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF)) 548 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 549 - } 550 - 551 - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) 552 - iwl_mld_decode_he_phy_data(phy_data, he, he_mu, rx_status, 553 - queue); 554 - 555 - /* update aggregation data for monitor sake on default queue */ 556 - if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && 557 - (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) { 558 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 559 - if (phy_data->data0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 560 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 561 - } 562 - 563 - if (he_type == RATE_MCS_HE_TYPE_EXT_SU && 564 - rate_n_flags & RATE_MCS_HE_106T_MSK) { 565 - rx_status->bw = RATE_INFO_BW_HE_RU; 566 - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; 567 - } 568 - 569 - /* actually data is filled in mac80211 */ 570 - if (he_type == RATE_MCS_HE_TYPE_SU || 571 - he_type == RATE_MCS_HE_TYPE_EXT_SU) 517 + switch (he_type) { 518 + case RATE_MCS_HE_TYPE_EXT_SU: 519 + /* 520 + * Except for this special case we won't have 521 + * HE RU allocation info outside of monitor mode 522 + * since we don't get the PHY notif. 523 + */ 524 + if (rate_n_flags & RATE_MCS_HE_106T_MSK) { 525 + rx_status->bw = RATE_INFO_BW_HE_RU; 526 + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; 527 + } 528 + fallthrough; 529 + case RATE_MCS_HE_TYPE_SU: 530 + /* actual data is filled in mac80211 */ 572 531 he->data1 |= 573 532 cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); 533 + break; 534 + } 574 535 575 536 #define CHECK_TYPE(F) \ 576 537 BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ ··· 566 567 if (rate_n_flags & RATE_MCS_BF_MSK) 567 568 he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); 568 569 569 - switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> 570 - RATE_MCS_HE_GI_LTF_POS) { 570 + switch (u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK)) { 571 571 case 0: 572 572 if (he_type == RATE_MCS_HE_TYPE_TRIG) 573 573 rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; ··· 607 609 608 610 he->data5 |= le16_encode_bits(ltf, 609 611 IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); 612 + 613 + if (likely(!phy_data->ntfy)) 614 + return; 615 + 616 + if (he_type == RATE_MCS_HE_TYPE_MU) { 617 + he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known)); 618 + rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; 619 + } 620 + 621 + iwl_mld_decode_he_phy_data(phy_data, he, he_mu, rx_status); 610 622 } 611 623 612 624 static void iwl_mld_decode_lsig(struct sk_buff *skb, 613 625 struct iwl_mld_rx_phy_data *phy_data) 614 626 { 615 627 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 628 + u32 format = phy_data->rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 616 629 struct ieee80211_radiotap_lsig *lsig; 630 + u32 lsig_len, rate; 617 631 618 - switch (phy_data->info_type) { 619 - case IWL_RX_PHY_INFO_TYPE_HT: 620 - case IWL_RX_PHY_INFO_TYPE_VHT_SU: 621 - case IWL_RX_PHY_INFO_TYPE_VHT_MU: 622 - case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: 623 - case IWL_RX_PHY_INFO_TYPE_HE_SU: 624 - case IWL_RX_PHY_INFO_TYPE_HE_MU: 625 - case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 626 - case IWL_RX_PHY_INFO_TYPE_HE_TB: 627 - case IWL_RX_PHY_INFO_TYPE_EHT_MU: 628 - case IWL_RX_PHY_INFO_TYPE_EHT_TB: 629 - case IWL_RX_PHY_INFO_TYPE_EHT_MU_EXT: 630 - case IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT: 631 - lsig = skb_put(skb, sizeof(*lsig)); 632 - lsig->data1 = cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_LENGTH_KNOWN); 633 - lsig->data2 = le16_encode_bits(le32_get_bits(phy_data->data1, 634 - IWL_RX_PHY_DATA1_LSIG_LEN_MASK), 635 - IEEE80211_RADIOTAP_LSIG_DATA2_LENGTH); 636 - rx_status->flag |= RX_FLAG_RADIOTAP_LSIG; 637 - break; 638 - default: 639 - break; 640 - } 632 + if (likely(!phy_data->ntfy)) 633 + return; 634 + 635 + /* 636 + * Technically legacy CCK/OFDM frames don't have an L-SIG 637 + * since that's the compat format for HT (non-greenfield) 638 + * and up. However, it's meant to be compatible with the 639 + * LENGTH and RATE fields in Clause 17 and 18 OFDM frames 640 + * so include the field for any non-CCK frame. For CCK it 641 + * cannot work, since the LENGTH field for them is 16-bit 642 + * and the radiotap field only has 12 bits. 643 + */ 644 + if (format == RATE_MCS_MOD_TYPE_CCK) 645 + return; 646 + 647 + lsig_len = le32_get_bits(phy_data->ntfy->legacy_sig.ofdm, 648 + OFDM_RX_LEGACY_LENGTH); 649 + rate = le32_get_bits(phy_data->ntfy->legacy_sig.ofdm, OFDM_RX_RATE); 650 + 651 + lsig = skb_put(skb, sizeof(*lsig)); 652 + lsig->data1 = cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_LENGTH_KNOWN) | 653 + cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_RATE_KNOWN); 654 + lsig->data2 = le16_encode_bits(lsig_len, 655 + IEEE80211_RADIOTAP_LSIG_DATA2_LENGTH) | 656 + le16_encode_bits(rate, IEEE80211_RADIOTAP_LSIG_DATA2_RATE); 657 + rx_status->flag |= RX_FLAG_RADIOTAP_LSIG; 641 658 } 642 659 643 660 /* Put a TLV on the skb and return data pointer ··· 680 667 (_usig)->value |= LE32_DEC_ENC(in_value, dec_bits, _enc_bits); \ 681 668 } while (0) 682 669 683 - #define __IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 684 - eht->data[(rt_data)] |= \ 685 - (cpu_to_le32 \ 686 - (IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru ## _KNOWN) | \ 687 - LE32_DEC_ENC(data ## fw_data, \ 688 - IWL_RX_PHY_DATA ## fw_data ## _EHT_MU_EXT_RU_ALLOC_ ## fw_ru, \ 689 - IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru)) 690 - 691 - #define _IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 692 - __IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) 693 - 694 - #define IEEE80211_RADIOTAP_RU_DATA_1_1_1 1 695 - #define IEEE80211_RADIOTAP_RU_DATA_2_1_1 2 696 - #define IEEE80211_RADIOTAP_RU_DATA_1_1_2 2 697 - #define IEEE80211_RADIOTAP_RU_DATA_2_1_2 2 698 - #define IEEE80211_RADIOTAP_RU_DATA_1_2_1 3 699 - #define IEEE80211_RADIOTAP_RU_DATA_2_2_1 3 700 - #define IEEE80211_RADIOTAP_RU_DATA_1_2_2 3 701 - #define IEEE80211_RADIOTAP_RU_DATA_2_2_2 4 702 - 703 - #define IWL_RX_RU_DATA_A1 2 704 - #define IWL_RX_RU_DATA_A2 2 705 - #define IWL_RX_RU_DATA_B1 2 706 - #define IWL_RX_RU_DATA_B2 4 707 - #define IWL_RX_RU_DATA_C1 3 708 - #define IWL_RX_RU_DATA_C2 3 709 - #define IWL_RX_RU_DATA_D1 4 710 - #define IWL_RX_RU_DATA_D2 4 711 - 712 - #define IWL_MLD_ENC_EHT_RU(rt_ru, fw_ru) \ 713 - _IWL_MLD_ENC_EHT_RU(IEEE80211_RADIOTAP_RU_DATA_ ## rt_ru, \ 714 - rt_ru, \ 715 - IWL_RX_RU_DATA_ ## fw_ru, \ 716 - fw_ru) 717 - 718 - static void iwl_mld_decode_eht_ext_mu(struct iwl_mld *mld, 719 - struct iwl_mld_rx_phy_data *phy_data, 720 - struct ieee80211_rx_status *rx_status, 721 - struct ieee80211_radiotap_eht *eht, 722 - struct ieee80211_radiotap_eht_usig *usig) 670 + static void iwl_mld_decode_eht_usig_tb(struct iwl_mld_rx_phy_data *phy_data, 671 + struct ieee80211_radiotap_eht_usig *usig) 723 672 { 724 - if (phy_data->with_data) { 725 - __le32 data1 = phy_data->data1; 726 - __le32 data2 = phy_data->data2; 727 - __le32 data3 = phy_data->data3; 728 - __le32 data4 = phy_data->eht_data4; 729 - __le32 data5 = phy_data->data5; 730 - u32 phy_bw = phy_data->rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 673 + __le32 usig_a1 = phy_data->ntfy->sigs.eht_tb.usig_a1; 674 + __le32 usig_a2 = phy_data->ntfy->sigs.eht_tb.usig_a2_eht; 731 675 732 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data5, 733 - IWL_RX_PHY_DATA5_EHT_TYPE_AND_COMP, 734 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE); 735 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data5, 736 - IWL_RX_PHY_DATA5_EHT_MU_PUNC_CH_CODE, 737 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO); 738 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data4, 739 - IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS, 740 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS); 741 - IWL_MLD_ENC_USIG_VALUE_MASK 742 - (usig, data1, IWL_RX_PHY_DATA1_EHT_MU_NUM_SIG_SYM_USIGA2, 743 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS); 744 - 745 - eht->user_info[0] |= 746 - cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN) | 747 - LE32_DEC_ENC(data5, IWL_RX_PHY_DATA5_EHT_MU_STA_ID_USR, 748 - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID); 749 - 750 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M); 751 - eht->data[7] |= LE32_DEC_ENC 752 - (data5, IWL_RX_PHY_DATA5_EHT_MU_NUM_USR_NON_OFDMA, 753 - IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); 754 - 755 - /* 756 - * Hardware labels the content channels/RU allocation values 757 - * as follows: 758 - * Content Channel 1 Content Channel 2 759 - * 20 MHz: A1 760 - * 40 MHz: A1 B1 761 - * 80 MHz: A1 C1 B1 D1 762 - * 160 MHz: A1 C1 A2 C2 B1 D1 B2 D2 763 - * 320 MHz: A1 C1 A2 C2 A3 C3 A4 C4 B1 D1 B2 D2 B3 D3 B4 D4 764 - * 765 - * However firmware can only give us A1-D2, so the higher 766 - * frequencies are missing. 767 - */ 768 - 769 - switch (phy_bw) { 770 - case RATE_MCS_CHAN_WIDTH_320: 771 - /* additional values are missing in RX metadata */ 772 - fallthrough; 773 - case RATE_MCS_CHAN_WIDTH_160: 774 - /* content channel 1 */ 775 - IWL_MLD_ENC_EHT_RU(1_2_1, A2); 776 - IWL_MLD_ENC_EHT_RU(1_2_2, C2); 777 - /* content channel 2 */ 778 - IWL_MLD_ENC_EHT_RU(2_2_1, B2); 779 - IWL_MLD_ENC_EHT_RU(2_2_2, D2); 780 - fallthrough; 781 - case RATE_MCS_CHAN_WIDTH_80: 782 - /* content channel 1 */ 783 - IWL_MLD_ENC_EHT_RU(1_1_2, C1); 784 - /* content channel 2 */ 785 - IWL_MLD_ENC_EHT_RU(2_1_2, D1); 786 - fallthrough; 787 - case RATE_MCS_CHAN_WIDTH_40: 788 - /* content channel 2 */ 789 - IWL_MLD_ENC_EHT_RU(2_1_1, B1); 790 - fallthrough; 791 - case RATE_MCS_CHAN_WIDTH_20: 792 - IWL_MLD_ENC_EHT_RU(1_1_1, A1); 793 - break; 794 - } 795 - } else { 796 - __le32 usig_a1 = phy_data->rx_vec[0]; 797 - __le32 usig_a2 = phy_data->rx_vec[1]; 798 - 799 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 800 - IWL_RX_USIG_A1_DISREGARD, 801 - IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD); 802 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 803 - IWL_RX_USIG_A1_VALIDATE, 804 - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE); 805 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 806 - IWL_RX_USIG_A2_EHT_PPDU_TYPE, 807 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE); 808 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 809 - IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B2, 810 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE); 811 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 812 - IWL_RX_USIG_A2_EHT_PUNC_CHANNEL, 813 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO); 814 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 815 - IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B8, 816 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE); 817 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 818 - IWL_RX_USIG_A2_EHT_SIG_MCS, 819 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS); 820 - IWL_MLD_ENC_USIG_VALUE_MASK 821 - (usig, usig_a2, IWL_RX_USIG_A2_EHT_SIG_SYM_NUM, 822 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS); 823 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 824 - IWL_RX_USIG_A2_EHT_CRC_OK, 825 - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC); 826 - } 676 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 677 + OFDM_RX_FRAME_EHT_USIG1_DISREGARD, 678 + IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD); 679 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 680 + OFDM_RX_FRAME_EHT_PPDU_TYPE, 681 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE); 682 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 683 + OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B2, 684 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE); 685 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 686 + OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_1, 687 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1); 688 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 689 + OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_2, 690 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2); 691 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 692 + OFDM_RX_FRAME_EHT_TRIG_USIG2_DISREGARD, 693 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD); 827 694 } 828 695 829 - static void iwl_mld_decode_eht_ext_tb(struct iwl_mld *mld, 830 - struct iwl_mld_rx_phy_data *phy_data, 831 - struct ieee80211_rx_status *rx_status, 832 - struct ieee80211_radiotap_eht *eht, 833 - struct ieee80211_radiotap_eht_usig *usig) 696 + static void iwl_mld_decode_eht_usig_non_tb(struct iwl_mld_rx_phy_data *phy_data, 697 + struct ieee80211_radiotap_eht_usig *usig) 834 698 { 835 - if (phy_data->with_data) { 836 - __le32 data5 = phy_data->data5; 699 + __le32 usig_a1 = phy_data->ntfy->sigs.eht.usig_a1; 700 + __le32 usig_a2 = phy_data->ntfy->sigs.eht.usig_a2_eht; 837 701 838 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data5, 839 - IWL_RX_PHY_DATA5_EHT_TYPE_AND_COMP, 840 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE); 841 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data5, 842 - IWL_RX_PHY_DATA5_EHT_TB_SPATIAL_REUSE1, 843 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1); 844 - 845 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, data5, 846 - IWL_RX_PHY_DATA5_EHT_TB_SPATIAL_REUSE2, 847 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2); 848 - } else { 849 - __le32 usig_a1 = phy_data->rx_vec[0]; 850 - __le32 usig_a2 = phy_data->rx_vec[1]; 851 - 852 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 853 - IWL_RX_USIG_A1_DISREGARD, 854 - IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD); 855 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 856 - IWL_RX_USIG_A2_EHT_PPDU_TYPE, 857 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE); 858 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 859 - IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B2, 860 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE); 861 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 862 - IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_1, 863 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1); 864 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 865 - IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_2, 866 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2); 867 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 868 - IWL_RX_USIG_A2_EHT_TRIG_USIG2_DISREGARD, 869 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD); 870 - IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 871 - IWL_RX_USIG_A2_EHT_CRC_OK, 872 - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC); 873 - } 702 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 703 + OFDM_RX_FRAME_EHT_USIG1_DISREGARD, 704 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD); 705 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a1, 706 + OFDM_RX_FRAME_EHT_USIG1_VALIDATE, 707 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE); 708 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 709 + OFDM_RX_FRAME_EHT_PPDU_TYPE, 710 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE); 711 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 712 + OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B2, 713 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE); 714 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 715 + OFDM_RX_FRAME_EHT_PUNC_CHANNEL, 716 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO); 717 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 718 + OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B8, 719 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE); 720 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 721 + OFDM_RX_FRAME_EHT_SIG_MCS, 722 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS); 723 + IWL_MLD_ENC_USIG_VALUE_MASK(usig, usig_a2, 724 + OFDM_RX_FRAME_EHT_SIG_SYM_NUM, 725 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS); 874 726 } 875 727 876 - static void iwl_mld_decode_eht_ru(struct iwl_mld *mld, 877 - struct ieee80211_rx_status *rx_status, 878 - struct ieee80211_radiotap_eht *eht) 728 + static void iwl_mld_decode_eht_usig(struct iwl_mld_rx_phy_data *phy_data, 729 + struct sk_buff *skb) 879 730 { 880 - u32 ru = le32_get_bits(eht->data[8], 881 - IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1); 731 + u32 he_type = phy_data->rate_n_flags & RATE_MCS_HE_TYPE_MSK; 732 + __le32 usig_a1 = phy_data->ntfy->sigs.eht.usig_a1; 733 + __le32 usig_a2 = phy_data->ntfy->sigs.eht.usig_a2_eht; 734 + struct ieee80211_radiotap_eht_usig *usig; 735 + u32 bw; 736 + 737 + usig = iwl_mld_radiotap_put_tlv(skb, IEEE80211_RADIOTAP_EHT_USIG, 738 + sizeof(*usig)); 739 + 740 + BUILD_BUG_ON(offsetof(union iwl_sigs, eht.usig_a1) != 741 + offsetof(union iwl_sigs, eht_tb.usig_a1)); 742 + BUILD_BUG_ON(offsetof(union iwl_sigs, eht.usig_a2_eht) != 743 + offsetof(union iwl_sigs, eht_tb.usig_a2_eht)); 744 + 745 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | 746 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | 747 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_CHECKED | 748 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | 749 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN); 750 + 751 + #define CHECK_BW(bw) \ 752 + BUILD_BUG_ON(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_ ## bw ## MHZ != \ 753 + RATE_MCS_CHAN_WIDTH_ ## bw ## _VAL) 754 + CHECK_BW(20); 755 + CHECK_BW(40); 756 + CHECK_BW(80); 757 + CHECK_BW(160); 758 + #undef CHECK_BW 759 + BUILD_BUG_ON(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_320MHZ_1 != 760 + RATE_MCS_CHAN_WIDTH_320_VAL); 761 + bw = u32_get_bits(phy_data->rate_n_flags, RATE_MCS_CHAN_WIDTH_MSK); 762 + /* specific handling for 320MHz-1/320MHz-2 */ 763 + if (bw == RATE_MCS_CHAN_WIDTH_320_VAL) 764 + bw += le32_get_bits(usig_a1, OFDM_RX_FRAME_EHT_BW320_SLOT); 765 + usig->common |= le32_encode_bits(bw, 766 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW); 767 + 768 + usig->common |= LE32_DEC_ENC(usig_a1, OFDM_RX_FRAME_ENHANCED_WIFI_UL_FLAG, 769 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL); 770 + usig->common |= LE32_DEC_ENC(usig_a1, OFDM_RX_FRAME_ENHANCED_WIFI_BSS_COLOR, 771 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR); 772 + 773 + if (le32_get_bits(usig_a1, OFDM_RX_FRAME_EHT_USIG1_VALIDATE) && 774 + le32_get_bits(usig_a2, OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B2) && 775 + le32_get_bits(usig_a2, OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B8)) 776 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_OK); 777 + 778 + usig->common |= LE32_DEC_ENC(usig_a1, 779 + OFDM_RX_FRAME_ENHANCED_WIFI_TXOP_DURATION, 780 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); 781 + 782 + if (!le32_get_bits(usig_a2, OFDM_RX_USIG_CRC_OK)) 783 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); 784 + 785 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN); 786 + usig->common |= LE32_DEC_ENC(usig_a1, 787 + OFDM_RX_FRAME_ENHANCED_WIFI_VER_ID, 788 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER); 789 + 790 + if (he_type == RATE_MCS_HE_TYPE_TRIG) 791 + iwl_mld_decode_eht_usig_tb(phy_data, usig); 792 + else 793 + iwl_mld_decode_eht_usig_non_tb(phy_data, usig); 794 + } 795 + 796 + static void 797 + iwl_mld_eht_set_ru_alloc(struct ieee80211_rx_status *rx_status, 798 + u32 ru_with_p80) 799 + { 882 800 enum nl80211_eht_ru_alloc nl_ru; 801 + u32 ru = ru_with_p80 >> 1; 883 802 884 - /* Using D1.5 Table 9-53a - Encoding of PS160 and RU Allocation subfields 885 - * in an EHT variant User Info field 803 + /* 804 + * HW always uses trigger frame format: 805 + * 806 + * Draft PIEEE802.11be D7.0 Table 9-46l - Encoding of the PS160 and 807 + * RU Allocation subfields in an EHT variant User Info field 886 808 */ 887 809 888 810 switch (ru) { ··· 877 929 rx_status->eht.ru = nl_ru; 878 930 } 879 931 880 - static void iwl_mld_decode_eht_phy_data(struct iwl_mld *mld, 881 - struct iwl_mld_rx_phy_data *phy_data, 882 - struct ieee80211_rx_status *rx_status, 883 - struct ieee80211_radiotap_eht *eht, 884 - struct ieee80211_radiotap_eht_usig *usig) 885 - 932 + static void iwl_mld_decode_eht_tb(struct iwl_mld_rx_phy_data *phy_data, 933 + struct ieee80211_rx_status *rx_status, 934 + struct ieee80211_radiotap_eht *eht) 886 935 { 887 - __le32 data0 = phy_data->data0; 888 - __le32 data1 = phy_data->data1; 889 - __le32 usig_a1 = phy_data->rx_vec[0]; 890 - u8 info_type = phy_data->info_type; 891 - 892 - /* Not in EHT range */ 893 - if (info_type < IWL_RX_PHY_INFO_TYPE_EHT_MU || 894 - info_type > IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT) 936 + if (!(phy_data->ntfy->flags & IWL_SNIF_FLAG_VALID_TB_RX)) 895 937 return; 896 938 897 - usig->common |= cpu_to_le32 898 - (IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | 899 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN); 900 - if (phy_data->with_data) { 901 - usig->common |= LE32_DEC_ENC(data0, 902 - IWL_RX_PHY_DATA0_EHT_UPLINK, 903 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL); 904 - usig->common |= LE32_DEC_ENC(data0, 905 - IWL_RX_PHY_DATA0_EHT_BSS_COLOR_MASK, 906 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR); 907 - } else { 908 - usig->common |= LE32_DEC_ENC(usig_a1, 909 - IWL_RX_USIG_A1_UL_FLAG, 910 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL); 911 - usig->common |= LE32_DEC_ENC(usig_a1, 912 - IWL_RX_USIG_A1_BSS_COLOR, 913 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR); 914 - } 939 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT | 940 + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | 941 + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | 942 + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | 943 + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | 944 + IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80); 915 945 916 - usig->common |= 917 - cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_CHECKED); 918 - usig->common |= 919 - LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_VALIDATE, 920 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_OK); 921 - 922 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE); 923 - eht->data[0] |= LE32_DEC_ENC(data0, 924 - IWL_RX_PHY_DATA0_ETH_SPATIAL_REUSE_MASK, 925 - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); 926 - 927 - /* All RU allocating size/index is in TB format */ 928 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT); 929 - eht->data[8] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PS160, 946 + eht->data[8] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx0, 947 + OFDM_UCODE_TRIG_BASE_PS160, 930 948 IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160); 931 - eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B0, 932 - IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0); 933 - eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B1_B7, 949 + eht->data[8] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx1, 950 + OFDM_UCODE_TRIG_BASE_RX_RU, 951 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0 | 934 952 IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1); 935 - 936 - iwl_mld_decode_eht_ru(mld, rx_status, eht); 937 - 938 - /* We only get here in case of IWL_RX_MPDU_PHY_TSF_OVERLOAD is set 939 - * which is on only in case of monitor mode so no need to check monitor 940 - * mode 941 - */ 942 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80); 943 - eht->data[1] |= 944 - le32_encode_bits(mld->monitor.p80, 945 - IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80); 946 - 947 - usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN); 948 - if (phy_data->with_data) 949 - usig->common |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_TXOP_DUR_MASK, 950 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); 951 - else 952 - usig->common |= LE32_DEC_ENC(usig_a1, IWL_RX_USIG_A1_TXOP_DURATION, 953 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); 954 - 955 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM); 956 - eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_LDPC_EXT_SYM, 953 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx1, 954 + OFDM_UCODE_TRIG_BASE_RX_CODING_EXTRA_SYM, 957 955 IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); 958 - 959 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM); 960 - eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PRE_FEC_PAD_MASK, 961 - IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); 962 - 963 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM); 964 - eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PE_DISAMBIG, 956 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx1, 957 + OFDM_UCODE_TRIG_BASE_RX_PRE_FEC_PAD_FACTOR, 958 + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); 959 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx1, 960 + OFDM_UCODE_TRIG_BASE_RX_PE_DISAMBIG, 965 961 IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); 962 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx1, 963 + OFDM_UCODE_TRIG_BASE_RX_NUM_OF_LTF_SYM, 964 + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); 965 + eht->data[1] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht_tb.tb_rx0, 966 + OFDM_UCODE_TRIG_BASE_RX_RU_P80, 967 + IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80); 966 968 967 - /* TODO: what about IWL_RX_PHY_DATA0_EHT_BW320_SLOT */ 969 + iwl_mld_eht_set_ru_alloc(rx_status, 970 + le32_get_bits(phy_data->ntfy->sigs.eht_tb.tb_rx1, 971 + OFDM_UCODE_TRIG_BASE_RX_RU)); 972 + } 968 973 969 - if (!le32_get_bits(data0, IWL_RX_PHY_DATA0_EHT_SIGA_CRC_OK)) 970 - usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); 974 + static void iwl_mld_eht_decode_user_ru(struct iwl_mld_rx_phy_data *phy_data, 975 + struct ieee80211_radiotap_eht *eht) 976 + { 977 + u32 phy_bw = phy_data->rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 971 978 972 - usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN); 973 - usig->common |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PHY_VER, 974 - IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER); 979 + if (!(phy_data->ntfy->flags & IWL_SNIF_FLAG_VALID_RU)) 980 + return; 981 + 982 + #define __IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 983 + eht->data[(rt_data)] |= \ 984 + (cpu_to_le32(IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru ## _KNOWN) | \ 985 + LE32_DEC_ENC(phy_data->ntfy->sigs.eht.cmn[fw_data], \ 986 + OFDM_RX_FRAME_EHT_RU_ALLOC_ ## fw_data ## _ ## fw_ru, \ 987 + IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru)) 988 + 989 + #define _IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 990 + __IWL_MLD_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) 991 + 992 + #define IEEE80211_RADIOTAP_RU_DATA_1_1_1 1 993 + #define IEEE80211_RADIOTAP_RU_DATA_2_1_1 2 994 + #define IEEE80211_RADIOTAP_RU_DATA_1_1_2 2 995 + #define IEEE80211_RADIOTAP_RU_DATA_2_1_2 2 996 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_1 3 997 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_1 3 998 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_2 3 999 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_2 4 1000 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_3 4 1001 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_3 4 1002 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_4 5 1003 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_4 5 1004 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_5 5 1005 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_5 6 1006 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_6 6 1007 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_6 6 1008 + 1009 + #define IWL_RX_RU_DATA_A1 0 1010 + #define IWL_RX_RU_DATA_A2 0 1011 + #define IWL_RX_RU_DATA_A3 0 1012 + #define IWL_RX_RU_DATA_A4 4 1013 + #define IWL_RX_RU_DATA_B1 1 1014 + #define IWL_RX_RU_DATA_B2 1 1015 + #define IWL_RX_RU_DATA_B3 1 1016 + #define IWL_RX_RU_DATA_B4 4 1017 + #define IWL_RX_RU_DATA_C1 2 1018 + #define IWL_RX_RU_DATA_C2 2 1019 + #define IWL_RX_RU_DATA_C3 2 1020 + #define IWL_RX_RU_DATA_C4 5 1021 + #define IWL_RX_RU_DATA_D1 3 1022 + #define IWL_RX_RU_DATA_D2 3 1023 + #define IWL_RX_RU_DATA_D3 3 1024 + #define IWL_RX_RU_DATA_D4 5 1025 + 1026 + #define IWL_MLD_ENC_EHT_RU(rt_ru, fw_ru) \ 1027 + _IWL_MLD_ENC_EHT_RU(IEEE80211_RADIOTAP_RU_DATA_ ## rt_ru, \ 1028 + rt_ru, \ 1029 + IWL_RX_RU_DATA_ ## fw_ru, \ 1030 + fw_ru) 975 1031 976 1032 /* 977 - * TODO: what about TB - IWL_RX_PHY_DATA1_EHT_TB_PILOT_TYPE, 978 - * IWL_RX_PHY_DATA1_EHT_TB_LOW_SS 1033 + * Hardware labels the content channels/RU allocation values 1034 + * as follows: 1035 + * 1036 + * Content Channel 1 Content Channel 2 1037 + * 20 MHz: A1 1038 + * 40 MHz: A1 B1 1039 + * 80 MHz: A1 C1 B1 D1 1040 + * 160 MHz: A1 C1 A2 C2 B1 D1 B2 D2 1041 + * 320 MHz: A1 C1 A2 C2 A3 C3 A4 C4 B1 D1 B2 D2 B3 D3 B4 D4 979 1042 */ 980 1043 981 - eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF); 982 - eht->data[0] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_SIG_LTF_NUM, 1044 + switch (phy_bw) { 1045 + case RATE_MCS_CHAN_WIDTH_320: 1046 + /* content channel 1 */ 1047 + IWL_MLD_ENC_EHT_RU(1_2_3, A3); 1048 + IWL_MLD_ENC_EHT_RU(1_2_4, C3); 1049 + IWL_MLD_ENC_EHT_RU(1_2_5, A4); 1050 + IWL_MLD_ENC_EHT_RU(1_2_6, C4); 1051 + /* content channel 2 */ 1052 + IWL_MLD_ENC_EHT_RU(2_2_3, B3); 1053 + IWL_MLD_ENC_EHT_RU(2_2_4, D3); 1054 + IWL_MLD_ENC_EHT_RU(2_2_5, B4); 1055 + IWL_MLD_ENC_EHT_RU(2_2_6, D4); 1056 + fallthrough; 1057 + case RATE_MCS_CHAN_WIDTH_160: 1058 + /* content channel 1 */ 1059 + IWL_MLD_ENC_EHT_RU(1_2_1, A2); 1060 + IWL_MLD_ENC_EHT_RU(1_2_2, C2); 1061 + /* content channel 2 */ 1062 + IWL_MLD_ENC_EHT_RU(2_2_1, B2); 1063 + IWL_MLD_ENC_EHT_RU(2_2_2, D2); 1064 + fallthrough; 1065 + case RATE_MCS_CHAN_WIDTH_80: 1066 + /* content channel 1 */ 1067 + IWL_MLD_ENC_EHT_RU(1_1_2, C1); 1068 + /* content channel 2 */ 1069 + IWL_MLD_ENC_EHT_RU(2_1_2, D1); 1070 + fallthrough; 1071 + case RATE_MCS_CHAN_WIDTH_40: 1072 + /* content channel 2 */ 1073 + IWL_MLD_ENC_EHT_RU(2_1_1, B1); 1074 + fallthrough; 1075 + case RATE_MCS_CHAN_WIDTH_20: 1076 + /* content channel 1 */ 1077 + IWL_MLD_ENC_EHT_RU(1_1_1, A1); 1078 + break; 1079 + } 1080 + } 1081 + 1082 + static void iwl_mld_decode_eht_non_tb(struct iwl_mld_rx_phy_data *phy_data, 1083 + struct ieee80211_rx_status *rx_status, 1084 + struct ieee80211_radiotap_eht *eht) 1085 + { 1086 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | 1087 + /* All RU allocating size/index is in TB format */ 1088 + IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT | 1089 + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | 1090 + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | 1091 + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | 1092 + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | 1093 + IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80 | 1094 + IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M); 1095 + 1096 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1097 + OFDM_RX_FRAME_EHT_SPATIAL_REUSE, 1098 + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); 1099 + eht->data[8] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b2, 1100 + OFDM_RX_FRAME_EHT_STA_RU_PS160, 1101 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160); 1102 + eht->data[8] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b2, 1103 + OFDM_RX_FRAME_EHT_STA_RU, 1104 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0 | 1105 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1); 1106 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1107 + OFDM_RX_FRAME_EHT_CODING_EXTRA_SYM, 1108 + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); 1109 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1110 + OFDM_RX_FRAME_EHT_PRE_FEC_PAD_FACTOR, 1111 + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); 1112 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1113 + OFDM_RX_FRAME_EHT_PE_DISAMBIG, 1114 + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); 1115 + eht->data[0] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1116 + OFDM_RX_FRAME_EHT_NUM_OF_LTF_SYM, 983 1117 IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); 1118 + eht->data[1] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b2, 1119 + OFDM_RX_FRAME_EHT_STA_RU_P80, 1120 + IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80); 1121 + eht->data[7] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1122 + OFDM_RX_FRAME_EHT_NUM_OF_USERS, 1123 + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); 984 1124 985 - if (info_type == IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT || 986 - info_type == IWL_RX_PHY_INFO_TYPE_EHT_TB) 987 - iwl_mld_decode_eht_ext_tb(mld, phy_data, rx_status, eht, usig); 1125 + iwl_mld_eht_decode_user_ru(phy_data, eht); 988 1126 989 - if (info_type == IWL_RX_PHY_INFO_TYPE_EHT_MU_EXT || 990 - info_type == IWL_RX_PHY_INFO_TYPE_EHT_MU) 991 - iwl_mld_decode_eht_ext_mu(mld, phy_data, rx_status, eht, usig); 1127 + iwl_mld_eht_set_ru_alloc(rx_status, 1128 + le32_get_bits(phy_data->ntfy->sigs.eht.b2, 1129 + OFDM_RX_FRAME_EHT_STA_RU)); 1130 + } 1131 + 1132 + static void iwl_mld_decode_eht_phy_data(struct iwl_mld_rx_phy_data *phy_data, 1133 + struct ieee80211_rx_status *rx_status, 1134 + struct ieee80211_radiotap_eht *eht) 1135 + { 1136 + u32 he_type = phy_data->rate_n_flags & RATE_MCS_HE_TYPE_MSK; 1137 + 1138 + if (he_type == RATE_MCS_HE_TYPE_TRIG) 1139 + iwl_mld_decode_eht_tb(phy_data, rx_status, eht); 1140 + else 1141 + iwl_mld_decode_eht_non_tb(phy_data, rx_status, eht); 992 1142 } 993 1143 994 1144 static void iwl_mld_rx_eht(struct iwl_mld *mld, struct sk_buff *skb, 995 - struct iwl_mld_rx_phy_data *phy_data, 996 - int queue) 1145 + struct iwl_mld_rx_phy_data *phy_data) 997 1146 { 998 1147 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 999 1148 struct ieee80211_radiotap_eht *eht; 1000 - struct ieee80211_radiotap_eht_usig *usig; 1001 1149 size_t eht_len = sizeof(*eht); 1002 - 1003 1150 u32 rate_n_flags = phy_data->rate_n_flags; 1004 1151 u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; 1005 1152 /* EHT and HE have the same values for LTF */ 1006 1153 u8 ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN; 1007 - u16 phy_info = phy_data->phy_info; 1008 - u32 bw; 1009 1154 1010 1155 /* u32 for 1 user_info */ 1011 1156 if (phy_data->with_data) ··· 1106 1065 1107 1066 eht = iwl_mld_radiotap_put_tlv(skb, IEEE80211_RADIOTAP_EHT, eht_len); 1108 1067 1109 - usig = iwl_mld_radiotap_put_tlv(skb, IEEE80211_RADIOTAP_EHT_USIG, 1110 - sizeof(*usig)); 1111 1068 rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; 1112 - usig->common |= 1113 - cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN); 1114 - 1115 - /* specific handling for 320MHz */ 1116 - bw = u32_get_bits(rate_n_flags, RATE_MCS_CHAN_WIDTH_MSK); 1117 - if (bw == RATE_MCS_CHAN_WIDTH_320_VAL) 1118 - bw += le32_get_bits(phy_data->data0, 1119 - IWL_RX_PHY_DATA0_EHT_BW320_SLOT); 1120 - 1121 - usig->common |= cpu_to_le32 1122 - (FIELD_PREP(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW, bw)); 1123 - 1124 - /* report the AMPDU-EOF bit on single frames */ 1125 - if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 1126 - rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 1127 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1128 - if (phy_data->data0 & 1129 - cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 1130 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1131 - } 1132 - 1133 - /* update aggregation data for monitor sake on default queue */ 1134 - if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && 1135 - (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) { 1136 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1137 - if (phy_data->data0 & 1138 - cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 1139 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1140 - } 1141 - 1142 - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) 1143 - iwl_mld_decode_eht_phy_data(mld, phy_data, rx_status, eht, usig); 1144 - 1145 - #define CHECK_TYPE(F) \ 1146 - BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ 1147 - (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) 1148 - 1149 - CHECK_TYPE(SU); 1150 - CHECK_TYPE(EXT_SU); 1151 - CHECK_TYPE(MU); 1152 - CHECK_TYPE(TRIG); 1153 1069 1154 1070 switch (u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK)) { 1155 1071 case 0: ··· 1142 1144 1143 1145 if (ltf != IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN) { 1144 1146 eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_GI); 1145 - eht->data[0] |= cpu_to_le32 1146 - (FIELD_PREP(IEEE80211_RADIOTAP_EHT_DATA0_LTF, 1147 - ltf) | 1148 - FIELD_PREP(IEEE80211_RADIOTAP_EHT_DATA0_GI, 1149 - rx_status->eht.gi)); 1147 + eht->data[0] |= le32_encode_bits(ltf, 1148 + IEEE80211_RADIOTAP_EHT_DATA0_LTF) | 1149 + le32_encode_bits(rx_status->eht.gi, 1150 + IEEE80211_RADIOTAP_EHT_DATA0_GI); 1150 1151 } 1151 1152 1152 1153 if (!phy_data->with_data) { 1153 1154 eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | 1154 1155 IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S); 1155 - eht->data[7] |= 1156 - le32_encode_bits(le32_get_bits(phy_data->rx_vec[2], 1157 - RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK), 1158 - IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); 1156 + eht->data[7] |= LE32_DEC_ENC(phy_data->ntfy->sigs.eht.b1, 1157 + OFDM_RX_FRAME_EHT_NSTS, 1158 + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); 1159 1159 if (rate_n_flags & RATE_MCS_BF_MSK) 1160 1160 eht->data[7] |= 1161 1161 cpu_to_le32(IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); ··· 1173 1177 eht->user_info[0] |= 1174 1178 cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_CODING); 1175 1179 1176 - eht->user_info[0] |= cpu_to_le32 1177 - (FIELD_PREP(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS, 1178 - u32_get_bits(rate_n_flags, 1179 - RATE_VHT_MCS_RATE_CODE_MSK)) | 1180 - FIELD_PREP(IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O, 1181 - u32_get_bits(rate_n_flags, 1182 - RATE_MCS_NSS_MSK))); 1180 + eht->user_info[0] |= 1181 + le32_encode_bits(u32_get_bits(rate_n_flags, 1182 + RATE_VHT_MCS_RATE_CODE_MSK), 1183 + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | 1184 + le32_encode_bits(u32_get_bits(rate_n_flags, 1185 + RATE_MCS_NSS_MSK), 1186 + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O); 1183 1187 } 1188 + 1189 + if (likely(!phy_data->ntfy)) 1190 + return; 1191 + 1192 + if (phy_data->with_data) { 1193 + eht->user_info[0] |= 1194 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN) | 1195 + LE32_DEC_ENC(phy_data->ntfy->sigs.eht.user_id, 1196 + OFDM_RX_FRAME_EHT_USER_FIELD_ID, 1197 + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID); 1198 + } 1199 + 1200 + iwl_mld_decode_eht_usig(phy_data, skb); 1201 + iwl_mld_decode_eht_phy_data(phy_data, rx_status, eht); 1184 1202 } 1185 1203 1186 1204 #ifdef CONFIG_IWLWIFI_DEBUGFS ··· 1217 1207 radiotap->oui[0] = 0xf6; 1218 1208 radiotap->oui[1] = 0x54; 1219 1209 radiotap->oui[2] = 0x25; 1220 - /* radiotap sniffer config sub-namespace */ 1210 + /* Intel OUI default radiotap subtype */ 1221 1211 radiotap->oui_subtype = 1; 1212 + /* Sniffer config element type */ 1222 1213 radiotap->vendor_type = 0; 1223 1214 1224 1215 /* fill the data now */ ··· 1230 1219 } 1231 1220 #endif 1232 1221 1233 - /* Note: hdr can be NULL */ 1234 - static void iwl_mld_rx_fill_status(struct iwl_mld *mld, int link_id, 1235 - struct ieee80211_hdr *hdr, 1236 - struct sk_buff *skb, 1237 - struct iwl_mld_rx_phy_data *phy_data, 1238 - int queue) 1222 + static void iwl_mld_add_rtap_sniffer_phy_data(struct iwl_mld *mld, 1223 + struct sk_buff *skb, 1224 + struct iwl_rx_phy_air_sniffer_ntfy *ntfy) 1239 1225 { 1240 1226 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 1241 - u32 format = phy_data->rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 1227 + struct ieee80211_radiotap_vendor_content *radiotap; 1228 + const u16 vendor_data_len = sizeof(*ntfy); 1229 + 1230 + radiotap = 1231 + iwl_mld_radiotap_put_tlv(skb, 1232 + IEEE80211_RADIOTAP_VENDOR_NAMESPACE, 1233 + sizeof(*radiotap) + vendor_data_len); 1234 + 1235 + /* Intel OUI */ 1236 + radiotap->oui[0] = 0xf6; 1237 + radiotap->oui[1] = 0x54; 1238 + radiotap->oui[2] = 0x25; 1239 + /* Intel OUI default radiotap subtype */ 1240 + radiotap->oui_subtype = 1; 1241 + /* PHY data element type */ 1242 + radiotap->vendor_type = cpu_to_le16(1); 1243 + 1244 + /* fill the data now */ 1245 + memcpy(radiotap->data, ntfy, vendor_data_len); 1246 + 1247 + rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; 1248 + } 1249 + 1250 + static void 1251 + iwl_mld_set_rx_nonlegacy_rate_info(u32 rate_n_flags, 1252 + struct ieee80211_rx_status *rx_status) 1253 + { 1254 + u8 stbc = u32_get_bits(rate_n_flags, RATE_MCS_STBC_MSK); 1255 + 1256 + /* NSS may be overridden by PHY ntfy with full value */ 1257 + rx_status->nss = u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 1; 1258 + rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; 1259 + rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; 1260 + if (rate_n_flags & RATE_MCS_LDPC_MSK) 1261 + rx_status->enc_flags |= RX_ENC_FLAG_LDPC; 1262 + } 1263 + 1264 + static void iwl_mld_set_rx_rate(struct iwl_mld *mld, 1265 + struct iwl_mld_rx_phy_data *phy_data, 1266 + struct ieee80211_rx_status *rx_status) 1267 + { 1242 1268 u32 rate_n_flags = phy_data->rate_n_flags; 1243 1269 u8 stbc = u32_get_bits(rate_n_flags, RATE_MCS_STBC_MSK); 1270 + u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 1244 1271 bool is_sgi = rate_n_flags & RATE_MCS_SGI_MSK; 1245 1272 1246 - phy_data->info_type = IWL_RX_PHY_INFO_TYPE_NONE; 1247 - 1248 - if (phy_data->phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) 1249 - phy_data->info_type = 1250 - le32_get_bits(phy_data->data1, 1251 - IWL_RX_PHY_DATA1_INFO_TYPE_MASK); 1252 - 1253 - /* set the preamble flag if appropriate */ 1254 - if (format == RATE_MCS_MOD_TYPE_CCK && 1255 - phy_data->phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) 1256 - rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; 1257 - 1258 - iwl_mld_fill_signal(mld, link_id, hdr, rx_status, phy_data); 1259 - 1260 - /* This may be overridden by iwl_mld_rx_he() to HE_RU */ 1273 + /* bandwidth may be overridden to RU by PHY ntfy */ 1261 1274 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { 1262 1275 case RATE_MCS_CHAN_WIDTH_20: 1263 1276 break; ··· 1299 1264 break; 1300 1265 } 1301 1266 1302 - /* must be before L-SIG data */ 1303 - if (format == RATE_MCS_MOD_TYPE_HE) 1304 - iwl_mld_rx_he(mld, skb, phy_data, queue); 1305 - 1306 - iwl_mld_decode_lsig(skb, phy_data); 1307 - 1308 - rx_status->device_timestamp = phy_data->gp2_on_air_rise; 1309 - 1310 - /* using TLV format and must be after all fixed len fields */ 1311 - if (format == RATE_MCS_MOD_TYPE_EHT) 1312 - iwl_mld_rx_eht(mld, skb, phy_data, queue); 1313 - 1314 - #ifdef CONFIG_IWLWIFI_DEBUGFS 1315 - if (unlikely(mld->monitor.on)) { 1316 - iwl_mld_add_rtap_sniffer_config(mld, skb); 1317 - 1318 - if (mld->monitor.ptp_time) { 1319 - u64 adj_time = 1320 - iwl_mld_ptp_get_adj_time(mld, 1321 - phy_data->gp2_on_air_rise * 1322 - NSEC_PER_USEC); 1323 - 1324 - rx_status->mactime = div64_u64(adj_time, NSEC_PER_USEC); 1325 - rx_status->flag |= RX_FLAG_MACTIME_IS_RTAP_TS64; 1326 - rx_status->flag &= ~RX_FLAG_MACTIME; 1327 - } 1328 - } 1329 - #endif 1330 - 1331 - if (format != RATE_MCS_MOD_TYPE_CCK && is_sgi) 1332 - rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; 1333 - 1334 - if (rate_n_flags & RATE_MCS_LDPC_MSK) 1335 - rx_status->enc_flags |= RX_ENC_FLAG_LDPC; 1336 - 1337 1267 switch (format) { 1338 - case RATE_MCS_MOD_TYPE_HT: 1339 - rx_status->encoding = RX_ENC_HT; 1340 - rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); 1341 - rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; 1342 - break; 1343 - case RATE_MCS_MOD_TYPE_VHT: 1344 - case RATE_MCS_MOD_TYPE_HE: 1345 - case RATE_MCS_MOD_TYPE_EHT: 1346 - if (format == RATE_MCS_MOD_TYPE_VHT) { 1347 - rx_status->encoding = RX_ENC_VHT; 1348 - } else if (format == RATE_MCS_MOD_TYPE_HE) { 1349 - rx_status->encoding = RX_ENC_HE; 1350 - rx_status->he_dcm = 1351 - !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); 1352 - } else if (format == RATE_MCS_MOD_TYPE_EHT) { 1353 - rx_status->encoding = RX_ENC_EHT; 1354 - } 1355 - 1356 - rx_status->nss = u32_get_bits(rate_n_flags, 1357 - RATE_MCS_NSS_MSK) + 1; 1358 - rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; 1359 - rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; 1360 - break; 1361 - default: { 1268 + case RATE_MCS_MOD_TYPE_CCK: 1269 + if (phy_data->phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) 1270 + rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; 1271 + fallthrough; 1272 + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: { 1362 1273 int rate = 1363 1274 iwl_mld_legacy_hw_idx_to_mac80211_idx(rate_n_flags, 1364 1275 rx_status->band); 1276 + 1277 + /* override BW - it could be DUP and indicate the wrong BW */ 1278 + rx_status->bw = RATE_INFO_BW_20; 1365 1279 1366 1280 /* valid rate */ 1367 1281 if (rate >= 0 && rate <= 0xFF) { ··· 1321 1337 /* invalid rate */ 1322 1338 rx_status->rate_idx = 0; 1323 1339 1324 - if (net_ratelimit()) 1340 + /* 1341 + * In monitor mode we can see CCK frames on 5 or 6 GHz, usually 1342 + * just the (possibly malformed) PHY header by accident, since 1343 + * the decoder doesn't seem to turn off CCK. We cannot correctly 1344 + * encode the rate to mac80211 (and therefore not in radiotap) 1345 + * since we give the per-band index which doesn't cover those 1346 + * rates. 1347 + */ 1348 + if (!mld->monitor.on && net_ratelimit()) 1325 1349 IWL_ERR(mld, "invalid rate_n_flags=0x%x, band=%d\n", 1326 1350 rate_n_flags, rx_status->band); 1327 1351 break; 1328 1352 } 1353 + case RATE_MCS_MOD_TYPE_HT: 1354 + rx_status->encoding = RX_ENC_HT; 1355 + rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); 1356 + rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; 1357 + break; 1358 + case RATE_MCS_MOD_TYPE_VHT: 1359 + rx_status->encoding = RX_ENC_VHT; 1360 + iwl_mld_set_rx_nonlegacy_rate_info(rate_n_flags, rx_status); 1361 + break; 1362 + case RATE_MCS_MOD_TYPE_HE: 1363 + rx_status->encoding = RX_ENC_HE; 1364 + rx_status->he_dcm = 1365 + !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); 1366 + iwl_mld_set_rx_nonlegacy_rate_info(rate_n_flags, rx_status); 1367 + break; 1368 + case RATE_MCS_MOD_TYPE_EHT: 1369 + rx_status->encoding = RX_ENC_EHT; 1370 + iwl_mld_set_rx_nonlegacy_rate_info(rate_n_flags, rx_status); 1371 + break; 1372 + default: 1373 + WARN_ON_ONCE(1); 1329 1374 } 1375 + 1376 + if (format != RATE_MCS_MOD_TYPE_CCK && is_sgi) 1377 + rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; 1378 + } 1379 + 1380 + /* Note: hdr can be NULL */ 1381 + static void iwl_mld_rx_fill_status(struct iwl_mld *mld, int link_id, 1382 + struct ieee80211_hdr *hdr, 1383 + struct sk_buff *skb, 1384 + struct iwl_mld_rx_phy_data *phy_data) 1385 + { 1386 + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 1387 + u32 rate_n_flags = phy_data->rate_n_flags; 1388 + u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 1389 + 1390 + iwl_mld_fill_signal(mld, link_id, hdr, rx_status, phy_data); 1391 + 1392 + rx_status->device_timestamp = phy_data->gp2_on_air_rise; 1393 + 1394 + iwl_mld_set_rx_rate(mld, phy_data, rx_status); 1395 + 1396 + /* must be before L-SIG data (radiotap field order) */ 1397 + if (format == RATE_MCS_MOD_TYPE_HE) 1398 + iwl_mld_rx_he(skb, phy_data); 1399 + 1400 + iwl_mld_decode_lsig(skb, phy_data); 1401 + 1402 + /* TLVs - must be after radiotap fixed fields */ 1403 + if (format == RATE_MCS_MOD_TYPE_EHT) 1404 + iwl_mld_rx_eht(mld, skb, phy_data); 1405 + 1406 + #ifdef CONFIG_IWLWIFI_DEBUGFS 1407 + if (unlikely(mld->monitor.on)) { 1408 + iwl_mld_add_rtap_sniffer_config(mld, skb); 1409 + 1410 + if (mld->monitor.ptp_time) { 1411 + u64 adj_time = 1412 + iwl_mld_ptp_get_adj_time(mld, 1413 + phy_data->gp2_on_air_rise * 1414 + NSEC_PER_USEC); 1415 + 1416 + rx_status->mactime = div64_u64(adj_time, NSEC_PER_USEC); 1417 + rx_status->flag |= RX_FLAG_MACTIME_IS_RTAP_TS64; 1418 + rx_status->flag &= ~RX_FLAG_MACTIME; 1419 + } 1420 + } 1421 + #endif 1422 + 1423 + if (phy_data->ntfy) 1424 + iwl_mld_add_rtap_sniffer_phy_data(mld, skb, phy_data->ntfy); 1330 1425 } 1331 1426 1332 1427 /* iwl_mld_create_skb adds the rxb to a new skb */ ··· 1826 1763 return 0; 1827 1764 } 1828 1765 1829 - static void iwl_mld_rx_update_ampdu_ref(struct iwl_mld *mld, 1830 - struct iwl_mld_rx_phy_data *phy_data, 1831 - struct ieee80211_rx_status *rx_status) 1766 + static void iwl_mld_rx_update_ampdu_data(struct iwl_mld *mld, 1767 + struct iwl_mld_rx_phy_data *phy_data, 1768 + struct ieee80211_rx_status *rx_status) 1832 1769 { 1770 + u32 format = phy_data->rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 1833 1771 bool toggle_bit = 1834 1772 phy_data->phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; 1773 + 1774 + switch (format) { 1775 + case RATE_MCS_MOD_TYPE_CCK: 1776 + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: 1777 + /* no aggregation possible */ 1778 + return; 1779 + case RATE_MCS_MOD_TYPE_HT: 1780 + case RATE_MCS_MOD_TYPE_VHT: 1781 + /* single frames are not A-MPDU format */ 1782 + if (!(phy_data->phy_info & IWL_RX_MPDU_PHY_AMPDU)) 1783 + return; 1784 + break; 1785 + default: 1786 + /* HE/EHT/UHR have A-MPDU format for single frames */ 1787 + if (!(phy_data->phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 1788 + rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 1789 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1790 + if (phy_data->phy_info & IWL_RX_MPDU_PHY_EOF_INDICATION) 1791 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1792 + return; 1793 + } 1794 + } 1835 1795 1836 1796 rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 1837 1797 /* Toggle is switched whenever new aggregation starts. Make ··· 1867 1781 mld->monitor.ampdu_ref++; 1868 1782 mld->monitor.ampdu_toggle = toggle_bit; 1869 1783 phy_data->first_subframe = true; 1784 + 1785 + /* report EOF bit on the first subframe */ 1786 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1787 + if (phy_data->phy_info & IWL_RX_MPDU_PHY_EOF_INDICATION) 1788 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1870 1789 } 1871 1790 rx_status->ampdu_reference = mld->monitor.ampdu_ref; 1872 1791 } ··· 1901 1810 u32 mpdu_len; 1902 1811 enum iwl_mld_reorder_result reorder_res; 1903 1812 struct ieee80211_rx_status *rx_status; 1813 + unsigned int alloc_size = 128; 1904 1814 1905 1815 if (unlikely(mld->fw_status.in_hw_restart)) 1906 1816 return; ··· 1916 1824 "FW lied about packet len (%d)\n", pkt_len)) 1917 1825 return; 1918 1826 1827 + iwl_mld_fill_phy_data_from_mpdu(mld, mpdu_desc, &phy_data); 1828 + 1919 1829 /* Don't use dev_alloc_skb(), we'll have enough headroom once 1920 1830 * ieee80211_hdr pulled. 1831 + * 1832 + * For monitor mode we need more space to include the full PHY 1833 + * notification data. 1921 1834 */ 1922 - skb = alloc_skb(128, GFP_ATOMIC); 1835 + if (unlikely(mld->monitor.on) && phy_data.ntfy) 1836 + alloc_size += sizeof(struct iwl_rx_phy_air_sniffer_ntfy); 1837 + skb = alloc_skb(alloc_size, GFP_ATOMIC); 1923 1838 if (!skb) { 1924 1839 IWL_ERR(mld, "alloc_skb failed\n"); 1925 1840 return; 1926 1841 } 1927 1842 1928 1843 hdr = (void *)(pkt->data + mpdu_desc_size); 1929 - 1930 - iwl_mld_fill_phy_data(mld, mpdu_desc, &phy_data); 1931 1844 1932 1845 if (mpdu_desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) { 1933 1846 /* If the device inserted padding it means that (it thought) ··· 1958 1861 if (drop) 1959 1862 goto drop; 1960 1863 1961 - /* update aggregation data for monitor sake on default queue */ 1962 - if (!queue && (phy_data.phy_info & IWL_RX_MPDU_PHY_AMPDU)) 1963 - iwl_mld_rx_update_ampdu_ref(mld, &phy_data, rx_status); 1864 + if (unlikely(mld->monitor.on)) 1865 + iwl_mld_rx_update_ampdu_data(mld, &phy_data, rx_status); 1964 1866 1965 1867 /* Keep packets with CRC errors (and with overrun) for monitor mode 1966 1868 * (otherwise the firmware discards them) but mark them as bad. ··· 1993 1897 link_id = u8_get_bits(mpdu_desc->mac_phy_band, 1994 1898 IWL_RX_MPDU_MAC_PHY_BAND_LINK_MASK); 1995 1899 1996 - iwl_mld_rx_fill_status(mld, link_id, hdr, skb, &phy_data, queue); 1900 + iwl_mld_rx_fill_status(mld, link_id, hdr, skb, &phy_data); 1997 1901 1998 1902 if (iwl_mld_rx_crypto(mld, sta, hdr, rx_status, mpdu_desc, queue, 1999 1903 le32_to_cpu(pkt->len_n_flags), &crypto_len)) ··· 2127 2031 wake_up(&mld->rxq_sync.waitq); 2128 2032 } 2129 2033 2130 - void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, 2131 - struct iwl_rx_packet *pkt, int queue) 2034 + static void iwl_mld_no_data_rx(struct iwl_mld *mld, 2035 + struct napi_struct *napi, 2036 + struct iwl_rx_phy_air_sniffer_ntfy *ntfy) 2132 2037 { 2133 - struct iwl_rx_no_data_ver_3 *desc; 2134 - struct iwl_mld_rx_phy_data phy_data; 2135 2038 struct ieee80211_rx_status *rx_status; 2039 + struct iwl_mld_rx_phy_data phy_data = { 2040 + .ntfy = ntfy, 2041 + .phy_info = 0, /* short preamble set below */ 2042 + .rate_n_flags = le32_to_cpu(ntfy->rate), 2043 + .gp2_on_air_rise = le32_to_cpu(ntfy->on_air_rise_time), 2044 + .energy_a = ntfy->rssi_a, 2045 + .energy_b = ntfy->rssi_b, 2046 + }; 2047 + u32 format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 2136 2048 struct sk_buff *skb; 2137 - u32 format, rssi; 2138 - u8 channel; 2139 2049 2140 - if (unlikely(mld->fw_status.in_hw_restart)) 2050 + skb = alloc_skb(128 + sizeof(struct iwl_rx_phy_air_sniffer_ntfy), 2051 + GFP_ATOMIC); 2052 + if (!skb) 2141 2053 return; 2142 - 2143 - if (IWL_FW_CHECK(mld, iwl_rx_packet_payload_len(pkt) < sizeof(*desc), 2144 - "Bad RX_NO_DATA_NOTIF size (%d)\n", 2145 - iwl_rx_packet_payload_len(pkt))) 2146 - return; 2147 - 2148 - desc = (void *)pkt->data; 2149 - 2150 - rssi = le32_to_cpu(desc->rssi); 2151 - channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK); 2152 - 2153 - phy_data.energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK); 2154 - phy_data.energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK); 2155 - phy_data.data0 = desc->phy_info[0]; 2156 - phy_data.data1 = desc->phy_info[1]; 2157 - phy_data.phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD; 2158 - phy_data.gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time); 2159 - phy_data.rate_n_flags = iwl_v3_rate_from_v2_v3(desc->rate, 2160 - mld->fw_rates_ver_3); 2161 - phy_data.with_data = false; 2162 - 2163 - BUILD_BUG_ON(sizeof(phy_data.rx_vec) != sizeof(desc->rx_vec)); 2164 - memcpy(phy_data.rx_vec, desc->rx_vec, sizeof(phy_data.rx_vec)); 2165 - 2166 - format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; 2167 - 2168 - /* Don't use dev_alloc_skb(), we'll have enough headroom once 2169 - * ieee80211_hdr pulled. 2170 - */ 2171 - skb = alloc_skb(128, GFP_ATOMIC); 2172 - if (!skb) { 2173 - IWL_ERR(mld, "alloc_skb failed\n"); 2174 - return; 2175 - } 2176 2054 2177 2055 rx_status = IEEE80211_SKB_RXCB(skb); 2178 2056 2179 2057 /* 0-length PSDU */ 2180 2058 rx_status->flag |= RX_FLAG_NO_PSDU; 2181 2059 2182 - /* mark as failed PLCP on any errors to skip checks in mac80211 */ 2183 - if (le32_get_bits(desc->info, RX_NO_DATA_INFO_ERR_MSK) != 2184 - RX_NO_DATA_INFO_ERR_NONE) 2185 - rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; 2186 - 2187 - switch (le32_get_bits(desc->info, RX_NO_DATA_INFO_TYPE_MSK)) { 2188 - case RX_NO_DATA_INFO_TYPE_NDP: 2060 + switch (ntfy->status) { 2061 + case IWL_SNIF_STAT_PLCP_RX_OK: 2062 + /* we only get here with sounding PPDUs */ 2189 2063 rx_status->zero_length_psdu_type = 2190 2064 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING; 2191 2065 break; 2192 - case RX_NO_DATA_INFO_TYPE_MU_UNMATCHED: 2193 - case RX_NO_DATA_INFO_TYPE_TB_UNMATCHED: 2066 + case IWL_SNIF_STAT_AID_NOT_FOR_US: 2194 2067 rx_status->zero_length_psdu_type = 2195 2068 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED; 2196 2069 break; 2070 + case IWL_SNIF_STAT_PLCP_RX_LSIG_ERR: 2071 + case IWL_SNIF_STAT_PLCP_RX_SIGA_ERR: 2072 + case IWL_SNIF_STAT_PLCP_RX_SIGB_ERR: 2073 + case IWL_SNIF_STAT_UNKNOWN_ERROR: 2197 2074 default: 2075 + rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; 2076 + fallthrough; 2077 + case IWL_SNIF_STAT_UNEXPECTED_TB: 2078 + case IWL_SNIF_STAT_UNSUPPORTED_RATE: 2198 2079 rx_status->zero_length_psdu_type = 2199 2080 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_VENDOR; 2200 - break; 2081 + /* we could include the real reason in a vendor TLV */ 2201 2082 } 2202 2083 2203 - rx_status->band = channel > 14 ? NL80211_BAND_5GHZ : 2204 - NL80211_BAND_2GHZ; 2084 + if (format == RATE_MCS_MOD_TYPE_CCK && 2085 + ntfy->legacy_sig.cck & cpu_to_le32(CCK_CRFR_SHORT_PREAMBLE)) 2086 + phy_data.phy_info |= IWL_RX_MPDU_PHY_SHORT_PREAMBLE; 2205 2087 2206 - rx_status->freq = ieee80211_channel_to_frequency(channel, 2207 - rx_status->band); 2088 + iwl_mld_fill_rx_status_band_freq(IEEE80211_SKB_RXCB(skb), 2089 + ntfy->band, ntfy->channel); 2208 2090 2209 2091 /* link ID is ignored for NULL header */ 2210 - iwl_mld_rx_fill_status(mld, -1, NULL, skb, &phy_data, queue); 2092 + iwl_mld_rx_fill_status(mld, -1, NULL, skb, &phy_data); 2211 2093 2212 2094 /* No more radiotap info should be added after this point. 2213 2095 * Mark it as mac header for upper layers to know where ··· 2193 2119 */ 2194 2120 skb_set_mac_header(skb, skb->len); 2195 2121 2196 - /* Override the nss from the rx_vec since the rate_n_flags has 2197 - * only 1 bit for the nss which gives a max of 2 ss but there 2198 - * may be up to 8 spatial streams. 2199 - */ 2200 - switch (format) { 2201 - case RATE_MCS_MOD_TYPE_VHT: 2202 - rx_status->nss = 2203 - le32_get_bits(desc->rx_vec[0], 2204 - RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; 2205 - break; 2206 - case RATE_MCS_MOD_TYPE_HE: 2207 - rx_status->nss = 2208 - le32_get_bits(desc->rx_vec[0], 2209 - RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1; 2210 - break; 2211 - case RATE_MCS_MOD_TYPE_EHT: 2212 - rx_status->nss = 2213 - le32_get_bits(desc->rx_vec[2], 2214 - RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK) + 1; 2215 - } 2216 - 2217 2122 /* pass the packet to mac80211 */ 2218 2123 rcu_read_lock(); 2219 2124 ieee80211_rx_napi(mld->hw, NULL, skb, napi); 2220 2125 rcu_read_unlock(); 2126 + } 2127 + 2128 + void iwl_mld_handle_phy_air_sniffer_notif(struct iwl_mld *mld, 2129 + struct napi_struct *napi, 2130 + struct iwl_rx_packet *pkt) 2131 + { 2132 + struct iwl_rx_phy_air_sniffer_ntfy *ntfy = (void *)pkt->data; 2133 + bool is_ndp = false; 2134 + u32 he_type; 2135 + 2136 + if (IWL_FW_CHECK(mld, iwl_rx_packet_payload_len(pkt) < sizeof(*ntfy), 2137 + "invalid air sniffer notification size\n")) 2138 + return; 2139 + 2140 + /* check if there's an old one to release as errored */ 2141 + if (mld->monitor.phy.valid && !mld->monitor.phy.used) { 2142 + /* didn't capture data, so override status */ 2143 + mld->monitor.phy.data.status = IWL_SNIF_STAT_AID_NOT_FOR_US; 2144 + iwl_mld_no_data_rx(mld, napi, &mld->monitor.phy.data); 2145 + } 2146 + 2147 + /* old data is no longer valid now */ 2148 + mld->monitor.phy.valid = false; 2149 + 2150 + he_type = le32_to_cpu(ntfy->rate) & RATE_MCS_HE_TYPE_MSK; 2151 + 2152 + switch (le32_to_cpu(ntfy->rate) & RATE_MCS_MOD_TYPE_MSK) { 2153 + case RATE_MCS_MOD_TYPE_HT: 2154 + is_ndp = !le32_get_bits(ntfy->sigs.ht.a1, 2155 + OFDM_RX_FRAME_HT_LENGTH); 2156 + break; 2157 + case RATE_MCS_MOD_TYPE_VHT: 2158 + is_ndp = le32_get_bits(ntfy->sigs.vht.a0, 2159 + OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM_VALID) && 2160 + !le32_get_bits(ntfy->sigs.vht.a0, 2161 + OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM); 2162 + break; 2163 + case RATE_MCS_MOD_TYPE_HE: 2164 + if (he_type == RATE_MCS_HE_TYPE_TRIG) 2165 + break; 2166 + is_ndp = le32_get_bits(ntfy->sigs.he.a3, 2167 + OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM_VALID) && 2168 + !le32_get_bits(ntfy->sigs.he.a3, 2169 + OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM); 2170 + break; 2171 + case RATE_MCS_MOD_TYPE_EHT: 2172 + if (he_type == RATE_MCS_HE_TYPE_TRIG) 2173 + break; 2174 + is_ndp = le32_get_bits(ntfy->sigs.eht.sig2, 2175 + OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM_VALID) && 2176 + !le32_get_bits(ntfy->sigs.eht.sig2, 2177 + OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM); 2178 + break; 2179 + } 2180 + 2181 + if (ntfy->status != IWL_SNIF_STAT_PLCP_RX_OK || is_ndp) { 2182 + iwl_mld_no_data_rx(mld, napi, ntfy); 2183 + return; 2184 + } 2185 + 2186 + /* hang on to it for the RX_MPDU data packet(s) */ 2187 + mld->monitor.phy.data = *ntfy; 2188 + mld->monitor.phy.valid = true; 2189 + mld->monitor.phy.used = false; 2221 2190 }
+3 -2
drivers/net/wireless/intel/iwlwifi/mld/rx.h
··· 66 66 struct sk_buff *skb, int queue, 67 67 struct ieee80211_sta *sta); 68 68 69 - void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi, 70 - struct iwl_rx_packet *pkt, int queue); 69 + void iwl_mld_handle_phy_air_sniffer_notif(struct iwl_mld *mld, 70 + struct napi_struct *napi, 71 + struct iwl_rx_packet *pkt); 71 72 72 73 #endif /* __iwl_mld_agg_h__ */
+1 -1
drivers/net/wireless/intel/iwlwifi/mld/sta.c
··· 890 890 sizeof(queue_counter->per_link)); 891 891 queue_counter->window_start_time = jiffies; 892 892 893 - IWL_DEBUG_INFO(mld, "MPDU counters are cleared\n"); 893 + IWL_DEBUG_EHT(mld, "MPDU counters are cleared\n"); 894 894 } 895 895 896 896 link_counter = &queue_counter->per_link[mld_link->fw_id];
+3 -12
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
··· 115 115 116 116 117 117 if (version >= 6) { 118 - struct iwl_alive_ntf_v6 *palive; 118 + struct iwl_alive_ntf_v7 *palive; 119 119 120 120 if (pkt_len < sizeof(*palive)) 121 121 return false; ··· 214 214 ~FW_ADDR_CACHE_CONTROL; 215 215 216 216 if (umac_error_table) { 217 - if (umac_error_table >= 218 - mvm->trans->mac_cfg->base->min_umac_error_event_table) { 219 - iwl_fw_umac_set_alive_err_table(mvm->trans, 220 - umac_error_table); 221 - } else { 222 - IWL_ERR(mvm, 223 - "Not valid error log pointer 0x%08X for %s uCode\n", 224 - umac_error_table, 225 - (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ? 226 - "Init" : "RT"); 227 - } 217 + iwl_fw_umac_set_alive_err_table(mvm->trans, 218 + umac_error_table); 228 219 } 229 220 230 221 alive_data->valid = status == IWL_ALIVE_STATUS_OK;
-3
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
··· 102 102 mvm->csme_vif = vif; 103 103 } 104 104 105 - if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) 106 - vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 107 - 108 105 return 0; 109 106 110 107 out_free_bf:
+5
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 2894 2894 2895 2895 void iwl_mvm_smps_workaround(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2896 2896 bool update); 2897 + 2898 + /* rate_n_flags conversion */ 2899 + u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver); 2900 + __le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver); 2901 + 2897 2902 #endif /* __IWL_MVM_H__ */
+6 -18
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2017 Intel Deutschland GmbH 6 6 */ ··· 202 202 static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm, 203 203 struct iwl_mvm_phy_ctxt *ctxt, 204 204 const struct cfg80211_chan_def *chandef, 205 - const struct cfg80211_chan_def *ap, 206 205 u8 chains_static, u8 chains_dynamic, 207 206 u32 action) 208 207 { 209 208 int ret; 210 209 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1); 211 210 212 - if (ver < 5 || !ap || !ap->chan) 213 - ap = NULL; 214 - 215 - if (ver >= 3 && ver <= 6) { 211 + if (ver >= 3 && ver <= 4) { 216 212 struct iwl_phy_context_cmd cmd = {}; 217 213 218 214 /* Set the command header fields */ ··· 218 222 iwl_mvm_phy_ctxt_cmd_data(mvm, ctxt, &cmd, chandef, 219 223 chains_static, 220 224 chains_dynamic); 221 - 222 - if (ap) { 223 - cmd.sbb_bandwidth = iwl_mvm_get_channel_width(ap); 224 - cmd.sbb_ctrl_channel_loc = iwl_mvm_get_ctrl_pos(ap); 225 - } 226 - 227 - if (ver == 6) 228 - cmd.puncture_mask = cpu_to_le16(chandef->punctured); 229 225 230 226 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, 231 227 0, sizeof(cmd), &cmd); ··· 272 284 ctxt->width = chandef->width; 273 285 ctxt->center_freq1 = chandef->center_freq1; 274 286 275 - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, 287 + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 276 288 chains_static, chains_dynamic, 277 289 FW_CTXT_ACTION_ADD); 278 290 ··· 330 342 int ret; 331 343 332 344 /* ... remove it here ...*/ 333 - ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, NULL, 345 + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 334 346 chains_static, chains_dynamic, 335 347 FW_CTXT_ACTION_REMOVE); 336 348 if (ret) ··· 344 356 ctxt->width = chandef->width; 345 357 ctxt->center_freq1 = chandef->center_freq1; 346 358 347 - return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap, 359 + return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 348 360 chains_static, chains_dynamic, 349 361 action); 350 362 } ··· 364 376 365 377 cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT); 366 378 367 - iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, NULL, 1, 1, 379 + iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1, 368 380 FW_CTXT_ACTION_REMOVE); 369 381 } 370 382
-164
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
··· 4178 4178 else 4179 4179 return rs_drv_tx_protection(mvm, mvmsta, enable); 4180 4180 } 4181 - 4182 - static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) 4183 - { 4184 - int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; 4185 - int idx; 4186 - bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); 4187 - int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; 4188 - int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; 4189 - 4190 - for (idx = offset; idx < last; idx++) 4191 - if (iwl_fw_rate_idx_to_plcp(idx) == rate) 4192 - return idx - offset; 4193 - return IWL_RATE_INVALID; 4194 - } 4195 - 4196 - u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver) 4197 - { 4198 - u32 rate_v3 = 0, rate_v1; 4199 - u32 dup = 0; 4200 - 4201 - if (rate_ver > 1) 4202 - return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3); 4203 - 4204 - rate_v1 = le32_to_cpu(rate); 4205 - if (rate_v1 == 0) 4206 - return rate_v1; 4207 - /* convert rate */ 4208 - if (rate_v1 & RATE_MCS_HT_MSK_V1) { 4209 - u32 nss; 4210 - 4211 - rate_v3 |= RATE_MCS_MOD_TYPE_HT; 4212 - rate_v3 |= 4213 - rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; 4214 - nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK); 4215 - rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); 4216 - } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || 4217 - rate_v1 & RATE_MCS_HE_MSK_V1) { 4218 - u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK); 4219 - 4220 - rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; 4221 - 4222 - rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); 4223 - 4224 - if (rate_v1 & RATE_MCS_HE_MSK_V1) { 4225 - u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; 4226 - u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; 4227 - u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> 4228 - RATE_MCS_HE_106T_POS_V1; 4229 - u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> 4230 - RATE_MCS_HE_GI_LTF_POS; 4231 - 4232 - if ((he_type_bits == RATE_MCS_HE_TYPE_SU || 4233 - he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && 4234 - he_gi_ltf == RATE_MCS_HE_SU_4_LTF) 4235 - /* the new rate have an additional bit to 4236 - * represent the value 4 rather then using SGI 4237 - * bit for this purpose - as it was done in the 4238 - * old rate 4239 - */ 4240 - he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> 4241 - RATE_MCS_SGI_POS_V1; 4242 - 4243 - rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; 4244 - rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS; 4245 - rate_v3 |= he_106t << RATE_MCS_HE_106T_POS; 4246 - rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; 4247 - rate_v3 |= RATE_MCS_MOD_TYPE_HE; 4248 - } else { 4249 - rate_v3 |= RATE_MCS_MOD_TYPE_VHT; 4250 - } 4251 - /* if legacy format */ 4252 - } else { 4253 - u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); 4254 - 4255 - if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) 4256 - legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? 4257 - IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; 4258 - 4259 - rate_v3 |= legacy_rate; 4260 - if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) 4261 - rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; 4262 - } 4263 - 4264 - /* convert flags */ 4265 - if (rate_v1 & RATE_MCS_LDPC_MSK_V1) 4266 - rate_v3 |= RATE_MCS_LDPC_MSK; 4267 - rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | 4268 - (rate_v1 & RATE_MCS_ANT_AB_MSK) | 4269 - (rate_v1 & RATE_MCS_STBC_MSK) | 4270 - (rate_v1 & RATE_MCS_BF_MSK); 4271 - 4272 - dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; 4273 - if (dup) { 4274 - rate_v3 |= RATE_MCS_DUP_MSK; 4275 - rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS; 4276 - } 4277 - 4278 - if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && 4279 - (rate_v1 & RATE_MCS_SGI_MSK_V1)) 4280 - rate_v3 |= RATE_MCS_SGI_MSK; 4281 - 4282 - return rate_v3; 4283 - } 4284 - 4285 - __le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver) 4286 - { 4287 - u32 result = 0; 4288 - int rate_idx; 4289 - 4290 - if (rate_ver > 1) 4291 - return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2); 4292 - 4293 - switch (rate & RATE_MCS_MOD_TYPE_MSK) { 4294 - case RATE_MCS_MOD_TYPE_CCK: 4295 - result = RATE_MCS_CCK_MSK_V1; 4296 - fallthrough; 4297 - case RATE_MCS_MOD_TYPE_LEGACY_OFDM: 4298 - rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK); 4299 - if (!(result & RATE_MCS_CCK_MSK_V1)) 4300 - rate_idx += IWL_FIRST_OFDM_RATE; 4301 - result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx), 4302 - RATE_LEGACY_RATE_MSK_V1); 4303 - break; 4304 - case RATE_MCS_MOD_TYPE_HT: 4305 - result = RATE_MCS_HT_MSK_V1; 4306 - result |= u32_encode_bits(u32_get_bits(rate, 4307 - RATE_HT_MCS_CODE_MSK), 4308 - RATE_HT_MCS_RATE_CODE_MSK_V1); 4309 - result |= u32_encode_bits(u32_get_bits(rate, 4310 - RATE_MCS_NSS_MSK), 4311 - RATE_HT_MCS_MIMO2_MSK); 4312 - break; 4313 - case RATE_MCS_MOD_TYPE_VHT: 4314 - result = RATE_MCS_VHT_MSK_V1; 4315 - result |= u32_encode_bits(u32_get_bits(rate, 4316 - RATE_VHT_MCS_NSS_MSK), 4317 - RATE_MCS_CODE_MSK); 4318 - result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), 4319 - RATE_VHT_MCS_NSS_MSK); 4320 - break; 4321 - case RATE_MCS_MOD_TYPE_HE: /* not generated */ 4322 - default: 4323 - WARN_ONCE(1, "bad modulation type %d\n", 4324 - u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK)); 4325 - return 0; 4326 - } 4327 - 4328 - if (rate & RATE_MCS_LDPC_MSK) 4329 - result |= RATE_MCS_LDPC_MSK_V1; 4330 - WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) > 4331 - RATE_MCS_CHAN_WIDTH_160_VAL); 4332 - result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) | 4333 - (rate & RATE_MCS_ANT_AB_MSK) | 4334 - (rate & RATE_MCS_STBC_MSK) | 4335 - (rate & RATE_MCS_BF_MSK); 4336 - 4337 - /* not handling DUP since we don't use it */ 4338 - WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK); 4339 - 4340 - if (rate & RATE_MCS_SGI_MSK) 4341 - result |= RATE_MCS_SGI_MSK_V1; 4342 - 4343 - return cpu_to_le32(result); 4344 - }
-3
drivers/net/wireless/intel/iwlwifi/mvm/rs.h
··· 425 425 426 426 struct iwl_mvm_sta; 427 427 428 - u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver); 429 - __le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver); 430 - 431 428 int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 432 429 bool enable); 433 430
+2
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
··· 519 519 return; 520 520 } 521 521 rx_status->rate_idx = rate; 522 + /* override BW - it could be DUP and indicate the wrong BW */ 523 + rx_status->bw = RATE_INFO_BW_20; 522 524 } 523 525 524 526 #ifdef CONFIG_IWLWIFI_DEBUGFS
+164
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
··· 1237 1237 1238 1238 return false; 1239 1239 } 1240 + 1241 + static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) 1242 + { 1243 + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; 1244 + int idx; 1245 + bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); 1246 + int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; 1247 + int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; 1248 + 1249 + for (idx = offset; idx < last; idx++) 1250 + if (iwl_fw_rate_idx_to_plcp(idx) == rate) 1251 + return idx - offset; 1252 + return IWL_RATE_INVALID; 1253 + } 1254 + 1255 + u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver) 1256 + { 1257 + u32 rate_v3 = 0, rate_v1; 1258 + u32 dup = 0; 1259 + 1260 + if (rate_ver > 1) 1261 + return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3); 1262 + 1263 + rate_v1 = le32_to_cpu(rate); 1264 + if (rate_v1 == 0) 1265 + return rate_v1; 1266 + /* convert rate */ 1267 + if (rate_v1 & RATE_MCS_HT_MSK_V1) { 1268 + u32 nss; 1269 + 1270 + rate_v3 |= RATE_MCS_MOD_TYPE_HT; 1271 + rate_v3 |= 1272 + rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; 1273 + nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK); 1274 + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); 1275 + } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || 1276 + rate_v1 & RATE_MCS_HE_MSK_V1) { 1277 + u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK); 1278 + 1279 + rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; 1280 + 1281 + rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK); 1282 + 1283 + if (rate_v1 & RATE_MCS_HE_MSK_V1) { 1284 + u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; 1285 + u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; 1286 + u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> 1287 + RATE_MCS_HE_106T_POS_V1; 1288 + u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> 1289 + RATE_MCS_HE_GI_LTF_POS; 1290 + 1291 + if ((he_type_bits == RATE_MCS_HE_TYPE_SU || 1292 + he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && 1293 + he_gi_ltf == RATE_MCS_HE_SU_4_LTF) 1294 + /* the new rate have an additional bit to 1295 + * represent the value 4 rather then using SGI 1296 + * bit for this purpose - as it was done in the 1297 + * old rate 1298 + */ 1299 + he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> 1300 + RATE_MCS_SGI_POS_V1; 1301 + 1302 + rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; 1303 + rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS; 1304 + rate_v3 |= he_106t << RATE_MCS_HE_106T_POS; 1305 + rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; 1306 + rate_v3 |= RATE_MCS_MOD_TYPE_HE; 1307 + } else { 1308 + rate_v3 |= RATE_MCS_MOD_TYPE_VHT; 1309 + } 1310 + /* if legacy format */ 1311 + } else { 1312 + u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); 1313 + 1314 + if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID)) 1315 + legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ? 1316 + IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE; 1317 + 1318 + rate_v3 |= legacy_rate; 1319 + if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) 1320 + rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; 1321 + } 1322 + 1323 + /* convert flags */ 1324 + if (rate_v1 & RATE_MCS_LDPC_MSK_V1) 1325 + rate_v3 |= RATE_MCS_LDPC_MSK; 1326 + rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | 1327 + (rate_v1 & RATE_MCS_ANT_AB_MSK) | 1328 + (rate_v1 & RATE_MCS_STBC_MSK) | 1329 + (rate_v1 & RATE_MCS_BF_MSK); 1330 + 1331 + dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; 1332 + if (dup) { 1333 + rate_v3 |= RATE_MCS_DUP_MSK; 1334 + rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS; 1335 + } 1336 + 1337 + if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && 1338 + (rate_v1 & RATE_MCS_SGI_MSK_V1)) 1339 + rate_v3 |= RATE_MCS_SGI_MSK; 1340 + 1341 + return rate_v3; 1342 + } 1343 + 1344 + __le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver) 1345 + { 1346 + u32 result = 0; 1347 + int rate_idx; 1348 + 1349 + if (rate_ver > 1) 1350 + return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2); 1351 + 1352 + switch (rate & RATE_MCS_MOD_TYPE_MSK) { 1353 + case RATE_MCS_MOD_TYPE_CCK: 1354 + result = RATE_MCS_CCK_MSK_V1; 1355 + fallthrough; 1356 + case RATE_MCS_MOD_TYPE_LEGACY_OFDM: 1357 + rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK); 1358 + if (!(result & RATE_MCS_CCK_MSK_V1)) 1359 + rate_idx += IWL_FIRST_OFDM_RATE; 1360 + result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx), 1361 + RATE_LEGACY_RATE_MSK_V1); 1362 + break; 1363 + case RATE_MCS_MOD_TYPE_HT: 1364 + result = RATE_MCS_HT_MSK_V1; 1365 + result |= u32_encode_bits(u32_get_bits(rate, 1366 + RATE_HT_MCS_CODE_MSK), 1367 + RATE_HT_MCS_RATE_CODE_MSK_V1); 1368 + result |= u32_encode_bits(u32_get_bits(rate, 1369 + RATE_MCS_NSS_MSK), 1370 + RATE_HT_MCS_MIMO2_MSK); 1371 + break; 1372 + case RATE_MCS_MOD_TYPE_VHT: 1373 + result = RATE_MCS_VHT_MSK_V1; 1374 + result |= u32_encode_bits(u32_get_bits(rate, 1375 + RATE_VHT_MCS_NSS_MSK), 1376 + RATE_MCS_CODE_MSK); 1377 + result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK), 1378 + RATE_VHT_MCS_NSS_MSK); 1379 + break; 1380 + case RATE_MCS_MOD_TYPE_HE: /* not generated */ 1381 + default: 1382 + WARN_ONCE(1, "bad modulation type %d\n", 1383 + u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK)); 1384 + return 0; 1385 + } 1386 + 1387 + if (rate & RATE_MCS_LDPC_MSK) 1388 + result |= RATE_MCS_LDPC_MSK_V1; 1389 + WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) > 1390 + RATE_MCS_CHAN_WIDTH_160_VAL); 1391 + result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) | 1392 + (rate & RATE_MCS_ANT_AB_MSK) | 1393 + (rate & RATE_MCS_STBC_MSK) | 1394 + (rate & RATE_MCS_BF_MSK); 1395 + 1396 + /* not handling DUP since we don't use it */ 1397 + WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK); 1398 + 1399 + if (rate & RATE_MCS_SGI_MSK) 1400 + result |= RATE_MCS_SGI_MSK_V1; 1401 + 1402 + return cpu_to_le32(result); 1403 + }
+8 -2
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
··· 1061 1061 1062 1062 /* WH RF */ 1063 1063 IWL_DEV_INFO(iwl_rf_wh, iwl_be211_name, RF_TYPE(WH)), 1064 + IWL_DEV_INFO(iwl_rf_wh_non_eht, iwl_ax221_name, RF_TYPE(WH), 1065 + SUBDEV(0x0514)), 1066 + IWL_DEV_INFO(iwl_rf_wh_non_eht, iwl_ax221_name, RF_TYPE(WH), 1067 + SUBDEV(0x4514)), 1064 1068 IWL_DEV_INFO(iwl_rf_wh_160mhz, iwl_be213_name, RF_TYPE(WH), BW_LIMITED), 1065 1069 1066 1070 /* PE RF */ 1067 1071 IWL_DEV_INFO(iwl_rf_pe, iwl_bn201_name, RF_TYPE(PE)), 1068 - IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE), SUBDEV(0x0524)), 1069 - IWL_DEV_INFO(iwl_rf_pe, iwl_be221_name, RF_TYPE(PE), SUBDEV(0x0324)), 1072 + IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE), 1073 + SUBDEV_MASKED(0x0524, 0xFFF)), 1074 + IWL_DEV_INFO(iwl_rf_pe, iwl_bn203_name, RF_TYPE(PE), 1075 + SUBDEV_MASKED(0x0324, 0xFFF)), 1070 1076 1071 1077 /* Killer */ 1072 1078 IWL_DEV_INFO(iwl_rf_wh, iwl_killer_be1775s_name, SUBDEV(0x1776)),
+9
drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
··· 4218 4218 pdev->device, pdev->subsystem_device, 4219 4219 info.hw_rev, info.hw_rf_id); 4220 4220 4221 + #if !IS_ENABLED(CONFIG_IWLMLD) 4222 + if (iwl_drv_is_wifi7_supported(iwl_trans)) { 4223 + IWL_ERR(iwl_trans, 4224 + "IWLMLD needs to be compiled to support this device\n"); 4225 + ret = -EOPNOTSUPP; 4226 + goto out_free_trans; 4227 + } 4228 + #endif 4229 + 4221 4230 dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device, 4222 4231 CSR_HW_RFID_TYPE(info.hw_rf_id), 4223 4232 CSR_HW_RFID_IS_CDB(info.hw_rf_id),
+29
drivers/net/wireless/intel/iwlwifi/tests/devinfo.c
··· 265 265 } 266 266 } 267 267 268 + static void devinfo_pci_ids_config(struct kunit *test) 269 + { 270 + for (int i = 0; iwl_hw_card_ids[i].vendor; i++) { 271 + const struct pci_device_id *s = &iwl_hw_card_ids[i]; 272 + const struct iwl_dev_info *di; 273 + 274 + if (s->device == PCI_ANY_ID || s->subdevice == PCI_ANY_ID) 275 + continue; 276 + 277 + #if IS_ENABLED(CONFIG_IWLMVM) || IS_ENABLED(CONFIG_IWLMLD) 278 + /* 279 + * The check below only works for old (pre-CNVI) devices. Most 280 + * new have subdevice==ANY, so are already skipped, but for some 281 + * Bz platform(s) we list all the RF PCI IDs. Skip those too. 282 + */ 283 + if (s->driver_data == (kernel_ulong_t)&iwl_bz_mac_cfg) 284 + continue; 285 + #endif 286 + 287 + di = iwl_pci_find_dev_info(s->device, s->subdevice, 288 + 0, 0, 0, 0, true); 289 + 290 + KUNIT_EXPECT_PTR_NE_MSG(test, di, NULL, 291 + "PCI ID %04x:%04x not found\n", 292 + s->device, s->subdevice); 293 + } 294 + } 295 + 268 296 static struct kunit_case devinfo_test_cases[] = { 269 297 KUNIT_CASE(devinfo_table_order), 270 298 KUNIT_CASE(devinfo_discrete_match), ··· 304 276 KUNIT_CASE(devinfo_pci_ids), 305 277 KUNIT_CASE(devinfo_no_mac_cfg_dups), 306 278 KUNIT_CASE(devinfo_api_range), 279 + KUNIT_CASE(devinfo_pci_ids_config), 307 280 {} 308 281 }; 309 282