mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
ath.git patches for v6.17
All ath drivers: Add "#include <linux/export.h>" to all files that use EXPORT_SYMBOL() to fix a newly introduced 'make W=1' check. Note that check has subsequently been changed to only test when W=2, but keep the fixes to suppress the warning for 'make W=2'. ath12k: Properly handle scan requests on multi-radio wiphy devices. Perform the usual set of bug fixes and cleanups. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCaFq4qwAKCRAsFbugiYzL e9nKAQC0wQ9QR53BFLGVu3TpR2hbaVaJmYlxCtf+DbrEUbOe1gEAgp2Cz0NdjUaQ IABFyUquZS/ZAkqytpjXMvoilyDawAg= =bBFE -----END PGP SIGNATURE----- Merge tag 'ath-next-20250624' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath Jeff Johnson says: ================== ath.git patches for v6.17 All ath drivers: Add "#include <linux/export.h>" to all files that use EXPORT_SYMBOL() to fix a newly introduced 'make W=1' check. Note that check has subsequently been changed to only test when W=2, but keep the fixes to suppress the warning for 'make W=2'. ath12k: Properly handle scan requests on multi-radio wiphy devices. Perform the usual set of bug fixes and cleanups. ================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
7322a7d80c
|
|
@ -3,8 +3,10 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "bmi.h"
|
||||
#include "hif.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018 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.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "hif.h"
|
||||
#include "ce.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of.h>
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
#include "coredump.h"
|
||||
|
||||
#include <linux/devcoredump.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/utsname.h>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/firmware.h>
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "hif.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@
|
|||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "htc.h"
|
||||
#include "htt.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include "htt.h"
|
||||
#include "mac.h"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mac.h"
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/*
|
||||
* Copyright (c) 2012 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "dp_rx.h"
|
||||
#include "debug.h"
|
||||
#include "hif.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* 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/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/remoteproc.h>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#include <linux/devcoredump.h>
|
||||
#include <linux/export.h>
|
||||
#include "hif.h"
|
||||
#include "coredump.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* Copyright (c) 2018-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/export.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "debugfs.h"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
/*
|
||||
* 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 <crypto/hash.h>
|
||||
#include <linux/export.h>
|
||||
#include "core.h"
|
||||
#include "dp_tx.h"
|
||||
#include "hal_tx.h"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "core.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/export.h>
|
||||
#include "hal_tx.h"
|
||||
#include "debug.h"
|
||||
#include "hal_desc.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 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.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "core.h"
|
||||
#include "pcic.h"
|
||||
#include "debug.h"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
/*
|
||||
* 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/elf.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include "qmi.h"
|
||||
#include "core.h"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
/*
|
||||
* 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/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/remoteproc.h>
|
||||
|
|
@ -1409,6 +1411,7 @@ void ath12k_core_halt(struct ath12k *ar)
|
|||
ath12k_mac_peer_cleanup_all(ar);
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
cancel_work_sync(&ar->regd_update_work);
|
||||
cancel_work_sync(&ar->regd_channel_update_work);
|
||||
cancel_work_sync(&ab->rfkill_work);
|
||||
cancel_work_sync(&ab->update_11d_work);
|
||||
|
||||
|
|
@ -1472,6 +1475,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
|||
complete(&ar->vdev_setup_done);
|
||||
complete(&ar->vdev_delete_done);
|
||||
complete(&ar->bss_survey_done);
|
||||
complete(&ar->regd_update_completed);
|
||||
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
idr_for_each(&ar->txmgmt_idr,
|
||||
|
|
@ -1511,6 +1515,9 @@ static void ath12k_update_11d(struct work_struct *work)
|
|||
ar = pdev->ar;
|
||||
|
||||
memcpy(&ar->alpha2, &arg.alpha2, 2);
|
||||
|
||||
reinit_completion(&ar->regd_update_completed);
|
||||
|
||||
ret = ath12k_wmi_send_set_current_country_cmd(ar, &arg);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab,
|
||||
|
|
|
|||
|
|
@ -345,6 +345,10 @@ struct ath12k_link_vif {
|
|||
bool is_sta_assoc_link;
|
||||
|
||||
struct ath12k_reg_tpc_power_info reg_tpc_info;
|
||||
|
||||
bool group_key_valid;
|
||||
struct wmi_vdev_install_key_arg group_key;
|
||||
bool pairwise_key_done;
|
||||
};
|
||||
|
||||
struct ath12k_vif {
|
||||
|
|
@ -380,9 +384,7 @@ struct ath12k_vif {
|
|||
struct ath12k_link_vif __rcu *link[ATH12K_NUM_MAX_LINKS];
|
||||
struct ath12k_vif_cache *cache[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||
/* indicates bitmap of link vif created in FW */
|
||||
u16 links_map;
|
||||
u8 last_scan_link;
|
||||
|
||||
u32 links_map;
|
||||
/* Must be last - ends in a flexible-array member.
|
||||
*
|
||||
* FIXME: Driver should not copy struct ieee80211_chanctx_conf,
|
||||
|
|
@ -719,7 +721,7 @@ struct ath12k {
|
|||
|
||||
/* protects the radio specific data like debug stats, ppdu_stats_info stats,
|
||||
* vdev_stop_status info, scan data, ath12k_sta info, ath12k_link_vif info,
|
||||
* channel context data, survey info, test mode data.
|
||||
* channel context data, survey info, test mode data, regd_channel_update_queue.
|
||||
*/
|
||||
spinlock_t data_lock;
|
||||
|
||||
|
|
@ -778,6 +780,8 @@ struct ath12k {
|
|||
struct completion bss_survey_done;
|
||||
|
||||
struct work_struct regd_update_work;
|
||||
struct work_struct regd_channel_update_work;
|
||||
struct list_head regd_channel_update_queue;
|
||||
|
||||
struct wiphy_work wmi_mgmt_tx_work;
|
||||
struct sk_buff_head wmi_mgmt_tx_queue;
|
||||
|
|
@ -811,6 +815,7 @@ struct ath12k {
|
|||
enum ath12k_11d_state state_11d;
|
||||
u8 alpha2[REG_ALPHA2_LEN];
|
||||
bool regdom_set_by_user;
|
||||
struct completion regd_update_completed;
|
||||
|
||||
struct completion fw_stats_complete;
|
||||
struct completion fw_stats_done;
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr)
|
|||
ret = ath12k_dp_rx_peer_frag_setup(ar, addr, vdev_id);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to setup rx defrag context\n");
|
||||
tid--;
|
||||
goto peer_clean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3761,7 +3761,6 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
|
|||
ath12k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
while (likely(*budget)) {
|
||||
*budget -= 1;
|
||||
mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);
|
||||
if (unlikely(!mon_dst_desc))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2533,31 +2533,15 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
|
|||
struct ath12k_dp_rx_info *rx_info)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
static const struct ieee80211_radiotap_he known = {
|
||||
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
|
||||
.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
|
||||
};
|
||||
struct ieee80211_radiotap_he *he;
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct ieee80211_sta *pubsta;
|
||||
struct ath12k_peer *peer;
|
||||
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
struct ieee80211_rx_status *status = rx_info->rx_status;
|
||||
u8 decap = DP_RX_DECAP_TYPE_RAW;
|
||||
u8 decap = rx_info->decap_type;
|
||||
bool is_mcbc = rxcb->is_mcbc;
|
||||
bool is_eapol = rxcb->is_eapol;
|
||||
|
||||
if (status->encoding == RX_ENC_HE && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
|
||||
!(status->flag & RX_FLAG_SKIP_MONITOR)) {
|
||||
he = skb_push(msdu, sizeof(known));
|
||||
memcpy(he, &known, sizeof(known));
|
||||
status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
}
|
||||
|
||||
if (!(status->flag & RX_FLAG_ONLY_MONITOR))
|
||||
decap = rx_info->decap_type;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@
|
|||
#include "mac.h"
|
||||
|
||||
static enum hal_tcl_encap_type
|
||||
ath12k_dp_tx_get_encap_type(struct ath12k_link_vif *arvif, struct sk_buff *skb)
|
||||
ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ath12k_base *ab = arvif->ar->ab;
|
||||
|
||||
if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
return HAL_TCL_ENCAP_TYPE_RAW;
|
||||
|
|
@ -305,7 +304,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
|||
u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
|
||||
}
|
||||
|
||||
ti.encap_type = ath12k_dp_tx_get_encap_type(arvif, skb);
|
||||
ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb);
|
||||
ti.addr_search_flags = arvif->hal_addr_search_flags;
|
||||
ti.search_type = arvif->search_type;
|
||||
ti.type = HAL_TCL_DESC_TYPE_BUFFER;
|
||||
|
|
|
|||
|
|
@ -1478,7 +1478,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
|||
.download_calib = true,
|
||||
.supports_suspend = false,
|
||||
.tcl_ring_retry = true,
|
||||
.reoq_lut_support = false,
|
||||
.reoq_lut_support = true,
|
||||
.supports_shadow_regs = false,
|
||||
|
||||
.num_tcl_banks = 48,
|
||||
|
|
|
|||
|
|
@ -693,6 +693,9 @@ static void ath12k_get_arvif_iter(void *data, u8 *mac,
|
|||
if (WARN_ON(!arvif))
|
||||
continue;
|
||||
|
||||
if (!arvif->is_created)
|
||||
continue;
|
||||
|
||||
if (arvif->vdev_id == arvif_iter->vdev_id &&
|
||||
arvif->ar == arvif_iter->ar) {
|
||||
arvif_iter->arvif = arvif;
|
||||
|
|
@ -1755,7 +1758,7 @@ static void ath12k_mac_handle_beacon_iter(void *data, u8 *mac,
|
|||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ath12k_link_vif *arvif = &ahvif->deflink;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
if (vif->type != NL80211_IFTYPE_STATION || !arvif->is_created)
|
||||
return;
|
||||
|
||||
if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
|
||||
|
|
@ -1778,16 +1781,16 @@ static void ath12k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
|
|||
u32 *vdev_id = data;
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ath12k_link_vif *arvif = &ahvif->deflink;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
if (arvif->vdev_id != *vdev_id)
|
||||
if (!arvif->is_created || arvif->vdev_id != *vdev_id)
|
||||
return;
|
||||
|
||||
if (!arvif->is_up)
|
||||
return;
|
||||
|
||||
ieee80211_beacon_loss(vif);
|
||||
hw = ath12k_ar_to_hw(arvif->ar);
|
||||
|
||||
/* Firmware doesn't report beacon loss events repeatedly. If AP probe
|
||||
* (done by mac80211) succeeds but beacons do not resume then it
|
||||
|
|
@ -3496,7 +3499,7 @@ static struct ath12k_link_vif *ath12k_mac_assign_link_vif(struct ath12k_hw *ah,
|
|||
/* If this is the first link arvif being created for an ML VIF
|
||||
* use the preallocated deflink memory except for scan arvifs
|
||||
*/
|
||||
if (!ahvif->links_map && link_id != ATH12K_DEFAULT_SCAN_LINK) {
|
||||
if (!ahvif->links_map && link_id < ATH12K_FIRST_SCAN_LINK) {
|
||||
arvif = &ahvif->deflink;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
|
|
@ -4149,8 +4152,9 @@ ath12k_mac_select_scan_device(struct ieee80211_hw *hw,
|
|||
band = NL80211_BAND_6GHZ;
|
||||
|
||||
for_each_ar(ah, ar, i) {
|
||||
/* TODO 5 GHz low high split changes */
|
||||
if (ar->mac.sbands[band].channels)
|
||||
if (ar->mac.sbands[band].channels &&
|
||||
center_freq >= KHZ_TO_MHZ(ar->freq_range.start_freq) &&
|
||||
center_freq <= KHZ_TO_MHZ(ar->freq_range.end_freq))
|
||||
return ar;
|
||||
}
|
||||
|
||||
|
|
@ -4274,6 +4278,23 @@ static void ath12k_scan_timeout_work(struct work_struct *work)
|
|||
wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
|
||||
}
|
||||
|
||||
static void ath12k_mac_scan_send_complete(struct ath12k *ar,
|
||||
struct cfg80211_scan_info *info)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ath12k *partner_ar;
|
||||
int i;
|
||||
|
||||
lockdep_assert_wiphy(ah->hw->wiphy);
|
||||
|
||||
for_each_ar(ah, partner_ar, i)
|
||||
if (partner_ar != ar &&
|
||||
partner_ar->scan.state == ATH12K_SCAN_RUNNING)
|
||||
return;
|
||||
|
||||
ieee80211_scan_completed(ah->hw, info);
|
||||
}
|
||||
|
||||
static void ath12k_scan_vdev_clean_work(struct wiphy *wiphy, struct wiphy_work *work)
|
||||
{
|
||||
struct ath12k *ar = container_of(work, struct ath12k,
|
||||
|
|
@ -4312,7 +4333,7 @@ static void ath12k_scan_vdev_clean_work(struct wiphy *wiphy, struct wiphy_work *
|
|||
ATH12K_SCAN_STARTING)),
|
||||
};
|
||||
|
||||
ieee80211_scan_completed(ar->ah->hw, &info);
|
||||
ath12k_mac_scan_send_complete(ar, &info);
|
||||
}
|
||||
|
||||
ar->scan.state = ATH12K_SCAN_IDLE;
|
||||
|
|
@ -4488,11 +4509,12 @@ ath12k_mac_find_link_id_by_ar(struct ath12k_vif *ahvif, struct ath12k *ar)
|
|||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k_hw *ah = ahvif->ah;
|
||||
unsigned long links = ahvif->links_map;
|
||||
unsigned long scan_links_map;
|
||||
u8 link_id;
|
||||
|
||||
lockdep_assert_wiphy(ah->hw->wiphy);
|
||||
|
||||
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
for_each_set_bit(link_id, &links, ATH12K_NUM_MAX_LINKS) {
|
||||
arvif = wiphy_dereference(ah->hw->wiphy, ahvif->link[link_id]);
|
||||
|
||||
if (!arvif || !arvif->is_created)
|
||||
|
|
@ -4502,18 +4524,30 @@ ath12k_mac_find_link_id_by_ar(struct ath12k_vif *ahvif, struct ath12k *ar)
|
|||
return link_id;
|
||||
}
|
||||
|
||||
/* input ar is not assigned to any of the links of ML VIF, use scan
|
||||
* link (15) for scan vdev creation.
|
||||
/* input ar is not assigned to any of the links of ML VIF, use next
|
||||
* available scan link for scan vdev creation. There are cases where
|
||||
* single scan req needs to be split in driver and initiate separate
|
||||
* scan requests to firmware based on device.
|
||||
*/
|
||||
return ATH12K_DEFAULT_SCAN_LINK;
|
||||
|
||||
/* Unset all non-scan links (0-14) of scan_links_map so that ffs() will
|
||||
* choose an available link among scan links (i.e link id >= 15)
|
||||
*/
|
||||
scan_links_map = ~ahvif->links_map & ATH12K_SCAN_LINKS_MASK;
|
||||
if (scan_links_map)
|
||||
return __ffs(scan_links_map);
|
||||
|
||||
return ATH12K_FIRST_SCAN_LINK;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req,
|
||||
int n_channels,
|
||||
struct ieee80211_channel **chan_list,
|
||||
struct ath12k *ar)
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
struct ath12k *ar;
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct cfg80211_scan_request *req = &hw_req->req;
|
||||
|
|
@ -4527,18 +4561,18 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
|||
|
||||
arvif = &ahvif->deflink;
|
||||
|
||||
/* Since the targeted scan device could depend on the frequency
|
||||
* requested in the hw_req, select the corresponding radio
|
||||
*/
|
||||
ar = ath12k_mac_select_scan_device(hw, vif, hw_req->req.channels[0]->center_freq);
|
||||
if (!ar)
|
||||
return -EINVAL;
|
||||
|
||||
/* check if any of the links of ML VIF is already started on
|
||||
* radio(ar) corresponding to given scan frequency and use it,
|
||||
* if not use scan link (link 15) for scan purpose.
|
||||
* if not use scan link (link id >= 15) for scan purpose.
|
||||
*/
|
||||
link_id = ath12k_mac_find_link_id_by_ar(ahvif, ar);
|
||||
/* All scan links are occupied. ideally this shouldn't happen as
|
||||
* mac80211 won't schedule scan for same band until ongoing scan is
|
||||
* completed, don't try to exceed max links just in case if it happens.
|
||||
*/
|
||||
if (link_id >= ATH12K_NUM_MAX_LINKS)
|
||||
return -EBUSY;
|
||||
|
||||
arvif = ath12k_mac_assign_link_vif(ah, vif, link_id);
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac link ID %d selected for scan",
|
||||
|
|
@ -4629,8 +4663,8 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
|||
arg->scan_f_passive = 1;
|
||||
}
|
||||
|
||||
if (req->n_channels) {
|
||||
arg->num_chan = req->n_channels;
|
||||
if (n_channels) {
|
||||
arg->num_chan = n_channels;
|
||||
arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
|
||||
GFP_KERNEL);
|
||||
if (!arg->chan_list) {
|
||||
|
|
@ -4639,7 +4673,7 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
for (i = 0; i < arg->num_chan; i++)
|
||||
arg->chan_list[i] = req->channels[i]->center_freq;
|
||||
arg->chan_list[i] = chan_list[i]->center_freq;
|
||||
}
|
||||
|
||||
ret = ath12k_start_scan(ar, arg);
|
||||
|
|
@ -4658,13 +4692,6 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
|||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac scan started");
|
||||
|
||||
/* As per cfg80211/mac80211 scan design, it allows only one
|
||||
* scan at a time. Hence last_scan link id is used for
|
||||
* tracking the link id on which the scan is been done on
|
||||
* this vif.
|
||||
*/
|
||||
ahvif->last_scan_link = arvif->link_id;
|
||||
|
||||
/* Add a margin to account for event/command processing */
|
||||
ieee80211_queue_delayed_work(ath12k_ar_to_hw(ar), &ar->scan.timeout,
|
||||
msecs_to_jiffies(arg->max_scan_time +
|
||||
|
|
@ -4685,25 +4712,108 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
{
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ieee80211_channel **chan_list, *chan;
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
unsigned long links_map, link_id;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k *ar, *scan_ar;
|
||||
int i, j, ret = 0;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
chan_list = kcalloc(hw_req->req.n_channels, sizeof(*chan_list), GFP_KERNEL);
|
||||
if (!chan_list)
|
||||
return -ENOMEM;
|
||||
|
||||
/* There could be channels that belong to multiple underlying radio
|
||||
* in same scan request as mac80211 sees it as single band. In that
|
||||
* case split the hw_req based on frequency range and schedule scans to
|
||||
* corresponding radio.
|
||||
*/
|
||||
for_each_ar(ah, ar, i) {
|
||||
int n_chans = 0;
|
||||
|
||||
for (j = 0; j < hw_req->req.n_channels; j++) {
|
||||
chan = hw_req->req.channels[j];
|
||||
scan_ar = ath12k_mac_select_scan_device(hw, vif,
|
||||
chan->center_freq);
|
||||
if (!scan_ar) {
|
||||
ath12k_hw_warn(ah, "unable to select scan device for freq %d\n",
|
||||
chan->center_freq);
|
||||
ret = -EINVAL;
|
||||
goto abort;
|
||||
}
|
||||
if (ar != scan_ar)
|
||||
continue;
|
||||
|
||||
chan_list[n_chans++] = chan;
|
||||
}
|
||||
if (n_chans) {
|
||||
ret = ath12k_mac_initiate_hw_scan(hw, vif, hw_req, n_chans,
|
||||
chan_list, ar);
|
||||
if (ret)
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
abort:
|
||||
/* If any of the parallel scans initiated fails, abort all and
|
||||
* remove the scan interfaces created. Return complete scan
|
||||
* failure as mac80211 assumes this as single scan request.
|
||||
*/
|
||||
if (ret) {
|
||||
ath12k_hw_warn(ah, "Scan failed %d , cleanup all scan vdevs\n", ret);
|
||||
links_map = ahvif->links_map;
|
||||
for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) {
|
||||
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
|
||||
if (!arvif)
|
||||
continue;
|
||||
|
||||
ar = arvif->ar;
|
||||
if (ar->scan.arvif == arvif) {
|
||||
wiphy_work_cancel(hw->wiphy, &ar->scan.vdev_clean_wk);
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ar->scan.arvif = NULL;
|
||||
ar->scan.state = ATH12K_SCAN_IDLE;
|
||||
ar->scan_channel = NULL;
|
||||
ar->scan.roc_freq = 0;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
if (link_id >= ATH12K_FIRST_SCAN_LINK) {
|
||||
ath12k_mac_remove_link_interface(hw, arvif);
|
||||
ath12k_mac_unassign_link_vif(arvif);
|
||||
}
|
||||
}
|
||||
}
|
||||
kfree(chan_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
u16 link_id = ahvif->last_scan_link;
|
||||
unsigned long link_id, links_map = ahvif->links_map;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k *ar;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
|
||||
if (!arvif || arvif->is_started)
|
||||
return;
|
||||
for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) {
|
||||
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
|
||||
if (!arvif || arvif->is_started)
|
||||
continue;
|
||||
|
||||
ar = arvif->ar;
|
||||
ar = arvif->ar;
|
||||
|
||||
ath12k_scan_abort(ar);
|
||||
ath12k_scan_abort(ar);
|
||||
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
static int ath12k_install_key(struct ath12k_link_vif *arvif,
|
||||
|
|
@ -4719,14 +4829,13 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
|
|||
.key_len = key->keylen,
|
||||
.key_data = key->key,
|
||||
.key_flags = flags,
|
||||
.ieee80211_key_cipher = key->cipher,
|
||||
.macaddr = macaddr,
|
||||
};
|
||||
struct ath12k_vif *ahvif = arvif->ahvif;
|
||||
|
||||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
reinit_completion(&ar->install_key_done);
|
||||
|
||||
if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
|
||||
return 0;
|
||||
|
||||
|
|
@ -4735,7 +4844,7 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
|
|||
/* arg.key_cipher = WMI_CIPHER_NONE; */
|
||||
arg.key_len = 0;
|
||||
arg.key_data = NULL;
|
||||
goto install;
|
||||
goto check_order;
|
||||
}
|
||||
|
||||
switch (key->cipher) {
|
||||
|
|
@ -4763,19 +4872,82 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
|
|||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV |
|
||||
IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
|
||||
|
||||
install:
|
||||
ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg);
|
||||
check_order:
|
||||
if (ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
|
||||
arg.key_flags == WMI_KEY_GROUP) {
|
||||
if (cmd == SET_KEY) {
|
||||
if (arvif->pairwise_key_done) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"vdev %u pairwise key done, go install group key\n",
|
||||
arg.vdev_id);
|
||||
goto install;
|
||||
} else {
|
||||
/* WCN7850 firmware requires pairwise key to be installed
|
||||
* before group key. In case group key comes first, cache
|
||||
* it and return. Will revisit it once pairwise key gets
|
||||
* installed.
|
||||
*/
|
||||
arvif->group_key = arg;
|
||||
arvif->group_key_valid = true;
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"vdev %u group key before pairwise key, cache and skip\n",
|
||||
arg.vdev_id);
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
arvif->group_key_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
install:
|
||||
reinit_completion(&ar->install_key_done);
|
||||
|
||||
ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
if (ether_addr_equal(macaddr, arvif->bssid))
|
||||
ahvif->key_cipher = key->cipher;
|
||||
if (ether_addr_equal(arg.macaddr, arvif->bssid))
|
||||
ahvif->key_cipher = arg.ieee80211_key_cipher;
|
||||
|
||||
return ar->install_key_status ? -EINVAL : 0;
|
||||
if (ar->install_key_status) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
|
||||
arg.key_flags == WMI_KEY_PAIRWISE) {
|
||||
if (cmd == SET_KEY) {
|
||||
arvif->pairwise_key_done = true;
|
||||
if (arvif->group_key_valid) {
|
||||
/* Install cached GTK */
|
||||
arvif->group_key_valid = false;
|
||||
arg = arvif->group_key;
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"vdev %u pairwise key done, group key ready, go install\n",
|
||||
arg.vdev_id);
|
||||
goto install;
|
||||
}
|
||||
} else {
|
||||
arvif->pairwise_key_done = false;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
/* In case of failure userspace may not do DISABLE_KEY
|
||||
* but triggers re-connection directly, so manually reset
|
||||
* status here.
|
||||
*/
|
||||
arvif->group_key_valid = false;
|
||||
arvif->pairwise_key_done = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif,
|
||||
|
|
@ -4869,9 +5041,9 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd,
|
|||
}
|
||||
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
|
||||
flags |= WMI_KEY_PAIRWISE;
|
||||
flags = WMI_KEY_PAIRWISE;
|
||||
else
|
||||
flags |= WMI_KEY_GROUP;
|
||||
flags = WMI_KEY_GROUP;
|
||||
|
||||
ret = ath12k_install_key(arvif, key, cmd, peer_addr, flags);
|
||||
if (ret) {
|
||||
|
|
@ -8114,7 +8286,17 @@ static int ath12k_mac_start(struct ath12k *ar)
|
|||
|
||||
/* TODO: Do we need to enable ANI? */
|
||||
|
||||
ath12k_reg_update_chan_list(ar, false);
|
||||
ret = ath12k_reg_update_chan_list(ar, false);
|
||||
|
||||
/* The ar state alone can be turned off for non supported country
|
||||
* without returning the error value. As we need to update the channel
|
||||
* for the next ar.
|
||||
*/
|
||||
if (ret) {
|
||||
if (ret == -EINVAL)
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ar->num_started_vdevs = 0;
|
||||
ar->num_created_vdevs = 0;
|
||||
|
|
@ -8286,6 +8468,7 @@ static void ath12k_mac_stop(struct ath12k *ar)
|
|||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct htt_ppdu_stats_info *ppdu_stats, *tmp;
|
||||
struct ath12k_wmi_scan_chan_list_arg *arg;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ah->hw_mutex);
|
||||
|
|
@ -8300,6 +8483,7 @@ static void ath12k_mac_stop(struct ath12k *ar)
|
|||
|
||||
cancel_delayed_work_sync(&ar->scan.timeout);
|
||||
wiphy_work_cancel(ath12k_ar_to_hw(ar)->wiphy, &ar->scan.vdev_clean_wk);
|
||||
cancel_work_sync(&ar->regd_channel_update_work);
|
||||
cancel_work_sync(&ar->regd_update_work);
|
||||
cancel_work_sync(&ar->ab->rfkill_work);
|
||||
cancel_work_sync(&ar->ab->update_11d_work);
|
||||
|
|
@ -8307,10 +8491,18 @@ static void ath12k_mac_stop(struct ath12k *ar)
|
|||
complete(&ar->completed_11d_scan);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {
|
||||
list_del(&ppdu_stats->list);
|
||||
kfree(ppdu_stats);
|
||||
}
|
||||
|
||||
while ((arg = list_first_entry_or_null(&ar->regd_channel_update_queue,
|
||||
struct ath12k_wmi_scan_chan_list_arg,
|
||||
list))) {
|
||||
list_del(&arg->list);
|
||||
kfree(arg);
|
||||
}
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
rcu_assign_pointer(ar->ab->pdevs_active[ar->pdev_idx], NULL);
|
||||
|
|
@ -9055,7 +9247,8 @@ static struct ath12k *ath12k_mac_assign_vif_to_vdev(struct ieee80211_hw *hw,
|
|||
struct ath12k_hw *ah = hw->priv;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_base *ab;
|
||||
u8 link_id = arvif->link_id;
|
||||
u8 link_id = arvif->link_id, scan_link_id;
|
||||
unsigned long scan_link_map;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
|
@ -9074,12 +9267,16 @@ static struct ath12k *ath12k_mac_assign_vif_to_vdev(struct ieee80211_hw *hw,
|
|||
* and now we want to create for actual usage.
|
||||
*/
|
||||
if (ieee80211_vif_is_mld(vif)) {
|
||||
scan_arvif = wiphy_dereference(hw->wiphy,
|
||||
ahvif->link[ATH12K_DEFAULT_SCAN_LINK]);
|
||||
if (scan_arvif && scan_arvif->ar == ar) {
|
||||
ar->scan.arvif = NULL;
|
||||
ath12k_mac_remove_link_interface(hw, scan_arvif);
|
||||
ath12k_mac_unassign_link_vif(scan_arvif);
|
||||
scan_link_map = ahvif->links_map & ATH12K_SCAN_LINKS_MASK;
|
||||
for_each_set_bit(scan_link_id, &scan_link_map, ATH12K_NUM_MAX_LINKS) {
|
||||
scan_arvif = wiphy_dereference(hw->wiphy,
|
||||
ahvif->link[scan_link_id]);
|
||||
if (scan_arvif && scan_arvif->ar == ar) {
|
||||
ar->scan.arvif = NULL;
|
||||
ath12k_mac_remove_link_interface(hw, scan_arvif);
|
||||
ath12k_mac_unassign_link_vif(scan_arvif);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9314,7 +9511,7 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw,
|
|||
.aborted = true,
|
||||
};
|
||||
|
||||
ieee80211_scan_completed(ar->ah->hw, &info);
|
||||
ath12k_mac_scan_send_complete(ar, &info);
|
||||
}
|
||||
|
||||
ar->scan.state = ATH12K_SCAN_IDLE;
|
||||
|
|
@ -9820,7 +10017,7 @@ ath12k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
|
|||
if (WARN_ON(!arvif))
|
||||
continue;
|
||||
|
||||
if (arvif->ar != arg->ar)
|
||||
if (!arvif->is_created || arvif->ar != arg->ar)
|
||||
continue;
|
||||
|
||||
link_conf = wiphy_dereference(ahvif->ah->hw->wiphy,
|
||||
|
|
@ -9855,7 +10052,7 @@ ath12k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
|
|||
if (WARN_ON(!arvif))
|
||||
continue;
|
||||
|
||||
if (arvif->ar != arg->ar)
|
||||
if (!arvif->is_created || arvif->ar != arg->ar)
|
||||
continue;
|
||||
|
||||
link_conf = wiphy_dereference(ahvif->ah->hw->wiphy,
|
||||
|
|
@ -11250,6 +11447,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
|
|||
struct wmi_set_current_country_arg arg = {};
|
||||
|
||||
memcpy(&arg.alpha2, ar->alpha2, 2);
|
||||
reinit_completion(&ar->regd_update_completed);
|
||||
ath12k_wmi_send_set_current_country_cmd(ar, &arg);
|
||||
}
|
||||
|
||||
|
|
@ -11761,6 +11959,32 @@ static u32 ath12k_get_phy_id(struct ath12k *ar, u32 band)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_mac_update_band(struct ath12k *ar,
|
||||
struct ieee80211_supported_band *orig_band,
|
||||
struct ieee80211_supported_band *new_band)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!orig_band || !new_band)
|
||||
return -EINVAL;
|
||||
|
||||
if (orig_band->band != new_band->band)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < new_band->n_channels; i++) {
|
||||
if (new_band->channels[i].flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
/* An enabled channel in new_band should not be already enabled
|
||||
* in the orig_band
|
||||
*/
|
||||
if (WARN_ON(!(orig_band->channels[i].flags &
|
||||
IEEE80211_CHAN_DISABLED)))
|
||||
return -EINVAL;
|
||||
orig_band->channels[i].flags &= ~IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
||||
u32 supported_bands,
|
||||
struct ieee80211_supported_band *bands[])
|
||||
|
|
@ -11771,6 +11995,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
u32 phy_id, freq_low, freq_high;
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
void *channels;
|
||||
int ret;
|
||||
|
||||
BUILD_BUG_ON((ARRAY_SIZE(ath12k_2ghz_channels) +
|
||||
ARRAY_SIZE(ath12k_5ghz_channels) +
|
||||
|
|
@ -11792,7 +12017,6 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
band->channels = channels;
|
||||
band->n_bitrates = ath12k_g_rates_size;
|
||||
band->bitrates = ath12k_g_rates;
|
||||
bands[NL80211_BAND_2GHZ] = band;
|
||||
|
||||
if (ab->hw_params->single_pdev_only) {
|
||||
phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2GHZ_CAP);
|
||||
|
|
@ -11809,6 +12033,22 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
reg_cap->high_2ghz_chan);
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
|
||||
if (!bands[NL80211_BAND_2GHZ]) {
|
||||
bands[NL80211_BAND_2GHZ] = band;
|
||||
} else {
|
||||
/* Split mac in same band under same wiphy */
|
||||
ret = ath12k_mac_update_band(ar, bands[NL80211_BAND_2GHZ], band);
|
||||
if (ret) {
|
||||
kfree(channels);
|
||||
band->channels = NULL;
|
||||
return ret;
|
||||
}
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 2 GHz split mac with start freq %d end freq %d",
|
||||
ar->pdev->pdev_id,
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq),
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq));
|
||||
}
|
||||
}
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
|
||||
|
|
@ -11827,7 +12067,6 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
band->channels = channels;
|
||||
band->n_bitrates = ath12k_a_rates_size;
|
||||
band->bitrates = ath12k_a_rates;
|
||||
bands[NL80211_BAND_6GHZ] = band;
|
||||
|
||||
freq_low = max(reg_cap->low_5ghz_chan,
|
||||
ab->reg_freq_6ghz.start_freq);
|
||||
|
|
@ -11840,6 +12079,26 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
ah->use_6ghz_regd = true;
|
||||
|
||||
if (!bands[NL80211_BAND_6GHZ]) {
|
||||
bands[NL80211_BAND_6GHZ] = band;
|
||||
} else {
|
||||
/* Split mac in same band under same wiphy */
|
||||
ret = ath12k_mac_update_band(ar,
|
||||
bands[NL80211_BAND_6GHZ],
|
||||
band);
|
||||
if (ret) {
|
||||
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
|
||||
ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL;
|
||||
kfree(channels);
|
||||
band->channels = NULL;
|
||||
return ret;
|
||||
}
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 6 GHz split mac with start freq %d end freq %d",
|
||||
ar->pdev->pdev_id,
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq),
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq));
|
||||
}
|
||||
}
|
||||
|
||||
if (reg_cap->low_5ghz_chan < ATH12K_MIN_6GHZ_FREQ) {
|
||||
|
|
@ -11858,7 +12117,6 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
band->channels = channels;
|
||||
band->n_bitrates = ath12k_a_rates_size;
|
||||
band->bitrates = ath12k_a_rates;
|
||||
bands[NL80211_BAND_5GHZ] = band;
|
||||
|
||||
if (ab->hw_params->single_pdev_only) {
|
||||
phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5GHZ_CAP);
|
||||
|
|
@ -11875,6 +12133,28 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
|
|||
reg_cap->high_5ghz_chan);
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
|
||||
if (!bands[NL80211_BAND_5GHZ]) {
|
||||
bands[NL80211_BAND_5GHZ] = band;
|
||||
} else {
|
||||
/* Split mac in same band under same wiphy */
|
||||
ret = ath12k_mac_update_band(ar,
|
||||
bands[NL80211_BAND_5GHZ],
|
||||
band);
|
||||
if (ret) {
|
||||
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
|
||||
ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL;
|
||||
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
|
||||
ar->mac.sbands[NL80211_BAND_2GHZ].channels = NULL;
|
||||
kfree(channels);
|
||||
band->channels = NULL;
|
||||
return ret;
|
||||
}
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac pdev %u identified as 5 GHz split mac with start freq %d end freq %d",
|
||||
ar->pdev->pdev_id,
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq),
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -12208,6 +12488,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
|
|||
int i;
|
||||
|
||||
for_each_ar(ah, ar, i) {
|
||||
cancel_work_sync(&ar->regd_channel_update_work);
|
||||
cancel_work_sync(&ar->regd_update_work);
|
||||
ath12k_debugfs_unregister(ar);
|
||||
ath12k_fw_stats_reset(ar);
|
||||
|
|
@ -12466,6 +12747,16 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
goto err_cleanup_if_combs;
|
||||
}
|
||||
|
||||
/* Boot-time regulatory updates have already been processed.
|
||||
* Mark them as complete now, because after registration,
|
||||
* cfg80211 will notify us again if there are any pending hints.
|
||||
* We need to wait for those hints to be processed, so it's
|
||||
* important to mark the boot-time updates as complete before
|
||||
* proceeding with registration.
|
||||
*/
|
||||
for_each_ar(ah, ar, i)
|
||||
complete(&ar->regd_update_completed);
|
||||
|
||||
ret = ieee80211_register_hw(hw);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "ieee80211 registration failed: %d\n", ret);
|
||||
|
|
@ -12493,6 +12784,9 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
|
||||
memcpy(¤t_cc.alpha2, ab->new_alpha2, 2);
|
||||
memcpy(&ar->alpha2, ab->new_alpha2, 2);
|
||||
|
||||
reinit_completion(&ar->regd_update_completed);
|
||||
|
||||
ret = ath12k_wmi_send_set_current_country_cmd(ar, ¤t_cc);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab,
|
||||
|
|
@ -12565,9 +12859,12 @@ static void ath12k_mac_setup(struct ath12k *ar)
|
|||
init_completion(&ar->scan.on_channel);
|
||||
init_completion(&ar->mlo_setup_done);
|
||||
init_completion(&ar->completed_11d_scan);
|
||||
init_completion(&ar->regd_update_completed);
|
||||
|
||||
INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work);
|
||||
wiphy_work_init(&ar->scan.vdev_clean_wk, ath12k_scan_vdev_clean_work);
|
||||
INIT_WORK(&ar->regd_channel_update_work, ath12k_regd_update_chan_list_work);
|
||||
INIT_LIST_HEAD(&ar->regd_channel_update_queue);
|
||||
INIT_WORK(&ar->regd_update_work, ath12k_regd_update_work);
|
||||
|
||||
wiphy_work_init(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
|
||||
|
|
|
|||
|
|
@ -51,8 +51,11 @@ struct ath12k_generic_iter {
|
|||
/* Default link after the IEEE802.11 defined Max link id limit
|
||||
* for driver usage purpose.
|
||||
*/
|
||||
#define ATH12K_DEFAULT_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS
|
||||
#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + 1)
|
||||
#define ATH12K_FIRST_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS
|
||||
#define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO
|
||||
/* Define 1 scan link for each radio for parallel scan purposes */
|
||||
#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS)
|
||||
#define ATH12K_SCAN_LINKS_MASK GENMASK(ATH12K_NUM_MAX_LINKS, IEEE80211_MLD_MAX_NUM_LINKS)
|
||||
|
||||
#define ATH12K_NUM_MAX_ACTIVE_LINKS_PER_DEVICE 2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
|
@ -124,7 +125,7 @@ static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
|
|||
|
||||
WARN_ON(!rcu_read_lock_any_held());
|
||||
arvif = &ahvif->deflink;
|
||||
if (arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id)
|
||||
if (!arvif->is_created || arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id)
|
||||
return;
|
||||
|
||||
ath12k_p2p_noa_update(arvif, arg->noa);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
|||
|
||||
for_each_ar(ah, ar, i) {
|
||||
ret = ath12k_reg_update_chan_list(ar, true);
|
||||
if (ret) {
|
||||
if (ret && ret != -EINVAL) {
|
||||
ath12k_warn(ar->ab,
|
||||
"failed to update chan list for pdev %u, ret %d\n",
|
||||
i, ret);
|
||||
|
|
@ -102,6 +102,8 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
|||
|
||||
/* Send the reg change request to all the radios */
|
||||
for_each_ar(ah, ar, i) {
|
||||
reinit_completion(&ar->regd_update_completed);
|
||||
|
||||
if (ar->ab->hw_params->current_cc_support) {
|
||||
memcpy(¤t_arg.alpha2, request->alpha2, 2);
|
||||
memcpy(&ar->alpha2, ¤t_arg.alpha2, 2);
|
||||
|
|
@ -137,32 +139,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
|
|||
struct ath12k_wmi_channel_arg *ch;
|
||||
enum nl80211_band band;
|
||||
int num_channels = 0;
|
||||
int i, ret, left;
|
||||
|
||||
if (wait && ar->state_11d == ATH12K_11D_RUNNING) {
|
||||
left = wait_for_completion_timeout(&ar->completed_11d_scan,
|
||||
ATH12K_SCAN_TIMEOUT_HZ);
|
||||
if (!left) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"failed to receive 11d scan complete: timed out\n");
|
||||
ar->state_11d = ATH12K_11D_IDLE;
|
||||
}
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"reg 11d scan wait left time %d\n", left);
|
||||
}
|
||||
|
||||
if (wait &&
|
||||
(ar->scan.state == ATH12K_SCAN_STARTING ||
|
||||
ar->scan.state == ATH12K_SCAN_RUNNING)) {
|
||||
left = wait_for_completion_timeout(&ar->scan.completed,
|
||||
ATH12K_SCAN_TIMEOUT_HZ);
|
||||
if (!left)
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"failed to receive hw scan complete: timed out\n");
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"reg hw scan wait left time %d\n", left);
|
||||
}
|
||||
int i, ret = 0;
|
||||
|
||||
if (ar->ah->state == ATH12K_HW_STATE_RESTARTING)
|
||||
return 0;
|
||||
|
|
@ -176,13 +153,22 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
|
|||
if (bands[band]->channels[i].flags &
|
||||
IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
/* Skip Channels that are not in current radio's range */
|
||||
if (bands[band]->channels[i].center_freq <
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq) ||
|
||||
bands[band]->channels[i].center_freq >
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq))
|
||||
continue;
|
||||
|
||||
num_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(!num_channels))
|
||||
if (!num_channels) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"pdev is not supported for this country\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arg = kzalloc(struct_size(arg, channel, num_channels), GFP_KERNEL);
|
||||
|
||||
|
|
@ -204,6 +190,13 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
|
|||
if (channel->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
/* Skip Channels that are not in current radio's range */
|
||||
if (bands[band]->channels[i].center_freq <
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq) ||
|
||||
bands[band]->channels[i].center_freq >
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq))
|
||||
continue;
|
||||
|
||||
/* TODO: Set to true/false based on some condition? */
|
||||
ch->allow_ht = true;
|
||||
ch->allow_vht = true;
|
||||
|
|
@ -244,6 +237,16 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
|
|||
}
|
||||
}
|
||||
|
||||
if (wait) {
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_add_tail(&arg->list, &ar->regd_channel_update_queue);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
queue_work(ar->ab->workqueue, &ar->regd_channel_update_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_send_scan_chan_list_cmd(ar, arg);
|
||||
kfree(arg);
|
||||
|
||||
|
|
@ -272,9 +275,19 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
|
|||
struct ieee80211_regdomain *regd, *regd_copy = NULL;
|
||||
int ret, regd_len, pdev_id;
|
||||
struct ath12k_base *ab;
|
||||
long time_left;
|
||||
|
||||
ab = ar->ab;
|
||||
|
||||
time_left = wait_for_completion_timeout(&ar->regd_update_completed,
|
||||
ATH12K_REG_UPDATE_TIMEOUT_HZ);
|
||||
if (time_left == 0) {
|
||||
ath12k_warn(ab, "Timeout while waiting for regulatory update");
|
||||
/* Even though timeout has occurred, still continue since at least boot
|
||||
* time data would be there to process
|
||||
*/
|
||||
}
|
||||
|
||||
supported_bands = ar->pdev->cap.supported_bands;
|
||||
reg_cap = &ab->hal_reg_cap[ar->pdev_idx];
|
||||
|
||||
|
|
@ -764,6 +777,54 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
|||
return new_regd;
|
||||
}
|
||||
|
||||
void ath12k_regd_update_chan_list_work(struct work_struct *work)
|
||||
{
|
||||
struct ath12k *ar = container_of(work, struct ath12k,
|
||||
regd_channel_update_work);
|
||||
struct ath12k_wmi_scan_chan_list_arg *arg;
|
||||
struct list_head local_update_list;
|
||||
int left;
|
||||
|
||||
INIT_LIST_HEAD(&local_update_list);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_splice_tail_init(&ar->regd_channel_update_queue, &local_update_list);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
while ((arg = list_first_entry_or_null(&local_update_list,
|
||||
struct ath12k_wmi_scan_chan_list_arg,
|
||||
list))) {
|
||||
if (ar->state_11d != ATH12K_11D_IDLE) {
|
||||
left = wait_for_completion_timeout(&ar->completed_11d_scan,
|
||||
ATH12K_SCAN_TIMEOUT_HZ);
|
||||
if (!left) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"failed to receive 11d scan complete: timed out\n");
|
||||
ar->state_11d = ATH12K_11D_IDLE;
|
||||
}
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"reg 11d scan wait left time %d\n", left);
|
||||
}
|
||||
|
||||
if ((ar->scan.state == ATH12K_SCAN_STARTING ||
|
||||
ar->scan.state == ATH12K_SCAN_RUNNING)) {
|
||||
left = wait_for_completion_timeout(&ar->scan.completed,
|
||||
ATH12K_SCAN_TIMEOUT_HZ);
|
||||
if (!left)
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"failed to receive hw scan complete: timed out\n");
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
"reg hw scan wait left time %d\n", left);
|
||||
}
|
||||
|
||||
ath12k_wmi_send_scan_chan_list_cmd(ar, arg);
|
||||
list_del(&arg->list);
|
||||
kfree(arg);
|
||||
}
|
||||
}
|
||||
|
||||
void ath12k_regd_update_work(struct work_struct *work)
|
||||
{
|
||||
struct ath12k *ar = container_of(work, struct ath12k,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
struct ath12k_base;
|
||||
struct ath12k;
|
||||
|
||||
#define ATH12K_REG_UPDATE_TIMEOUT_HZ (3 * HZ)
|
||||
|
||||
#define ATH12K_2GHZ_MAX_FREQUENCY 2495
|
||||
#define ATH12K_5GHZ_MAX_FREQUENCY 5920
|
||||
|
||||
|
|
@ -113,6 +115,7 @@ int ath12k_reg_handle_chan_list(struct ath12k_base *ab,
|
|||
struct ath12k_reg_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
void ath12k_regd_update_chan_list_work(struct work_struct *work);
|
||||
enum wmi_reg_6g_ap_type
|
||||
ath12k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
|
||||
enum ath12k_reg_status ath12k_reg_validate_reg_info(struct ath12k_base *ab,
|
||||
|
|
|
|||
|
|
@ -6445,9 +6445,16 @@ static int freq_to_idx(struct ath12k *ar, int freq)
|
|||
if (!sband)
|
||||
continue;
|
||||
|
||||
for (ch = 0; ch < sband->n_channels; ch++, idx++)
|
||||
for (ch = 0; ch < sband->n_channels; ch++, idx++) {
|
||||
if (sband->channels[ch].center_freq <
|
||||
KHZ_TO_MHZ(ar->freq_range.start_freq) ||
|
||||
sband->channels[ch].center_freq >
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq))
|
||||
continue;
|
||||
|
||||
if (sband->channels[ch].center_freq == freq)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
|
@ -6677,7 +6684,8 @@ static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab,
|
|||
static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct ath12k_reg_info *reg_info;
|
||||
u8 pdev_idx;
|
||||
struct ath12k *ar = NULL;
|
||||
u8 pdev_idx = 255;
|
||||
int ret;
|
||||
|
||||
reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
|
||||
|
|
@ -6732,7 +6740,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
|
|||
kfree(reg_info);
|
||||
|
||||
if (ret == ATH12K_REG_STATUS_VALID)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
fallback:
|
||||
/* Fallback to older reg (by sending previous country setting
|
||||
|
|
@ -6746,6 +6754,18 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
|
|||
WARN_ON(1);
|
||||
|
||||
out:
|
||||
/* In some error cases, even a valid pdev_idx might not be available */
|
||||
if (pdev_idx != 255)
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
|
||||
/* During the boot-time update, 'ar' might not be allocated,
|
||||
* so the completion cannot be marked at that point.
|
||||
* This boot-time update is handled in ath12k_mac_hw_register()
|
||||
* before registering the hardware.
|
||||
*/
|
||||
if (ar)
|
||||
complete(&ar->regd_update_completed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3760,6 +3760,7 @@ struct wmi_vdev_install_key_arg {
|
|||
u32 key_idx;
|
||||
u32 key_flags;
|
||||
u32 key_cipher;
|
||||
u32 ieee80211_key_cipher;
|
||||
u32 key_len;
|
||||
u32 key_txmic_len;
|
||||
u32 key_rxmic_len;
|
||||
|
|
@ -3948,6 +3949,7 @@ struct wmi_stop_scan_cmd {
|
|||
} __packed;
|
||||
|
||||
struct ath12k_wmi_scan_chan_list_arg {
|
||||
struct list_head list;
|
||||
u32 pdev_id;
|
||||
u16 nallchans;
|
||||
struct ath12k_wmi_channel_arg channel[];
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "common.h"
|
||||
|
||||
#define FUDGE 2
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "common.h"
|
||||
|
||||
static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
/* We use the hw_value as an index into our private channel structure */
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "common.h"
|
||||
|
||||
#define CHAN2G(_freq, _idx) { \
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/relay.h>
|
||||
#include <linux/random.h>
|
||||
#include "ath9k.h"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
* Module for common driver code between ath9k and ath9k_htc
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "ath9k.h"
|
||||
#include "hw.h"
|
||||
#include "dynack.h"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user