mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 03:53:37 +02:00
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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmkLbdQACgkQ10qiO8sP aABJ2g/6A6nRAIyYZLGdSRCdZ/j6zZ+OhSvBvw1C4Rp9eWfPFwzX7qOfmFb9j00t 5/l4Oby0Z6G8Ftv7/GRpss5IsfPYFDszaDyJmEtqWgmXFH3D3AUA5IQH6ImbfVHy Bnae+F+AHxp9vyUMwqToMJAfjJMufOsJFzmEEkHj6tlrs89ABe7hdzK557SZnLka 6+p3bIT7knSBzfRKEsdWtKyNZW2r2s7sPpT4Yi6b4IS35v59fdugI9VDjDgwrStF ao227VlRLUEYGGyeVEcvq3NQFpVBaLX2dXeJD8kQ3j/If/W/XKI8xpVf453hxBk/ Lxg/74cgew8wWf8otzSXQCaldLC6U6XyOZ+/j3phtKVzeL0TeUM8+0Mdg8BGQD9c 2Ov36cXSze9UcB/izEanfExKLiFvh+QbVpFVt1lfwWgt2KFzdTSeG75n36ajWf3X JRKJHZincmCgT8KB4yIzz6/CH3pZaJGZ7MovT58xAM5k+sAFaZNNAnieeA6ilc7Q mAhHML7w1ABgDbrdUmhtPdbBlUoWB7eVOO5U71saEPirwAF3gZmG/ZZm5lPciZrS Q9zDgROvZ9w0J1+r/mS4dFfmqdsol7J8kDGsr8wFvWO/f/BUt0KhXP4J+AGaMqsm gon2wco7QRQz/7Qj7Pu2EGI+9y+2kwO2zfu46glH0K6GqPl8FJk= =1BIh -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
9b73cdad58
|
|
@ -3,7 +3,6 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -1187,7 +1186,7 @@ static int ath10k_download_fw(struct ath10k *ar)
|
|||
u32 address, data_len;
|
||||
const void *data;
|
||||
int ret;
|
||||
struct pm_qos_request latency_qos;
|
||||
struct pm_qos_request latency_qos = {};
|
||||
|
||||
address = ar->hw_params.patch_load_addr;
|
||||
|
||||
|
|
@ -1221,7 +1220,6 @@ static int ath10k_download_fw(struct ath10k *ar)
|
|||
ret);
|
||||
}
|
||||
|
||||
memset(&latency_qos, 0, sizeof(latency_qos));
|
||||
cpu_latency_qos_add_request(&latency_qos, 0);
|
||||
|
||||
ret = ath10k_bmi_fast_download(ar, address, data, data_len);
|
||||
|
|
@ -2493,8 +2491,9 @@ static int ath10k_init_hw_params(struct ath10k *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool ath10k_core_needs_recovery(struct ath10k *ar)
|
||||
static void ath10k_core_recovery_check_work(struct work_struct *work)
|
||||
{
|
||||
struct ath10k *ar = container_of(work, struct ath10k, recovery_check_work);
|
||||
long time_left;
|
||||
|
||||
/* Sometimes the recovery will fail and then the next all recovery fail,
|
||||
|
|
@ -2504,7 +2503,7 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar)
|
|||
ath10k_err(ar, "consecutive fail %d times, will shutdown driver!",
|
||||
atomic_read(&ar->fail_cont_count));
|
||||
ar->state = ATH10K_STATE_WEDGED;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "total recovery count: %d", ++ar->recovery_count);
|
||||
|
|
@ -2518,27 +2517,24 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar)
|
|||
ATH10K_RECOVERY_TIMEOUT_HZ);
|
||||
if (time_left) {
|
||||
ath10k_warn(ar, "previous recovery succeeded, skip this!\n");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Record the continuous recovery fail count when recovery failed. */
|
||||
atomic_inc(&ar->fail_cont_count);
|
||||
|
||||
/* Avoid having multiple recoveries at the same time. */
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_inc(&ar->pending_recovery);
|
||||
|
||||
return true;
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
}
|
||||
|
||||
void ath10k_core_start_recovery(struct ath10k *ar)
|
||||
{
|
||||
if (!ath10k_core_needs_recovery(ar))
|
||||
return;
|
||||
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
/* Use workqueue_aux to avoid blocking recovery tracking */
|
||||
queue_work(ar->workqueue_aux, &ar->recovery_check_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_core_start_recovery);
|
||||
|
||||
|
|
@ -3356,7 +3352,7 @@ EXPORT_SYMBOL(ath10k_core_stop);
|
|||
*/
|
||||
static int ath10k_core_probe_fw(struct ath10k *ar)
|
||||
{
|
||||
struct bmi_target_info target_info;
|
||||
struct bmi_target_info target_info = {};
|
||||
int ret = 0;
|
||||
|
||||
ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
|
||||
|
|
@ -3367,7 +3363,6 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
|
||||
switch (ar->hif.bus) {
|
||||
case ATH10K_BUS_SDIO:
|
||||
memset(&target_info, 0, sizeof(target_info));
|
||||
ret = ath10k_bmi_get_target_info_sdio(ar, &target_info);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
||||
|
|
@ -3379,7 +3374,6 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
case ATH10K_BUS_PCI:
|
||||
case ATH10K_BUS_AHB:
|
||||
case ATH10K_BUS_USB:
|
||||
memset(&target_info, 0, sizeof(target_info));
|
||||
ret = ath10k_bmi_get_target_info(ar, &target_info);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
||||
|
|
@ -3389,7 +3383,6 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
ar->hw->wiphy->hw_version = target_info.version;
|
||||
break;
|
||||
case ATH10K_BUS_SNOC:
|
||||
memset(&target_info, 0, sizeof(target_info));
|
||||
ret = ath10k_hif_get_target_info(ar, &target_info);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
||||
|
|
@ -3734,6 +3727,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
|
||||
INIT_WORK(&ar->register_work, ath10k_core_register_work);
|
||||
INIT_WORK(&ar->restart_work, ath10k_core_restart);
|
||||
INIT_WORK(&ar->recovery_check_work, ath10k_core_recovery_check_work);
|
||||
INIT_WORK(&ar->set_coverage_class_work,
|
||||
ath10k_core_set_coverage_class_work);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -1208,6 +1207,7 @@ struct ath10k {
|
|||
|
||||
struct work_struct register_work;
|
||||
struct work_struct restart_work;
|
||||
struct work_struct recovery_check_work;
|
||||
struct work_struct bundle_tx_work;
|
||||
struct work_struct tx_complete_work;
|
||||
|
||||
|
|
@ -1259,9 +1259,13 @@ struct ath10k {
|
|||
struct {
|
||||
/* protected by conf_mutex */
|
||||
struct ath10k_fw_components utf_mode_fw;
|
||||
u8 ftm_msgref;
|
||||
|
||||
/* protected by data_lock */
|
||||
bool utf_monitor;
|
||||
u32 data_pos;
|
||||
u32 expected_seq;
|
||||
u8 *eventdata;
|
||||
} testmode;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -5428,6 +5427,7 @@ static void ath10k_stop(struct ieee80211_hw *hw, bool suspend)
|
|||
cancel_work_sync(&ar->set_coverage_class_work);
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
cancel_work_sync(&ar->restart_work);
|
||||
cancel_work_sync(&ar->recovery_check_work);
|
||||
}
|
||||
|
||||
static int ath10k_config_ps(struct ath10k *ar)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/*
|
||||
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "testmode.h"
|
||||
|
|
@ -10,12 +11,17 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "wmi.h"
|
||||
#include "wmi-tlv.h"
|
||||
#include "hif.h"
|
||||
#include "hw.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "testmode_i.h"
|
||||
|
||||
#define ATH10K_FTM_SEG_NONE ((u32)-1)
|
||||
#define ATH10K_FTM_SEGHDR_CURRENT_SEQ GENMASK(3, 0)
|
||||
#define ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS GENMASK(7, 4)
|
||||
|
||||
static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = {
|
||||
[ATH10K_TM_ATTR_CMD] = { .type = NLA_U32 },
|
||||
[ATH10K_TM_ATTR_DATA] = { .type = NLA_BINARY,
|
||||
|
|
@ -25,14 +31,137 @@ static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = {
|
|||
[ATH10K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static void ath10k_tm_event_unsegmented(struct ath10k *ar, u32 cmd_id,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nl_skb;
|
||||
int ret;
|
||||
|
||||
nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
|
||||
2 * sizeof(u32) + skb->len,
|
||||
GFP_ATOMIC);
|
||||
if (!nl_skb) {
|
||||
ath10k_warn(ar,
|
||||
"failed to allocate skb for testmode wmi event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to put testmode wmi event cmd attribute: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to put testmode wmi event cmd_id: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to copy skb to testmode wmi event: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
cfg80211_testmode_event(nl_skb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static void ath10k_tm_event_segmented(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_ftm_cmd *ftm = (struct wmi_ftm_cmd *)skb->data;
|
||||
u8 total_segments, current_seq;
|
||||
struct sk_buff *nl_skb;
|
||||
u8 const *buf_pos;
|
||||
u16 datalen;
|
||||
u32 data_pos;
|
||||
int ret;
|
||||
|
||||
if (skb->len < sizeof(*ftm)) {
|
||||
ath10k_warn(ar, "Invalid ftm event length: %d\n", skb->len);
|
||||
return;
|
||||
}
|
||||
|
||||
current_seq = FIELD_GET(ATH10K_FTM_SEGHDR_CURRENT_SEQ,
|
||||
__le32_to_cpu(ftm->seg_hdr.segmentinfo));
|
||||
total_segments = FIELD_GET(ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS,
|
||||
__le32_to_cpu(ftm->seg_hdr.segmentinfo));
|
||||
datalen = skb->len - sizeof(*ftm);
|
||||
buf_pos = ftm->data;
|
||||
|
||||
if (current_seq == 0) {
|
||||
ar->testmode.expected_seq = 0;
|
||||
ar->testmode.data_pos = 0;
|
||||
}
|
||||
|
||||
data_pos = ar->testmode.data_pos;
|
||||
|
||||
if ((data_pos + datalen) > ATH_FTM_EVENT_MAX_BUF_LENGTH) {
|
||||
ath10k_warn(ar, "Invalid ftm event length at %u: %u\n",
|
||||
data_pos, datalen);
|
||||
ret = -EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&ar->testmode.eventdata[data_pos], buf_pos, datalen);
|
||||
data_pos += datalen;
|
||||
|
||||
if (++ar->testmode.expected_seq != total_segments) {
|
||||
ar->testmode.data_pos = data_pos;
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "partial data received %u/%u\n",
|
||||
current_seq + 1, total_segments);
|
||||
return;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "total data length %u\n", data_pos);
|
||||
|
||||
nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
|
||||
2 * sizeof(u32) + data_pos,
|
||||
GFP_ATOMIC);
|
||||
if (!nl_skb) {
|
||||
ath10k_warn(ar, "failed to allocate skb for testmode wmi event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_TLV);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to put testmode wmi event attribute: %d\n", ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to put testmode wmi event cmd_id: %d\n", ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, data_pos, &ar->testmode.eventdata[0]);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to copy skb to testmode wmi event: %d\n", ret);
|
||||
kfree_skb(nl_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
cfg80211_testmode_event(nl_skb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
/* Returns true if callee consumes the skb and the skb should be discarded.
|
||||
* Returns false if skb is not used. Does not sleep.
|
||||
*/
|
||||
bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nl_skb;
|
||||
bool consumed;
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
|
||||
"testmode event wmi cmd_id %d skb %p skb->len %d\n",
|
||||
|
|
@ -53,43 +182,10 @@ bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
|||
*/
|
||||
consumed = true;
|
||||
|
||||
nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
|
||||
2 * sizeof(u32) + skb->len,
|
||||
GFP_ATOMIC);
|
||||
if (!nl_skb) {
|
||||
ath10k_warn(ar,
|
||||
"failed to allocate skb for testmode wmi event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to put testmode wmi event cmd attribute: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to put testmode wmi event cmd_id: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to copy skb to testmode wmi event: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cfg80211_testmode_event(nl_skb, GFP_ATOMIC);
|
||||
if (ar->testmode.expected_seq != ATH10K_FTM_SEG_NONE)
|
||||
ath10k_tm_event_segmented(ar, cmd_id, skb);
|
||||
else
|
||||
ath10k_tm_event_unsegmented(ar, cmd_id, skb);
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
|
@ -281,12 +377,18 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
|
|||
goto err_release_utf_mode_fw;
|
||||
}
|
||||
|
||||
ar->testmode.eventdata = kzalloc(ATH_FTM_EVENT_MAX_BUF_LENGTH, GFP_KERNEL);
|
||||
if (!ar->testmode.eventdata) {
|
||||
ret = -ENOMEM;
|
||||
goto err_power_down;
|
||||
}
|
||||
|
||||
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_UTF,
|
||||
&ar->testmode.utf_mode_fw);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to start core (testmode): %d\n", ret);
|
||||
ar->state = ATH10K_STATE_OFF;
|
||||
goto err_power_down;
|
||||
goto err_release_eventdata;
|
||||
}
|
||||
|
||||
ar->state = ATH10K_STATE_UTF;
|
||||
|
|
@ -302,6 +404,10 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
|
|||
|
||||
return 0;
|
||||
|
||||
err_release_eventdata:
|
||||
kfree(ar->testmode.eventdata);
|
||||
ar->testmode.eventdata = NULL;
|
||||
|
||||
err_power_down:
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
|
|
@ -341,6 +447,9 @@ static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar)
|
|||
release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware);
|
||||
ar->testmode.utf_mode_fw.fw_file.firmware = NULL;
|
||||
|
||||
kfree(ar->testmode.eventdata);
|
||||
ar->testmode.eventdata = NULL;
|
||||
|
||||
ar->state = ATH10K_STATE_OFF;
|
||||
}
|
||||
|
||||
|
|
@ -424,6 +533,85 @@ static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[])
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_tm_cmd_tlv(struct ath10k *ar, struct nlattr *tb[])
|
||||
{
|
||||
u16 total_bytes, num_segments;
|
||||
u32 cmd_id, buf_len;
|
||||
u8 segnumber = 0;
|
||||
u8 *bufpos;
|
||||
void *buf;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_UTF) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = nla_data(tb[ATH10K_TM_ATTR_DATA]);
|
||||
buf_len = nla_len(tb[ATH10K_TM_ATTR_DATA]);
|
||||
cmd_id = WMI_PDEV_UTF_CMDID;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
|
||||
"cmd wmi ftm cmd_id %d buffer length %d\n",
|
||||
cmd_id, buf_len);
|
||||
ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len);
|
||||
|
||||
bufpos = buf;
|
||||
total_bytes = buf_len;
|
||||
num_segments = total_bytes / MAX_WMI_UTF_LEN;
|
||||
ar->testmode.expected_seq = 0;
|
||||
|
||||
if (buf_len - (num_segments * MAX_WMI_UTF_LEN))
|
||||
num_segments++;
|
||||
|
||||
while (buf_len) {
|
||||
u16 chunk_len = min_t(u16, buf_len, MAX_WMI_UTF_LEN);
|
||||
struct wmi_ftm_cmd *ftm_cmd;
|
||||
struct sk_buff *skb;
|
||||
u32 hdr_info;
|
||||
u8 seginfo;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, (chunk_len +
|
||||
sizeof(struct wmi_ftm_cmd)));
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ftm_cmd = (struct wmi_ftm_cmd *)skb->data;
|
||||
hdr_info = FIELD_PREP(WMI_TLV_TAG, WMI_TLV_TAG_ARRAY_BYTE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, (chunk_len +
|
||||
sizeof(struct wmi_ftm_seg_hdr)));
|
||||
ftm_cmd->tlv_header = __cpu_to_le32(hdr_info);
|
||||
ftm_cmd->seg_hdr.len = __cpu_to_le32(total_bytes);
|
||||
ftm_cmd->seg_hdr.msgref = __cpu_to_le32(ar->testmode.ftm_msgref);
|
||||
seginfo = FIELD_PREP(ATH10K_FTM_SEGHDR_TOTAL_SEGMENTS, num_segments) |
|
||||
FIELD_PREP(ATH10K_FTM_SEGHDR_CURRENT_SEQ, segnumber);
|
||||
ftm_cmd->seg_hdr.segmentinfo = __cpu_to_le32(seginfo);
|
||||
segnumber++;
|
||||
|
||||
memcpy(&ftm_cmd->data, bufpos, chunk_len);
|
||||
|
||||
ret = ath10k_wmi_cmd_send(ar, skb, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to send wmi ftm command: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf_len -= chunk_len;
|
||||
bufpos += chunk_len;
|
||||
}
|
||||
|
||||
ar->testmode.ftm_msgref++;
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
void *data, int len)
|
||||
{
|
||||
|
|
@ -439,9 +627,14 @@ int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
if (!tb[ATH10K_TM_ATTR_CMD])
|
||||
return -EINVAL;
|
||||
|
||||
ar->testmode.expected_seq = ATH10K_FTM_SEG_NONE;
|
||||
|
||||
switch (nla_get_u32(tb[ATH10K_TM_ATTR_CMD])) {
|
||||
case ATH10K_TM_CMD_GET_VERSION:
|
||||
return ath10k_tm_cmd_get_version(ar, tb);
|
||||
if (!tb[ATH10K_TM_ATTR_DATA])
|
||||
return ath10k_tm_cmd_get_version(ar, tb);
|
||||
else /* ATH10K_TM_CMD_TLV */
|
||||
return ath10k_tm_cmd_tlv(ar, tb);
|
||||
case ATH10K_TM_CMD_UTF_START:
|
||||
return ath10k_tm_cmd_utf_start(ar, tb);
|
||||
case ATH10K_TM_CMD_UTF_STOP:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/*
|
||||
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
/* "API" level of the ath10k testmode interface. Bump it after every
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
#define ATH10K_TESTMODE_VERSION_MINOR 0
|
||||
|
||||
#define ATH10K_TM_DATA_MAX_LEN 5000
|
||||
#define ATH_FTM_EVENT_MAX_BUF_LENGTH 2048
|
||||
|
||||
enum ath10k_tm_attr {
|
||||
__ATH10K_TM_ATTR_INVALID = 0,
|
||||
|
|
@ -57,4 +59,17 @@ enum ath10k_tm_cmd {
|
|||
* ATH10K_TM_ATTR_DATA.
|
||||
*/
|
||||
ATH10K_TM_CMD_WMI = 3,
|
||||
|
||||
/* The command used to transmit a test command to the firmware
|
||||
* and the event to receive test events from the firmware. The data
|
||||
* received only contain the TLV payload, need to add the tlv header
|
||||
* and send the cmd to firmware with command id WMI_PDEV_UTF_CMDID.
|
||||
* The data payload size could be large and the driver needs to
|
||||
* send segmented data to firmware.
|
||||
*
|
||||
* This legacy testmode command shares the same value as the get-version
|
||||
* command. To distinguish between them, we check whether the data attribute
|
||||
* is present.
|
||||
*/
|
||||
ATH10K_TM_CMD_TLV = ATH10K_TM_CMD_GET_VERSION,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef _WMI_H_
|
||||
|
|
@ -7418,6 +7418,23 @@ struct wmi_pdev_bb_timing_cfg_cmd {
|
|||
__le32 bb_xpa_timing;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ftm_seg_hdr {
|
||||
__le32 len;
|
||||
__le32 msgref;
|
||||
__le32 segmentinfo;
|
||||
__le32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_ftm_cmd {
|
||||
__le32 tlv_header;
|
||||
struct wmi_ftm_seg_hdr seg_hdr;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#define WMI_TLV_LEN GENMASK(15, 0)
|
||||
#define WMI_TLV_TAG GENMASK(31, 16)
|
||||
#define MAX_WMI_UTF_LEN 252
|
||||
|
||||
struct ath10k;
|
||||
struct ath10k_vif;
|
||||
struct ath10k_fw_stats_pdev;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_HAL_H
|
||||
|
|
@ -43,14 +43,14 @@ struct ath11k_base;
|
|||
#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000
|
||||
#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000
|
||||
#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000
|
||||
#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(x) \
|
||||
(ab->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(x) \
|
||||
(ab->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(x) \
|
||||
(ab->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(x) \
|
||||
(ab->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \
|
||||
((ab)->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \
|
||||
((ab)->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \
|
||||
((ab)->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \
|
||||
((ab)->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg)
|
||||
#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000
|
||||
|
||||
#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000
|
||||
|
|
@ -209,10 +209,10 @@ struct ath11k_base;
|
|||
#define HAL_REO_STATUS_HP(ab) ab->hw_params.regs->hal_reo_status_hp
|
||||
|
||||
/* WBM Idle R0 address */
|
||||
#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(x) \
|
||||
(ab->hw_params.regs->hal_wbm_idle_link_ring_base_lsb)
|
||||
#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(x) \
|
||||
(ab->hw_params.regs->hal_wbm_idle_link_ring_misc)
|
||||
#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \
|
||||
((ab)->hw_params.regs->hal_wbm_idle_link_ring_base_lsb)
|
||||
#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \
|
||||
((ab)->hw_params.regs->hal_wbm_idle_link_ring_misc)
|
||||
#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR 0x00000048
|
||||
#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR 0x0000004c
|
||||
#define HAL_WBM_SCATTERED_RING_BASE_LSB 0x00000058
|
||||
|
|
@ -227,17 +227,17 @@ struct ath11k_base;
|
|||
#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b0
|
||||
|
||||
/* SW2WBM R0 release address */
|
||||
#define HAL_WBM_RELEASE_RING_BASE_LSB(x) \
|
||||
(ab->hw_params.regs->hal_wbm_release_ring_base_lsb)
|
||||
#define HAL_WBM_RELEASE_RING_BASE_LSB(ab) \
|
||||
((ab)->hw_params.regs->hal_wbm_release_ring_base_lsb)
|
||||
|
||||
/* SW2WBM R2 release address */
|
||||
#define HAL_WBM_RELEASE_RING_HP 0x00003018
|
||||
|
||||
/* WBM2SW R0 release address */
|
||||
#define HAL_WBM0_RELEASE_RING_BASE_LSB(x) \
|
||||
(ab->hw_params.regs->hal_wbm0_release_ring_base_lsb)
|
||||
#define HAL_WBM1_RELEASE_RING_BASE_LSB(x) \
|
||||
(ab->hw_params.regs->hal_wbm1_release_ring_base_lsb)
|
||||
#define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \
|
||||
((ab)->hw_params.regs->hal_wbm0_release_ring_base_lsb)
|
||||
#define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \
|
||||
((ab)->hw_params.regs->hal_wbm1_release_ring_base_lsb)
|
||||
|
||||
/* WBM2SW R2 release address */
|
||||
#define HAL_WBM0_RELEASE_RING_HP 0x000030c0
|
||||
|
|
|
|||
|
|
@ -2235,9 +2235,9 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar,
|
|||
arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
|
||||
arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
|
||||
arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
|
||||
arg->rx_mcs_set = ath11k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask);
|
||||
arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
|
||||
arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit(
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
|
||||
arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
|
||||
|
||||
/* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default.
|
||||
* VHT mcs rate 10 and 11 is not supported in 11ac standard.
|
||||
|
|
@ -2522,10 +2522,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
|||
he_tx_mcs = v;
|
||||
}
|
||||
v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
|
||||
v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
|
||||
arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
|
||||
|
||||
v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);
|
||||
v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
|
||||
arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
|
||||
|
||||
arg->peer_he_mcs_count++;
|
||||
|
|
@ -2535,10 +2535,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
|||
|
||||
default:
|
||||
v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
|
||||
v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
|
||||
arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
|
||||
|
||||
v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
|
||||
v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
|
||||
arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
|
||||
|
||||
arg->peer_he_mcs_count++;
|
||||
|
|
@ -4028,6 +4028,150 @@ static int ath11k_start_scan(struct ath11k *ar,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ath11k_mac_fw_stats_reset(struct ath11k *ar)
|
||||
{
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
|
||||
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
|
||||
ar->fw_stats.num_vdev_recvd = 0;
|
||||
ar->fw_stats.num_bcn_recvd = 0;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
int ath11k_mac_fw_stats_request(struct ath11k *ar,
|
||||
struct stats_request_params *req_param)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
unsigned long time_left;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
ath11k_mac_fw_stats_reset(ar);
|
||||
|
||||
reinit_completion(&ar->fw_stats_complete);
|
||||
reinit_completion(&ar->fw_stats_done);
|
||||
|
||||
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "could not request fw stats (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* FW stats can get split when exceeding the stats data buffer limit.
|
||||
* In that case, since there is no end marking for the back-to-back
|
||||
* received 'update stats' event, we keep a 3 seconds timeout in case,
|
||||
* fw_stats_done is not marked yet
|
||||
*/
|
||||
time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id,
|
||||
u32 vdev_id, u32 stats_id)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct stats_request_params req_param;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH11K_STATE_ON)
|
||||
return -ENETDOWN;
|
||||
|
||||
req_param.pdev_id = pdev_id;
|
||||
req_param.vdev_id = vdev_id;
|
||||
req_param.stats_id = stats_id;
|
||||
|
||||
ret = ath11k_mac_fw_stats_request(ar, &req_param);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
|
||||
pdev_id, vdev_id, stats_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_handle_get_txpower(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
int *dbm)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_fw_stats_pdev *pdev;
|
||||
int ret;
|
||||
|
||||
/* Final Tx power is minimum of Target Power, CTL power, Regulatory
|
||||
* Power, PSD EIRP Power. We just know the Regulatory power from the
|
||||
* regulatory rules obtained. FW knows all these power and sets the min
|
||||
* of these. Hence, we request the FW pdev stats in which FW reports
|
||||
* the minimum of all vdev's channel Tx power.
|
||||
*/
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
/* Firmware doesn't provide Tx power during CAC hence no need to fetch
|
||||
* the stats.
|
||||
*/
|
||||
if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags))
|
||||
return -EAGAIN;
|
||||
|
||||
ret = ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,
|
||||
WMI_REQUEST_PDEV_STAT);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
|
||||
goto err_fallback;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
pdev = list_first_entry_or_null(&ar->fw_stats.pdevs,
|
||||
struct ath11k_fw_stats_pdev, list);
|
||||
if (!pdev) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
goto err_fallback;
|
||||
}
|
||||
|
||||
/* tx power is set as 2 units per dBm in FW. */
|
||||
*dbm = pdev->chan_tx_power / 2;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware %d, reported %d dBm\n",
|
||||
pdev->chan_tx_power, *dbm);
|
||||
return 0;
|
||||
|
||||
err_fallback:
|
||||
/* We didn't get txpower from FW. Hence, relying on vif->bss_conf.txpower */
|
||||
*dbm = vif->bss_conf.txpower;
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware NaN, reported %d dBm\n",
|
||||
*dbm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
unsigned int link_id,
|
||||
int *dbm)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ret = ath11k_mac_handle_get_txpower(ar, vif, dbm);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
|
|
@ -6107,6 +6251,159 @@ static void ath11k_mgmt_over_wmi_tx_purge(struct ath11k *ar)
|
|||
ath11k_mgmt_over_wmi_tx_drop(ar, skb);
|
||||
}
|
||||
|
||||
static int ath11k_mac_mgmt_action_frame_fill_elem_data(struct ath11k_vif *arvif,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
u8 category, *buf, iv_len, action_code, dialog_token;
|
||||
int cur_tx_power, max_tx_power;
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct cfg80211_chan_def def;
|
||||
struct ath11k_skb_cb *skb_cb;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
unsigned int remaining_len;
|
||||
bool has_protected;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
/* make sure category field is present */
|
||||
if (skb->len < IEEE80211_MIN_ACTION_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE;
|
||||
has_protected = ieee80211_has_protected(hdr->frame_control);
|
||||
|
||||
/* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
|
||||
* we can't put in data in this case
|
||||
*/
|
||||
if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
|
||||
has_protected)
|
||||
return 0;
|
||||
|
||||
mgmt = (struct ieee80211_mgmt *)hdr;
|
||||
buf = (u8 *)&mgmt->u.action;
|
||||
|
||||
/* FCTL_PROTECTED frame might have extra space added for HDR_LEN. Offset that
|
||||
* many bytes if it is there
|
||||
*/
|
||||
if (has_protected) {
|
||||
skb_cb = ATH11K_SKB_CB(skb);
|
||||
|
||||
switch (skb_cb->cipher) {
|
||||
/* Cipher suite having flag %IEEE80211_KEY_FLAG_GENERATE_IV_MGMT set in
|
||||
* key needs to be processed. See ath11k_install_key()
|
||||
*/
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
iv_len = IEEE80211_CCMP_HDR_LEN;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
iv_len = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (remaining_len < iv_len)
|
||||
return -EINVAL;
|
||||
|
||||
buf += iv_len;
|
||||
remaining_len -= iv_len;
|
||||
}
|
||||
|
||||
category = *buf++;
|
||||
/* category code is already taken care in %IEEE80211_MIN_ACTION_SIZE hence
|
||||
* no need to adjust remaining_len
|
||||
*/
|
||||
|
||||
switch (category) {
|
||||
case WLAN_CATEGORY_RADIO_MEASUREMENT:
|
||||
/* need action code and dialog token */
|
||||
if (remaining_len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Packet Format:
|
||||
* Action Code | Dialog Token | Variable Len (based on Action Code)
|
||||
*/
|
||||
action_code = *buf++;
|
||||
dialog_token = *buf++;
|
||||
remaining_len -= 2;
|
||||
|
||||
if (ath11k_mac_vif_chan(arvif->vif, &def))
|
||||
return -ENOENT;
|
||||
|
||||
cur_tx_power = arvif->vif->bss_conf.txpower;
|
||||
max_tx_power = min(def.chan->max_reg_power, (int)ar->max_tx_power / 2);
|
||||
ath11k_mac_handle_get_txpower(ar, arvif->vif, &cur_tx_power);
|
||||
|
||||
switch (action_code) {
|
||||
case WLAN_RM_ACTION_LINK_MEASUREMENT_REQUEST:
|
||||
/* need variable fields to be present in len */
|
||||
if (remaining_len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Variable length format as defined in IEEE 802.11-2024,
|
||||
* Figure 9-1187-Link Measurement Request frame Action field
|
||||
* format.
|
||||
* Transmit Power | Max Tx Power
|
||||
* We fill both of these.
|
||||
*/
|
||||
*buf++ = cur_tx_power;
|
||||
*buf = max_tx_power;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
"RRM: Link Measurement Req dialog_token %u cur_tx_power %d max_tx_power %d\n",
|
||||
dialog_token, cur_tx_power, max_tx_power);
|
||||
break;
|
||||
case WLAN_RM_ACTION_LINK_MEASUREMENT_REPORT:
|
||||
/* need variable fields to be present in len */
|
||||
if (remaining_len < 3)
|
||||
return -EINVAL;
|
||||
|
||||
/* Variable length format as defined in IEEE 802.11-2024,
|
||||
* Figure 9-1188-Link Measurement Report frame Action field format
|
||||
* TPC Report | Variable Fields
|
||||
*
|
||||
* TPC Report Format:
|
||||
* Element ID | Len | Tx Power | Link Margin
|
||||
*
|
||||
* We fill Tx power in the TPC Report (2nd index)
|
||||
*/
|
||||
buf[2] = cur_tx_power;
|
||||
|
||||
/* TODO: At present, Link margin data is not present so can't
|
||||
* really fill it now. Once it is available, it can be added
|
||||
* here
|
||||
*/
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
"RRM: Link Measurement Report dialog_token %u cur_tx_power %d\n",
|
||||
dialog_token, cur_tx_power);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* nothing to fill */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_mgmt_frame_fill_elem_data(struct ath11k_vif *arvif,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
if (!ieee80211_is_action(hdr->frame_control))
|
||||
return 0;
|
||||
|
||||
return ath11k_mac_mgmt_action_frame_fill_elem_data(arvif, skb);
|
||||
}
|
||||
|
||||
static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work)
|
||||
{
|
||||
struct ath11k *ar = container_of(work, struct ath11k, wmi_mgmt_tx_work);
|
||||
|
|
@ -6126,6 +6423,19 @@ static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work)
|
|||
arvif = ath11k_vif_to_arvif(skb_cb->vif);
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) {
|
||||
/* Fill in the data which is required to be filled by the driver
|
||||
* For example: Max Tx power in Link Measurement Request/Report
|
||||
*/
|
||||
ret = ath11k_mac_mgmt_frame_fill_elem_data(arvif, skb);
|
||||
if (ret) {
|
||||
/* If we couldn't fill the data due to any reason,
|
||||
* let's not discard transmitting the packet.
|
||||
*/
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
"Failed to fill the required data for the mgmt packet err %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",
|
||||
|
|
@ -9079,81 +9389,6 @@ static void ath11k_mac_put_chain_rssi(struct station_info *sinfo,
|
|||
}
|
||||
}
|
||||
|
||||
static void ath11k_mac_fw_stats_reset(struct ath11k *ar)
|
||||
{
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
|
||||
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
|
||||
ar->fw_stats.num_vdev_recvd = 0;
|
||||
ar->fw_stats.num_bcn_recvd = 0;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
int ath11k_mac_fw_stats_request(struct ath11k *ar,
|
||||
struct stats_request_params *req_param)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
unsigned long time_left;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
ath11k_mac_fw_stats_reset(ar);
|
||||
|
||||
reinit_completion(&ar->fw_stats_complete);
|
||||
reinit_completion(&ar->fw_stats_done);
|
||||
|
||||
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "could not request fw stats (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* FW stats can get split when exceeding the stats data buffer limit.
|
||||
* In that case, since there is no end marking for the back-to-back
|
||||
* received 'update stats' event, we keep a 3 seconds timeout in case,
|
||||
* fw_stats_done is not marked yet
|
||||
*/
|
||||
time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id,
|
||||
u32 vdev_id, u32 stats_id)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct stats_request_params req_param;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH11K_STATE_ON)
|
||||
return -ENETDOWN;
|
||||
|
||||
req_param.pdev_id = pdev_id;
|
||||
req_param.vdev_id = vdev_id;
|
||||
req_param.stats_id = stats_id;
|
||||
|
||||
ret = ath11k_mac_fw_stats_request(ar, &req_param);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
|
||||
pdev_id, vdev_id, stats_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
|
|
@ -9539,66 +9774,6 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
unsigned int link_id,
|
||||
int *dbm)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_fw_stats_pdev *pdev;
|
||||
int ret;
|
||||
|
||||
/* Final Tx power is minimum of Target Power, CTL power, Regulatory
|
||||
* Power, PSD EIRP Power. We just know the Regulatory power from the
|
||||
* regulatory rules obtained. FW knows all these power and sets the min
|
||||
* of these. Hence, we request the FW pdev stats in which FW reports
|
||||
* the minimum of all vdev's channel Tx power.
|
||||
*/
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
/* Firmware doesn't provide Tx power during CAC hence no need to fetch
|
||||
* the stats.
|
||||
*/
|
||||
if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ret = ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,
|
||||
WMI_REQUEST_PDEV_STAT);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
|
||||
goto err_fallback;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
pdev = list_first_entry_or_null(&ar->fw_stats.pdevs,
|
||||
struct ath11k_fw_stats_pdev, list);
|
||||
if (!pdev) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
goto err_fallback;
|
||||
}
|
||||
|
||||
/* tx power is set as 2 units per dBm in FW. */
|
||||
*dbm = pdev->chan_tx_power / 2;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware %d, reported %d dBm\n",
|
||||
pdev->chan_tx_power, *dbm);
|
||||
return 0;
|
||||
|
||||
err_fallback:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
/* We didn't get txpower from FW. Hence, relying on vif->bss_conf.txpower */
|
||||
*dbm = vif->bss_conf.txpower;
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware NaN, reported %d dBm\n",
|
||||
*dbm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_station_add(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
|
|
@ -10368,6 +10543,8 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
|||
ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
|
||||
NL80211_FEATURE_AP_SCAN;
|
||||
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
|
||||
|
||||
ar->max_num_stations = TARGET_NUM_STATIONS(ab);
|
||||
ar->max_num_peers = TARGET_NUM_PEERS_PDEV(ab);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -177,6 +177,19 @@ static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci)
|
|||
ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
|
||||
}
|
||||
|
||||
static void ath11k_pci_restore_window(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
|
||||
spin_lock_bh(&ab_pci->window_lock);
|
||||
|
||||
iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | ab_pci->register_window,
|
||||
ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
|
||||
ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
|
||||
|
||||
spin_unlock_bh(&ab_pci->window_lock);
|
||||
}
|
||||
|
||||
static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)
|
||||
{
|
||||
u32 val, delay;
|
||||
|
|
@ -201,6 +214,11 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)
|
|||
val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET);
|
||||
if (val == 0xffffffff)
|
||||
ath11k_warn(ab, "link down error during global reset\n");
|
||||
|
||||
/* Restore window register as its content is cleared during
|
||||
* hardware global reset, such that it aligns with host cache.
|
||||
*/
|
||||
ath11k_pci_restore_window(ab);
|
||||
}
|
||||
|
||||
static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#ifndef _ATH11K_PCI_H
|
||||
#define _ATH11K_PCI_H
|
||||
|
|
@ -35,18 +35,18 @@
|
|||
#define PCIE_SMLH_REQ_RST_LINK_DOWN 0x2
|
||||
#define PCIE_INT_CLEAR_ALL 0xffffffff
|
||||
|
||||
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(x) \
|
||||
(ab->hw_params.regs->pcie_qserdes_sysclk_en_sel)
|
||||
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab) \
|
||||
((ab)->hw_params.regs->pcie_qserdes_sysclk_en_sel)
|
||||
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL 0x10
|
||||
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK 0xffffffff
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG1_REG(x) \
|
||||
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab) \
|
||||
((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG1_VAL 0x02
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG2_REG(x) \
|
||||
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0x4)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab) \
|
||||
((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0x4)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG2_VAL 0x52
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG4_REG(x) \
|
||||
(ab->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0xc)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab) \
|
||||
((ab)->hw_params.regs->pcie_pcs_osc_dtct_config_base + 0xc)
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG4_VAL 0xff
|
||||
#define PCIE_PCS_OSC_DTCT_CONFIG_MSK 0x000000ff
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ctype.h>
|
||||
|
|
@ -2061,10 +2061,13 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
|
|||
cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override;
|
||||
|
||||
if (param->vht_capable) {
|
||||
mcs->rx_max_rate = param->rx_max_rate;
|
||||
mcs->rx_mcs_set = param->rx_mcs_set;
|
||||
mcs->tx_max_rate = param->tx_max_rate;
|
||||
mcs->tx_mcs_set = param->tx_mcs_set;
|
||||
/* firmware interprets mcs->tx_mcs_set field as peer's
|
||||
* RX capability
|
||||
*/
|
||||
mcs->tx_max_rate = param->rx_max_rate;
|
||||
mcs->tx_mcs_set = param->rx_mcs_set;
|
||||
mcs->rx_max_rate = param->tx_max_rate;
|
||||
mcs->rx_mcs_set = param->tx_mcs_set;
|
||||
}
|
||||
|
||||
/* HE Rates */
|
||||
|
|
@ -2088,8 +2091,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
|
|||
FIELD_PREP(WMI_TLV_LEN,
|
||||
sizeof(*he_mcs) - TLV_HDR_SIZE);
|
||||
|
||||
he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i];
|
||||
he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i];
|
||||
/* firmware interprets mcs->rx_mcs_set field as peer's
|
||||
* RX capability
|
||||
*/
|
||||
he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i];
|
||||
he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i];
|
||||
ptr += sizeof(*he_mcs);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_WMI_H
|
||||
|
|
@ -3463,20 +3463,6 @@ struct scan_cancel_param {
|
|||
u32 pdev_id;
|
||||
};
|
||||
|
||||
struct wmi_bcn_send_from_host_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
u32 data_len;
|
||||
union {
|
||||
u32 frag_ptr;
|
||||
u32 frag_ptr_lo;
|
||||
};
|
||||
u32 frame_ctrl;
|
||||
u32 dtim_flag;
|
||||
u32 bcn_antenna;
|
||||
u32 frag_ptr_hi;
|
||||
};
|
||||
|
||||
#define WMI_CHAN_INFO_MODE GENMASK(5, 0)
|
||||
#define WMI_CHAN_INFO_HT40_PLUS BIT(6)
|
||||
#define WMI_CHAN_INFO_PASSIVE BIT(7)
|
||||
|
|
@ -4133,8 +4119,10 @@ struct wmi_rate_set {
|
|||
struct wmi_vht_rate_set {
|
||||
u32 tlv_header;
|
||||
u32 rx_max_rate;
|
||||
/* MCS at which the peer can transmit */
|
||||
u32 rx_mcs_set;
|
||||
u32 tx_max_rate;
|
||||
/* MCS at which the peer can receive */
|
||||
u32 tx_mcs_set;
|
||||
u32 tx_max_mcs_nss;
|
||||
} __packed;
|
||||
|
|
|
|||
|
|
@ -2106,14 +2106,27 @@ static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag)
|
|||
ret = ath12k_core_soc_create(ab);
|
||||
if (ret) {
|
||||
mutex_unlock(&ab->core_lock);
|
||||
ath12k_err(ab, "failed to create soc core: %d\n", ret);
|
||||
return ret;
|
||||
ath12k_err(ab, "failed to create soc %d core: %d\n", i, ret);
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
mutex_unlock(&ab->core_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
destroy:
|
||||
for (i--; i >= 0; i--) {
|
||||
ab = ag->ab[i];
|
||||
if (!ab)
|
||||
continue;
|
||||
|
||||
mutex_lock(&ab->core_lock);
|
||||
ath12k_core_soc_destroy(ab);
|
||||
mutex_unlock(&ab->core_lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag)
|
||||
|
|
@ -2188,7 +2201,7 @@ int ath12k_core_init(struct ath12k_base *ab)
|
|||
if (ret) {
|
||||
mutex_unlock(&ag->mutex);
|
||||
ath12k_warn(ab, "unable to create hw group\n");
|
||||
goto err_destroy_hw_group;
|
||||
goto err_unassign_hw_group;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2196,8 +2209,7 @@ int ath12k_core_init(struct ath12k_base *ab)
|
|||
|
||||
return 0;
|
||||
|
||||
err_destroy_hw_group:
|
||||
ath12k_core_hw_group_destroy(ab->ag);
|
||||
err_unassign_hw_group:
|
||||
ath12k_core_hw_group_unassign(ab);
|
||||
err_unregister_notifier:
|
||||
ath12k_core_panic_notifier_unregister(ab);
|
||||
|
|
|
|||
|
|
@ -355,6 +355,8 @@ struct ath12k_link_vif {
|
|||
struct wmi_vdev_install_key_arg group_key;
|
||||
bool pairwise_key_done;
|
||||
u16 num_stations;
|
||||
bool is_csa_in_progress;
|
||||
struct wiphy_work bcn_tx_work;
|
||||
};
|
||||
|
||||
struct ath12k_vif {
|
||||
|
|
@ -963,6 +965,7 @@ struct ath12k_device_dp_stats {
|
|||
u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX];
|
||||
u32 tx_enqueued[DP_TCL_NUM_RING_MAX];
|
||||
u32 tx_completed[DP_TCL_NUM_RING_MAX];
|
||||
u32 reo_excep_msdu_buf_type;
|
||||
};
|
||||
|
||||
struct ath12k_reg_freq {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
|
|
@ -1178,6 +1178,9 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
|
|||
len += scnprintf(buf + len, size - len, "\n");
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nREO excep MSDU buf type:%u\n",
|
||||
device_stats->reo_excep_msdu_buf_type);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n");
|
||||
|
||||
for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "dp_mon.h"
|
||||
|
|
@ -105,7 +105,7 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh
|
|||
if (ppdu_info->is_stbc && nsts > 0)
|
||||
nsts = ((nsts + 1) >> 1) - 1;
|
||||
|
||||
ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK);
|
||||
ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1;
|
||||
ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW);
|
||||
ppdu_info->beamformed = u32_get_bits(info1,
|
||||
HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED);
|
||||
|
|
@ -129,7 +129,7 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig,
|
|||
ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC);
|
||||
ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING);
|
||||
ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);
|
||||
ppdu_info->nss = (ppdu_info->mcs >> 3);
|
||||
ppdu_info->nss = (ppdu_info->mcs >> 3) + 1;
|
||||
}
|
||||
|
||||
static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb,
|
||||
|
|
@ -233,7 +233,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of
|
|||
value = value << HE_STA_ID_SHIFT;
|
||||
ppdu_info->he_data4 |= value;
|
||||
|
||||
ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS);
|
||||
ppdu_info->nss =
|
||||
u32_get_bits(info0,
|
||||
HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1;
|
||||
ppdu_info->beamformed = u32_get_bits(info0,
|
||||
HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);
|
||||
}
|
||||
|
|
@ -261,7 +263,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b
|
|||
value = value << HE_STA_ID_SHIFT;
|
||||
ppdu_info->he_data4 |= value;
|
||||
|
||||
ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);
|
||||
ppdu_info->nss =
|
||||
u32_get_bits(info0,
|
||||
HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -553,7 +557,8 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *
|
|||
ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);
|
||||
ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);
|
||||
dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);
|
||||
ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);
|
||||
ppdu_info->nss = u32_get_bits(info0,
|
||||
HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1;
|
||||
ppdu_info->dcm = dcm;
|
||||
}
|
||||
|
||||
|
|
@ -2179,7 +2184,7 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
|
|||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
rxs->flag |= RX_FLAG_MACTIME_START;
|
||||
rxs->nss = ppduinfo->nss + 1;
|
||||
rxs->nss = ppduinfo->nss;
|
||||
if (test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map))
|
||||
rxs->signal = ppduinfo->rssi_comb;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
|
|
@ -1089,6 +1089,8 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp,
|
|||
{
|
||||
struct dp_reo_update_rx_queue_elem *elem;
|
||||
|
||||
lockdep_assert_held(&dp->ab->base_lock);
|
||||
|
||||
elem = kzalloc(sizeof(*elem), GFP_ATOMIC);
|
||||
if (!elem)
|
||||
return -ENOMEM;
|
||||
|
|
@ -3781,6 +3783,50 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab,
|
||||
struct list_head *list,
|
||||
struct hal_reo_dest_ring *desc)
|
||||
{
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
struct sk_buff *msdu;
|
||||
u64 desc_va;
|
||||
|
||||
ab->device_stats.reo_excep_msdu_buf_type++;
|
||||
|
||||
desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 |
|
||||
le32_to_cpu(desc->buf_va_lo);
|
||||
desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va;
|
||||
if (!desc_info) {
|
||||
u32 cookie;
|
||||
|
||||
cookie = le32_get_bits(desc->buf_addr_info.info1,
|
||||
BUFFER_ADDR_INFO1_SW_COOKIE);
|
||||
desc_info = ath12k_dp_get_rx_desc(ab, cookie);
|
||||
if (!desc_info) {
|
||||
ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n",
|
||||
cookie);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) {
|
||||
ath12k_warn(ab, "rx exception, magic check failed with value: %u\n",
|
||||
desc_info->magic);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msdu = desc_info->skb;
|
||||
desc_info->skb = NULL;
|
||||
list_add_tail(&desc_info->list, list);
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu),
|
||||
DMA_FROM_DEVICE);
|
||||
dev_kfree_skb_any(msdu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
int budget)
|
||||
{
|
||||
|
|
@ -3825,6 +3871,26 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
|||
drop = false;
|
||||
ab->device_stats.err_ring_pkts++;
|
||||
|
||||
hw_link_id = le32_get_bits(reo_desc->info0,
|
||||
HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
|
||||
device_id = hw_links[hw_link_id].device_id;
|
||||
partner_ab = ath12k_ag_to_ab(ag, device_id);
|
||||
|
||||
/* Below case is added to handle data packet from un-associated clients.
|
||||
* As it is expected that AST lookup will fail for
|
||||
* un-associated station's data packets.
|
||||
*/
|
||||
if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) ==
|
||||
HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) {
|
||||
if (!ath12k_dp_h_msdu_buffer_type(partner_ab,
|
||||
&rx_desc_used_list[device_id],
|
||||
reo_desc)) {
|
||||
num_buffs_reaped[device_id]++;
|
||||
tot_n_bufs_reaped++;
|
||||
}
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr,
|
||||
&desc_bank);
|
||||
if (ret) {
|
||||
|
|
@ -3833,11 +3899,6 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
|||
continue;
|
||||
}
|
||||
|
||||
hw_link_id = le32_get_bits(reo_desc->info0,
|
||||
HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
|
||||
device_id = hw_links[hw_link_id].device_id;
|
||||
partner_ab = ath12k_ag_to_ab(ag, device_id);
|
||||
|
||||
pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
|
||||
hw_links[hw_link_id].pdev_idx);
|
||||
ar = partner_ab->pdevs[pdev_id].ar;
|
||||
|
|
@ -3886,6 +3947,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
|||
}
|
||||
}
|
||||
|
||||
next_desc:
|
||||
if (tot_n_bufs_reaped >= quota) {
|
||||
tot_n_bufs_reaped = quota;
|
||||
goto exit;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
|
@ -323,7 +323,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
|
|||
{
|
||||
enum hal_reo_dest_ring_push_reason push_reason;
|
||||
enum hal_reo_dest_ring_error_code err_code;
|
||||
u32 cookie, val;
|
||||
u32 cookie;
|
||||
|
||||
push_reason = le32_get_bits(desc->info0,
|
||||
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
|
||||
|
|
@ -338,12 +338,6 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE);
|
||||
if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) {
|
||||
ath12k_warn(ab, "expected buffer type link_desc");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie);
|
||||
*desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_MAC_H
|
||||
|
|
@ -84,6 +84,18 @@ enum ath12k_supported_bw {
|
|||
ATH12K_BW_320 = 4,
|
||||
};
|
||||
|
||||
enum ath12k_gi {
|
||||
ATH12K_RATE_INFO_GI_0_8,
|
||||
ATH12K_RATE_INFO_GI_1_6,
|
||||
ATH12K_RATE_INFO_GI_3_2,
|
||||
};
|
||||
|
||||
enum ath12k_ltf {
|
||||
ATH12K_RATE_INFO_1XLTF,
|
||||
ATH12K_RATE_INFO_2XLTF,
|
||||
ATH12K_RATE_INFO_4XLTF,
|
||||
};
|
||||
|
||||
struct ath12k_mac_get_any_chanctx_conf_arg {
|
||||
struct ath12k *ar;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -218,6 +218,19 @@ static inline bool ath12k_pci_is_offset_within_mhi_region(u32 offset)
|
|||
return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END);
|
||||
}
|
||||
|
||||
static void ath12k_pci_restore_window(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
|
||||
|
||||
spin_lock_bh(&ab_pci->window_lock);
|
||||
|
||||
iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window,
|
||||
ab->mem + WINDOW_REG_ADDRESS);
|
||||
ioread32(ab->mem + WINDOW_REG_ADDRESS);
|
||||
|
||||
spin_unlock_bh(&ab_pci->window_lock);
|
||||
}
|
||||
|
||||
static void ath12k_pci_soc_global_reset(struct ath12k_base *ab)
|
||||
{
|
||||
u32 val, delay;
|
||||
|
|
@ -242,6 +255,11 @@ static void ath12k_pci_soc_global_reset(struct ath12k_base *ab)
|
|||
val = ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET);
|
||||
if (val == 0xffffffff)
|
||||
ath12k_warn(ab, "link down error during global reset\n");
|
||||
|
||||
/* Restore window register as its content is cleared during
|
||||
* hardware global reset, such that it aligns with host cache.
|
||||
*/
|
||||
ath12k_pci_restore_window(ab);
|
||||
}
|
||||
|
||||
static void ath12k_pci_clear_dbg_registers(struct ath12k_base *ab)
|
||||
|
|
@ -1871,3 +1889,7 @@ void ath12k_pci_exit(void)
|
|||
{
|
||||
pci_unregister_driver(&ath12k_pci_driver);
|
||||
}
|
||||
|
||||
/* firmware files */
|
||||
MODULE_FIRMWARE(ATH12K_FW_DIR "/QCN9274/hw2.0/*");
|
||||
MODULE_FIRMWARE(ATH12K_FW_DIR "/WCN7850/hw2.0/*");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/elf.h>
|
||||
|
|
@ -3114,9 +3114,10 @@ static void ath12k_qmi_m3_free(struct ath12k_base *ab)
|
|||
if (!m3_mem->vaddr)
|
||||
return;
|
||||
|
||||
dma_free_coherent(ab->dev, m3_mem->size,
|
||||
dma_free_coherent(ab->dev, m3_mem->total_size,
|
||||
m3_mem->vaddr, m3_mem->paddr);
|
||||
m3_mem->vaddr = NULL;
|
||||
m3_mem->total_size = 0;
|
||||
m3_mem->size = 0;
|
||||
}
|
||||
|
||||
|
|
@ -3152,7 +3153,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
|
|||
|
||||
/* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
|
||||
if (m3_mem->vaddr) {
|
||||
if (m3_mem->size >= m3_len)
|
||||
if (m3_mem->total_size >= m3_len)
|
||||
goto skip_m3_alloc;
|
||||
|
||||
/* Old buffer is too small, free and reallocate */
|
||||
|
|
@ -3164,11 +3165,13 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
|
|||
GFP_KERNEL);
|
||||
if (!m3_mem->vaddr) {
|
||||
ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
|
||||
fw->size);
|
||||
m3_len);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
m3_mem->total_size = m3_len;
|
||||
|
||||
skip_m3_alloc:
|
||||
memcpy(m3_mem->vaddr, m3_data, m3_len);
|
||||
m3_mem->size = m3_len;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_QMI_H
|
||||
|
|
@ -120,6 +120,9 @@ struct target_info {
|
|||
};
|
||||
|
||||
struct m3_mem_region {
|
||||
/* total memory allocated */
|
||||
u32 total_size;
|
||||
/* actual memory being used */
|
||||
u32 size;
|
||||
dma_addr_t paddr;
|
||||
void *vaddr;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ctype.h>
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/uuid.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include "core.h"
|
||||
#include "debugfs.h"
|
||||
#include "debug.h"
|
||||
|
|
@ -190,6 +191,8 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
|
|||
.min_len = sizeof(struct wmi_11d_new_cc_event) },
|
||||
[WMI_TAG_PER_CHAIN_RSSI_STATS] = {
|
||||
.min_len = sizeof(struct wmi_per_chain_rssi_stat_params) },
|
||||
[WMI_TAG_OBSS_COLOR_COLLISION_EVT] = {
|
||||
.min_len = sizeof(struct wmi_obss_color_collision_event) },
|
||||
};
|
||||
|
||||
__le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len)
|
||||
|
|
@ -2367,10 +2370,13 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
|||
cmd->peer_bw_rxnss_override |= cpu_to_le32(arg->peer_bw_rxnss_override);
|
||||
|
||||
if (arg->vht_capable) {
|
||||
mcs->rx_max_rate = cpu_to_le32(arg->rx_max_rate);
|
||||
mcs->rx_mcs_set = cpu_to_le32(arg->rx_mcs_set);
|
||||
mcs->tx_max_rate = cpu_to_le32(arg->tx_max_rate);
|
||||
mcs->tx_mcs_set = cpu_to_le32(arg->tx_mcs_set);
|
||||
/* Firmware interprets mcs->tx_mcs_set field as peer's
|
||||
* RX capability
|
||||
*/
|
||||
mcs->rx_max_rate = cpu_to_le32(arg->tx_max_rate);
|
||||
mcs->rx_mcs_set = cpu_to_le32(arg->tx_mcs_set);
|
||||
mcs->tx_max_rate = cpu_to_le32(arg->rx_max_rate);
|
||||
mcs->tx_mcs_set = cpu_to_le32(arg->rx_mcs_set);
|
||||
}
|
||||
|
||||
/* HE Rates */
|
||||
|
|
@ -3847,6 +3853,58 @@ int ath12k_wmi_fils_discovery(struct ath12k *ar, u32 vdev_id, u32 interval,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_wmi_obss_color_collision_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
const struct wmi_obss_color_collision_event *ev;
|
||||
struct ath12k_link_vif *arvif;
|
||||
u32 vdev_id, evt_type;
|
||||
u64 bitmap;
|
||||
|
||||
const void **tb __free(kfree) = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ath12k_warn(ab, "failed to parse OBSS color collision tlv %ld\n",
|
||||
PTR_ERR(tb));
|
||||
return;
|
||||
}
|
||||
|
||||
ev = tb[WMI_TAG_OBSS_COLOR_COLLISION_EVT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch OBSS color collision event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vdev_id = le32_to_cpu(ev->vdev_id);
|
||||
evt_type = le32_to_cpu(ev->evt_type);
|
||||
bitmap = le64_to_cpu(ev->obss_color_bitmap);
|
||||
|
||||
guard(rcu)();
|
||||
|
||||
arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_id);
|
||||
if (!arvif) {
|
||||
ath12k_warn(ab, "no arvif found for vdev %u in OBSS color collision event\n",
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (evt_type) {
|
||||
case WMI_BSS_COLOR_COLLISION_DETECTION:
|
||||
ieee80211_obss_color_collision_notify(arvif->ahvif->vif,
|
||||
bitmap,
|
||||
arvif->link_id);
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"obss color collision detected vdev %u event %d bitmap %016llx\n",
|
||||
vdev_id, evt_type, bitmap);
|
||||
break;
|
||||
case WMI_BSS_COLOR_COLLISION_DISABLE:
|
||||
case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
|
||||
case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
|
||||
break;
|
||||
default:
|
||||
ath12k_warn(ab, "unknown OBSS color collision event type %d\n", evt_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_fill_band_to_mac_param(struct ath12k_base *soc,
|
||||
struct ath12k_wmi_pdev_band_arg *arg)
|
||||
|
|
@ -7011,12 +7069,26 @@ static void ath12k_vdev_start_resp_event(struct ath12k_base *ab, struct sk_buff
|
|||
|
||||
static void ath12k_bcn_tx_status_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k *ar;
|
||||
u32 vdev_id, tx_status;
|
||||
|
||||
if (ath12k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) {
|
||||
ath12k_warn(ab, "failed to extract bcn tx status");
|
||||
return;
|
||||
}
|
||||
|
||||
guard(rcu)();
|
||||
|
||||
arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_id);
|
||||
if (!arvif) {
|
||||
ath12k_warn(ab, "invalid vdev %u in bcn tx status\n",
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
ar = arvif->ar;
|
||||
wiphy_work_queue(ath12k_ar_to_hw(ar)->wiphy, &arvif->bcn_tx_work);
|
||||
}
|
||||
|
||||
static void ath12k_vdev_stopped_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
|
|
@ -9874,6 +9946,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
case WMI_PDEV_RSSI_DBM_CONVERSION_PARAMS_INFO_EVENTID:
|
||||
ath12k_wmi_rssi_dbm_conversion_params_info_event(ab, skb);
|
||||
break;
|
||||
case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID:
|
||||
ath12k_wmi_obss_color_collision_event(ab, skb);
|
||||
break;
|
||||
/* add Unsupported events (rare) here */
|
||||
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
|
||||
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
|
||||
|
|
@ -9884,7 +9959,6 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
/* add Unsupported events (frequent) here */
|
||||
case WMI_PDEV_GET_HALPHY_CAL_STATUS_EVENTID:
|
||||
case WMI_MGMT_RX_FW_CONSUMED_EVENTID:
|
||||
case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID:
|
||||
/* debug might flood hence silently ignore (no-op) */
|
||||
break;
|
||||
case WMI_PDEV_UTF_EVENTID:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_WMI_H
|
||||
|
|
@ -223,15 +223,15 @@ enum WMI_HOST_WLAN_BAND {
|
|||
};
|
||||
|
||||
/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command.
|
||||
* Used only for HE auto rate mode.
|
||||
* Used for HE and EHT auto rate mode.
|
||||
*/
|
||||
enum {
|
||||
/* HE LTF related configuration */
|
||||
WMI_HE_AUTORATE_LTF_1X = BIT(0),
|
||||
WMI_HE_AUTORATE_LTF_2X = BIT(1),
|
||||
WMI_HE_AUTORATE_LTF_4X = BIT(2),
|
||||
/* LTF related configuration */
|
||||
WMI_AUTORATE_LTF_1X = BIT(0),
|
||||
WMI_AUTORATE_LTF_2X = BIT(1),
|
||||
WMI_AUTORATE_LTF_4X = BIT(2),
|
||||
|
||||
/* HE GI related configuration */
|
||||
/* GI related configuration */
|
||||
WMI_AUTORATE_400NS_GI = BIT(8),
|
||||
WMI_AUTORATE_800NS_GI = BIT(9),
|
||||
WMI_AUTORATE_1600NS_GI = BIT(10),
|
||||
|
|
@ -1197,6 +1197,7 @@ enum wmi_tlv_vdev_param {
|
|||
WMI_VDEV_PARAM_SET_HEMU_MODE,
|
||||
WMI_VDEV_PARAM_HEOPS_0_31 = 0x8003,
|
||||
WMI_VDEV_PARAM_SET_EHT_MU_MODE = 0x8005,
|
||||
WMI_VDEV_PARAM_EHT_LTF,
|
||||
};
|
||||
|
||||
enum wmi_tlv_peer_flags {
|
||||
|
|
@ -3609,20 +3610,6 @@ struct ath12k_wmi_scan_cancel_arg {
|
|||
u32 pdev_id;
|
||||
};
|
||||
|
||||
struct wmi_bcn_send_from_host_cmd {
|
||||
__le32 tlv_header;
|
||||
__le32 vdev_id;
|
||||
__le32 data_len;
|
||||
union {
|
||||
__le32 frag_ptr;
|
||||
__le32 frag_ptr_lo;
|
||||
};
|
||||
__le32 frame_ctrl;
|
||||
__le32 dtim_flag;
|
||||
__le32 bcn_antenna;
|
||||
__le32 frag_ptr_hi;
|
||||
};
|
||||
|
||||
#define WMI_CHAN_INFO_MODE GENMASK(5, 0)
|
||||
#define WMI_CHAN_INFO_HT40_PLUS BIT(6)
|
||||
#define WMI_CHAN_INFO_PASSIVE BIT(7)
|
||||
|
|
@ -4218,8 +4205,10 @@ struct wmi_unit_test_cmd {
|
|||
struct ath12k_wmi_vht_rate_set_params {
|
||||
__le32 tlv_header;
|
||||
__le32 rx_max_rate;
|
||||
/* MCS at which the peer can transmit */
|
||||
__le32 rx_mcs_set;
|
||||
__le32 tx_max_rate;
|
||||
/* MCS at which the peer can receive */
|
||||
__le32 tx_mcs_set;
|
||||
__le32 tx_max_mcs_nss;
|
||||
} __packed;
|
||||
|
|
@ -4940,6 +4929,24 @@ struct wmi_obss_spatial_reuse_params_cmd {
|
|||
#define ATH12K_BSS_COLOR_STA_PERIODS 10000
|
||||
#define ATH12K_BSS_COLOR_AP_PERIODS 5000
|
||||
|
||||
/**
|
||||
* enum wmi_bss_color_collision - Event types for BSS color collision handling
|
||||
* @WMI_BSS_COLOR_COLLISION_DISABLE: Indicates that BSS color collision detection
|
||||
* is disabled.
|
||||
* @WMI_BSS_COLOR_COLLISION_DETECTION: Event triggered when a BSS color collision
|
||||
* is detected.
|
||||
* @WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY: Event indicating that the timer for waiting
|
||||
* on a free BSS color slot has expired.
|
||||
* @WMI_BSS_COLOR_FREE_SLOT_AVAILABLE: Event indicating that a free BSS color slot
|
||||
* has become available.
|
||||
*/
|
||||
enum wmi_bss_color_collision {
|
||||
WMI_BSS_COLOR_COLLISION_DISABLE = 0,
|
||||
WMI_BSS_COLOR_COLLISION_DETECTION,
|
||||
WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY,
|
||||
WMI_BSS_COLOR_FREE_SLOT_AVAILABLE,
|
||||
};
|
||||
|
||||
struct wmi_obss_color_collision_cfg_params_cmd {
|
||||
__le32 tlv_header;
|
||||
__le32 vdev_id;
|
||||
|
|
@ -4957,6 +4964,12 @@ struct wmi_bss_color_change_enable_params_cmd {
|
|||
__le32 enable;
|
||||
} __packed;
|
||||
|
||||
struct wmi_obss_color_collision_event {
|
||||
__le32 vdev_id;
|
||||
__le32 evt_type;
|
||||
__le64 obss_color_bitmap;
|
||||
} __packed;
|
||||
|
||||
#define ATH12K_IPV4_TH_SEED_SIZE 5
|
||||
#define ATH12K_IPV6_TH_SEED_SIZE 11
|
||||
|
||||
|
|
|
|||
|
|
@ -758,6 +758,7 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
|
|||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n",
|
||||
arvif->vdev_id, enable, ret);
|
||||
kfree(offload);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4484,80 +4484,6 @@ struct set_rssi_filter_resp {
|
|||
u32 status;
|
||||
};
|
||||
|
||||
/* Update scan params - sent from host to PNO to be used during PNO
|
||||
* scanningx */
|
||||
struct wcn36xx_hal_update_scan_params_req {
|
||||
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
/* Host setting for 11d */
|
||||
u8 dot11d_enabled;
|
||||
|
||||
/* Lets PNO know that host has determined the regulatory domain */
|
||||
u8 dot11d_resolved;
|
||||
|
||||
/* Channels on which PNO is allowed to scan */
|
||||
u8 channel_count;
|
||||
u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS];
|
||||
|
||||
/* Minimum channel time */
|
||||
u16 active_min_ch_time;
|
||||
|
||||
/* Maximum channel time */
|
||||
u16 active_max_ch_time;
|
||||
|
||||
/* Minimum channel time */
|
||||
u16 passive_min_ch_time;
|
||||
|
||||
/* Maximum channel time */
|
||||
u16 passive_max_ch_time;
|
||||
|
||||
/* Cb State */
|
||||
enum phy_chan_bond_state state;
|
||||
} __packed;
|
||||
|
||||
/* Update scan params - sent from host to PNO to be used during PNO
|
||||
* scanningx */
|
||||
struct wcn36xx_hal_update_scan_params_req_ex {
|
||||
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
/* Host setting for 11d */
|
||||
u8 dot11d_enabled;
|
||||
|
||||
/* Lets PNO know that host has determined the regulatory domain */
|
||||
u8 dot11d_resolved;
|
||||
|
||||
/* Channels on which PNO is allowed to scan */
|
||||
u8 channel_count;
|
||||
u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
|
||||
|
||||
/* Minimum channel time */
|
||||
u16 active_min_ch_time;
|
||||
|
||||
/* Maximum channel time */
|
||||
u16 active_max_ch_time;
|
||||
|
||||
/* Minimum channel time */
|
||||
u16 passive_min_ch_time;
|
||||
|
||||
/* Maximum channel time */
|
||||
u16 passive_max_ch_time;
|
||||
|
||||
/* Cb State */
|
||||
enum phy_chan_bond_state state;
|
||||
} __packed;
|
||||
|
||||
/* Update scan params - sent from host to PNO to be used during PNO
|
||||
* scanningx */
|
||||
struct wcn36xx_hal_update_scan_params_resp {
|
||||
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
/* status of the request */
|
||||
u32 status;
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_set_tx_per_tracking_req_msg {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
|
|
|
|||
|
|
@ -1127,66 +1127,6 @@ int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
|
||||
{
|
||||
struct wcn36xx_hal_update_scan_params_resp *rsp;
|
||||
|
||||
rsp = buf;
|
||||
|
||||
/* Remove the PNO version bit */
|
||||
rsp->status &= (~(WCN36XX_FW_MSG_PNO_VERSION_MASK));
|
||||
|
||||
if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) {
|
||||
wcn36xx_warn("error response from update scan\n");
|
||||
return rsp->status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn,
|
||||
u8 *channels, size_t channel_count)
|
||||
{
|
||||
struct wcn36xx_hal_update_scan_params_req_ex msg_body;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ);
|
||||
|
||||
msg_body.dot11d_enabled = false;
|
||||
msg_body.dot11d_resolved = true;
|
||||
|
||||
msg_body.channel_count = channel_count;
|
||||
memcpy(msg_body.channels, channels, channel_count);
|
||||
msg_body.active_min_ch_time = 60;
|
||||
msg_body.active_max_ch_time = 120;
|
||||
msg_body.passive_min_ch_time = 60;
|
||||
msg_body.passive_max_ch_time = 110;
|
||||
msg_body.state = PHY_SINGLE_CHANNEL_CENTERED;
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL,
|
||||
"hal update scan params channel_count %d\n",
|
||||
msg_body.channel_count);
|
||||
|
||||
ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
|
||||
if (ret) {
|
||||
wcn36xx_err("Sending hal_update_scan_params failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_update_scan_params_rsp(wcn->hal_buf,
|
||||
wcn->hal_rsp_len);
|
||||
if (ret) {
|
||||
wcn36xx_err("hal_update_scan_params response failed err=%d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&wcn->hal_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif,
|
||||
void *buf,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
|
|||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
|
||||
int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
|
||||
struct cfg80211_scan_request *req);
|
||||
int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ static const struct iwl_family_base_params iwl_22000_base = {
|
|||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x400000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ static const struct iwl_family_base_params iwl8000_base = {
|
|||
.smem_offset = IWL8260_SMEM_OFFSET,
|
||||
.smem_len = IWL8260_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.min_umac_error_event_table = 0x800000,
|
||||
};
|
||||
|
||||
static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ static const struct iwl_family_base_params iwl9000_base = {
|
|||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x800000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 92 * 1024,
|
||||
.nvm_hw_section_num = 10,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ static const struct iwl_family_base_params iwl_ax210_base = {
|
|||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x400000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_BZ_UCODE_CORE_MAX 99
|
||||
#define IWL_BZ_UCODE_CORE_MAX 101
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MIN 100
|
||||
|
|
@ -38,7 +38,6 @@ static const struct iwl_family_base_params iwl_bz_base = {
|
|||
.smem_len = IWL_BZ_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
|
|
@ -90,6 +89,7 @@ const struct iwl_mac_cfg iwl_bz_mac_cfg = {
|
|||
.low_latency_xtal = true,
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_bz_mac_cfg);
|
||||
|
||||
const struct iwl_mac_cfg iwl_gl_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_BZ,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_DR_UCODE_CORE_MAX 99
|
||||
#define IWL_DR_UCODE_CORE_MAX 101
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_DR_UCODE_API_MIN 100
|
||||
|
|
@ -33,7 +33,6 @@ static const struct iwl_family_base_params iwl_dr_base = {
|
|||
.smem_len = IWL_DR_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
.non_shared_ant = ANT_B, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.uhb_supported = true, \
|
||||
.eht_supported = true, \
|
||||
.num_rbds = IWL_NUM_RBDS_EHT, \
|
||||
.nvm_ver = IWL_FM_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@ const char iwl_killer_bn1850i_name[] =
|
|||
"Killer(R) Wi-Fi 8 BN1850i 320MHz Wireless Network Adapter (BN201.NGW)";
|
||||
|
||||
const char iwl_bn201_name[] = "Intel(R) Wi-Fi 8 BN201";
|
||||
const char iwl_bn203_name[] = "Intel(R) Wi-Fi 8 BN203";
|
||||
const char iwl_be221_name[] = "Intel(R) Wi-Fi 7 BE221";
|
||||
const char iwl_be223_name[] = "Intel(R) Wi-Fi 7 BE223";
|
||||
|
|
|
|||
|
|
@ -4,8 +4,31 @@
|
|||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_WH_NVM_VERSION 0x0a1d
|
||||
|
||||
#define IWL_DEVICE_WH \
|
||||
.ht_params = { \
|
||||
.stbc = true, \
|
||||
.ldpc = true, \
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | \
|
||||
BIT(NL80211_BAND_5GHZ), \
|
||||
}, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.uhb_supported = true, \
|
||||
.num_rbds = IWL_NUM_RBDS_EHT, \
|
||||
.nvm_ver = IWL_WH_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
||||
/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_wh_non_eht = {
|
||||
IWL_DEVICE_WH,
|
||||
.eht_supported = false,
|
||||
};
|
||||
|
||||
const char iwl_killer_be1775s_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1775s 320MHz Wireless Network Adapter (BE211D2W)";
|
||||
const char iwl_killer_be1775i_name[] =
|
||||
|
|
@ -13,3 +36,4 @@ const char iwl_killer_be1775i_name[] =
|
|||
|
||||
const char iwl_be211_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz";
|
||||
const char iwl_be213_name[] = "Intel(R) Wi-Fi 7 BE213 160MHz";
|
||||
const char iwl_ax221_name[] = "Intel(R) Wi-Fi 6E AX221 160MHz";
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware core release supported */
|
||||
#define IWL_SC_UCODE_CORE_MAX 99
|
||||
#define IWL_SC_UCODE_CORE_MAX 101
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MIN 100
|
||||
|
|
@ -41,7 +41,6 @@ static const struct iwl_family_base_params iwl_sc_base = {
|
|||
.smem_len = IWL_SC_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ union acpi_object *iwl_acpi_get_dsm_object(struct device *dev, int rev,
|
|||
* @mcc: output buffer (3 bytes) that will get the MCC
|
||||
*
|
||||
* This function tries to read the current MCC from ACPI if available.
|
||||
* Return: 0 on success, or a negative error code
|
||||
*/
|
||||
int iwl_acpi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ struct iwl_imr_alive_info {
|
|||
__le32 enabled;
|
||||
} __packed; /* IMR_ALIVE_INFO_API_S_VER_1 */
|
||||
|
||||
struct iwl_alive_ntf_v6 {
|
||||
struct iwl_alive_ntf_v7 {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
struct iwl_lmac_alive lmac_data[2];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -98,7 +98,7 @@ struct iwl_cmd_header {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_cmd_header_wide
|
||||
* struct iwl_cmd_header_wide - wide command header
|
||||
*
|
||||
* This header format appears in the beginning of each command sent from the
|
||||
* driver, and each response/notification received from uCode.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
* Copyright (C) 2023-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2014, 2018-2019 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
|
|
@ -52,7 +52,7 @@ struct iwl_bt_coex_cmd {
|
|||
} __packed; /* BT_COEX_CMD_API_S_VER_6 */
|
||||
|
||||
/**
|
||||
* struct iwl_bt_coex_reduced_txp_update_cmd
|
||||
* struct iwl_bt_coex_reduced_txp_update_cmd - reduced TX power command
|
||||
* @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
|
||||
* bits are the sta_id (value)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ enum iwl_legacy_cmds {
|
|||
* @UCODE_ALIVE_NTFY:
|
||||
* Alive data from the firmware, as described in
|
||||
* &struct iwl_alive_ntf_v3 or &struct iwl_alive_ntf_v4 or
|
||||
* &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v6.
|
||||
* &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v7.
|
||||
*/
|
||||
UCODE_ALIVE_NTFY = 0x1,
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,11 @@ enum iwl_data_path_subcmd_ids {
|
|||
*/
|
||||
BEACON_FILTER_IN_NOTIF = 0xF8,
|
||||
|
||||
/**
|
||||
* @PHY_AIR_SNIFFER_NOTIF: &struct iwl_rx_phy_air_sniffer_ntfy
|
||||
*/
|
||||
PHY_AIR_SNIFFER_NOTIF = 0xF9,
|
||||
|
||||
/**
|
||||
* @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#define IWL_FW_INI_PRESET_DISABLE 0xff
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_hcmd
|
||||
* struct iwl_fw_ini_hcmd - debug configuration host command
|
||||
*
|
||||
* @id: the debug configuration command type for instance: 0xf6 / 0xf5 / DHC
|
||||
* @group: the desired cmd group
|
||||
|
|
@ -199,7 +199,7 @@ struct iwl_fw_ini_region_tlv {
|
|||
} __packed; /* FW_TLV_DEBUG_REGION_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_debug_info_tlv
|
||||
* struct iwl_fw_ini_debug_info_tlv - debug info TLV
|
||||
*
|
||||
* debug configuration name for a specific image
|
||||
*
|
||||
|
|
@ -311,7 +311,7 @@ struct iwl_fw_ini_conf_set_tlv {
|
|||
} __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_config_set_type
|
||||
* enum iwl_fw_ini_config_set_type - configuration set type
|
||||
*
|
||||
* @IWL_FW_INI_CONFIG_SET_TYPE_INVALID: invalid config set
|
||||
* @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: for PERIPHERY MAC configuration
|
||||
|
|
@ -337,7 +337,7 @@ enum iwl_fw_ini_config_set_type {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_allocation_id
|
||||
* enum iwl_fw_ini_allocation_id - allocation ID
|
||||
*
|
||||
* @IWL_FW_INI_ALLOCATION_INVALID: invalid
|
||||
* @IWL_FW_INI_ALLOCATION_ID_DBGC1: allocation meant for DBGC1 configuration
|
||||
|
|
@ -356,7 +356,7 @@ enum iwl_fw_ini_allocation_id {
|
|||
}; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_buffer_location
|
||||
* enum iwl_fw_ini_buffer_location - buffer location
|
||||
*
|
||||
* @IWL_FW_INI_LOCATION_INVALID: invalid
|
||||
* @IWL_FW_INI_LOCATION_SRAM_PATH: SRAM location
|
||||
|
|
@ -373,7 +373,7 @@ enum iwl_fw_ini_buffer_location {
|
|||
}; /* FW_DEBUG_TLV_BUFFER_LOCATION_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_region_type
|
||||
* enum iwl_fw_ini_region_type - region type
|
||||
*
|
||||
* @IWL_FW_INI_REGION_INVALID: invalid
|
||||
* @IWL_FW_INI_REGION_TLV: uCode and debug TLVs
|
||||
|
|
@ -437,7 +437,7 @@ enum iwl_fw_ini_region_device_memory_subtype {
|
|||
}; /* FW_TLV_DEBUG_REGION_DEVICE_MEMORY_SUBTYPE_API_E */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_time_point
|
||||
* enum iwl_fw_ini_time_point - time point type
|
||||
*
|
||||
* Hard coded time points in which the driver can send hcmd or perform dump
|
||||
* collection
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ struct iwl_dbgc1_info {
|
|||
} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_dbg_host_event_cfg_cmd
|
||||
* struct iwl_dbg_host_event_cfg_cmd - host event config command
|
||||
* @enabled_severities: enabled severities
|
||||
*/
|
||||
struct iwl_dbg_host_event_cfg_cmd {
|
||||
|
|
|
|||
|
|
@ -1092,7 +1092,7 @@ struct iwl_tof_range_req_ap_entry {
|
|||
} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_9 */
|
||||
|
||||
/**
|
||||
* enum iwl_tof_response_mode
|
||||
* enum iwl_tof_response_mode - TOF response mode
|
||||
* @IWL_MVM_TOF_RESPONSE_ASAP: report each AP measurement separately as soon as
|
||||
* possible (not supported for this release)
|
||||
* @IWL_MVM_TOF_RESPONSE_TIMEOUT: report all AP measurements as a batch upon
|
||||
|
|
@ -1108,7 +1108,7 @@ enum iwl_tof_response_mode {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum iwl_tof_initiator_flags
|
||||
* enum iwl_tof_initiator_flags - TOF initiator flags
|
||||
*
|
||||
* @IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED: disable fast algo, meaning run
|
||||
* the algo on ant A+B, instead of only one of them.
|
||||
|
|
@ -1409,7 +1409,7 @@ enum iwl_tof_range_request_status {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum iwl_tof_entry_status
|
||||
* enum iwl_tof_entry_status - TOF entry status
|
||||
*
|
||||
* @IWL_TOF_ENTRY_SUCCESS: successful measurement.
|
||||
* @IWL_TOF_ENTRY_GENERAL_FAILURE: General failure.
|
||||
|
|
@ -1856,7 +1856,7 @@ struct iwl_tof_mcsi_notif {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_abort_cmd
|
||||
* struct iwl_tof_range_abort_cmd - TOF range abort command
|
||||
* @request_id: corresponds to a range request
|
||||
* @reserved: reserved
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,13 +18,8 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
|
|||
|
||||
/**
|
||||
* @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd_v1,
|
||||
* &struct iwl_lari_config_change_cmd_v2,
|
||||
* &struct iwl_lari_config_change_cmd_v3,
|
||||
* &struct iwl_lari_config_change_cmd_v4,
|
||||
* &struct iwl_lari_config_change_cmd_v5,
|
||||
* &struct iwl_lari_config_change_cmd_v6,
|
||||
* &struct iwl_lari_config_change_cmd_v7,
|
||||
* &struct iwl_lari_config_change_cmd_v10 or
|
||||
* &struct iwl_lari_config_change_cmd_v8,
|
||||
* &struct iwl_lari_config_change_cmd
|
||||
*/
|
||||
LARI_CONFIG_CHANGE = 0x1,
|
||||
|
|
@ -564,74 +559,6 @@ struct iwl_lari_config_change_cmd_v1 {
|
|||
__le32 config_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v2 - change LARI configuration
|
||||
* @config_bitmap: bit map of the config commands. each bit will trigger a
|
||||
* different predefined FW config operation
|
||||
* @oem_uhb_allow_bitmap: bitmap of UHB enabled MCC sets
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v2 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v3 - change LARI configuration
|
||||
* @config_bitmap: bit map of the config commands. each bit will trigger a
|
||||
* different predefined FW config operation
|
||||
* @oem_uhb_allow_bitmap: bitmap of UHB enabled MCC sets
|
||||
* @oem_11ax_allow_bitmap: bitmap of 11ax allowed MCCs.
|
||||
* For each supported country, a pair of regulatory override bit and 11ax mode exist
|
||||
* in the bit field.
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v3 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
__le32 oem_11ax_allow_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v4 - change LARI configuration
|
||||
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
|
||||
* different predefined FW config operation.
|
||||
* @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
|
||||
* @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate the value to use.
|
||||
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate allow/disallow unii4 channels.
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v4 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
__le32 oem_11ax_allow_bitmap;
|
||||
__le32 oem_unii4_allow_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_4 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v5 - change LARI configuration
|
||||
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
|
||||
* different predefined FW config operation.
|
||||
* @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
|
||||
* @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate the value to use.
|
||||
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate allow/disallow unii4 channels.
|
||||
* @chan_state_active_bitmap: Bitmap for overriding channel state to active.
|
||||
* Each bit represents a country or region to activate, according to the BIOS
|
||||
* definitions.
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v5 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
__le32 oem_11ax_allow_bitmap;
|
||||
__le32 oem_unii4_allow_bitmap;
|
||||
__le32 chan_state_active_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v6 - change LARI configuration
|
||||
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
|
||||
|
|
@ -659,8 +586,7 @@ struct iwl_lari_config_change_cmd_v6 {
|
|||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_6 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v7 - change LARI configuration
|
||||
* This structure is used also for lari cmd version 8 and 9.
|
||||
* struct iwl_lari_config_change_cmd_v8 - change LARI configuration
|
||||
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
|
||||
* different predefined FW config operation.
|
||||
* @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
|
||||
|
|
@ -670,21 +596,19 @@ struct iwl_lari_config_change_cmd_v6 {
|
|||
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate allow/disallow unii4 channels.
|
||||
* For LARI cmd version 4 to 8 - bits 0:3 are supported.
|
||||
* For LARI cmd version 9 - bits 0:5 are supported.
|
||||
* bit 0 - 3: supported.
|
||||
* @chan_state_active_bitmap: Bitmap to enable different bands per country
|
||||
* or region.
|
||||
* Each bit represents a country or region, and a band to activate
|
||||
* according to the BIOS definitions.
|
||||
* For LARI cmd version 7 - bits 0:3 are supported.
|
||||
* For LARI cmd version 8 - bits 0:4 are supported.
|
||||
* bit 0 - 4: supported.
|
||||
* @force_disable_channels_bitmap: Bitmap of disabled bands/channels.
|
||||
* Each bit represents a set of channels in a specific band that should be
|
||||
* disabled
|
||||
* @edt_bitmap: Bitmap of energy detection threshold table.
|
||||
* Disable/enable the EDT optimization method for different band.
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v7 {
|
||||
struct iwl_lari_config_change_cmd_v8 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
__le32 oem_11ax_allow_bitmap;
|
||||
|
|
@ -693,48 +617,8 @@ struct iwl_lari_config_change_cmd_v7 {
|
|||
__le32 force_disable_channels_bitmap;
|
||||
__le32 edt_bitmap;
|
||||
} __packed;
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_7 */
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_8 */
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_9 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd_v10 - change LARI configuration
|
||||
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
|
||||
* different predefined FW config operation.
|
||||
* @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
|
||||
* @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate the value to use.
|
||||
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate allow/disallow unii4 channels.
|
||||
* For LARI cmd version 10 - bits 0:5 are supported.
|
||||
* @chan_state_active_bitmap: Bitmap to enable different bands per country
|
||||
* or region.
|
||||
* Each bit represents a country or region, and a band to activate
|
||||
* according to the BIOS definitions.
|
||||
* For LARI cmd version 10 - bits 0:4 are supported.
|
||||
* @force_disable_channels_bitmap: Bitmap of disabled bands/channels.
|
||||
* Each bit represents a set of channels in a specific band that should be
|
||||
* disabled
|
||||
* @edt_bitmap: Bitmap of energy detection threshold table.
|
||||
* Disable/enable the EDT optimization method for different band.
|
||||
* @oem_320mhz_allow_bitmap: 320Mhz bandwidth enablement bitmap per MCC.
|
||||
* bit0: enable 320Mhz in Japan.
|
||||
* bit1: enable 320Mhz in South Korea.
|
||||
* bit 2 - 31: reserved.
|
||||
*/
|
||||
struct iwl_lari_config_change_cmd_v10 {
|
||||
__le32 config_bitmap;
|
||||
__le32 oem_uhb_allow_bitmap;
|
||||
__le32 oem_11ax_allow_bitmap;
|
||||
__le32 oem_unii4_allow_bitmap;
|
||||
__le32 chan_state_active_bitmap;
|
||||
__le32 force_disable_channels_bitmap;
|
||||
__le32 edt_bitmap;
|
||||
__le32 oem_320mhz_allow_bitmap;
|
||||
} __packed;
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_10 */
|
||||
|
||||
/**
|
||||
* struct iwl_lari_config_change_cmd - change LARI configuration
|
||||
|
|
@ -747,14 +631,11 @@ struct iwl_lari_config_change_cmd_v10 {
|
|||
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
|
||||
* per country, one to indicate whether to override and the other to
|
||||
* indicate allow/disallow unii4 channels.
|
||||
* For LARI cmd version 11 - bits 0:5 are supported.
|
||||
* @chan_state_active_bitmap: Bitmap to enable different bands per country
|
||||
* or region.
|
||||
* Each bit represents a country or region, and a band to activate
|
||||
* according to the BIOS definitions.
|
||||
* For LARI cmd version 11 - bits 0:4 are supported.
|
||||
* For LARI cmd version 12 - bits 0:6 are supported and bits 7:31 are
|
||||
* reserved.
|
||||
* bit 0 - 6: supported.
|
||||
* @force_disable_channels_bitmap: Bitmap of disabled bands/channels.
|
||||
* Each bit represents a set of channels in a specific band that should be
|
||||
* disabled
|
||||
|
|
@ -781,12 +662,11 @@ struct iwl_lari_config_change_cmd {
|
|||
__le32 oem_320mhz_allow_bitmap;
|
||||
__le32 oem_11be_allow_bitmap;
|
||||
} __packed;
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_11 */
|
||||
/* LARI_CHANGE_CONF_CMD_S_VER_12 */
|
||||
|
||||
/* Activate UNII-1 (5.2GHz) for World Wide */
|
||||
#define ACTIVATE_5G2_IN_WW_MASK BIT(4)
|
||||
#define CHAN_STATE_ACTIVE_BITMAP_CMD_V11 0x1F
|
||||
#define CHAN_STATE_ACTIVE_BITMAP_CMD_V8 0x1F
|
||||
#define CHAN_STATE_ACTIVE_BITMAP_CMD_V12 0x7F
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ struct iwl_sar_offset_mapping_cmd {
|
|||
} __packed; /*SAR_OFFSET_MAPPING_TABLE_CMD_API_S*/
|
||||
|
||||
/**
|
||||
* struct iwl_beacon_filter_cmd
|
||||
* struct iwl_beacon_filter_cmd - beacon filter command
|
||||
* REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
|
||||
* @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
|
||||
* to driver if delta in Energy values calculated for this and last
|
||||
|
|
@ -762,7 +762,7 @@ enum iwl_6ghz_ap_type {
|
|||
}; /* PHY_AP_TYPE_API_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_txpower_constraints_cmd
|
||||
* struct iwl_txpower_constraints_cmd - TX power constraints command
|
||||
* AP_TX_POWER_CONSTRAINTS_CMD
|
||||
* Used for VLP/LPI/AFC Access Point power constraints for 6GHz channels
|
||||
* @link_id: linkId
|
||||
|
|
@ -786,4 +786,5 @@ struct iwl_txpower_constraints_cmd {
|
|||
__s8 psd_pwr[IWL_MAX_TX_EIRP_PSD_PWR_MAX_SIZE];
|
||||
u8 reserved[3];
|
||||
} __packed; /* PHY_AP_TX_POWER_CONSTRAINTS_CMD_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_power_h__ */
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ enum iwl_rx_mpdu_reorder_data {
|
|||
};
|
||||
|
||||
enum iwl_rx_mpdu_phy_info {
|
||||
IWL_RX_MPDU_PHY_EOF_INDICATION = BIT(0),
|
||||
IWL_RX_MPDU_PHY_AMPDU = BIT(5),
|
||||
IWL_RX_MPDU_PHY_AMPDU_TOGGLE = BIT(6),
|
||||
IWL_RX_MPDU_PHY_SHORT_PREAMBLE = BIT(7),
|
||||
|
|
@ -1041,4 +1042,289 @@ struct iwl_beacon_filter_notif {
|
|||
__le32 link_id;
|
||||
} __packed; /* BEACON_FILTER_IN_NTFY_API_S_VER_2 */
|
||||
|
||||
union iwl_legacy_sig {
|
||||
#define OFDM_RX_LEGACY_LENGTH 0x00000fff
|
||||
#define OFDM_RX_RATE 0x0000f000
|
||||
__le32 ofdm;
|
||||
#define CCK_CRFR_SHORT_PREAMBLE 0x00000040
|
||||
__le32 cck;
|
||||
};
|
||||
|
||||
struct iwl_ht_sigs {
|
||||
#define OFDM_RX_FRAME_HT_MCS 0x0000007f
|
||||
#define OFDM_RX_FRAME_HT_BANDWIDTH 0x00000080
|
||||
#define OFDM_RX_FRAME_HT_LENGTH 0x03ffff00
|
||||
__le32 a1;
|
||||
__le32 a2;
|
||||
};
|
||||
|
||||
struct iwl_vht_sigs {
|
||||
#define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM 0x000007ff
|
||||
#define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM_VALID 0x80000000
|
||||
__le32 a0;
|
||||
__le32 a1, a2;
|
||||
};
|
||||
|
||||
struct iwl_he_sigs {
|
||||
#define OFDM_RX_FRAME_HE_BEAM_CHANGE 0x00000001
|
||||
#define OFDM_RX_FRAME_HE_UL_FLAG 0x00000002
|
||||
#define OFDM_RX_FRAME_HE_MCS 0x0000003c
|
||||
#define OFDM_RX_FRAME_HE_DCM 0x00000040
|
||||
#define OFDM_RX_FRAME_HE_BSS_COLOR 0x00001f80
|
||||
#define OFDM_RX_FRAME_HE_SPATIAL_REUSE 0x0001e000
|
||||
#define OFDM_RX_FRAME_HE_BANDWIDTH 0x00060000
|
||||
#define OFDM_RX_FRAME_HE_SU_EXT_BW10 0x00080000
|
||||
#define OFDM_RX_FRAME_HE_GI_LTF_TYPE 0x00700000
|
||||
#define OFDM_RX_FRAME_HE_NSTS 0x03800000
|
||||
#define OFDM_RX_FRAME_HE_PRMBL_PUNC_TYPE 0x0c000000
|
||||
__le32 a1;
|
||||
#define OFDM_RX_FRAME_HE_TXOP_DURATION 0x0000007f
|
||||
#define OFDM_RX_FRAME_HE_CODING 0x00000080
|
||||
#define OFDM_RX_FRAME_HE_CODING_EXTRA_SYM 0x00000100
|
||||
#define OFDM_RX_FRAME_HE_STBC 0x00000200
|
||||
#define OFDM_RX_FRAME_HE_BF 0x00000400
|
||||
#define OFDM_RX_FRAME_HE_PRE_FEC_PAD_FACTOR 0x00001800
|
||||
#define OFDM_RX_FRAME_HE_PE_DISAMBIG 0x00002000
|
||||
#define OFDM_RX_FRAME_HE_DOPPLER 0x00004000
|
||||
#define OFDM_RX_FRAME_HE_TYPE 0x00038000
|
||||
#define OFDM_RX_FRAME_HE_MU_NUM_OF_SIGB_SYM_OR_USER_NUM 0x003c0000
|
||||
#define OFDM_RX_FRAME_HE_MU_SIGB_COMP 0x00400000
|
||||
#define OFDM_RX_FRAME_HE_MU_NUM_OF_LTF_SYM 0x03800000
|
||||
__le32 a2;
|
||||
#define OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM 0x000007ff
|
||||
#define OFDM_RX_FRAME_HE_PE_DURATION 0x00003800
|
||||
#define OFDM_RX_FRAME_HE_NUM_OF_DATA_SYM_VALID 0x80000000
|
||||
__le32 a3;
|
||||
#define OFDM_RX_FRAME_HE_SIGB_STA_ID_FOUND 0x00000001
|
||||
#define OFDM_RX_FRAME_HE_SIGB_STA_ID_INDX 0x0000000e
|
||||
#define OFDM_RX_FRAME_HE_SIGB_NSTS 0x00000070
|
||||
#define OFDM_RX_FRAME_HE_SIGB_BF 0x00000080
|
||||
#define OFDM_RX_FRAME_HE_SIGB_MCS 0x00000f00
|
||||
#define OFDM_RX_FRAME_HE_SIGB_DCM 0x00001000
|
||||
#define OFDM_RX_FRAME_HE_SIGB_CODING 0x00002000
|
||||
#define OFDM_RX_FRAME_HE_SIGB_SPATIAL_CONFIG 0x0003c000
|
||||
#define OFDM_RX_FRAME_HE_SIGB_STA_RU 0x03fc0000
|
||||
#define OFDM_RX_FRAME_HE_SIGB_NUM_OF_SYM 0x3c000000
|
||||
#define OFDM_RX_FRAME_HE_SIGB_CRC_OK 0x40000000
|
||||
__le32 b;
|
||||
/* index 0 */
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_0_A1 0x000000ff
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_0_A2 0x0000ff00
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_0_B1 0x00ff0000
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_0_B2 0xff000000
|
||||
/* index 1 */
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_1_C1 0x000000ff
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_1_C2 0x0000ff00
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_1_D1 0x00ff0000
|
||||
#define OFDM_RX_FRAME_HE_RU_ALLOC_1_D2 0xff000000
|
||||
/* index 2 */
|
||||
#define OFDM_RX_FRAME_HE_CENTER_RU_CC1 0x00000001
|
||||
#define OFDM_RX_FRAME_HE_CENTER_RU_CC2 0x00000002
|
||||
#define OFDM_RX_FRAME_HE_COMMON_CC1_CRC_OK 0x00000004
|
||||
#define OFDM_RX_FRAME_HE_COMMON_CC2_CRC_OK 0x00000008
|
||||
__le32 cmn[3];
|
||||
};
|
||||
|
||||
struct iwl_he_tb_sigs {
|
||||
#define OFDM_RX_HE_TRIG_FORMAT 0x00000001
|
||||
#define OFDM_RX_HE_TRIG_BSS_COLOR 0x0000007e
|
||||
#define OFDM_RX_HE_TRIG_SPATIAL_REUSE_1 0x00000780
|
||||
#define OFDM_RX_HE_TRIG_SPATIAL_REUSE_2 0x00007800
|
||||
#define OFDM_RX_HE_TRIG_SPATIAL_REUSE_3 0x00078000
|
||||
#define OFDM_RX_HE_TRIG_SPATIAL_REUSE_4 0x00780000
|
||||
#define OFDM_RX_HE_TRIG_BANDWIDTH 0x03000000
|
||||
__le32 a1;
|
||||
#define OFDM_RX_HE_TRIG_TXOP_DURATION 0x0000007f
|
||||
#define OFDM_RX_HE_TRIG_SIG2_RESERVED 0x0000ff80
|
||||
#define OFDM_RX_HE_TRIG_FORMAT_ERR 0x08000000
|
||||
#define OFDM_RX_HE_TRIG_BW_ERR 0x10000000
|
||||
#define OFDM_RX_HE_TRIG_LEGACY_LENGTH_ERR 0x20000000
|
||||
#define OFDM_RX_HE_TRIG_CRC_OK 0x40000000
|
||||
__le32 a2;
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_LGCY_LENGTH 0x00000fff
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_BANDWIDTH 0x00007000
|
||||
#define OFDM_UCODE_TRIG_BASE_PS160 0x00008000
|
||||
#define OFDM_UCODE_EHT_TRIG_CONTROL_CHANNEL 0x000f0000
|
||||
__le32 tb_rx0;
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_MCS 0x0000000f
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_DCM 0x00000010
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_GI_LTF_TYPE 0x00000060
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_NSTS 0x00000380
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_CODING 0x00000400
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_CODING_EXTRA_SYM 0x00000800
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_STBC 0x00001000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_PRE_FEC_PAD_FACTOR 0x00006000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_PE_DISAMBIG 0x00008000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_DOPPLER 0x00010000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_RU 0x01fe0000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_RU_P80 0x00020000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_NUM_OF_LTF_SYM 0x0e000000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_LTF_PILOT_TYPE 0x10000000
|
||||
#define OFDM_UCODE_TRIG_BASE_RX_LOWEST_SS_ALLOCATION 0xe0000000
|
||||
__le32 tb_rx1;
|
||||
};
|
||||
|
||||
struct iwl_eht_sigs {
|
||||
#define OFDM_RX_FRAME_ENHANCED_WIFI_VER_ID 0x00000007
|
||||
#define OFDM_RX_FRAME_ENHANCED_WIFI_BANDWIDTH 0x00000038
|
||||
#define OFDM_RX_FRAME_ENHANCED_WIFI_UL_FLAG 0x00000040
|
||||
#define OFDM_RX_FRAME_ENHANCED_WIFI_BSS_COLOR 0x00001f80
|
||||
#define OFDM_RX_FRAME_ENHANCED_WIFI_TXOP_DURATION 0x000fe000
|
||||
#define OFDM_RX_FRAME_EHT_USIG1_DISREGARD 0x01f00000
|
||||
#define OFDM_RX_FRAME_EHT_USIG1_VALIDATE 0x02000000
|
||||
#define OFDM_RX_FRAME_EHT_BW320_SLOT 0x04000000
|
||||
#define OFDM_RX_FRAME_EHT_TYPE 0x18000000
|
||||
#define OFDM_RX_FRAME_ENHANCED_ER_NO_STREAMS 0x20000000
|
||||
__le32 usig_a1;
|
||||
#define OFDM_RX_FRAME_EHT_PPDU_TYPE 0x00000003
|
||||
#define OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B2 0x00000004
|
||||
#define OFDM_RX_FRAME_EHT_PUNC_CHANNEL 0x000000f8
|
||||
#define OFDM_RX_FRAME_EHT_USIG2_VALIDATE_B8 0x00000100
|
||||
#define OFDM_RX_FRAME_EHT_SIG_MCS 0x00000600
|
||||
#define OFDM_RX_FRAME_EHT_SIG_SYM_NUM 0x0000f800
|
||||
#define OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_1 0x000f0000
|
||||
#define OFDM_RX_FRAME_EHT_TRIG_SPATIAL_REUSE_2 0x00f00000
|
||||
#define OFDM_RX_FRAME_EHT_TRIG_USIG2_DISREGARD 0x1f000000
|
||||
#define OFDM_RX_FRAME_EHT_TRIG_NO_STREAMS 0x20000000
|
||||
#define OFDM_RX_USIG_CRC_OK 0x40000000
|
||||
__le32 usig_a2_eht;
|
||||
#define OFDM_RX_FRAME_EHT_SPATIAL_REUSE 0x0000000f
|
||||
#define OFDM_RX_FRAME_EHT_GI_LTF_TYPE 0x00000030
|
||||
#define OFDM_RX_FRAME_EHT_NUM_OF_LTF_SYM 0x000001c0
|
||||
#define OFDM_RX_FRAME_EHT_CODING_EXTRA_SYM 0x00000200
|
||||
#define OFDM_RX_FRAME_EHT_PRE_FEC_PAD_FACTOR 0x00000c00
|
||||
#define OFDM_RX_FRAME_EHT_PE_DISAMBIG 0x00001000
|
||||
#define OFDM_RX_FRAME_EHT_USIG_OVF_DISREGARD 0x0001e000
|
||||
#define OFDM_RX_FRAME_EHT_NUM_OF_USERS 0x000e0000
|
||||
#define OFDM_RX_FRAME_EHT_NSTS 0x00f00000
|
||||
#define OFDM_RX_FRAME_EHT_BF 0x01000000
|
||||
#define OFDM_RX_FRAME_EHT_USIG_OVF_NDP_DISREGARD 0x06000000
|
||||
#define OFDM_RX_FRAME_EHTSIG_COMM_CC1_CRC_OK 0x08000000
|
||||
#define OFDM_RX_FRAME_EHTSIG_COMM_CC2_CRC_OK 0x10000000
|
||||
#define OFDM_RX_FRAME_EHT_NON_VALID_RU_ALLOC 0x20000000
|
||||
#define OFDM_RX_FRAME_EHT_NO_STREAMS 0x40000000
|
||||
__le32 b1;
|
||||
#define OFDM_RX_FRAME_EHT_MATCH_ID_FOUND 0x00000001
|
||||
#define OFDM_RX_FRAME_EHT_ID_INDX 0x0000000e
|
||||
#define OFDM_RX_FRAME_EHT_MCS 0x000000f0
|
||||
#define OFDM_RX_FRAME_EHT_CODING 0x00000100
|
||||
#define OFDM_RX_FRAME_EHT_SPATIAL_CONFIG 0x00007e00
|
||||
#define OFDM_RX_FRAME_EHT_STA_RU 0x007f8000
|
||||
#define OFDM_RX_FRAME_EHT_STA_RU_P80 0x00008000
|
||||
#define OFDM_RX_FRAME_EHT_STA_RU_PS160 0x00800000
|
||||
#define OFDM_RX_FRAME_EHT_USER_FIELD_CRC_OK 0x40000000
|
||||
__le32 b2;
|
||||
#define OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM 0x000007ff
|
||||
#define OFDM_RX_FRAME_EHT_PE_DURATION 0x00003800
|
||||
#define OFDM_RX_FRAME_EHT_NUM_OF_DATA_SYM_VALID 0x80000000
|
||||
__le32 sig2;
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A1 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A2 0x0003fe00
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_0_A3 0x07fc0000
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B1 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B2 0x0003fe00
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_1_B3 0x07fc0000
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C1 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C2 0x0003fe00
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_2_C3 0x07fc0000
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D1 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D2 0x0003fe00
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_3_D3 0x07fc0000
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_4_A4 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_4_B4 0x0003fe00
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_5_C4 0x000001ff
|
||||
#define OFDM_RX_FRAME_EHT_RU_ALLOC_5_D4 0x0003fe00
|
||||
__le32 cmn[6];
|
||||
#define OFDM_RX_FRAME_EHT_USER_FIELD_ID 0x000007ff
|
||||
__le32 user_id;
|
||||
};
|
||||
|
||||
struct iwl_eht_tb_sigs {
|
||||
/* same as non-TB above */
|
||||
__le32 usig_a1, usig_a2_eht;
|
||||
/* same as HE TB above */
|
||||
__le32 tb_rx0, tb_rx1;
|
||||
};
|
||||
|
||||
struct iwl_uhr_sigs {
|
||||
__le32 usig_a1, usig_a1_uhr, usig_a2_uhr, b1, b2;
|
||||
__le32 sig2;
|
||||
__le32 cmn[6];
|
||||
__le32 user_id;
|
||||
};
|
||||
|
||||
struct iwl_uhr_tb_sigs {
|
||||
__le32 usig_a1, usig_a2_uhr, tb_rx0, tb_rx1;
|
||||
};
|
||||
|
||||
struct iwl_uhr_elr_sigs {
|
||||
__le32 usig_a1, usig_a2_uhr;
|
||||
__le32 uhr_sig_elr1, uhr_sig_elr2;
|
||||
};
|
||||
|
||||
union iwl_sigs {
|
||||
struct iwl_ht_sigs ht;
|
||||
struct iwl_vht_sigs vht;
|
||||
struct iwl_he_sigs he;
|
||||
struct iwl_he_tb_sigs he_tb;
|
||||
struct iwl_eht_sigs eht;
|
||||
struct iwl_eht_tb_sigs eht_tb;
|
||||
struct iwl_uhr_sigs uhr;
|
||||
struct iwl_uhr_tb_sigs uhr_tb;
|
||||
struct iwl_uhr_elr_sigs uhr_elr;
|
||||
};
|
||||
|
||||
enum iwl_sniffer_status {
|
||||
IWL_SNIF_STAT_PLCP_RX_OK = 0,
|
||||
IWL_SNIF_STAT_AID_NOT_FOR_US = 1,
|
||||
IWL_SNIF_STAT_PLCP_RX_LSIG_ERR = 2,
|
||||
IWL_SNIF_STAT_PLCP_RX_SIGA_ERR = 3,
|
||||
IWL_SNIF_STAT_PLCP_RX_SIGB_ERR = 4,
|
||||
IWL_SNIF_STAT_UNEXPECTED_TB = 5,
|
||||
IWL_SNIF_STAT_UNSUPPORTED_RATE = 6,
|
||||
IWL_SNIF_STAT_UNKNOWN_ERROR = 7,
|
||||
}; /* AIR_SNIFFER_STATUS_E_VER_1 */
|
||||
|
||||
enum iwl_sniffer_flags {
|
||||
IWL_SNIF_FLAG_VALID_TB_RX = BIT(0),
|
||||
IWL_SNIF_FLAG_VALID_RU = BIT(1),
|
||||
}; /* AIR_SNIFFER_FLAGS_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_rx_phy_air_sniffer_ntfy - air sniffer notification
|
||||
*
|
||||
* @status: &enum iwl_sniffer_status
|
||||
* @flags: &enum iwl_sniffer_flags
|
||||
* @reserved1: reserved
|
||||
* @rssi_a: energy chain-A in negative dBm, measured at FINA time
|
||||
* @rssi_b: energy chain-B in negative dBm, measured at FINA time
|
||||
* @channel: channel number
|
||||
* @band: band information, PHY_BAND_*
|
||||
* @on_air_rise_time: GP2 at on air rise
|
||||
* @frame_time: frame time in us
|
||||
* @rate: RATE_MCS_*
|
||||
* @bytecount: byte count for legay and HT, otherwise number of symbols
|
||||
* @legacy_sig: CCK signal information if %RATE_MCS_MOD_TYPE_MSK in @rate is
|
||||
* %RATE_MCS_MOD_TYPE_CCK, otherwise OFDM signal information
|
||||
* @sigs: PHY signal information, depending on %RATE_MCS_MOD_TYPE_MSK in @rate
|
||||
* @reserved2: reserved
|
||||
*
|
||||
* Sent for every frame and before the normal RX command if data is included.
|
||||
*/
|
||||
struct iwl_rx_phy_air_sniffer_ntfy {
|
||||
u8 status;
|
||||
u8 flags;
|
||||
u8 reserved1[2];
|
||||
u8 rssi_a, rssi_b;
|
||||
u8 channel, band;
|
||||
__le32 on_air_rise_time;
|
||||
__le32 frame_time;
|
||||
/* note: MCS in rate is not valid for MU-VHT */
|
||||
__le32 rate;
|
||||
__le32 bytecount;
|
||||
union iwl_legacy_sig legacy_sig;
|
||||
union iwl_sigs sigs;
|
||||
__le32 reserved2;
|
||||
}; /* RX_PHY_AIR_SNIFFER_NTFY_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_rx_h__ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -129,7 +129,7 @@ struct iwl_scan_offload_profile {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profile_cfg_data
|
||||
* struct iwl_scan_offload_profile_cfg_data - scan offload profile configs
|
||||
* @blocklist_len: length of blocklist
|
||||
* @num_profiles: num of profiles in the list
|
||||
* @match_notify: clients waiting for match found notification
|
||||
|
|
@ -159,7 +159,7 @@ struct iwl_scan_offload_profile_cfg_v1 {
|
|||
} __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1-2*/
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profile_cfg
|
||||
* struct iwl_scan_offload_profile_cfg - scan offload profile config
|
||||
* @profiles: profiles to search for match
|
||||
* @data: the rest of the data for profile_cfg
|
||||
*/
|
||||
|
|
@ -507,7 +507,7 @@ enum iwl_uhb_chan_cfg_flags {
|
|||
IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE = BIT(26),
|
||||
};
|
||||
/**
|
||||
* struct iwl_scan_dwell
|
||||
* struct iwl_scan_dwell - scan dwell configuration
|
||||
* @active: default dwell time for active scan
|
||||
* @passive: default dwell time for passive scan
|
||||
* @fragmented: default dwell time for fragmented scan
|
||||
|
|
@ -728,7 +728,7 @@ enum iwl_umac_scan_general_params_flags2 {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct iwl_scan_channel_cfg_umac
|
||||
* struct iwl_scan_channel_cfg_umac - scan channel config
|
||||
* @flags: bitmap - 0-19: directed scan to i'th ssid.
|
||||
* @channel_num: channel number 1-13 etc.
|
||||
* @v1: command version 1
|
||||
|
|
@ -774,7 +774,7 @@ struct iwl_scan_channel_cfg_umac {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_scan_umac_schedule
|
||||
* struct iwl_scan_umac_schedule - scan schedule parameters
|
||||
* @interval: interval in seconds between scan iterations
|
||||
* @iter_count: num of scan iterations for schedule plan, 0xff for infinite loop
|
||||
* @reserved: for alignment and future use
|
||||
|
|
@ -815,7 +815,7 @@ struct iwl_scan_req_umac_tail_v2 {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_scan_umac_chan_param
|
||||
* struct iwl_scan_umac_chan_param - scan channel parameters
|
||||
* @flags: channel flags &enum iwl_scan_channel_flags
|
||||
* @count: num of channels in scan request
|
||||
* @reserved: for future use and alignment
|
||||
|
|
@ -827,33 +827,37 @@ struct iwl_scan_umac_chan_param {
|
|||
} __packed; /*SCAN_CHANNEL_PARAMS_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_req_umac
|
||||
* struct iwl_scan_req_umac - scan request command
|
||||
* @flags: &enum iwl_umac_scan_flags
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @ooc_priority: out of channel priority - &enum iwl_scan_priority
|
||||
* @general_flags: &enum iwl_umac_scan_general_flags
|
||||
* @reserved: reserved
|
||||
* @scan_start_mac_id: report the scan start TSF time according to this mac TSF
|
||||
* @extended_dwell: dwell time for channels 1, 6 and 11
|
||||
* @active_dwell: dwell time for active scan per LMAC
|
||||
* @passive_dwell: dwell time for passive scan per LMAC
|
||||
* @fragmented_dwell: dwell time for fragmented passive scan
|
||||
* @adwell_default_n_aps: for adaptive dwell the default number of APs
|
||||
* @v1: version 1 command data
|
||||
* @v6: version 6 command data
|
||||
* @v7: version 7 command data
|
||||
* @v8: version 8 command data
|
||||
* @v9: version 9 command data
|
||||
* @v1.extended_dwell: dwell time for channels 1, 6 and 11
|
||||
* @v1.active_dwell: dwell time for active scan per LMAC
|
||||
* @v1.passive_dwell: dwell time for passive scan per LMAC
|
||||
* @v1.fragmented_dwell: dwell time for fragmented passive scan
|
||||
* @v7.adwell_default_n_aps: for adaptive dwell the default number of APs
|
||||
* per channel
|
||||
* @adwell_default_n_aps_social: for adaptive dwell the default
|
||||
* @v7.adwell_default_n_aps_social: for adaptive dwell the default
|
||||
* number of APs per social (1,6,11) channel
|
||||
* @general_flags2: &enum iwl_umac_scan_general_flags2
|
||||
* @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added
|
||||
* to total scan time
|
||||
* @max_out_time: max out of serving channel time, per LMAC - for CDB there
|
||||
* are 2 LMACs
|
||||
* @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs
|
||||
* @scan_priority: scan internal prioritization &enum iwl_scan_priority
|
||||
* @num_of_fragments: Number of fragments needed for full coverage per band.
|
||||
* @v8.general_flags2: &enum iwl_umac_scan_general_flags2
|
||||
* @v7.adwell_max_budget: for adaptive dwell the maximal budget of TU to be
|
||||
* added to total scan time
|
||||
* @v1.max_out_time: max out of serving channel time, per LMAC - for CDB
|
||||
* there are 2 LMACs
|
||||
* @v1.suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs
|
||||
* @v1.scan_priority: scan internal prioritization &enum iwl_scan_priority
|
||||
* @v8.num_of_fragments: Number of fragments needed for full coverage per band.
|
||||
* Relevant only for fragmented scan.
|
||||
* @channel: &struct iwl_scan_umac_chan_param
|
||||
* @reserved: for future use and alignment
|
||||
* @reserved3: for future use and alignment
|
||||
* @data: &struct iwl_scan_channel_cfg_umac and
|
||||
* @v1.channel: &struct iwl_scan_umac_chan_param
|
||||
* @v1.data: &struct iwl_scan_channel_cfg_umac and
|
||||
* &struct iwl_scan_req_umac_tail
|
||||
*/
|
||||
struct iwl_scan_req_umac {
|
||||
|
|
@ -939,7 +943,7 @@ struct iwl_scan_req_umac {
|
|||
#define IWL_SCAN_REQ_UMAC_SIZE_V1 36
|
||||
|
||||
/**
|
||||
* struct iwl_scan_probe_params_v3
|
||||
* struct iwl_scan_probe_params_v3 - scan probe parameters
|
||||
* @preq: scan probe request params
|
||||
* @ssid_num: number of valid SSIDs in direct scan array
|
||||
* @short_ssid_num: number of valid short SSIDs in short ssid array
|
||||
|
|
@ -961,7 +965,7 @@ struct iwl_scan_probe_params_v3 {
|
|||
} __packed; /* SCAN_PROBE_PARAMS_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_probe_params_v4
|
||||
* struct iwl_scan_probe_params_v4 - scan probe parameters
|
||||
* @preq: scan probe request params
|
||||
* @short_ssid_num: number of valid short SSIDs in short ssid array
|
||||
* @bssid_num: number of valid bssid in bssids array
|
||||
|
|
@ -983,7 +987,7 @@ struct iwl_scan_probe_params_v4 {
|
|||
#define SCAN_MAX_NUM_CHANS_V3 67
|
||||
|
||||
/**
|
||||
* struct iwl_scan_channel_params_v4
|
||||
* struct iwl_scan_channel_params_v4 - channel params
|
||||
* @flags: channel flags &enum iwl_scan_channel_flags
|
||||
* @count: num of channels in scan request
|
||||
* @num_of_aps_override: override the number of APs the FW uses to calculate
|
||||
|
|
@ -1006,7 +1010,7 @@ struct iwl_scan_channel_params_v4 {
|
|||
SCAN_CHANNEL_PARAMS_API_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_channel_params_v7
|
||||
* struct iwl_scan_channel_params_v7 - channel params
|
||||
* @flags: channel flags &enum iwl_scan_channel_flags
|
||||
* @count: num of channels in scan request
|
||||
* @n_aps_override: override the number of APs the FW uses to calculate dwell
|
||||
|
|
@ -1024,7 +1028,7 @@ struct iwl_scan_channel_params_v7 {
|
|||
} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_general_params_v11
|
||||
* struct iwl_scan_general_params_v11 - channel params
|
||||
* @flags: &enum iwl_umac_scan_general_flags_v2
|
||||
* @reserved: reserved for future
|
||||
* @scan_start_mac_or_link_id: report the scan start TSF time according to this
|
||||
|
|
@ -1066,7 +1070,7 @@ struct iwl_scan_general_params_v11 {
|
|||
} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_12, *_VER_11 and *_VER_10 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_periodic_parms_v1
|
||||
* struct iwl_scan_periodic_parms_v1 - periodicity parameters
|
||||
* @schedule: can scheduling parameter
|
||||
* @delay: initial delay of the periodic scan in seconds
|
||||
* @reserved: reserved for future
|
||||
|
|
@ -1078,7 +1082,7 @@ struct iwl_scan_periodic_parms_v1 {
|
|||
} __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_req_params_v12
|
||||
* struct iwl_scan_req_params_v12 - scan request parameters (v12)
|
||||
* @general_params: &struct iwl_scan_general_params_v11
|
||||
* @channel_params: &struct iwl_scan_channel_params_v4
|
||||
* @periodic_params: &struct iwl_scan_periodic_parms_v1
|
||||
|
|
@ -1106,7 +1110,7 @@ struct iwl_scan_req_params_v17 {
|
|||
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_17 - 14 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_req_umac_v12
|
||||
* struct iwl_scan_req_umac_v12 - scan request command (v12)
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @ooc_priority: out of channel priority - &enum iwl_scan_priority
|
||||
* @scan_params: scan parameters
|
||||
|
|
@ -1130,7 +1134,7 @@ struct iwl_scan_req_umac_v17 {
|
|||
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_17 - 14 */
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_abort
|
||||
* struct iwl_umac_scan_abort - scan abort command
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @flags: reserved
|
||||
*/
|
||||
|
|
@ -1140,7 +1144,7 @@ struct iwl_umac_scan_abort {
|
|||
} __packed; /* SCAN_ABORT_CMD_UMAC_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_umac_scan_abort_status
|
||||
* enum iwl_umac_scan_abort_status - scan abort status
|
||||
*
|
||||
* @IWL_UMAC_SCAN_ABORT_STATUS_SUCCESS: scan was successfully aborted
|
||||
* @IWL_UMAC_SCAN_ABORT_STATUS_IN_PROGRESS: scan abort is in progress
|
||||
|
|
@ -1153,7 +1157,7 @@ enum iwl_umac_scan_abort_status {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_complete
|
||||
* struct iwl_umac_scan_complete - scan complete notification
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @last_schedule: last scheduling line
|
||||
* @last_iter: last scan iteration number
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2021, 2023 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2021, 2023, 2025 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -428,7 +428,7 @@ struct iwl_mvm_rm_sta_cmd {
|
|||
} __packed; /* REMOVE_STA_CMD_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_mgmt_mcast_key_cmd_v1
|
||||
* struct iwl_mvm_mgmt_mcast_key_cmd_v1 - IGTK command
|
||||
* ( MGMT_MCAST_KEY = 0x1f )
|
||||
* @ctrl_flags: &enum iwl_sta_key_flag
|
||||
* @igtk: IGTK key material
|
||||
|
|
@ -449,7 +449,7 @@ struct iwl_mvm_mgmt_mcast_key_cmd_v1 {
|
|||
} __packed; /* SEC_MGMT_MULTICAST_KEY_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_mgmt_mcast_key_cmd
|
||||
* struct iwl_mvm_mgmt_mcast_key_cmd - IGTK command
|
||||
* ( MGMT_MCAST_KEY = 0x1f )
|
||||
* @ctrl_flags: &enum iwl_sta_key_flag
|
||||
* @igtk: IGTK master key
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ struct mvm_statistics_div {
|
|||
} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct mvm_statistics_rx_non_phy
|
||||
* struct mvm_statistics_rx_non_phy - non-PHY RX statistics
|
||||
* @bogus_cts: CTS received when not expecting CTS
|
||||
* @bogus_ack: ACK received when not expecting ACK
|
||||
* @non_channel_beacons: beacons with our bss id but not on our serving channel
|
||||
|
|
@ -456,7 +456,7 @@ struct iwl_system_statistics_cmd {
|
|||
} __packed; /* STATISTICS_FW_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_statistics_type
|
||||
* enum iwl_fw_statistics_type - statistics type
|
||||
*
|
||||
* @FW_STATISTICS_OPERATIONAL: operational statistics
|
||||
* @FW_STATISTICS_PHY: phy statistics
|
||||
|
|
@ -478,7 +478,7 @@ enum iwl_fw_statistics_type {
|
|||
|
||||
#define IWL_STATISTICS_TYPE_MSK 0x7f
|
||||
/**
|
||||
* struct iwl_statistics_ntfy_hdr
|
||||
* struct iwl_statistics_ntfy_hdr - statistics notification header
|
||||
*
|
||||
* @type: struct type
|
||||
* @version: version of the struct
|
||||
|
|
@ -491,7 +491,7 @@ struct iwl_statistics_ntfy_hdr {
|
|||
}; /* STATISTICS_NTFY_HDR_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_stats_ntfy_per_link
|
||||
* struct iwl_stats_ntfy_per_link - per-link statistics
|
||||
*
|
||||
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
|
||||
* antennas.
|
||||
|
|
@ -514,7 +514,7 @@ struct iwl_stats_ntfy_per_link {
|
|||
} __packed; /* STATISTICS_NTFY_PER_LINK_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_stats_ntfy_part1_per_link
|
||||
* struct iwl_stats_ntfy_part1_per_link - part1 per link statistics
|
||||
*
|
||||
* @rx_time: rx time
|
||||
* @tx_time: tx time
|
||||
|
|
@ -533,7 +533,7 @@ struct iwl_stats_ntfy_part1_per_link {
|
|||
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_PER_LINK_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_stats_ntfy_per_mac
|
||||
* struct iwl_stats_ntfy_per_mac - per MAC statistics
|
||||
*
|
||||
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
|
||||
* antennas.
|
||||
|
|
@ -556,7 +556,8 @@ struct iwl_stats_ntfy_per_mac {
|
|||
} __packed; /* STATISTICS_NTFY_PER_MAC_API_S_VER_1 */
|
||||
|
||||
#define IWL_STATS_MAX_BW_INDEX 5
|
||||
/** struct iwl_stats_ntfy_per_phy
|
||||
/**
|
||||
* struct iwl_stats_ntfy_per_phy - per PHY statistics
|
||||
* @channel_load: channel load
|
||||
* @channel_load_by_us: device contribution to MCLM
|
||||
* @channel_load_not_by_us: other devices' contribution to MCLM
|
||||
|
|
@ -588,7 +589,7 @@ struct iwl_stats_ntfy_per_phy {
|
|||
#define IWL_STATS_UNKNOWN_CHANNEL_LOAD 0xffffffff
|
||||
|
||||
/**
|
||||
* struct iwl_stats_ntfy_per_sta
|
||||
* struct iwl_stats_ntfy_per_sta - per STA statistics
|
||||
*
|
||||
* @average_energy: in fact it is minus the energy..
|
||||
*/
|
||||
|
|
@ -600,7 +601,7 @@ struct iwl_stats_ntfy_per_sta {
|
|||
#define IWL_STATS_MAX_FW_LINKS (IWL_FW_MAX_LINK_ID + 1)
|
||||
|
||||
/**
|
||||
* struct iwl_system_statistics_notif_oper
|
||||
* struct iwl_system_statistics_notif_oper - statistics notification
|
||||
*
|
||||
* @time_stamp: time when the notification is sent from firmware
|
||||
* @per_link: per link statistics, &struct iwl_stats_ntfy_per_link
|
||||
|
|
@ -615,7 +616,7 @@ struct iwl_system_statistics_notif_oper {
|
|||
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_system_statistics_part1_notif_oper
|
||||
* struct iwl_system_statistics_part1_notif_oper - part1 stats notification
|
||||
*
|
||||
* @time_stamp: time when the notification is sent from firmware
|
||||
* @per_link: per link statistics &struct iwl_stats_ntfy_part1_per_link
|
||||
|
|
@ -628,7 +629,7 @@ struct iwl_system_statistics_part1_notif_oper {
|
|||
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_API_S_VER_4 */
|
||||
|
||||
/**
|
||||
* struct iwl_system_statistics_end_notif
|
||||
* struct iwl_system_statistics_end_notif - statistics end notification
|
||||
*
|
||||
* @time_stamp: time when the notification is sent from firmware
|
||||
*/
|
||||
|
|
@ -637,7 +638,7 @@ struct iwl_system_statistics_end_notif {
|
|||
} __packed; /* STATISTICS_FW_NTFY_END_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_operational_ntfy
|
||||
* struct iwl_statistics_operational_ntfy - operational stats notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @flags: bitmap of possible notification structures
|
||||
|
|
@ -662,7 +663,7 @@ struct iwl_statistics_operational_ntfy {
|
|||
} __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_15 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_operational_ntfy_ver_14
|
||||
* struct iwl_statistics_operational_ntfy_ver_14 - operational stats notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @flags: bitmap of possible notification structures
|
||||
|
|
@ -707,7 +708,7 @@ struct iwl_statistics_operational_ntfy_ver_14 {
|
|||
} __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_14 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_phy_ntfy
|
||||
* struct iwl_statistics_phy_ntfy - PHY statistics notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* RX PHY related statistics
|
||||
|
|
@ -808,7 +809,7 @@ struct iwl_statistics_phy_ntfy {
|
|||
} __packed; /* STATISTICS_PHY_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_mac_ntfy
|
||||
* struct iwl_statistics_mac_ntfy - MAC statistics notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @bcast_filter_passed_per_mac: bcast filter passed per mac
|
||||
|
|
@ -827,7 +828,7 @@ struct iwl_statistics_mac_ntfy {
|
|||
} __packed; /* STATISTICS_MAC_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_rx_ntfy
|
||||
* struct iwl_statistics_rx_ntfy - RX statistics notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @rx_agg_mpdu_cnt: aggregation frame count (number of
|
||||
|
|
@ -867,7 +868,7 @@ struct iwl_statistics_rx_ntfy {
|
|||
} __packed; /* STATISTICS_RX_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_tx_ntfy
|
||||
* struct iwl_statistics_tx_ntfy - TX statistics notification
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @cts_timeout: timeout when waiting for CTS
|
||||
|
|
@ -976,7 +977,7 @@ struct iwl_statistics_tx_ntfy {
|
|||
} __packed; /* STATISTICS_TX_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_duration_ntfy
|
||||
* struct iwl_statistics_duration_ntfy - burst/duration statistics
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @cont_burst_chk_cnt: number of times continuation or
|
||||
|
|
@ -995,7 +996,7 @@ struct iwl_statistics_duration_ntfy {
|
|||
} __packed; /* STATISTICS_DURATION_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_he_ntfy
|
||||
* struct iwl_statistics_he_ntfy - HE statistics
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* received HE frames
|
||||
|
|
|
|||
|
|
@ -963,7 +963,7 @@ struct iwl_scd_txq_cfg_cmd {
|
|||
} __packed; /* SCD_QUEUE_CFG_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_scd_txq_cfg_rsp
|
||||
* struct iwl_scd_txq_cfg_rsp - scheduler TXQ configuration response
|
||||
* @token: taken from the command
|
||||
* @sta_id: station id from the command
|
||||
* @tid: tid from the command
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ struct iwl_fw_ini_error_dump_data {
|
|||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_dump_entry
|
||||
* struct iwl_fw_ini_dump_entry - dump entry descriptor
|
||||
* @list: list of dump entries
|
||||
* @size: size of the data
|
||||
* @data: entry data
|
||||
|
|
@ -305,7 +305,7 @@ struct iwl_fw_ini_fifo_hdr {
|
|||
* @dram_base_addr: base address of dram monitor range
|
||||
* @page_num: page number of memory range
|
||||
* @fifo_hdr: fifo header of memory range
|
||||
* @fw_pkt: FW packet header of memory range
|
||||
* @fw_pkt_hdr: FW packet header of memory range
|
||||
* @data: the actual memory
|
||||
*/
|
||||
struct iwl_fw_ini_error_dump_range {
|
||||
|
|
|
|||
|
|
@ -222,7 +222,10 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
|||
* @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement.
|
||||
* @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2
|
||||
* @IWL_UCODE_TLV_API_ADAPTIVE_DWELL: support for adaptive dwell in scanning
|
||||
* @IWL_UCODE_TLV_API_OCE: support for OCE
|
||||
* @IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE: new beacon template
|
||||
* @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
|
||||
* @IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL: WoWLAN key material support
|
||||
* @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field
|
||||
* indicating low latency direction.
|
||||
* @IWL_UCODE_TLV_API_DEPRECATE_TTAK: RX status flag TTAK ok (bit 7) is
|
||||
|
|
@ -245,6 +248,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
|||
* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S.
|
||||
* @IWL_UCODE_TLV_API_MBSSID_HE: This ucode supports v2 of
|
||||
* STA_CONTEXT_DOT11AX_API_S
|
||||
* @IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE: WoWLAN TCP-SYN wake support
|
||||
* @IWL_UCODE_TLV_API_FTM_RTT_ACCURACY: version 7 of the range response API
|
||||
* is supported by FW, this indicates the RTT confidence value
|
||||
* @IWL_UCODE_TLV_API_SAR_TABLE_VER: This ucode supports different sar
|
||||
|
|
@ -253,6 +257,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
|||
* SCAN_CONFIG_DB_CMD_API_S.
|
||||
* @IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP: support for setting adaptive dwell
|
||||
* number of APs in the 5 GHz band
|
||||
* @IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER: extended channel config in scan
|
||||
* @IWL_UCODE_TLV_API_BAND_IN_RX_DATA: FW reports band number in RX notification
|
||||
* @IWL_UCODE_TLV_API_NO_HOST_DISABLE_TX: Firmware offloaded the station disable tx
|
||||
* logic.
|
||||
|
|
@ -352,16 +357,24 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||
* @IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT: the firmware supports setting
|
||||
* stabilization latency for SoCs.
|
||||
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
|
||||
* @IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT: binding CDB support
|
||||
* @IWL_UCODE_TLV_CAPA_CDB_SUPPORT: CDB support
|
||||
* @IWL_UCODE_TLV_CAPA_D0I3_END_FIRST: D0I3 end command comes first
|
||||
* @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm
|
||||
* @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related
|
||||
* @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2
|
||||
* IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command
|
||||
* @IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command
|
||||
* @IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS: firmware supports ultra high band
|
||||
* (6 GHz).
|
||||
* @IWL_UCODE_TLV_CAPA_CS_MODIFY: firmware supports modify action CSA command
|
||||
* @IWL_UCODE_TLV_CAPA_SET_LTR_GEN2: LTR gen2 support
|
||||
* @IWL_UCODE_TLV_CAPA_TAS_CFG: TAS configuration support
|
||||
* @IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD: session protection command
|
||||
* @IWL_UCODE_TLV_CAPA_SET_PPAG: PPAG support
|
||||
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
|
||||
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
|
||||
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
|
||||
* @IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT: MQ RX support
|
||||
* @IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD: the firmware supports CSA
|
||||
* countdown offloading. Beacon notifications are not sent to the host.
|
||||
* The fw also offloads TBTT alignment.
|
||||
|
|
@ -383,23 +396,46 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||
* command size (command version 4) that supports toggling ACK TX
|
||||
* power reduction.
|
||||
* @IWL_UCODE_TLV_CAPA_D3_DEBUG: supports debug recording during D3
|
||||
* @IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT: LED command support
|
||||
* @IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT: MCC response support 11ax
|
||||
* capability.
|
||||
* @IWL_UCODE_TLV_CAPA_CSI_REPORTING: firmware is capable of being configured
|
||||
* to report the CSI information with (certain) RX frames
|
||||
* @IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP: suspend/resume command
|
||||
* @IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP: support for DBGC
|
||||
* buffer allocation command
|
||||
* @IWL_UCODE_TLV_CAPA_FTM_CALIBRATED: has FTM calibrated and thus supports both
|
||||
* initiator and responder
|
||||
* @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA: supports (de)activating UNII-4
|
||||
* for US/CA/WW from BIOS
|
||||
* @IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT: supports PSC channels
|
||||
* @IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT: BIGTK support
|
||||
* @IWL_UCODE_TLV_CAPA_PROTECTED_TWT: Supports protection of TWT action frames
|
||||
* @IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE: Supports the firmware handshake in
|
||||
* reset flow
|
||||
* @IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN: Support for passive scan on 6GHz PSC
|
||||
* channels even when these are not enabled.
|
||||
* @IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN: hidden SSID 6 GHz scan support
|
||||
* @IWL_UCODE_TLV_CAPA_BROADCAST_TWT: broadcast TWT support
|
||||
* @IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO: support for BT-coex high
|
||||
* priority for 802.1X/4-way-HS
|
||||
* @IWL_UCODE_TLV_CAPA_BAID_ML_SUPPORT: multi-link BAID support
|
||||
* @IWL_UCODE_TLV_CAPA_SYNCED_TIME: synced time command support
|
||||
* @IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM: time sync support
|
||||
* @IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT: BIGTK TX support
|
||||
* @IWL_UCODE_TLV_CAPA_MLD_API_SUPPORT: MLD API support
|
||||
* @IWL_UCODE_TLV_CAPA_SCAN_DONT_TOGGLE_ANT: fixed antenna scan support
|
||||
* @IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT: PPAG China BIOS support
|
||||
* @IWL_UCODE_TLV_CAPA_OFFLOAD_BTM_SUPPORT: BTM protocol offload support
|
||||
* @IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT: STA command MFP support
|
||||
* @IWL_UCODE_TLV_CAPA_SNIFF_VALIDATE_SUPPORT: sniffer validate bits support
|
||||
* @IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT: China 2022 regulator support
|
||||
* @IWL_UCODE_TLV_CAPA_DUMP_COMPLETE_SUPPORT: Support for indicating dump collection
|
||||
* complete to FW.
|
||||
* @IWL_UCODE_TLV_CAPA_SPP_AMSDU_SUPPORT: Support SPP (signaling and payload
|
||||
* protected) A-MSDU.
|
||||
* @IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT: support for DBGC fragmented
|
||||
* DRAM buffers
|
||||
* @IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT: Support secure LTF measurement.
|
||||
* @IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS: Support monitor mode on otherwise
|
||||
* passive channels
|
||||
|
|
@ -407,6 +443,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
|||
* for CA from BIOS.
|
||||
* @IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT: supports %TAS_UHB_ALLOWED_CANADA
|
||||
* @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support
|
||||
* @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed
|
||||
* during assert handling even if the dump isn't split
|
||||
* @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of
|
||||
* handling raw DSM table data.
|
||||
*
|
||||
|
|
@ -487,12 +525,7 @@ enum iwl_ucode_tlv_capa {
|
|||
|
||||
/* set 3 */
|
||||
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA = (__force iwl_ucode_tlv_capa_t)96,
|
||||
|
||||
/*
|
||||
* @IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT: supports PSC channels
|
||||
*/
|
||||
IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)98,
|
||||
|
||||
IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100,
|
||||
IWL_UCODE_TLV_CAPA_SPP_AMSDU_SUPPORT = (__force iwl_ucode_tlv_capa_t)103,
|
||||
IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104,
|
||||
|
|
@ -514,11 +547,8 @@ enum iwl_ucode_tlv_capa {
|
|||
IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT = (__force iwl_ucode_tlv_capa_t)125,
|
||||
|
||||
/* set 4 */
|
||||
/**
|
||||
* @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed
|
||||
* during assert handling even if the dump isn't split
|
||||
*/
|
||||
IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0),
|
||||
|
||||
IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0),
|
||||
IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 1),
|
||||
NUM_IWL_UCODE_TLV_CAPA
|
||||
/*
|
||||
|
|
@ -852,6 +882,8 @@ struct iwl_fw_dbg_trigger_low_rssi {
|
|||
* @start_assoc_denied: number of denied association to start recording
|
||||
* @start_assoc_timeout: number of association timeout to start recording
|
||||
* @start_connection_loss: number of connection loss to start recording
|
||||
* @reserved: reserved
|
||||
* @reserved2: reserved
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_mlme {
|
||||
u8 stop_auth_denied;
|
||||
|
|
@ -885,6 +917,7 @@ struct iwl_fw_dbg_trigger_mlme {
|
|||
* @p2p_device: timeout for the queues of a P2P device in ms
|
||||
* @ibss: timeout for the queues of an IBSS in ms
|
||||
* @tdls: timeout for the queues of a TDLS station in ms
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_txq_timer {
|
||||
__le32 command_queue;
|
||||
|
|
@ -900,7 +933,7 @@ struct iwl_fw_dbg_trigger_txq_timer {
|
|||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_time_event - configures a time event trigger
|
||||
* time_Events: a list of tuples <id, action_bitmap>. The driver will issue a
|
||||
* @time_events: a list of tuples <id, action_bitmap>. The driver will issue a
|
||||
* trigger each time a time event notification that relates to time event
|
||||
* id with one of the actions in the bitmap is received and
|
||||
* BIT(notif->status) is set in status_bitmap.
|
||||
|
|
@ -916,19 +949,19 @@ struct iwl_fw_dbg_trigger_time_event {
|
|||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_ba - configures BlockAck related trigger
|
||||
* rx_ba_start: tid bitmap to configure on what tid the trigger should occur
|
||||
* @rx_ba_start: tid bitmap to configure on what tid the trigger should occur
|
||||
* when an Rx BlockAck session is started.
|
||||
* rx_ba_stop: tid bitmap to configure on what tid the trigger should occur
|
||||
* @rx_ba_stop: tid bitmap to configure on what tid the trigger should occur
|
||||
* when an Rx BlockAck session is stopped.
|
||||
* tx_ba_start: tid bitmap to configure on what tid the trigger should occur
|
||||
* @tx_ba_start: tid bitmap to configure on what tid the trigger should occur
|
||||
* when a Tx BlockAck session is started.
|
||||
* tx_ba_stop: tid bitmap to configure on what tid the trigger should occur
|
||||
* @tx_ba_stop: tid bitmap to configure on what tid the trigger should occur
|
||||
* when a Tx BlockAck session is stopped.
|
||||
* rx_bar: tid bitmap to configure on what tid the trigger should occur
|
||||
* @rx_bar: tid bitmap to configure on what tid the trigger should occur
|
||||
* when a BAR is received (for a Tx BlockAck session).
|
||||
* tx_bar: tid bitmap to configure on what tid the trigger should occur
|
||||
* @tx_bar: tid bitmap to configure on what tid the trigger should occur
|
||||
* when a BAR is send (for an Rx BlocAck session).
|
||||
* frame_timeout: tid bitmap to configure on what tid the trigger should occur
|
||||
* @frame_timeout: tid bitmap to configure on what tid the trigger should occur
|
||||
* when a frame times out in the reordering buffer.
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_ba {
|
||||
|
|
@ -946,6 +979,7 @@ struct iwl_fw_dbg_trigger_ba {
|
|||
* @action_bitmap: the TDLS action to trigger the collection upon
|
||||
* @peer_mode: trigger on specific peer or all
|
||||
* @peer: the TDLS peer to trigger the collection on
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_tdls {
|
||||
u8 action_bitmap;
|
||||
|
|
@ -958,6 +992,7 @@ struct iwl_fw_dbg_trigger_tdls {
|
|||
* struct iwl_fw_dbg_trigger_tx_status - configures trigger for tx response
|
||||
* status.
|
||||
* @statuses: the list of statuses to trigger the collection on
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_tx_status {
|
||||
struct tx_status {
|
||||
|
|
@ -971,6 +1006,7 @@ struct iwl_fw_dbg_trigger_tx_status {
|
|||
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
|
||||
* @id: conf id
|
||||
* @usniffer: should the uSniffer image be used
|
||||
* @reserved: reserved
|
||||
* @num_of_hcmds: how many HCMDs to send are present here
|
||||
* @hcmd: a variable length host command to be sent to apply the configuration.
|
||||
* If there is more than one HCMD to send, they will appear one after the
|
||||
|
|
|
|||
|
|
@ -14,14 +14,13 @@
|
|||
#include "error-dump.h"
|
||||
|
||||
/**
|
||||
* enum iwl_ucode_type
|
||||
*
|
||||
* The type of ucode.
|
||||
* enum iwl_ucode_type - type of ucode
|
||||
*
|
||||
* @IWL_UCODE_REGULAR: Normal runtime ucode
|
||||
* @IWL_UCODE_INIT: Initial ucode
|
||||
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
|
||||
* @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
|
||||
* @IWL_UCODE_TYPE_MAX: (internal value)
|
||||
*/
|
||||
enum iwl_ucode_type {
|
||||
IWL_UCODE_REGULAR,
|
||||
|
|
@ -122,7 +121,7 @@ struct fw_img {
|
|||
#define FW_ADDR_CACHE_CONTROL 0xC0000000UL
|
||||
|
||||
/**
|
||||
* struct iwl_fw_paging
|
||||
* struct iwl_fw_paging - FW paging descriptor
|
||||
* @fw_paging_phys: page phy pointer
|
||||
* @fw_paging_block: pointer to the allocated block
|
||||
* @fw_paging_size: page size
|
||||
|
|
@ -197,6 +196,11 @@ struct iwl_dump_exclude {
|
|||
* @dump_excl_wowlan: image dump exclusion areas for WoWLAN image
|
||||
* @pnvm_data: PNVM data embedded in the .ucode file, if any
|
||||
* @pnvm_size: size of the embedded PNVM data
|
||||
* @dbg: debug data, see &struct iwl_fw_dbg
|
||||
* @default_calib: default calibration data
|
||||
* @phy_config: PHY configuration flags
|
||||
* @valid_rx_ant: valid RX antenna bitmap
|
||||
* @valid_tx_ant: valid TX antenna bitmap
|
||||
*/
|
||||
struct iwl_fw {
|
||||
u32 ucode_ver;
|
||||
|
|
|
|||
|
|
@ -543,32 +543,14 @@ static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver)
|
|||
|
||||
switch (cmd_ver) {
|
||||
case 12:
|
||||
case 11:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd);
|
||||
break;
|
||||
case 10:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v10);
|
||||
break;
|
||||
case 9:
|
||||
case 8:
|
||||
case 7:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7);
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v8);
|
||||
break;
|
||||
case 6:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6);
|
||||
break;
|
||||
case 5:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5);
|
||||
break;
|
||||
case 4:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4);
|
||||
break;
|
||||
case 3:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3);
|
||||
break;
|
||||
case 2:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2);
|
||||
break;
|
||||
default:
|
||||
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1);
|
||||
break;
|
||||
|
|
@ -609,11 +591,11 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
if (!has_raw_dsm_capa)
|
||||
value &= DSM_UNII4_ALLOW_BITMAP;
|
||||
|
||||
/* Since version 9, bits 4 and 5 are supported
|
||||
/* Since version 12, bits 4 and 5 are supported
|
||||
* regardless of this capability, By pass this masking
|
||||
* if firmware has capability of accepting raw DSM table.
|
||||
*/
|
||||
if (!has_raw_dsm_capa && cmd_ver < 9 &&
|
||||
if (!has_raw_dsm_capa && cmd_ver < 12 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA))
|
||||
value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |
|
||||
|
|
@ -637,7 +619,7 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|||
if (!has_raw_dsm_capa && cmd_ver < 12 &&
|
||||
!fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA))
|
||||
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;
|
||||
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V8;
|
||||
|
||||
cmd->chan_state_active_bitmap = cpu_to_le32(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ struct iwl_fwrt_shared_mem_cfg {
|
|||
* struct iwl_fwrt_dump_data - dump data
|
||||
* @trig: trigger the worker was scheduled upon
|
||||
* @fw_pkt: packet received from FW
|
||||
* @desc: dump descriptor
|
||||
* @monitor_only: only dump for monitor
|
||||
*
|
||||
* Note that the decision which part of the union is used
|
||||
* is based on iwl_trans_dbg_ini_valid(): the 'trig' part
|
||||
|
|
@ -68,6 +70,7 @@ struct iwl_fwrt_dump_data {
|
|||
* struct iwl_fwrt_wk_data - dump worker data struct
|
||||
* @idx: index of the worker
|
||||
* @wk: worker
|
||||
* @dump_data: dump data
|
||||
*/
|
||||
struct iwl_fwrt_wk_data {
|
||||
u8 idx;
|
||||
|
|
@ -91,8 +94,8 @@ struct iwl_txf_iter_data {
|
|||
|
||||
/**
|
||||
* struct iwl_fw_runtime - runtime data for firmware
|
||||
* @trans: transport pointer
|
||||
* @fw: firmware image
|
||||
* @cfg: NIC configuration
|
||||
* @dev: device pointer
|
||||
* @ops: user ops
|
||||
* @ops_ctx: user ops context
|
||||
|
|
@ -117,6 +120,23 @@ struct iwl_txf_iter_data {
|
|||
* zero (default initialization) means it hasn't been read yet,
|
||||
* and BIT(0) is set when it has since function 0 also has this
|
||||
* bitmap and is always supported
|
||||
* @geo_enabled: WGDS table is present
|
||||
* @geo_num_profiles: number of geo profiles
|
||||
* @geo_rev: geo profiles table revision
|
||||
* @ppag_chains: PPAG table data
|
||||
* @ppag_flags: PPAG flags
|
||||
* @reduced_power_flags: reduced power flags
|
||||
* @sanitize_ctx: context for dump sanitizer
|
||||
* @sanitize_ops: dump sanitizer ops
|
||||
* @sar_chain_a_profile: SAR chain A profile
|
||||
* @sar_chain_b_profile: SAR chain B profile
|
||||
* @sgom_enabled: SGOM enabled
|
||||
* @sgom_table: SGOM table
|
||||
* @timestamp: timestamp marker data
|
||||
* @timestamp.wk: timestamp marking worker
|
||||
* @timestamp.seq: timestamp marking sequence
|
||||
* @timestamp.delay: timestamp marking worker delay
|
||||
* @tpc_enabled: TPC enabled
|
||||
*/
|
||||
struct iwl_fw_runtime {
|
||||
struct iwl_trans *trans;
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ struct iwl_fw_mon_regs {
|
|||
* for aggregation
|
||||
* @min_txq_size: minimum number of slots required in a TX queue
|
||||
* @gp2_reg_addr: GP2 (timer) register address
|
||||
* @min_umac_error_event_table: minimum SMEM location of UMAC error table
|
||||
* @mon_dbgi_regs: monitor DBGI registers
|
||||
* @mon_dram_regs: monitor DRAM registers
|
||||
* @mon_smem_regs: monitor SMEM registers
|
||||
|
|
@ -203,7 +202,6 @@ struct iwl_family_base_params {
|
|||
netdev_features_t features;
|
||||
u32 smem_offset;
|
||||
u32 smem_len;
|
||||
u32 min_umac_error_event_table;
|
||||
u32 d3_debug_data_base_addr;
|
||||
u32 d3_debug_data_length;
|
||||
u32 min_txq_size;
|
||||
|
|
@ -385,7 +383,7 @@ struct iwl_mac_cfg {
|
|||
#define IWL_NUM_RBDS_EHT (512 * 8)
|
||||
|
||||
/**
|
||||
* struct iwl_rf_cfg
|
||||
* struct iwl_rf_cfg - RF/CRF configuration data
|
||||
* @fw_name_pre: Firmware filename prefix. The api version and extension
|
||||
* (.ucode) will be added to filename before loading from disk. The
|
||||
* filename is constructed as <fw_name_pre>-<api>.ucode.
|
||||
|
|
@ -418,6 +416,7 @@ struct iwl_mac_cfg {
|
|||
* @vht_mu_mimo_supported: VHT MU-MIMO support
|
||||
* @nvm_type: see &enum iwl_nvm_type
|
||||
* @uhb_supported: ultra high band channels supported
|
||||
* @eht_supported: EHT supported
|
||||
* @num_rbds: number of receive buffer descriptors to use
|
||||
* (only used for multi-queue capable devices)
|
||||
*
|
||||
|
|
@ -450,7 +449,8 @@ struct iwl_rf_cfg {
|
|||
host_interrupt_operation_mode:1,
|
||||
lp_xtal_workaround:1,
|
||||
vht_mu_mimo_supported:1,
|
||||
uhb_supported:1;
|
||||
uhb_supported:1,
|
||||
eht_supported:1;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
u8 non_shared_ant;
|
||||
|
|
@ -686,8 +686,10 @@ extern const char iwl_be211_name[];
|
|||
extern const char iwl_killer_bn1850w2_name[];
|
||||
extern const char iwl_killer_bn1850i_name[];
|
||||
extern const char iwl_bn201_name[];
|
||||
extern const char iwl_bn203_name[];
|
||||
extern const char iwl_be221_name[];
|
||||
extern const char iwl_be223_name[];
|
||||
extern const char iwl_ax221_name[];
|
||||
#if IS_ENABLED(CONFIG_IWLDVM)
|
||||
extern const struct iwl_rf_cfg iwl5300_agn_cfg;
|
||||
extern const struct iwl_rf_cfg iwl5350_agn_cfg;
|
||||
|
|
@ -743,6 +745,7 @@ extern const struct iwl_rf_cfg iwl_rf_fm;
|
|||
extern const struct iwl_rf_cfg iwl_rf_fm_160mhz;
|
||||
#define iwl_rf_wh iwl_rf_fm
|
||||
#define iwl_rf_wh_160mhz iwl_rf_fm_160mhz
|
||||
extern const struct iwl_rf_cfg iwl_rf_wh_non_eht;
|
||||
#define iwl_rf_pe iwl_rf_fm
|
||||
#endif /* CONFIG_IWLMLD */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2018-2023 Intel Corporation
|
||||
* Copyright (C) 2018-2023, 2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_dbg_tlv_h__
|
||||
#define __iwl_dbg_tlv_h__
|
||||
|
|
@ -32,7 +32,7 @@ union iwl_dbg_tlv_tp_data {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct iwl_dbg_tlv_time_point_data
|
||||
* struct iwl_dbg_tlv_time_point_data - debug time point data
|
||||
* @trig_list: list of triggers
|
||||
* @active_trig_list: list of active triggers
|
||||
* @hcmd_list: list of host commands
|
||||
|
|
|
|||
|
|
@ -177,9 +177,10 @@ static inline char iwl_drv_get_step(int step)
|
|||
return 'a' + step;
|
||||
}
|
||||
|
||||
static bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans)
|
||||
bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans)
|
||||
{
|
||||
return CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM;
|
||||
return trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ &&
|
||||
CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM;
|
||||
}
|
||||
|
||||
const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf)
|
||||
|
|
@ -347,8 +348,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
|||
|
||||
if (first)
|
||||
drv->fw_index = ucode_api_max;
|
||||
else if (drv->fw_index == ENCODE_CORE_AS_API(99))
|
||||
drv->fw_index = 101; /* last API-scheme number below core 99 */
|
||||
else if (drv->fw_index == ENCODE_CORE_AS_API(100))
|
||||
drv->fw_index = 102; /* last API-scheme number below core 100 */
|
||||
else
|
||||
drv->fw_index--;
|
||||
|
||||
|
|
@ -427,7 +428,6 @@ struct iwl_firmware_pieces {
|
|||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
|
||||
size_t n_mem_tlv;
|
||||
u32 major;
|
||||
};
|
||||
|
||||
static void alloc_sec_data(struct iwl_firmware_pieces *pieces,
|
||||
|
|
@ -1069,19 +1069,19 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
break;
|
||||
case IWL_UCODE_TLV_FW_VERSION: {
|
||||
const __le32 *ptr = (const void *)tlv_data;
|
||||
u32 minor;
|
||||
u32 major, minor;
|
||||
u8 local_comp;
|
||||
|
||||
if (tlv_len != sizeof(u32) * 3)
|
||||
goto invalid_tlv_len;
|
||||
|
||||
pieces->major = le32_to_cpup(ptr++);
|
||||
major = le32_to_cpup(ptr++);
|
||||
minor = le32_to_cpup(ptr++);
|
||||
local_comp = le32_to_cpup(ptr);
|
||||
|
||||
snprintf(drv->fw.fw_version,
|
||||
sizeof(drv->fw.fw_version),
|
||||
"%u.%08x.%u %s", pieces->major, minor,
|
||||
"%u.%08x.%u %s", major, minor,
|
||||
local_comp, iwl_reduced_fw_name(drv));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1589,8 +1589,6 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv)
|
|||
}
|
||||
}
|
||||
|
||||
#define IWL_MLD_SUPPORTED_FW_VERSION 97
|
||||
|
||||
/*
|
||||
* iwl_req_fw_callback - callback when firmware was loaded
|
||||
*
|
||||
|
|
@ -1859,17 +1857,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMLD)
|
||||
if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION &&
|
||||
iwl_drv_is_wifi7_supported(drv->trans))
|
||||
if (iwl_drv_is_wifi7_supported(drv->trans))
|
||||
op = &iwlwifi_opmode_table[MLD_OP_MODE];
|
||||
#else
|
||||
if (pieces->major >= IWL_MLD_SUPPORTED_FW_VERSION &&
|
||||
iwl_drv_is_wifi7_supported(drv->trans)) {
|
||||
IWL_ERR(drv,
|
||||
"IWLMLD needs to be compiled to support this firmware\n");
|
||||
mutex_unlock(&iwlwifi_opmode_table_mtx);
|
||||
goto out_unbind;
|
||||
}
|
||||
#endif
|
||||
|
||||
IWL_INFO(drv, "loaded firmware version %s op_mode %s\n",
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ struct iwl_rf_cfg;
|
|||
* starts the driver: fetches the firmware. This should be called by bus
|
||||
* specific system flows implementations. For example, the bus specific probe
|
||||
* function should do bus related operations only, and then call to this
|
||||
* function. It returns the driver object or %NULL if an error occurred.
|
||||
* function.
|
||||
* Return: the driver object or %NULL if an error occurred.
|
||||
*/
|
||||
struct iwl_drv *iwl_drv_start(struct iwl_trans *trans);
|
||||
|
||||
|
|
@ -77,6 +78,12 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans);
|
|||
*/
|
||||
void iwl_drv_stop(struct iwl_drv *drv);
|
||||
|
||||
/*
|
||||
* iwl_drv_is_wifi7_supported - returns if wifi7 is supported
|
||||
* If yes, iwlmld needs to be used to drive the device.
|
||||
*/
|
||||
bool iwl_drv_is_wifi7_supported(struct iwl_trans *trans);
|
||||
|
||||
/*
|
||||
* exported symbol management
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2022, 2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2022, 2024-2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_modparams_h__
|
||||
#define __iwl_modparams_h__
|
||||
|
|
@ -42,7 +42,7 @@ enum iwl_uapsd_disable {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct iwl_mod_params
|
||||
* struct iwl_mod_params - module parameters for iwlwifi
|
||||
*
|
||||
* Holds the module parameters
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2080,7 +2080,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
|
|||
!!(mac_flags & NVM_MAC_SKU_FLAGS_BAND_5_2_ENABLED);
|
||||
nvm->sku_cap_mimo_disabled =
|
||||
!!(mac_flags & NVM_MAC_SKU_FLAGS_MIMO_DISABLED);
|
||||
if (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) >= IWL_CFG_RF_TYPE_FM)
|
||||
if (trans->cfg->eht_supported)
|
||||
nvm->sku_cap_11be_enable = true;
|
||||
|
||||
/* Initialize PHY sku data */
|
||||
|
|
|
|||
|
|
@ -115,11 +115,12 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
* iwl_parse_nvm_mcc_info - parse MCC (mobile country code) info coming from FW
|
||||
*
|
||||
* This function parses the regulatory channel data received as a
|
||||
* MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain,
|
||||
* to be fed into the regulatory core. In case the geo_info is set handle
|
||||
* accordingly. An ERR_PTR is returned on error.
|
||||
* If not given to the regulatory core, the user is responsible for freeing
|
||||
* the regdomain returned here with kfree.
|
||||
* MCC_UPDATE_CMD command.
|
||||
*
|
||||
* Return: a newly allocation regulatory domain, to be given to the regulatory
|
||||
* core. In case the geo_info is set handle accordingly. An ERR_PTR is
|
||||
* returned on error. If not given to the regulatory core, the user is
|
||||
* responsible for freeing the regdomain returned here with kfree().
|
||||
*
|
||||
* @trans: the transport
|
||||
* @num_of_ch: the number of channels
|
||||
|
|
@ -140,6 +141,8 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
|
|||
* This struct holds an NVM section read from the NIC using NVM_ACCESS_CMD,
|
||||
* and saved for later use by the driver. Not all NVM sections are saved
|
||||
* this way, only the needed ones.
|
||||
* @length: length of the section
|
||||
* @data: section data
|
||||
*/
|
||||
struct iwl_nvm_section {
|
||||
u16 length;
|
||||
|
|
@ -148,6 +151,10 @@ struct iwl_nvm_section {
|
|||
|
||||
/**
|
||||
* iwl_read_external_nvm - Reads external NVM from a file into nvm_sections
|
||||
* @trans: the transport
|
||||
* @nvm_file_name: the filename to request
|
||||
* @nvm_sections: sections data to fill
|
||||
* Return: 0 on success or an error code
|
||||
*/
|
||||
int iwl_read_external_nvm(struct iwl_trans *trans,
|
||||
const char *nvm_file_name,
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ void iwl_opmode_deregister(const char *name);
|
|||
/**
|
||||
* struct iwl_op_mode - operational mode
|
||||
* @ops: pointer to its own ops
|
||||
* @op_mode_specific: per-opmode data
|
||||
*
|
||||
* This holds an implementation of the mac80211 / fw API.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ enum CMD_MODE {
|
|||
#define DEF_CMD_PAYLOAD_SIZE 320
|
||||
|
||||
/**
|
||||
* struct iwl_device_cmd
|
||||
* struct iwl_device_cmd - device command structure
|
||||
*
|
||||
* For allocation of the command and tx queues, this establishes the overall
|
||||
* size of the largest command we send to uCode, except for commands that
|
||||
|
|
@ -516,7 +516,7 @@ enum iwl_trans_state {
|
|||
*/
|
||||
|
||||
/**
|
||||
* enum iwl_ini_cfg_state
|
||||
* enum iwl_ini_cfg_state - debug config state
|
||||
* @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given
|
||||
* @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded
|
||||
* @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs
|
||||
|
|
@ -532,7 +532,7 @@ enum iwl_ini_cfg_state {
|
|||
#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
|
||||
|
||||
/**
|
||||
* struct iwl_dram_data
|
||||
* struct iwl_dram_data - DRAM data descriptor
|
||||
* @physical: page phy pointer
|
||||
* @block: pointer to the allocated block/page
|
||||
* @size: size of the block/page
|
||||
|
|
|
|||
|
|
@ -75,5 +75,7 @@
|
|||
#define IWL_MLD_FTM_RESP_LMR_FEEDBACK_SUPPORT true
|
||||
#define IWL_MLD_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 7
|
||||
#define IWL_MLD_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000
|
||||
#define IWL_MLD_STA_EXT_CAPA_SIZE 9
|
||||
#define IWL_MLD_EXT_CAPA_NUM_IFTYPES 1
|
||||
|
||||
#endif /* __iwl_mld_constants_h__ */
|
||||
|
|
|
|||
|
|
@ -1794,6 +1794,10 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
|
|||
u32 enabled = 0;
|
||||
|
||||
cmd = kzalloc(hcmd.len[0], GFP_KERNEL);
|
||||
if (!cmd) {
|
||||
IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
|
|
|
|||
|
|
@ -124,9 +124,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
u16 status;
|
||||
|
||||
switch (version) {
|
||||
case 6:
|
||||
case 7:
|
||||
expected_sz = sizeof(struct iwl_alive_ntf_v6);
|
||||
expected_sz = sizeof(struct iwl_alive_ntf_v7);
|
||||
break;
|
||||
case 8:
|
||||
expected_sz = sizeof(struct iwl_alive_ntf);
|
||||
|
|
@ -168,11 +167,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
umac_error_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr) &
|
||||
~FW_ADDR_CACHE_CONTROL;
|
||||
|
||||
if (umac_error_table >= trans->mac_cfg->base->min_umac_error_event_table)
|
||||
iwl_fw_umac_set_alive_err_table(trans, umac_error_table);
|
||||
else
|
||||
IWL_ERR(mld, "Not valid error log pointer 0x%08X\n",
|
||||
umac_error_table);
|
||||
iwl_fw_umac_set_alive_err_table(trans, umac_error_table);
|
||||
|
||||
alive_data->valid = status == IWL_ALIVE_STATUS_OK;
|
||||
|
||||
|
|
@ -188,9 +183,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
le32_to_cpu(umac->umac_major),
|
||||
le32_to_cpu(umac->umac_minor));
|
||||
|
||||
if (version >= 7)
|
||||
IWL_DEBUG_FW(mld, "FW alive flags 0x%x\n",
|
||||
le16_to_cpu(palive->flags));
|
||||
IWL_DEBUG_FW(mld, "FW alive flags 0x%x\n",
|
||||
le16_to_cpu(palive->flags));
|
||||
|
||||
if (version >= 8)
|
||||
IWL_DEBUG_FW(mld, "platform_id 0x%llx\n",
|
||||
|
|
|
|||
|
|
@ -528,6 +528,19 @@ void iwl_mld_handle_probe_resp_data_notif(struct iwl_mld *mld,
|
|||
|
||||
mld_link = &iwl_mld_vif_from_mac80211(vif)->deflink;
|
||||
|
||||
/* len_low should be 2 + n*13 (where n is the number of descriptors.
|
||||
* 13 is the size of a NoA descriptor). We can have either one or two
|
||||
* descriptors.
|
||||
*/
|
||||
if (IWL_FW_CHECK(mld, notif->noa_active &&
|
||||
notif->noa_attr.len_low != 2 +
|
||||
sizeof(struct ieee80211_p2p_noa_desc) &&
|
||||
notif->noa_attr.len_low != 2 +
|
||||
sizeof(struct ieee80211_p2p_noa_desc) * 2,
|
||||
"Invalid noa_attr.len_low (%d)\n",
|
||||
notif->noa_attr.len_low))
|
||||
return;
|
||||
|
||||
new_data = kzalloc(sizeof(*new_data), GFP_KERNEL);
|
||||
if (!new_data)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -465,10 +465,13 @@ int iwl_mld_add_link(struct iwl_mld *mld,
|
|||
int ret;
|
||||
|
||||
if (!link) {
|
||||
if (is_deflink)
|
||||
if (is_deflink) {
|
||||
link = &mld_vif->deflink;
|
||||
else
|
||||
} else {
|
||||
link = kzalloc(sizeof(*link), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
WARN_ON(!mld->fw_status.in_hw_restart);
|
||||
}
|
||||
|
|
@ -572,8 +575,12 @@ void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
|
|||
/* Not in EMLSR and we can't hear the link.
|
||||
* Try to switch to a better link. EMLSR case is handled below.
|
||||
*/
|
||||
if (!iwl_mld_emlsr_active(vif))
|
||||
if (!iwl_mld_emlsr_active(vif)) {
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"missed beacons exceeds threshold. link_id=%u. Try to switch to a better link.\n",
|
||||
link_id);
|
||||
iwl_mld_int_mlo_scan(mld, vif);
|
||||
}
|
||||
}
|
||||
|
||||
/* no more logic if we're not in EMLSR */
|
||||
|
|
@ -592,7 +599,8 @@ void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
|
|||
return;
|
||||
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"missed bcn on the other link (link_id=%u): %u\n",
|
||||
"missed bcn link_id=%u: %u consecutive=%u, other link_id=%u: %u\n",
|
||||
link_id, missed_bcon, missed_bcon_since_rx,
|
||||
other_link->link_id, scnd_lnk_bcn_lost);
|
||||
|
||||
/* Exit EMLSR if we lost more than
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "roc.h"
|
||||
#include "mlo.h"
|
||||
#include "stats.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
#include "ftm-initiator.h"
|
||||
#include "low_latency.h"
|
||||
#include "fw/api/scan.h"
|
||||
|
|
@ -75,13 +76,12 @@ iwl_mld_iface_combinations[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const u8 if_types_ext_capa_sta[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF |
|
||||
WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB,
|
||||
[8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB,
|
||||
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
|
||||
static const u8 ext_capa_base[IWL_MLD_STA_EXT_CAPA_SIZE] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF |
|
||||
WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB,
|
||||
[8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB,
|
||||
};
|
||||
|
||||
#define IWL_MLD_EMLSR_CAPA (IEEE80211_EML_CAP_EMLSR_SUPP | \
|
||||
|
|
@ -94,18 +94,6 @@ static const u8 if_types_ext_capa_sta[] = {
|
|||
IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME) | \
|
||||
IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT)
|
||||
|
||||
static const struct wiphy_iftype_ext_capab iftypes_ext_capa[] = {
|
||||
{
|
||||
.iftype = NL80211_IFTYPE_STATION,
|
||||
.extended_capabilities = if_types_ext_capa_sta,
|
||||
.extended_capabilities_mask = if_types_ext_capa_sta,
|
||||
.extended_capabilities_len = sizeof(if_types_ext_capa_sta),
|
||||
/* relevant only if EHT is supported */
|
||||
.eml_capabilities = IWL_MLD_EMLSR_CAPA,
|
||||
.mld_capa_and_ops = IWL_MLD_CAPA_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
static void iwl_mld_hw_set_addresses(struct iwl_mld *mld)
|
||||
{
|
||||
struct wiphy *wiphy = mld->wiphy;
|
||||
|
|
@ -335,21 +323,37 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)
|
|||
if (fw_has_capa(ucode_capa, IWL_UCODE_TLV_CAPA_PROTECTED_TWT))
|
||||
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PROTECTED_TWT);
|
||||
|
||||
wiphy->iftype_ext_capab = NULL;
|
||||
wiphy->num_iftype_ext_capab = 0;
|
||||
|
||||
if (!iwlwifi_mod_params.disable_11ax) {
|
||||
wiphy->iftype_ext_capab = iftypes_ext_capa;
|
||||
wiphy->num_iftype_ext_capab = ARRAY_SIZE(iftypes_ext_capa);
|
||||
|
||||
ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
|
||||
ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID);
|
||||
}
|
||||
|
||||
if (iwlmld_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
|
||||
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
else
|
||||
wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
/* We are done for non-HE */
|
||||
if (iwlwifi_mod_params.disable_11ax)
|
||||
return;
|
||||
|
||||
ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
|
||||
ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID);
|
||||
|
||||
wiphy->iftype_ext_capab = mld->ext_capab;
|
||||
wiphy->num_iftype_ext_capab = ARRAY_SIZE(mld->ext_capab);
|
||||
|
||||
BUILD_BUG_ON(sizeof(mld->sta_ext_capab) < sizeof(ext_capa_base));
|
||||
|
||||
memcpy(mld->sta_ext_capab, ext_capa_base, sizeof(ext_capa_base));
|
||||
|
||||
mld->ext_capab[0].iftype = NL80211_IFTYPE_STATION;
|
||||
mld->ext_capab[0].extended_capabilities = mld->sta_ext_capab;
|
||||
mld->ext_capab[0].extended_capabilities_mask = mld->sta_ext_capab;
|
||||
mld->ext_capab[0].extended_capabilities_len = sizeof(mld->sta_ext_capab);
|
||||
|
||||
if (!mld->nvm_data->sku_cap_11be_enable ||
|
||||
iwlwifi_mod_params.disable_11be)
|
||||
return;
|
||||
|
||||
mld->ext_capab[0].eml_capabilities = IWL_MLD_EMLSR_CAPA;
|
||||
mld->ext_capab[0].mld_capa_and_ops = IWL_MLD_CAPA_OPS;
|
||||
|
||||
}
|
||||
|
||||
static void iwl_mac_hw_set_misc(struct iwl_mld *mld)
|
||||
|
|
@ -393,11 +397,9 @@ static int iwl_mld_hw_verify_preconditions(struct iwl_mld *mld)
|
|||
TLC_MNG_UPDATE_NOTIF, 0) >= 4) +
|
||||
(iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP,
|
||||
REPLY_RX_MPDU_CMD, 0) >= 6) +
|
||||
(iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP,
|
||||
RX_NO_DATA_NOTIF, 0) >= 4) +
|
||||
(iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP, TX_CMD, 0) >= 9);
|
||||
|
||||
if (ratecheck != 0 && ratecheck != 5) {
|
||||
if (ratecheck != 0 && ratecheck != 4) {
|
||||
IWL_ERR(mld, "Firmware has inconsistent rates\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -680,6 +682,8 @@ void iwl_mld_mac80211_remove_interface(struct ieee80211_hw *hw,
|
|||
#endif
|
||||
|
||||
iwl_mld_rm_vif(mld, vif);
|
||||
|
||||
mld->monitor.phy.valid = false;
|
||||
}
|
||||
|
||||
struct iwl_mld_mc_iter_data {
|
||||
|
|
@ -2591,11 +2595,44 @@ iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
return NEG_TTLM_RES_ACCEPT;
|
||||
}
|
||||
|
||||
static int iwl_mld_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
|
||||
*tx_ant = iwl_mld_get_valid_tx_ant(mld);
|
||||
*rx_ant = iwl_mld_get_valid_rx_ant(mld);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mld_set_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
|
||||
if (WARN_ON(!mld->nvm_data))
|
||||
return -EBUSY;
|
||||
|
||||
/* mac80211 ensures the device is not started,
|
||||
* so the firmware cannot be running
|
||||
*/
|
||||
|
||||
mld->set_tx_ant = tx_ant;
|
||||
mld->set_rx_ant = rx_ant;
|
||||
|
||||
iwl_reinit_cab(mld->trans, mld->nvm_data, tx_ant, rx_ant, mld->fw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct ieee80211_ops iwl_mld_hw_ops = {
|
||||
.tx = iwl_mld_mac80211_tx,
|
||||
.start = iwl_mld_mac80211_start,
|
||||
.stop = iwl_mld_mac80211_stop,
|
||||
.config = iwl_mld_mac80211_config,
|
||||
.get_antenna = iwl_mld_get_antenna,
|
||||
.set_antenna = iwl_mld_set_antenna,
|
||||
.add_interface = iwl_mld_mac80211_add_interface,
|
||||
.remove_interface = iwl_mld_mac80211_remove_interface,
|
||||
.conf_tx = iwl_mld_mac80211_conf_tx,
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ static const struct iwl_hcmd_names iwl_mld_data_path_names[] = {
|
|||
HCMD_NAME(MONITOR_NOTIF),
|
||||
HCMD_NAME(TLC_MNG_UPDATE_NOTIF),
|
||||
HCMD_NAME(BEACON_FILTER_IN_NOTIF),
|
||||
HCMD_NAME(PHY_AIR_SNIFFER_NOTIF),
|
||||
HCMD_NAME(MU_GROUP_MGMT_NOTIF),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,11 @@
|
|||
* @monitor.cur_bssid: current bssid tracked by the sniffer
|
||||
* @monitor.ptp_time: set the Rx mactime using the device's PTP clock time
|
||||
* @monitor.p80: primary channel position relative to he whole bandwidth, in
|
||||
* steps of 80 MHz
|
||||
* steps of 80 MHz
|
||||
* @monitor.phy: PHY data information
|
||||
* @monitor.phy.data: PHY data (&struct iwl_rx_phy_air_sniffer_ntfy) received
|
||||
* @monitor.phy.valid: PHY data is valid (was received)
|
||||
* @monitor.phy.used: PHY data was used by an RX
|
||||
* @fw_id_to_link_sta: maps a fw id of a sta to the corresponding
|
||||
* ieee80211_link_sta. This is not cleaned up on restart since we want to
|
||||
* preserve the fw sta ids during a restart (for SN/PN restoring).
|
||||
|
|
@ -134,6 +138,8 @@
|
|||
* @fw: a pointer to the fw object
|
||||
* @hw: pointer to the hw object.
|
||||
* @wiphy: a pointer to the wiphy struct, for easier access to it.
|
||||
* @ext_capab: extended capabilities that will be set to wiphy on registration.
|
||||
* @sta_ext_capab: extended capabilities for the station interface.
|
||||
* @nvm_data: pointer to the nvm_data that includes all our capabilities
|
||||
* @fwrt: fw runtime data
|
||||
* @debugfs_dir: debugfs directory
|
||||
|
|
@ -180,6 +186,8 @@
|
|||
* @mcast_filter_cmd: pointer to the multicast filter command.
|
||||
* @mgmt_tx_ant: stores the last TX antenna index; used for setting
|
||||
* TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure).
|
||||
* @set_tx_ant: stores the last TX antenna bitmask set by user space (if any)
|
||||
* @set_rx_ant: stores the last RX antenna bitmask set by user space (if any)
|
||||
* @fw_rates_ver_3: FW rates are in version 3
|
||||
* @low_latency: low-latency manager.
|
||||
* @tzone: thermal zone device's data
|
||||
|
|
@ -205,6 +213,10 @@ struct iwl_mld {
|
|||
u32 ampdu_ref;
|
||||
bool ampdu_toggle;
|
||||
u8 p80;
|
||||
struct {
|
||||
struct iwl_rx_phy_air_sniffer_ntfy data;
|
||||
u8 valid:1, used:1;
|
||||
} phy;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
__le16 cur_aid;
|
||||
u8 cur_bssid[ETH_ALEN];
|
||||
|
|
@ -225,6 +237,8 @@ struct iwl_mld {
|
|||
const struct iwl_fw *fw;
|
||||
struct ieee80211_hw *hw;
|
||||
struct wiphy *wiphy;
|
||||
struct wiphy_iftype_ext_capab ext_capab[IWL_MLD_EXT_CAPA_NUM_IFTYPES];
|
||||
u8 sta_ext_capab[IWL_MLD_STA_EXT_CAPA_SIZE];
|
||||
struct iwl_nvm_data *nvm_data;
|
||||
struct iwl_fw_runtime fwrt;
|
||||
struct dentry *debugfs_dir;
|
||||
|
|
@ -279,6 +293,9 @@ struct iwl_mld {
|
|||
|
||||
u8 mgmt_tx_ant;
|
||||
|
||||
u8 set_tx_ant;
|
||||
u8 set_rx_ant;
|
||||
|
||||
bool fw_rates_ver_3;
|
||||
|
||||
struct iwl_mld_low_latency low_latency;
|
||||
|
|
@ -374,6 +391,9 @@ static inline u8 iwl_mld_get_valid_tx_ant(const struct iwl_mld *mld)
|
|||
if (mld->nvm_data && mld->nvm_data->valid_tx_ant)
|
||||
tx_ant &= mld->nvm_data->valid_tx_ant;
|
||||
|
||||
if (mld->set_tx_ant)
|
||||
tx_ant &= mld->set_tx_ant;
|
||||
|
||||
return tx_ant;
|
||||
}
|
||||
|
||||
|
|
@ -384,6 +404,9 @@ static inline u8 iwl_mld_get_valid_rx_ant(const struct iwl_mld *mld)
|
|||
if (mld->nvm_data && mld->nvm_data->valid_rx_ant)
|
||||
rx_ant &= mld->nvm_data->valid_rx_ant;
|
||||
|
||||
if (mld->set_rx_ant)
|
||||
rx_ant &= mld->set_rx_ant;
|
||||
|
||||
return rx_ant;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,9 @@ static void iwl_mld_print_emlsr_blocked(struct iwl_mld *mld, u32 mask)
|
|||
{
|
||||
#define NAME_FMT(x) "%s"
|
||||
#define NAME_PR(x) (mask & IWL_MLD_EMLSR_BLOCKED_##x) ? "[" #x "]" : "",
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"EMLSR blocked = " HANDLE_EMLSR_BLOCKED_REASONS(NAME_FMT)
|
||||
" (0x%x)\n",
|
||||
HANDLE_EMLSR_BLOCKED_REASONS(NAME_PR)
|
||||
mask);
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"EMLSR blocked = " HANDLE_EMLSR_BLOCKED_REASONS(NAME_FMT)
|
||||
" (0x%x)\n", HANDLE_EMLSR_BLOCKED_REASONS(NAME_PR) mask);
|
||||
#undef NAME_FMT
|
||||
#undef NAME_PR
|
||||
}
|
||||
|
|
@ -72,11 +70,9 @@ static void iwl_mld_print_emlsr_exit(struct iwl_mld *mld, u32 mask)
|
|||
{
|
||||
#define NAME_FMT(x) "%s"
|
||||
#define NAME_PR(x) (mask & IWL_MLD_EMLSR_EXIT_##x) ? "[" #x "]" : "",
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"EMLSR exit = " HANDLE_EMLSR_EXIT_REASONS(NAME_FMT)
|
||||
" (0x%x)\n",
|
||||
HANDLE_EMLSR_EXIT_REASONS(NAME_PR)
|
||||
mask);
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"EMLSR exit = " HANDLE_EMLSR_EXIT_REASONS(NAME_FMT)
|
||||
" (0x%x)\n", HANDLE_EMLSR_EXIT_REASONS(NAME_PR) mask);
|
||||
#undef NAME_FMT
|
||||
#undef NAME_PR
|
||||
}
|
||||
|
|
@ -170,10 +166,10 @@ static void iwl_mld_check_emlsr_prevention(struct iwl_mld *mld,
|
|||
WARN_ON(mld_vif->emlsr.exit_repeat_count > 3);
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Preventing EMLSR for %ld seconds due to %u exits with the reason = %s (0x%x)\n",
|
||||
delay / HZ, mld_vif->emlsr.exit_repeat_count,
|
||||
iwl_mld_get_emlsr_exit_string(reason), reason);
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"Preventing EMLSR for %ld seconds due to %u exits with the reason = %s (0x%x)\n",
|
||||
delay / HZ, mld_vif->emlsr.exit_repeat_count,
|
||||
iwl_mld_get_emlsr_exit_string(reason), reason);
|
||||
|
||||
wiphy_delayed_work_queue(mld->wiphy,
|
||||
&mld_vif->emlsr.prevent_done_wk, delay);
|
||||
|
|
@ -217,10 +213,10 @@ static int _iwl_mld_exit_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
link_to_keep = __ffs(vif->active_links);
|
||||
|
||||
new_active_links = BIT(link_to_keep);
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Exiting EMLSR. reason = %s (0x%x). Current active links=0x%x, new active links = 0x%x\n",
|
||||
iwl_mld_get_emlsr_exit_string(exit), exit,
|
||||
vif->active_links, new_active_links);
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"Exiting EMLSR. reason = %s (0x%x). Current active links=0x%x, new active links = 0x%x\n",
|
||||
iwl_mld_get_emlsr_exit_string(exit), exit,
|
||||
vif->active_links, new_active_links);
|
||||
|
||||
if (sync)
|
||||
ret = ieee80211_set_active_links(vif, new_active_links);
|
||||
|
|
@ -262,9 +258,8 @@ static int _iwl_mld_emlsr_block(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
|
||||
mld_vif->emlsr.blocked_reasons |= reason;
|
||||
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Blocking EMLSR mode. reason = %s (0x%x)\n",
|
||||
iwl_mld_get_emlsr_blocked_string(reason), reason);
|
||||
IWL_DEBUG_EHT(mld, "Blocking EMLSR mode. reason = %s (0x%x)\n",
|
||||
iwl_mld_get_emlsr_blocked_string(reason), reason);
|
||||
iwl_mld_print_emlsr_blocked(mld, mld_vif->emlsr.blocked_reasons);
|
||||
|
||||
if (reason == IWL_MLD_EMLSR_BLOCKED_TPT)
|
||||
|
|
@ -335,9 +330,8 @@ void iwl_mld_unblock_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
|
||||
mld_vif->emlsr.blocked_reasons &= ~reason;
|
||||
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Unblocking EMLSR mode. reason = %s (0x%x)\n",
|
||||
iwl_mld_get_emlsr_blocked_string(reason), reason);
|
||||
IWL_DEBUG_EHT(mld, "Unblocking EMLSR mode. reason = %s (0x%x)\n",
|
||||
iwl_mld_get_emlsr_blocked_string(reason), reason);
|
||||
iwl_mld_print_emlsr_blocked(mld, mld_vif->emlsr.blocked_reasons);
|
||||
|
||||
if (reason == IWL_MLD_EMLSR_BLOCKED_TPT)
|
||||
|
|
@ -348,7 +342,7 @@ void iwl_mld_unblock_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif,
|
|||
if (mld_vif->emlsr.blocked_reasons)
|
||||
return;
|
||||
|
||||
IWL_DEBUG_INFO(mld, "EMLSR is unblocked\n");
|
||||
IWL_DEBUG_EHT(mld, "EMLSR is unblocked\n");
|
||||
iwl_mld_int_mlo_scan(mld, vif);
|
||||
}
|
||||
|
||||
|
|
@ -365,18 +359,17 @@ iwl_mld_vif_iter_emlsr_mode_notif(void *data, u8 *mac,
|
|||
|
||||
switch (action) {
|
||||
case ESR_RECOMMEND_LEAVE:
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW recommend leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
IWL_DEBUG_EHT(mld_vif->mld,
|
||||
"FW recommend leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
|
||||
iwl_mld_exit_emlsr(mld_vif->mld, vif,
|
||||
IWL_MLD_EMLSR_EXIT_FW_REQUEST,
|
||||
iwl_mld_get_primary_link(vif));
|
||||
break;
|
||||
case ESR_FORCE_LEAVE:
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW force leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
IWL_DEBUG_EHT(mld_vif->mld, "FW force leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
fallthrough;
|
||||
case ESR_RECOMMEND_ENTER:
|
||||
default:
|
||||
|
|
@ -412,11 +405,12 @@ void iwl_mld_handle_emlsr_trans_fail_notif(struct iwl_mld *mld,
|
|||
struct ieee80211_bss_conf *bss_conf =
|
||||
iwl_mld_fw_id_to_link_conf(mld, fw_link_id);
|
||||
|
||||
IWL_DEBUG_INFO(mld, "Failed to %s EMLSR on link %d (FW: %d), reason %d\n",
|
||||
le32_to_cpu(notif->activation) ? "enter" : "exit",
|
||||
bss_conf ? bss_conf->link_id : -1,
|
||||
le32_to_cpu(notif->link_id),
|
||||
le32_to_cpu(notif->err_code));
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"Failed to %s EMLSR on link %d (FW: %d), reason %d\n",
|
||||
le32_to_cpu(notif->activation) ? "enter" : "exit",
|
||||
bss_conf ? bss_conf->link_id : -1,
|
||||
le32_to_cpu(notif->link_id),
|
||||
le32_to_cpu(notif->err_code));
|
||||
|
||||
if (IWL_FW_CHECK(mld, !bss_conf,
|
||||
"FW reported failure to %sactivate EMLSR on a non-existing link: %d\n",
|
||||
|
|
@ -590,8 +584,8 @@ void iwl_mld_emlsr_check_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
|
|||
spin_unlock_bh(&queue_counter->lock);
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(mld, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
|
||||
total_tx, total_rx);
|
||||
IWL_DEBUG_EHT(mld, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
|
||||
total_tx, total_rx);
|
||||
|
||||
/* If we don't have enough MPDUs - exit EMLSR */
|
||||
if (total_tx < IWL_MLD_ENTER_EMLSR_TPT_THRESH &&
|
||||
|
|
@ -603,10 +597,10 @@ void iwl_mld_emlsr_check_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
|
|||
|
||||
/* EMLSR is not active */
|
||||
if (sec_link_id == -1)
|
||||
return;
|
||||
goto schedule;
|
||||
|
||||
IWL_DEBUG_INFO(mld, "Secondary Link %d: Tx MPDUs: %ld. Rx MPDUs: %ld\n",
|
||||
sec_link_id, sec_link_tx, sec_link_rx);
|
||||
IWL_DEBUG_EHT(mld, "Secondary Link %d: Tx MPDUs: %ld. Rx MPDUs: %ld\n",
|
||||
sec_link_id, sec_link_tx, sec_link_rx);
|
||||
|
||||
/* Calculate the percentage of the secondary link TX/RX */
|
||||
sec_link_tx_perc = total_tx ? sec_link_tx * 100 / total_tx : 0;
|
||||
|
|
@ -625,6 +619,7 @@ void iwl_mld_emlsr_check_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
|
|||
return;
|
||||
}
|
||||
|
||||
schedule:
|
||||
/* Check again when the next window ends */
|
||||
wiphy_delayed_work_queue(mld_vif->mld->wiphy,
|
||||
&mld_vif->emlsr.check_tpt_wk,
|
||||
|
|
@ -702,10 +697,8 @@ iwl_mld_emlsr_disallowed_with_link(struct iwl_mld *mld,
|
|||
ret |= IWL_MLD_EMLSR_EXIT_CSA;
|
||||
|
||||
if (ret) {
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Link %d is not allowed for EMLSR as %s\n",
|
||||
link->link_id,
|
||||
primary ? "primary" : "secondary");
|
||||
IWL_DEBUG_EHT(mld, "Link %d is not allowed for EMLSR as %s\n",
|
||||
link->link_id, primary ? "primary" : "secondary");
|
||||
iwl_mld_print_emlsr_exit(mld, ret);
|
||||
}
|
||||
|
||||
|
|
@ -869,13 +862,12 @@ iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif,
|
|||
reason_mask |= IWL_MLD_EMLSR_EXIT_CHAN_LOAD;
|
||||
|
||||
if (reason_mask) {
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Links %d and %d are not a valid pair for EMLSR\n",
|
||||
a->link_id, b->link_id);
|
||||
IWL_DEBUG_INFO(mld,
|
||||
"Links bandwidth are: %d and %d\n",
|
||||
nl80211_chan_width_to_mhz(a->chandef->width),
|
||||
nl80211_chan_width_to_mhz(b->chandef->width));
|
||||
IWL_DEBUG_EHT(mld,
|
||||
"Links %d and %d are not a valid pair for EMLSR\n",
|
||||
a->link_id, b->link_id);
|
||||
IWL_DEBUG_EHT(mld, "Links bandwidth are: %d and %d\n",
|
||||
nl80211_chan_width_to_mhz(a->chandef->width),
|
||||
nl80211_chan_width_to_mhz(b->chandef->width));
|
||||
iwl_mld_print_emlsr_exit(mld, reason_mask);
|
||||
}
|
||||
|
||||
|
|
@ -993,8 +985,8 @@ static void _iwl_mld_select_links(struct iwl_mld *mld,
|
|||
}
|
||||
|
||||
set_active:
|
||||
IWL_DEBUG_INFO(mld, "Link selection result: 0x%x. Primary = %d\n",
|
||||
new_active, new_primary);
|
||||
IWL_DEBUG_EHT(mld, "Link selection result: 0x%x. Primary = %d\n",
|
||||
new_active, new_primary);
|
||||
|
||||
mld_vif->emlsr.selected_primary = new_primary;
|
||||
mld_vif->emlsr.selected_links = new_active;
|
||||
|
|
|
|||
|
|
@ -589,8 +589,8 @@ void iwl_mld_rx(struct iwl_op_mode *op_mode, struct napi_struct *napi,
|
|||
else if (unlikely(cmd_id == WIDE_ID(DATA_PATH_GROUP,
|
||||
RX_QUEUES_NOTIFICATION)))
|
||||
iwl_mld_handle_rx_queues_sync_notif(mld, napi, pkt, 0);
|
||||
else if (cmd_id == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
|
||||
iwl_mld_rx_monitor_no_data(mld, napi, pkt, 0);
|
||||
else if (cmd_id == WIDE_ID(DATA_PATH_GROUP, PHY_AIR_SNIFFER_NOTIF))
|
||||
iwl_mld_handle_phy_air_sniffer_notif(mld, napi, pkt);
|
||||
else
|
||||
iwl_mld_rx_notif(mld, rxb, pkt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,9 @@ void iwl_mld_handle_roc_notif(struct iwl_mld *mld,
|
|||
struct ieee80211_vif *vif;
|
||||
|
||||
vif = iwl_mld_find_roc_vif(mld, activity);
|
||||
if (WARN_ON(!vif))
|
||||
if (IWL_FW_CHECK(mld, !vif,
|
||||
"unexpected ROC notif from FW for activity %d\n",
|
||||
activity))
|
||||
return;
|
||||
|
||||
mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -66,7 +66,8 @@ void iwl_mld_pass_packet_to_mac80211(struct iwl_mld *mld,
|
|||
struct sk_buff *skb, int queue,
|
||||
struct ieee80211_sta *sta);
|
||||
|
||||
void iwl_mld_rx_monitor_no_data(struct iwl_mld *mld, struct napi_struct *napi,
|
||||
struct iwl_rx_packet *pkt, int queue);
|
||||
void iwl_mld_handle_phy_air_sniffer_notif(struct iwl_mld *mld,
|
||||
struct napi_struct *napi,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
#endif /* __iwl_mld_agg_h__ */
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ static void iwl_mld_count_mpdu(struct ieee80211_link_sta *link_sta, int queue,
|
|||
sizeof(queue_counter->per_link));
|
||||
queue_counter->window_start_time = jiffies;
|
||||
|
||||
IWL_DEBUG_INFO(mld, "MPDU counters are cleared\n");
|
||||
IWL_DEBUG_EHT(mld, "MPDU counters are cleared\n");
|
||||
}
|
||||
|
||||
link_counter = &queue_counter->per_link[mld_link->fw_id];
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
|
||||
|
||||
if (version >= 6) {
|
||||
struct iwl_alive_ntf_v6 *palive;
|
||||
struct iwl_alive_ntf_v7 *palive;
|
||||
|
||||
if (pkt_len < sizeof(*palive))
|
||||
return false;
|
||||
|
|
@ -214,17 +214,8 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
~FW_ADDR_CACHE_CONTROL;
|
||||
|
||||
if (umac_error_table) {
|
||||
if (umac_error_table >=
|
||||
mvm->trans->mac_cfg->base->min_umac_error_event_table) {
|
||||
iwl_fw_umac_set_alive_err_table(mvm->trans,
|
||||
umac_error_table);
|
||||
} else {
|
||||
IWL_ERR(mvm,
|
||||
"Not valid error log pointer 0x%08X for %s uCode\n",
|
||||
umac_error_table,
|
||||
(mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ?
|
||||
"Init" : "RT");
|
||||
}
|
||||
iwl_fw_umac_set_alive_err_table(mvm->trans,
|
||||
umac_error_table);
|
||||
}
|
||||
|
||||
alive_data->valid = status == IWL_ALIVE_STATUS_OK;
|
||||
|
|
|
|||
|
|
@ -102,9 +102,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
|
|||
mvm->csme_vif = vif;
|
||||
}
|
||||
|
||||
if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5)
|
||||
vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_bf:
|
||||
|
|
|
|||
|
|
@ -2894,4 +2894,9 @@ iwl_mvm_send_ap_tx_power_constraint_cmd(struct iwl_mvm *mvm,
|
|||
|
||||
void iwl_mvm_smps_workaround(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
bool update);
|
||||
|
||||
/* rate_n_flags conversion */
|
||||
u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver);
|
||||
__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver);
|
||||
|
||||
#endif /* __IWL_MVM_H__ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -202,17 +202,13 @@ int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||
static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_phy_ctxt *ctxt,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
const struct cfg80211_chan_def *ap,
|
||||
u8 chains_static, u8 chains_dynamic,
|
||||
u32 action)
|
||||
{
|
||||
int ret;
|
||||
int ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1);
|
||||
|
||||
if (ver < 5 || !ap || !ap->chan)
|
||||
ap = NULL;
|
||||
|
||||
if (ver >= 3 && ver <= 6) {
|
||||
if (ver >= 3 && ver <= 4) {
|
||||
struct iwl_phy_context_cmd cmd = {};
|
||||
|
||||
/* Set the command header fields */
|
||||
|
|
@ -223,14 +219,6 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
|
|||
chains_static,
|
||||
chains_dynamic);
|
||||
|
||||
if (ap) {
|
||||
cmd.sbb_bandwidth = iwl_mvm_get_channel_width(ap);
|
||||
cmd.sbb_ctrl_channel_loc = iwl_mvm_get_ctrl_pos(ap);
|
||||
}
|
||||
|
||||
if (ver == 6)
|
||||
cmd.puncture_mask = cpu_to_le16(chandef->punctured);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD,
|
||||
0, sizeof(cmd), &cmd);
|
||||
} else if (ver < 3) {
|
||||
|
|
@ -284,7 +272,7 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||
ctxt->width = chandef->width;
|
||||
ctxt->center_freq1 = chandef->center_freq1;
|
||||
|
||||
ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap,
|
||||
ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
|
||||
chains_static, chains_dynamic,
|
||||
FW_CTXT_ACTION_ADD);
|
||||
|
||||
|
|
@ -342,7 +330,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||
int ret;
|
||||
|
||||
/* ... remove it here ...*/
|
||||
ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, NULL,
|
||||
ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
|
||||
chains_static, chains_dynamic,
|
||||
FW_CTXT_ACTION_REMOVE);
|
||||
if (ret)
|
||||
|
|
@ -356,7 +344,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
|||
ctxt->width = chandef->width;
|
||||
ctxt->center_freq1 = chandef->center_freq1;
|
||||
|
||||
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap,
|
||||
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
|
||||
chains_static, chains_dynamic,
|
||||
action);
|
||||
}
|
||||
|
|
@ -376,7 +364,7 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
|
|||
|
||||
cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT);
|
||||
|
||||
iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, NULL, 1, 1,
|
||||
iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1,
|
||||
FW_CTXT_ACTION_REMOVE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4178,167 +4178,3 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
|||
else
|
||||
return rs_drv_tx_protection(mvm, mvmsta, enable);
|
||||
}
|
||||
|
||||
static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
|
||||
{
|
||||
int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
|
||||
int idx;
|
||||
bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
|
||||
int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
|
||||
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
for (idx = offset; idx < last; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - offset;
|
||||
return IWL_RATE_INVALID;
|
||||
}
|
||||
|
||||
u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver)
|
||||
{
|
||||
u32 rate_v3 = 0, rate_v1;
|
||||
u32 dup = 0;
|
||||
|
||||
if (rate_ver > 1)
|
||||
return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3);
|
||||
|
||||
rate_v1 = le32_to_cpu(rate);
|
||||
if (rate_v1 == 0)
|
||||
return rate_v1;
|
||||
/* convert rate */
|
||||
if (rate_v1 & RATE_MCS_HT_MSK_V1) {
|
||||
u32 nss;
|
||||
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_HT;
|
||||
rate_v3 |=
|
||||
rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1;
|
||||
nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK);
|
||||
rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK);
|
||||
} else if (rate_v1 & RATE_MCS_VHT_MSK_V1 ||
|
||||
rate_v1 & RATE_MCS_HE_MSK_V1) {
|
||||
u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK);
|
||||
|
||||
rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
|
||||
rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK);
|
||||
|
||||
if (rate_v1 & RATE_MCS_HE_MSK_V1) {
|
||||
u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1;
|
||||
u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1;
|
||||
u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >>
|
||||
RATE_MCS_HE_106T_POS_V1;
|
||||
u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >>
|
||||
RATE_MCS_HE_GI_LTF_POS;
|
||||
|
||||
if ((he_type_bits == RATE_MCS_HE_TYPE_SU ||
|
||||
he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) &&
|
||||
he_gi_ltf == RATE_MCS_HE_SU_4_LTF)
|
||||
/* the new rate have an additional bit to
|
||||
* represent the value 4 rather then using SGI
|
||||
* bit for this purpose - as it was done in the
|
||||
* old rate
|
||||
*/
|
||||
he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >>
|
||||
RATE_MCS_SGI_POS_V1;
|
||||
|
||||
rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS;
|
||||
rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS;
|
||||
rate_v3 |= he_106t << RATE_MCS_HE_106T_POS;
|
||||
rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK;
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_HE;
|
||||
} else {
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_VHT;
|
||||
}
|
||||
/* if legacy format */
|
||||
} else {
|
||||
u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1);
|
||||
|
||||
if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID))
|
||||
legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ?
|
||||
IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
rate_v3 |= legacy_rate;
|
||||
if (!(rate_v1 & RATE_MCS_CCK_MSK_V1))
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM;
|
||||
}
|
||||
|
||||
/* convert flags */
|
||||
if (rate_v1 & RATE_MCS_LDPC_MSK_V1)
|
||||
rate_v3 |= RATE_MCS_LDPC_MSK;
|
||||
rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) |
|
||||
(rate_v1 & RATE_MCS_ANT_AB_MSK) |
|
||||
(rate_v1 & RATE_MCS_STBC_MSK) |
|
||||
(rate_v1 & RATE_MCS_BF_MSK);
|
||||
|
||||
dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1;
|
||||
if (dup) {
|
||||
rate_v3 |= RATE_MCS_DUP_MSK;
|
||||
rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS;
|
||||
}
|
||||
|
||||
if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) &&
|
||||
(rate_v1 & RATE_MCS_SGI_MSK_V1))
|
||||
rate_v3 |= RATE_MCS_SGI_MSK;
|
||||
|
||||
return rate_v3;
|
||||
}
|
||||
|
||||
__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver)
|
||||
{
|
||||
u32 result = 0;
|
||||
int rate_idx;
|
||||
|
||||
if (rate_ver > 1)
|
||||
return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2);
|
||||
|
||||
switch (rate & RATE_MCS_MOD_TYPE_MSK) {
|
||||
case RATE_MCS_MOD_TYPE_CCK:
|
||||
result = RATE_MCS_CCK_MSK_V1;
|
||||
fallthrough;
|
||||
case RATE_MCS_MOD_TYPE_LEGACY_OFDM:
|
||||
rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK);
|
||||
if (!(result & RATE_MCS_CCK_MSK_V1))
|
||||
rate_idx += IWL_FIRST_OFDM_RATE;
|
||||
result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx),
|
||||
RATE_LEGACY_RATE_MSK_V1);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_HT:
|
||||
result = RATE_MCS_HT_MSK_V1;
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_HT_MCS_CODE_MSK),
|
||||
RATE_HT_MCS_RATE_CODE_MSK_V1);
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_MCS_NSS_MSK),
|
||||
RATE_HT_MCS_MIMO2_MSK);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_VHT:
|
||||
result = RATE_MCS_VHT_MSK_V1;
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_VHT_MCS_NSS_MSK),
|
||||
RATE_MCS_CODE_MSK);
|
||||
result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK),
|
||||
RATE_VHT_MCS_NSS_MSK);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_HE: /* not generated */
|
||||
default:
|
||||
WARN_ONCE(1, "bad modulation type %d\n",
|
||||
u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate & RATE_MCS_LDPC_MSK)
|
||||
result |= RATE_MCS_LDPC_MSK_V1;
|
||||
WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) >
|
||||
RATE_MCS_CHAN_WIDTH_160_VAL);
|
||||
result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) |
|
||||
(rate & RATE_MCS_ANT_AB_MSK) |
|
||||
(rate & RATE_MCS_STBC_MSK) |
|
||||
(rate & RATE_MCS_BF_MSK);
|
||||
|
||||
/* not handling DUP since we don't use it */
|
||||
WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK);
|
||||
|
||||
if (rate & RATE_MCS_SGI_MSK)
|
||||
result |= RATE_MCS_SGI_MSK_V1;
|
||||
|
||||
return cpu_to_le32(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -425,9 +425,6 @@ void iwl_mvm_rate_control_unregister(void);
|
|||
|
||||
struct iwl_mvm_sta;
|
||||
|
||||
u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver);
|
||||
__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver);
|
||||
|
||||
int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
||||
bool enable);
|
||||
|
||||
|
|
|
|||
|
|
@ -519,6 +519,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
return;
|
||||
}
|
||||
rx_status->rate_idx = rate;
|
||||
/* override BW - it could be DUP and indicate the wrong BW */
|
||||
rx_status->bw = RATE_INFO_BW_20;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
|
|
|
|||
|
|
@ -1237,3 +1237,167 @@ bool iwl_mvm_vif_is_active(struct iwl_mvm_vif *mvmvif)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
|
||||
{
|
||||
int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
|
||||
int idx;
|
||||
bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
|
||||
int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
|
||||
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
for (idx = offset; idx < last; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - offset;
|
||||
return IWL_RATE_INVALID;
|
||||
}
|
||||
|
||||
u32 iwl_mvm_v3_rate_from_fw(__le32 rate, u8 rate_ver)
|
||||
{
|
||||
u32 rate_v3 = 0, rate_v1;
|
||||
u32 dup = 0;
|
||||
|
||||
if (rate_ver > 1)
|
||||
return iwl_v3_rate_from_v2_v3(rate, rate_ver >= 3);
|
||||
|
||||
rate_v1 = le32_to_cpu(rate);
|
||||
if (rate_v1 == 0)
|
||||
return rate_v1;
|
||||
/* convert rate */
|
||||
if (rate_v1 & RATE_MCS_HT_MSK_V1) {
|
||||
u32 nss;
|
||||
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_HT;
|
||||
rate_v3 |=
|
||||
rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1;
|
||||
nss = u32_get_bits(rate_v1, RATE_HT_MCS_MIMO2_MSK);
|
||||
rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK);
|
||||
} else if (rate_v1 & RATE_MCS_VHT_MSK_V1 ||
|
||||
rate_v1 & RATE_MCS_HE_MSK_V1) {
|
||||
u32 nss = u32_get_bits(rate_v1, RATE_VHT_MCS_NSS_MSK);
|
||||
|
||||
rate_v3 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
|
||||
rate_v3 |= u32_encode_bits(nss, RATE_MCS_NSS_MSK);
|
||||
|
||||
if (rate_v1 & RATE_MCS_HE_MSK_V1) {
|
||||
u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1;
|
||||
u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1;
|
||||
u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >>
|
||||
RATE_MCS_HE_106T_POS_V1;
|
||||
u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >>
|
||||
RATE_MCS_HE_GI_LTF_POS;
|
||||
|
||||
if ((he_type_bits == RATE_MCS_HE_TYPE_SU ||
|
||||
he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) &&
|
||||
he_gi_ltf == RATE_MCS_HE_SU_4_LTF)
|
||||
/* the new rate have an additional bit to
|
||||
* represent the value 4 rather then using SGI
|
||||
* bit for this purpose - as it was done in the
|
||||
* old rate
|
||||
*/
|
||||
he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >>
|
||||
RATE_MCS_SGI_POS_V1;
|
||||
|
||||
rate_v3 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS;
|
||||
rate_v3 |= he_type << RATE_MCS_HE_TYPE_POS;
|
||||
rate_v3 |= he_106t << RATE_MCS_HE_106T_POS;
|
||||
rate_v3 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK;
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_HE;
|
||||
} else {
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_VHT;
|
||||
}
|
||||
/* if legacy format */
|
||||
} else {
|
||||
u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1);
|
||||
|
||||
if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID))
|
||||
legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ?
|
||||
IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
rate_v3 |= legacy_rate;
|
||||
if (!(rate_v1 & RATE_MCS_CCK_MSK_V1))
|
||||
rate_v3 |= RATE_MCS_MOD_TYPE_LEGACY_OFDM;
|
||||
}
|
||||
|
||||
/* convert flags */
|
||||
if (rate_v1 & RATE_MCS_LDPC_MSK_V1)
|
||||
rate_v3 |= RATE_MCS_LDPC_MSK;
|
||||
rate_v3 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) |
|
||||
(rate_v1 & RATE_MCS_ANT_AB_MSK) |
|
||||
(rate_v1 & RATE_MCS_STBC_MSK) |
|
||||
(rate_v1 & RATE_MCS_BF_MSK);
|
||||
|
||||
dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1;
|
||||
if (dup) {
|
||||
rate_v3 |= RATE_MCS_DUP_MSK;
|
||||
rate_v3 |= dup << RATE_MCS_CHAN_WIDTH_POS;
|
||||
}
|
||||
|
||||
if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) &&
|
||||
(rate_v1 & RATE_MCS_SGI_MSK_V1))
|
||||
rate_v3 |= RATE_MCS_SGI_MSK;
|
||||
|
||||
return rate_v3;
|
||||
}
|
||||
|
||||
__le32 iwl_mvm_v3_rate_to_fw(u32 rate, u8 rate_ver)
|
||||
{
|
||||
u32 result = 0;
|
||||
int rate_idx;
|
||||
|
||||
if (rate_ver > 1)
|
||||
return iwl_v3_rate_to_v2_v3(rate, rate_ver > 2);
|
||||
|
||||
switch (rate & RATE_MCS_MOD_TYPE_MSK) {
|
||||
case RATE_MCS_MOD_TYPE_CCK:
|
||||
result = RATE_MCS_CCK_MSK_V1;
|
||||
fallthrough;
|
||||
case RATE_MCS_MOD_TYPE_LEGACY_OFDM:
|
||||
rate_idx = u32_get_bits(rate, RATE_LEGACY_RATE_MSK);
|
||||
if (!(result & RATE_MCS_CCK_MSK_V1))
|
||||
rate_idx += IWL_FIRST_OFDM_RATE;
|
||||
result |= u32_encode_bits(iwl_fw_rate_idx_to_plcp(rate_idx),
|
||||
RATE_LEGACY_RATE_MSK_V1);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_HT:
|
||||
result = RATE_MCS_HT_MSK_V1;
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_HT_MCS_CODE_MSK),
|
||||
RATE_HT_MCS_RATE_CODE_MSK_V1);
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_MCS_NSS_MSK),
|
||||
RATE_HT_MCS_MIMO2_MSK);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_VHT:
|
||||
result = RATE_MCS_VHT_MSK_V1;
|
||||
result |= u32_encode_bits(u32_get_bits(rate,
|
||||
RATE_VHT_MCS_NSS_MSK),
|
||||
RATE_MCS_CODE_MSK);
|
||||
result |= u32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK),
|
||||
RATE_VHT_MCS_NSS_MSK);
|
||||
break;
|
||||
case RATE_MCS_MOD_TYPE_HE: /* not generated */
|
||||
default:
|
||||
WARN_ONCE(1, "bad modulation type %d\n",
|
||||
u32_get_bits(rate, RATE_MCS_MOD_TYPE_MSK));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate & RATE_MCS_LDPC_MSK)
|
||||
result |= RATE_MCS_LDPC_MSK_V1;
|
||||
WARN_ON_ONCE(u32_get_bits(rate, RATE_MCS_CHAN_WIDTH_MSK) >
|
||||
RATE_MCS_CHAN_WIDTH_160_VAL);
|
||||
result |= (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) |
|
||||
(rate & RATE_MCS_ANT_AB_MSK) |
|
||||
(rate & RATE_MCS_STBC_MSK) |
|
||||
(rate & RATE_MCS_BF_MSK);
|
||||
|
||||
/* not handling DUP since we don't use it */
|
||||
WARN_ON_ONCE(rate & RATE_MCS_DUP_MSK);
|
||||
|
||||
if (rate & RATE_MCS_SGI_MSK)
|
||||
result |= RATE_MCS_SGI_MSK_V1;
|
||||
|
||||
return cpu_to_le32(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1061,12 +1061,18 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = {
|
|||
|
||||
/* WH RF */
|
||||
IWL_DEV_INFO(iwl_rf_wh, iwl_be211_name, RF_TYPE(WH)),
|
||||
IWL_DEV_INFO(iwl_rf_wh_non_eht, iwl_ax221_name, RF_TYPE(WH),
|
||||
SUBDEV(0x0514)),
|
||||
IWL_DEV_INFO(iwl_rf_wh_non_eht, iwl_ax221_name, RF_TYPE(WH),
|
||||
SUBDEV(0x4514)),
|
||||
IWL_DEV_INFO(iwl_rf_wh_160mhz, iwl_be213_name, RF_TYPE(WH), BW_LIMITED),
|
||||
|
||||
/* PE RF */
|
||||
IWL_DEV_INFO(iwl_rf_pe, iwl_bn201_name, RF_TYPE(PE)),
|
||||
IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE), SUBDEV(0x0524)),
|
||||
IWL_DEV_INFO(iwl_rf_pe, iwl_be221_name, RF_TYPE(PE), SUBDEV(0x0324)),
|
||||
IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE),
|
||||
SUBDEV_MASKED(0x0524, 0xFFF)),
|
||||
IWL_DEV_INFO(iwl_rf_pe, iwl_bn203_name, RF_TYPE(PE),
|
||||
SUBDEV_MASKED(0x0324, 0xFFF)),
|
||||
|
||||
/* Killer */
|
||||
IWL_DEV_INFO(iwl_rf_wh, iwl_killer_be1775s_name, SUBDEV(0x1776)),
|
||||
|
|
|
|||
|
|
@ -4218,6 +4218,15 @@ int iwl_pci_gen1_2_probe(struct pci_dev *pdev,
|
|||
pdev->device, pdev->subsystem_device,
|
||||
info.hw_rev, info.hw_rf_id);
|
||||
|
||||
#if !IS_ENABLED(CONFIG_IWLMLD)
|
||||
if (iwl_drv_is_wifi7_supported(iwl_trans)) {
|
||||
IWL_ERR(iwl_trans,
|
||||
"IWLMLD needs to be compiled to support this device\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out_free_trans;
|
||||
}
|
||||
#endif
|
||||
|
||||
dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
|
||||
CSR_HW_RFID_TYPE(info.hw_rf_id),
|
||||
CSR_HW_RFID_IS_CDB(info.hw_rf_id),
|
||||
|
|
|
|||
|
|
@ -265,6 +265,34 @@ static void devinfo_api_range(struct kunit *test)
|
|||
}
|
||||
}
|
||||
|
||||
static void devinfo_pci_ids_config(struct kunit *test)
|
||||
{
|
||||
for (int i = 0; iwl_hw_card_ids[i].vendor; i++) {
|
||||
const struct pci_device_id *s = &iwl_hw_card_ids[i];
|
||||
const struct iwl_dev_info *di;
|
||||
|
||||
if (s->device == PCI_ANY_ID || s->subdevice == PCI_ANY_ID)
|
||||
continue;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMVM) || IS_ENABLED(CONFIG_IWLMLD)
|
||||
/*
|
||||
* The check below only works for old (pre-CNVI) devices. Most
|
||||
* new have subdevice==ANY, so are already skipped, but for some
|
||||
* Bz platform(s) we list all the RF PCI IDs. Skip those too.
|
||||
*/
|
||||
if (s->driver_data == (kernel_ulong_t)&iwl_bz_mac_cfg)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
di = iwl_pci_find_dev_info(s->device, s->subdevice,
|
||||
0, 0, 0, 0, true);
|
||||
|
||||
KUNIT_EXPECT_PTR_NE_MSG(test, di, NULL,
|
||||
"PCI ID %04x:%04x not found\n",
|
||||
s->device, s->subdevice);
|
||||
}
|
||||
}
|
||||
|
||||
static struct kunit_case devinfo_test_cases[] = {
|
||||
KUNIT_CASE(devinfo_table_order),
|
||||
KUNIT_CASE(devinfo_discrete_match),
|
||||
|
|
@ -276,6 +304,7 @@ static struct kunit_case devinfo_test_cases[] = {
|
|||
KUNIT_CASE(devinfo_pci_ids),
|
||||
KUNIT_CASE(devinfo_no_mac_cfg_dups),
|
||||
KUNIT_CASE(devinfo_api_range),
|
||||
KUNIT_CASE(devinfo_pci_ids_config),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user