mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 14:30:06 -04:00
Merge tag 'wireless-next-2025-06-25' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Johannes Berg says: ==================== The usual features/cleanups/etc., notably: - rtw88: IBSS mode for SDIO devices - rtw89: - BT coex for MLO/WiFi7 - work on station + P2P concurrency - ath: fix W=2 export.h warnings - ath12k: fix scan on multi-radio devices - cfg80211/mac80211: MLO statistics - mac80211: S1G aggregation - cfg80211/mac80211: per-radio RTS threshold * tag 'wireless-next-2025-06-25' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (171 commits) wifi: iwlwifi: dvm: fix potential overflow in rs_fill_link_cmd() iwlwifi: Add missing check for alloc_ordered_workqueue wifi: iwlwifi: Fix memory leak in iwl_mvm_init() iwlwifi: api: delete repeated words iwlwifi: remove unused no_sleep_autoadjust declaration iwlwifi: Fix comment typo iwlwifi: use DECLARE_BITMAP macro iwlwifi: fw: simplify the iwl_fw_dbg_collect_trig() wifi: iwlwifi: mld: ftm: fix switch end indentation MAINTAINERS: update iwlwifi git link wifi: iwlwifi: pcie: fix non-MSIX handshake register wifi: iwlwifi: mld: don't exit EMLSR when we shouldn't wifi: iwlwifi: move _iwl_trans_set_bits_mask utilities wifi: iwlwifi: mld: make iwl_mld_add_all_rekeys void wifi: iwlwifi: move iwl_trans_pcie_write_mem to iwl-trans.c wifi: iwlwifi: pcie: move iwl_trans_pcie_dump_regs() to utils.c wifi: iwlwifi: mld: advertise support for TTLM changes wifi: iwlwifi: mld: Block EMLSR when scanning on P2P Device wifi: iwlwifi: mld: use the correct struct size for tracing wifi: iwlwifi: support RZL platform device ID ... ==================== Link: https://patch.msgid.link/20250625120135.41933-55-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -12521,7 +12521,7 @@ M: Miri Korenblit <miriam.rachel.korenblit@intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/
|
||||
F: drivers/net/wireless/intel/iwlwifi/
|
||||
|
||||
INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
|
||||
|
||||
@@ -1293,7 +1293,7 @@ static void adm8211_set_bssid(struct ieee80211_hw *dev, const u8 *bssid)
|
||||
ADM8211_CSR_WRITE(ABDA1, reg);
|
||||
}
|
||||
|
||||
static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
|
||||
static int adm8211_config(struct ieee80211_hw *dev, int radio_idx, u32 changed)
|
||||
{
|
||||
struct adm8211_priv *priv = dev->priv;
|
||||
struct ieee80211_conf *conf = &dev->conf;
|
||||
|
||||
@@ -1083,7 +1083,8 @@ static void ar5523_stop(struct ieee80211_hw *hw, bool suspend)
|
||||
mutex_unlock(&ar->mutex);
|
||||
}
|
||||
|
||||
static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 value)
|
||||
{
|
||||
struct ar5523 *ar = hw->priv;
|
||||
int ret;
|
||||
@@ -1137,7 +1138,7 @@ static void ar5523_remove_interface(struct ieee80211_hw *hw,
|
||||
ar->vif = NULL;
|
||||
}
|
||||
|
||||
static int ar5523_hwconfig(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ar5523_hwconfig(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ar5523 *ar = hw->priv;
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -2606,7 +2608,7 @@ static void ath10k_core_set_coverage_class_work(struct work_struct *work)
|
||||
set_coverage_class_work);
|
||||
|
||||
if (ar->hw_params.hw_ops->set_coverage_class)
|
||||
ar->hw_params.hw_ops->set_coverage_class(ar, -1);
|
||||
ar->hw_params.hw_ops->set_coverage_class(ar, -1, -1);
|
||||
}
|
||||
|
||||
static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -590,6 +590,7 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
|
||||
* function monitors and modifies the corresponding MAC registers.
|
||||
*/
|
||||
static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar,
|
||||
int radio_idx,
|
||||
s16 value)
|
||||
{
|
||||
u32 slottime_reg;
|
||||
|
||||
@@ -646,7 +646,7 @@ struct htt_rx_ring_rx_desc_offsets;
|
||||
|
||||
/* Defines needed for Rx descriptor abstraction */
|
||||
struct ath10k_hw_ops {
|
||||
void (*set_coverage_class)(struct ath10k *ar, s16 value);
|
||||
void (*set_coverage_class)(struct ath10k *ar, int radio_idx, s16 value);
|
||||
int (*enable_pll_clk)(struct ath10k *ar);
|
||||
int (*tx_data_rssi_pad_bytes)(struct htt_resp *htt);
|
||||
int (*is_rssi_enable)(struct htt_resp *resp);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "mac.h"
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/etherdevice.h>
|
||||
@@ -4820,7 +4821,8 @@ void ath10k_halt(struct ath10k *ar)
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
static int ath10k_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
|
||||
@@ -5067,7 +5069,8 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
static int ath10k_set_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
int ret;
|
||||
@@ -5437,7 +5440,7 @@ static int ath10k_config_ps(struct ath10k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ath10k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
@@ -6336,7 +6339,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
|
||||
static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
|
||||
s16 value)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
|
||||
@@ -6347,7 +6351,7 @@ static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
|
||||
WARN_ON_ONCE(1);
|
||||
return;
|
||||
}
|
||||
ar->hw_params.hw_ops->set_coverage_class(ar, value);
|
||||
ar->hw_params.hw_ops->set_coverage_class(ar, -1, value);
|
||||
}
|
||||
|
||||
struct ath10k_mac_tdls_iter_data {
|
||||
@@ -8035,7 +8039,8 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw,
|
||||
* in ath10k, but device-specific in mac80211.
|
||||
*/
|
||||
|
||||
static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 value)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif;
|
||||
@@ -8058,7 +8063,8 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
/* Even though there's a WMI enum for fragmentation threshold no known
|
||||
* firmware actually implements it. Moreover it is not possible to rely
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1283,7 +1283,7 @@ static int ath11k_mac_config_ps(struct ath11k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ath11k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
@@ -7044,7 +7044,8 @@ static void ath11k_mac_op_configure_filter(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
|
||||
@@ -7058,7 +7059,8 @@ static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
static int ath11k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
int ret;
|
||||
@@ -8182,7 +8184,8 @@ ath11k_set_vdev_param_to_all_vifs(struct ath11k *ar, int param, u32 value)
|
||||
/* mac80211 stores device specific RTS/Fragmentation threshold value,
|
||||
* this is set interface specific to firmware from ath11k driver
|
||||
*/
|
||||
static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD;
|
||||
@@ -8190,7 +8193,8 @@ static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
return ath11k_set_vdev_param_to_all_vifs(ar, param_id, value);
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
/* Even though there's a WMI vdev param for fragmentation threshold no
|
||||
* known firmware actually implements it. Moreover it is not possible to
|
||||
|
||||
@@ -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;
|
||||
@@ -1392,7 +1395,7 @@ int ath12k_mac_vdev_stop(struct ath12k_link_vif *arvif)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -9354,7 +9551,8 @@ static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw,
|
||||
ar->filter_flags = *total_flags;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
int antennas_rx = 0, antennas_tx = 0;
|
||||
@@ -9374,7 +9572,8 @@ static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
struct ath12k *ar;
|
||||
@@ -9818,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,
|
||||
@@ -9853,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,
|
||||
@@ -10735,7 +10934,8 @@ ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value)
|
||||
/* mac80211 stores device specific RTS/Fragmentation threshold value,
|
||||
* this is set interface specific to firmware from ath12k driver
|
||||
*/
|
||||
static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
struct ath12k *ar;
|
||||
@@ -10760,7 +10960,8 @@ static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
/* Even though there's a WMI vdev param for fragmentation threshold no
|
||||
* known firmware actually implements it. Moreover it is not possible to
|
||||
@@ -11246,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);
|
||||
}
|
||||
|
||||
@@ -11757,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[])
|
||||
@@ -11767,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) +
|
||||
@@ -11788,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);
|
||||
@@ -11805,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) {
|
||||
@@ -11823,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);
|
||||
@@ -11836,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) {
|
||||
@@ -11854,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);
|
||||
@@ -11871,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12204,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);
|
||||
@@ -12462,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);
|
||||
@@ -12489,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,
|
||||
@@ -12561,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[];
|
||||
|
||||
@@ -192,7 +192,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
|
||||
* TODO: Phy disable/diversity etc
|
||||
*/
|
||||
static int
|
||||
ath5k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
ath5k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ath5k_hw *ah = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
@@ -686,6 +686,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
|
||||
* ath5k_set_coverage_class - Set IEEE 802.11 coverage class
|
||||
*
|
||||
* @hw: struct ieee80211_hw pointer
|
||||
* @radio_idx: Radio index
|
||||
* @coverage_class: IEEE 802.11 coverage class number
|
||||
*
|
||||
* Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
|
||||
@@ -693,7 +694,8 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
|
||||
* reset.
|
||||
*/
|
||||
static void
|
||||
ath5k_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
|
||||
ath5k_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
|
||||
s16 coverage_class)
|
||||
{
|
||||
struct ath5k_hw *ah = hw->priv;
|
||||
|
||||
@@ -704,7 +706,8 @@ ath5k_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
|
||||
|
||||
|
||||
static int
|
||||
ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
ath5k_set_antenna(struct ieee80211_hw *hw, int radio_idx, u32 tx_ant,
|
||||
u32 rx_ant)
|
||||
{
|
||||
struct ath5k_hw *ah = hw->priv;
|
||||
|
||||
@@ -721,7 +724,8 @@ ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
|
||||
|
||||
static int
|
||||
ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
ath5k_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath5k_hw *ah = hw->priv;
|
||||
|
||||
|
||||
@@ -1376,7 +1376,8 @@ void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
|
||||
u32 changed)
|
||||
{
|
||||
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
|
||||
struct ath6kl_vif *vif;
|
||||
@@ -1405,6 +1406,7 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
|
||||
static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
int radio_idx,
|
||||
enum nl80211_tx_power_setting type,
|
||||
int mbm)
|
||||
{
|
||||
@@ -1441,6 +1443,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
|
||||
|
||||
static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
int radio_idx,
|
||||
unsigned int link_id,
|
||||
int *dbm)
|
||||
{
|
||||
@@ -3242,7 +3245,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
wait, buf, len, no_cck);
|
||||
}
|
||||
|
||||
static int ath6kl_get_antenna(struct wiphy *wiphy,
|
||||
static int ath6kl_get_antenna(struct wiphy *wiphy, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath6kl *ar = wiphy_priv(wiphy);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1172,7 +1172,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ath9k_htc_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
@@ -1737,12 +1737,14 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw,
|
||||
int radio_idx, u32 value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
|
||||
int radio_idx,
|
||||
s16 coverage_class)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
@@ -1841,8 +1843,8 @@ struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
|
||||
}
|
||||
|
||||
|
||||
static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
|
||||
u32 *rx_ant)
|
||||
static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1484,7 +1484,7 @@ static void ath9k_disable_ps(struct ath_softc *sc)
|
||||
ath_dbg(common, PS, "PowerSave disabled\n");
|
||||
}
|
||||
|
||||
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int ath9k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -2114,6 +2114,7 @@ static void ath9k_enable_dynack(struct ath_softc *sc)
|
||||
}
|
||||
|
||||
static void ath9k_set_coverage_class(struct ieee80211_hw *hw,
|
||||
int radio_idx,
|
||||
s16 coverage_class)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
@@ -2338,7 +2339,8 @@ static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
static int ath9k_set_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -2367,7 +2369,8 @@ static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
static int ath9k_get_antenna(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
|
||||
@@ -890,7 +890,7 @@ static void carl9170_stat_work(struct work_struct *work)
|
||||
round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK)));
|
||||
}
|
||||
|
||||
static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int carl9170_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct ar9170 *ar = hw->priv;
|
||||
int err = 0;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
|
||||
return;
|
||||
}
|
||||
|
||||
static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int wcn36xx_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
int ret;
|
||||
@@ -965,7 +965,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
/* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */
|
||||
static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 value)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
|
||||
|
||||
@@ -1408,7 +1408,8 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
|
||||
u32 changed)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
@@ -2002,7 +2002,7 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at76_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int at76_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct at76_priv *priv = hw->priv;
|
||||
|
||||
|
||||
@@ -3975,7 +3975,7 @@ static void b43_set_retry_limits(struct b43_wldev *dev,
|
||||
long_retry);
|
||||
}
|
||||
|
||||
static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int b43_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct b43_wl *wl = hw_to_b43_wl(hw);
|
||||
struct b43_wldev *dev = wl->current_dev;
|
||||
@@ -5073,7 +5073,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
|
||||
* may hang the system.
|
||||
*/
|
||||
if (!err)
|
||||
b43_op_config(hw, ~0);
|
||||
b43_op_config(hw, -1, ~0);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -5248,7 +5248,7 @@ static void b43_chip_reset(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* reload configuration */
|
||||
b43_op_config(wl->hw, ~0);
|
||||
b43_op_config(wl->hw, -1, ~0);
|
||||
if (wl->vif)
|
||||
b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
|
||||
|
||||
|
||||
@@ -2662,7 +2662,7 @@ static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
|
||||
b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
|
||||
}
|
||||
|
||||
static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
|
||||
static int b43legacy_op_dev_config(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 changed)
|
||||
{
|
||||
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
|
||||
|
||||
@@ -1043,6 +1043,21 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
|
||||
}
|
||||
}
|
||||
|
||||
bool brcmf_is_apmode_operating(struct wiphy *wiphy)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
bool ret = false;
|
||||
|
||||
list_for_each_entry(vif, &cfg->vif_list, list) {
|
||||
if (brcmf_is_apmode(vif) &&
|
||||
test_bit(BRCMF_VIF_STATUS_AP_CREATED, &vif->sme_state))
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le,
|
||||
struct brcmf_scan_params_le *params_le)
|
||||
{
|
||||
@@ -1622,7 +1637,8 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
|
||||
u32 changed)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct net_device *ndev = cfg_to_ndev(cfg);
|
||||
@@ -2630,7 +2646,8 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
enum nl80211_tx_power_setting type, s32 mbm)
|
||||
int radio_idx, enum nl80211_tx_power_setting type,
|
||||
s32 mbm)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct net_device *ndev = cfg_to_ndev(cfg);
|
||||
@@ -2681,7 +2698,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
unsigned int link_id, s32 *dbm)
|
||||
int radio_idx, unsigned int link_id, s32 *dbm)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
|
||||
@@ -5416,8 +5433,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||
bphy_err(drvr, "bss_enable config failed %d\n", err);
|
||||
}
|
||||
brcmf_set_mpc(ifp, 1);
|
||||
brcmf_configure_arp_nd_offload(ifp, true);
|
||||
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
brcmf_configure_arp_nd_offload(ifp, true);
|
||||
brcmf_net_setcarrier(ifp, false);
|
||||
|
||||
return err;
|
||||
|
||||
@@ -487,6 +487,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
|
||||
struct brcmf_if *ifp, bool aborted,
|
||||
bool fw_abort);
|
||||
void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
|
||||
bool brcmf_is_apmode_operating(struct wiphy *wiphy);
|
||||
void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
|
||||
void brcmf_cfg80211_free_netdev(struct net_device *ndev);
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
|
||||
s32 err;
|
||||
u32 mode;
|
||||
|
||||
if (enable && brcmf_is_apmode_operating(ifp->drvr->wiphy)) {
|
||||
brcmf_dbg(TRACE, "Skip ARP/ND offload enable when soft AP is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
|
||||
else
|
||||
|
||||
@@ -654,17 +654,19 @@ brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
|
||||
static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
struct brcmf_core *core;
|
||||
u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD,
|
||||
BRCMF_PCIE_CFGREG_PM_CSR,
|
||||
BRCMF_PCIE_CFGREG_MSI_CAP,
|
||||
BRCMF_PCIE_CFGREG_MSI_ADDR_L,
|
||||
BRCMF_PCIE_CFGREG_MSI_ADDR_H,
|
||||
BRCMF_PCIE_CFGREG_MSI_DATA,
|
||||
BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2,
|
||||
BRCMF_PCIE_CFGREG_RBAR_CTRL,
|
||||
BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1,
|
||||
BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG,
|
||||
BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG };
|
||||
static const u16 cfg_offset[] = {
|
||||
BRCMF_PCIE_CFGREG_STATUS_CMD,
|
||||
BRCMF_PCIE_CFGREG_PM_CSR,
|
||||
BRCMF_PCIE_CFGREG_MSI_CAP,
|
||||
BRCMF_PCIE_CFGREG_MSI_ADDR_L,
|
||||
BRCMF_PCIE_CFGREG_MSI_ADDR_H,
|
||||
BRCMF_PCIE_CFGREG_MSI_DATA,
|
||||
BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2,
|
||||
BRCMF_PCIE_CFGREG_RBAR_CTRL,
|
||||
BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1,
|
||||
BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG,
|
||||
BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG
|
||||
};
|
||||
u32 i;
|
||||
u32 val;
|
||||
u32 lsc;
|
||||
|
||||
@@ -525,7 +525,8 @@ brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
spin_unlock_bh(&wl->lock);
|
||||
}
|
||||
|
||||
static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
|
||||
static int brcms_ops_config(struct ieee80211_hw *hw, int radio_idx,
|
||||
u32 changed)
|
||||
{
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
struct brcms_info *wl = hw->priv;
|
||||
|
||||
@@ -83,7 +83,7 @@ void libipw_networks_age(struct libipw_device *ieee,
|
||||
{
|
||||
struct libipw_network *network = NULL;
|
||||
unsigned long flags;
|
||||
unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
|
||||
unsigned long age_jiffies = secs_to_jiffies(age_secs);
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
list_for_each_entry(network, &ieee->network_list, list) {
|
||||
|
||||
@@ -1382,7 +1382,7 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
* we get a thermal update even if the uCode doesn't give us one
|
||||
*/
|
||||
mod_timer(&il->stats_periodic,
|
||||
jiffies + msecs_to_jiffies(recalib_seconds * 1000));
|
||||
jiffies + secs_to_jiffies(recalib_seconds));
|
||||
|
||||
if (unlikely(!test_bit(S_SCANNING, &il->status)) &&
|
||||
(pkt->hdr.cmd == N_STATS)) {
|
||||
@@ -1575,8 +1575,11 @@ il4965_tx_cmd_build_rate(struct il_priv *il,
|
||||
|| rate_idx > RATE_COUNT_LEGACY)
|
||||
rate_idx = rate_lowest_index(&il->bands[info->band], sta);
|
||||
/* For 5 GHZ band, remap mac80211 rate indices into driver indices */
|
||||
if (info->band == NL80211_BAND_5GHZ)
|
||||
if (info->band == NL80211_BAND_5GHZ) {
|
||||
rate_idx += IL_FIRST_OFDM_RATE;
|
||||
if (rate_idx > IL_LAST_OFDM_RATE)
|
||||
rate_idx = IL_LAST_OFDM_RATE;
|
||||
}
|
||||
/* Get PLCP rate for tx_cmd->rate_n_flags */
|
||||
rate_plcp = il_rates[rate_idx].plcp;
|
||||
/* Zero out flags for this packet */
|
||||
|
||||
@@ -4990,7 +4990,7 @@ il_update_qos(struct il_priv *il)
|
||||
* il_mac_config - mac80211 config callback
|
||||
*/
|
||||
int
|
||||
il_mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||
il_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct il_priv *il = hw->priv;
|
||||
const struct il_channel_info *ch_info;
|
||||
|
||||
@@ -1956,7 +1956,7 @@ il_get_hw_mode(struct il_priv *il, enum nl80211_band band)
|
||||
}
|
||||
|
||||
/* mac80211 handlers */
|
||||
int il_mac_config(struct ieee80211_hw *hw, u32 changed);
|
||||
int il_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed);
|
||||
void il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
void il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf, u64 changes);
|
||||
|
||||
@@ -97,6 +97,7 @@ config IWLWIFI_OPMODE_MODULAR
|
||||
default y if IWLDVM=m
|
||||
default y if IWLMVM=m
|
||||
default y if IWLMLD=m
|
||||
default y if IWLWIFI_KUNIT_TESTS=m
|
||||
|
||||
comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM or IWLMLD"
|
||||
depends on IWLDVM=n && IWLMVM=n && IWLMLD=n
|
||||
|
||||
@@ -7,9 +7,11 @@ iwlwifi-objs += iwl-debug.o
|
||||
iwlwifi-objs += iwl-nvm-utils.o
|
||||
iwlwifi-objs += iwl-utils.o
|
||||
iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
|
||||
iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
|
||||
iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o
|
||||
iwlwifi-objs += pcie/trans-gen2.o pcie/tx-gen2.o
|
||||
|
||||
# Bus
|
||||
iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o pcie/drv.o pcie/utils.o
|
||||
iwlwifi-objs += pcie/gen1_2/rx.o pcie/gen1_2/tx.o pcie/gen1_2/trans.o
|
||||
iwlwifi-objs += pcie/gen1_2/trans-gen2.o pcie/gen1_2/tx-gen2.o
|
||||
|
||||
CFLAGS_pcie/drv.o += -Wno-override-init
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define IWL_BZ_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MIN 93
|
||||
#define IWL_BZ_UCODE_API_MIN 94
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_BZ_SMEM_OFFSET 0x400000
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define IWL_DR_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_DR_UCODE_API_MIN 97
|
||||
#define IWL_DR_UCODE_API_MIN 98
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_DR_SMEM_OFFSET 0x400000
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define IWL_SC_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MIN 97
|
||||
#define IWL_SC_UCODE_API_MIN 98
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_SC_NVM_VERSION 0x0a1d
|
||||
|
||||
@@ -88,7 +88,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
|
||||
int iwlagn_set_pan_params(struct iwl_priv *priv);
|
||||
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
|
||||
int iwlagn_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed);
|
||||
void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
@@ -397,6 +397,8 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
|
||||
* returns a (newly allocated) struct containing all the
|
||||
* relevant values for driver use. The struct must be freed
|
||||
* later with iwl_free_nvm_data().
|
||||
*
|
||||
* Return: the parsed NVM data
|
||||
*/
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2023-2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2023-2025 Intel Corporation
|
||||
*/
|
||||
/*
|
||||
* Please use this file (commands.h) only for uCode API definitions.
|
||||
@@ -614,7 +614,7 @@ struct iwl_rxon_time_cmd {
|
||||
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
|
||||
*/
|
||||
/**
|
||||
* struct iwl5000_channel_switch_cmd
|
||||
* struct iwl5000_channel_switch_cmd - channel switch command (5000 series)
|
||||
* @band: 0- 5.2GHz, 1- 2.4GHz
|
||||
* @expect_beacon: 0- resume transmits after channel switch
|
||||
* 1- wait for beacon to resume transmits
|
||||
@@ -635,7 +635,7 @@ struct iwl5000_channel_switch_cmd {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl6000_channel_switch_cmd
|
||||
* struct iwl6000_channel_switch_cmd - channel switch command (6000 series)
|
||||
* @band: 0- 5.2GHz, 1- 2.4GHz
|
||||
* @expect_beacon: 0- resume transmits after channel switch
|
||||
* 1- wait for beacon to resume transmits
|
||||
@@ -791,7 +791,7 @@ struct iwl_keyinfo {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct sta_id_modify
|
||||
* struct sta_id_modify - station modify command
|
||||
* @addr: station's MAC address
|
||||
* @reserved1: reserved for alignment
|
||||
* @sta_id: index of station in uCode's station table
|
||||
@@ -2026,7 +2026,7 @@ struct iwl_spectrum_notification {
|
||||
u8 channel;
|
||||
u8 type; /* see enum iwl_measurement_type */
|
||||
u8 reserved1;
|
||||
/* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
|
||||
/* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only
|
||||
* valid if applicable for measurement type requested. */
|
||||
__le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */
|
||||
__le32 cca_cck; /* cca fraction time in 44Mhz clock periods */
|
||||
@@ -2992,7 +2992,7 @@ struct iwl_missed_beacon_notif {
|
||||
#define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1)
|
||||
|
||||
/**
|
||||
* struct iwl_sensitivity_cmd
|
||||
* struct iwl_sensitivity_cmd - sensitivity configuration command
|
||||
* @control: (1) updates working table, (0) updates default table
|
||||
* @table: energy threshold values, use HD_* as index into table
|
||||
*
|
||||
@@ -3848,7 +3848,7 @@ struct iwlagn_wowlan_status {
|
||||
#define IWL_MIN_SLOT_TIME 20
|
||||
|
||||
/**
|
||||
* struct iwl_wipan_slot
|
||||
* struct iwl_wipan_slot - WiPAN slot configuration
|
||||
* @width: Time in TU
|
||||
* @type:
|
||||
* 0 - BSS
|
||||
@@ -3868,7 +3868,7 @@ struct iwl_wipan_slot {
|
||||
#define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5)
|
||||
|
||||
/**
|
||||
* struct iwl_wipan_params_cmd
|
||||
* struct iwl_wipan_params_cmd - WiPAN parameters
|
||||
* @flags:
|
||||
* bit0: reserved
|
||||
* bit1: CP leave channel with CTS
|
||||
|
||||
@@ -104,7 +104,7 @@ struct iwl_qos_info {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_agg_state
|
||||
* enum iwl_agg_state - aggregation state
|
||||
*
|
||||
* The state machine of the BA agreement establishment / tear down.
|
||||
* These states relate to a specific RA / TID.
|
||||
@@ -519,7 +519,7 @@ enum iwl_scan_type {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_hw_params
|
||||
* struct iwl_hw_params - HW parameters
|
||||
*
|
||||
* Holds the module parameters
|
||||
*
|
||||
|
||||
@@ -55,6 +55,7 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
|
||||
* iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
|
||||
* @priv: pointer to iwl_priv data structure
|
||||
* @tsf_bits: number of bits need to shift for masking)
|
||||
* Return: low 32 bits of beacon time mask
|
||||
*/
|
||||
static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
|
||||
u16 tsf_bits)
|
||||
@@ -66,6 +67,7 @@ static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
|
||||
* iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
|
||||
* @priv: pointer to iwl_priv data structure
|
||||
* @tsf_bits: number of bits need to shift for masking)
|
||||
* Return: high 32 bits of beacon time mask
|
||||
*/
|
||||
static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
|
||||
u16 tsf_bits)
|
||||
|
||||
@@ -586,7 +586,7 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
|
||||
return false;
|
||||
}
|
||||
|
||||
ave_rssi = ieee80211_ave_rssi(ctx->vif);
|
||||
ave_rssi = ieee80211_ave_rssi(ctx->vif, -1);
|
||||
if (!ave_rssi) {
|
||||
/* no rssi data, no changes to reduce tx power */
|
||||
IWL_DEBUG_COEX(priv, "no rssi data available\n");
|
||||
|
||||
@@ -1049,9 +1049,11 @@ static void iwl_bg_restart(struct work_struct *data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
static int iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
{
|
||||
priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0);
|
||||
if (!priv->workqueue)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&priv->restart, iwl_bg_restart);
|
||||
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
|
||||
@@ -1068,6 +1070,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
timer_setup(&priv->statistics_periodic, iwl_bg_statistics_periodic, 0);
|
||||
|
||||
timer_setup(&priv->ucode_trace, iwl_bg_ucode_trace, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwl_cancel_deferred_work(struct iwl_priv *priv)
|
||||
@@ -1463,7 +1467,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
/********************
|
||||
* 6. Setup services
|
||||
********************/
|
||||
iwl_setup_deferred_work(priv);
|
||||
if (iwl_setup_deferred_work(priv))
|
||||
goto out_uninit_drv;
|
||||
|
||||
iwl_setup_rx_handlers(priv);
|
||||
|
||||
iwl_power_initialize(priv);
|
||||
@@ -1502,6 +1508,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
iwl_cancel_deferred_work(priv);
|
||||
destroy_workqueue(priv->workqueue);
|
||||
priv->workqueue = NULL;
|
||||
out_uninit_drv:
|
||||
iwl_uninit_drv(priv);
|
||||
out_free_eeprom_blob:
|
||||
kfree(priv->eeprom_blob);
|
||||
|
||||
@@ -23,6 +23,4 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
|
||||
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
|
||||
void iwl_power_initialize(struct iwl_priv *priv);
|
||||
|
||||
extern bool no_sleep_autoadjust;
|
||||
|
||||
#endif /* __iwl_power_setting_h__ */
|
||||
|
||||
@@ -2899,7 +2899,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
|
||||
/* Repeat initial/next rate.
|
||||
* For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
|
||||
* For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
|
||||
while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
|
||||
while (repeat_rate > 0 && index < (LINK_QUAL_MAX_RETRY_NUM - 1)) {
|
||||
if (is_legacy(tbl_type.lq_type)) {
|
||||
if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
|
||||
ant_toggle_cnt++;
|
||||
|
||||
@@ -429,7 +429,7 @@ static void iwlagn_rx_statistics(struct iwl_priv *priv,
|
||||
* thermal update even if the uCode doesn't give
|
||||
* us one */
|
||||
mod_timer(&priv->statistics_periodic, jiffies +
|
||||
msecs_to_jiffies(reg_recalib_period * 1000));
|
||||
secs_to_jiffies(reg_recalib_period));
|
||||
|
||||
if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
|
||||
(pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
|
||||
|
||||
@@ -1149,7 +1149,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
|
||||
}
|
||||
}
|
||||
|
||||
int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||
int iwlagn_mac_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
struct iwl_rxon_context *ctx;
|
||||
|
||||
@@ -232,6 +232,8 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
|
||||
* that may be %NULL, for example during TX or key setup. In
|
||||
* that case, we need to use the broadcast station, so this
|
||||
* inline wraps that pattern.
|
||||
*
|
||||
* Return: station ID for mac80211 station (or broadcast if %NULL)
|
||||
*/
|
||||
static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context,
|
||||
struct ieee80211_sta *sta)
|
||||
|
||||
@@ -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) 2015-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@@ -19,9 +19,11 @@ enum iwl_d0i3_flags {
|
||||
/**
|
||||
* enum iwl_d3_wakeup_flags - D3 manager wakeup flags
|
||||
* @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert
|
||||
* @IWL_WAKEUP_D3_HOST_TIMER: wake up on host timer expiry
|
||||
*/
|
||||
enum iwl_d3_wakeup_flags {
|
||||
IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0),
|
||||
IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0),
|
||||
IWL_WAKEUP_D3_HOST_TIMER = BIT(1),
|
||||
}; /* D3_MANAGER_WAKEUP_CONFIG_API_E_VER_3 */
|
||||
|
||||
/**
|
||||
|
||||
@@ -864,7 +864,7 @@ struct iwl_extended_beacon_notif {
|
||||
|
||||
/**
|
||||
* enum iwl_dump_control - dump (flush) control flags
|
||||
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
|
||||
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the FIFO is empty
|
||||
* and the TFD queues are empty.
|
||||
*/
|
||||
enum iwl_dump_control {
|
||||
|
||||
@@ -1106,6 +1106,7 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
|
||||
u32 prph_val;
|
||||
u32 dphy_state;
|
||||
u32 dphy_addr;
|
||||
u32 prph_stts;
|
||||
int i;
|
||||
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
@@ -1133,6 +1134,21 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
iwl_write_prph_no_grab(fwrt->trans, indirect_wr_addr,
|
||||
WMAL_INDRCT_CMD(addr + i));
|
||||
|
||||
if (fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF1 &&
|
||||
fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_JF2 &&
|
||||
fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR1 &&
|
||||
fwrt->trans->info.hw_rf_id != IWL_CFG_RF_TYPE_HR2) {
|
||||
udelay(2);
|
||||
prph_stts = iwl_read_prph_no_grab(fwrt->trans,
|
||||
WMAL_MRSPF_STTS);
|
||||
|
||||
/* Abort dump if status is 0xA5A5A5A2 or FIFO1 empty */
|
||||
if (prph_stts == WMAL_TIMEOUT_VAL ||
|
||||
!WMAL_MRSPF_STTS_IS_FIFO1_NOT_EMPTY(prph_stts))
|
||||
break;
|
||||
}
|
||||
|
||||
prph_val = iwl_read_prph_no_grab(fwrt->trans,
|
||||
indirect_rd_addr);
|
||||
*val++ = cpu_to_le32(prph_val);
|
||||
@@ -3008,6 +3024,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
unsigned int delay = 0;
|
||||
bool monitor_only = false;
|
||||
int ret;
|
||||
|
||||
if (trigger) {
|
||||
u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
|
||||
@@ -3038,7 +3055,11 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
desc->trig_desc.type = cpu_to_le32(trig);
|
||||
memcpy(desc->trig_desc.data, str, len);
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
|
||||
ret = iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
|
||||
if (ret)
|
||||
kfree(desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
|
||||
|
||||
@@ -3046,7 +3067,7 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
int ret, len = 0;
|
||||
int len = 0;
|
||||
char buf[64];
|
||||
|
||||
if (iwl_trans_dbg_ini_valid(fwrt->trans))
|
||||
@@ -3068,13 +3089,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
len = strlen(buf) + 1;
|
||||
}
|
||||
|
||||
ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_trig);
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay)
|
||||
|
||||
iwl_fw_cancel_timestamp(fwrt);
|
||||
|
||||
fwrt->timestamp.delay = msecs_to_jiffies(delay * 1000);
|
||||
fwrt->timestamp.delay = secs_to_jiffies(delay);
|
||||
|
||||
schedule_delayed_work(&fwrt->timestamp.wk,
|
||||
round_jiffies_relative(fwrt->timestamp.delay));
|
||||
|
||||
@@ -53,8 +53,8 @@ struct iwl_ucode_capabilities {
|
||||
u32 num_stations;
|
||||
u32 num_links;
|
||||
u32 num_beacons;
|
||||
unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
|
||||
unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
|
||||
DECLARE_BITMAP(_api, NUM_IWL_UCODE_TLV_API);
|
||||
DECLARE_BITMAP(_capa, NUM_IWL_UCODE_TLV_CAPA);
|
||||
|
||||
const struct iwl_fw_cmd_version *cmd_versions;
|
||||
u32 n_cmd_versions;
|
||||
|
||||
@@ -332,7 +332,7 @@ iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans,
|
||||
ret = iwl_trans_load_pnvm(trans, pnvm_data, capa);
|
||||
if (ret)
|
||||
goto free;
|
||||
IWL_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version);
|
||||
IWL_DEBUG_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version);
|
||||
|
||||
set:
|
||||
iwl_trans_set_pnvm(trans, capa);
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
#define CSR_IPC_STATE_RESET_SW_READY 1
|
||||
#define CSR_IPC_STATE_RESET_TOP_READY 2
|
||||
#define CSR_IPC_STATE_RESET_TOP_FOLLOWER 3
|
||||
#define CSR_IPC_STATE_TOP_RESET_REQ BIT(6)
|
||||
|
||||
#define CSR_IPC_SLEEP_CONTROL (CSR_BASE + 0x114)
|
||||
#define CSR_IPC_SLEEP_CONTROL_SUSPEND 0x3
|
||||
|
||||
@@ -1276,8 +1276,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
if (tlv_len != sizeof(*fseq_ver))
|
||||
goto invalid_tlv_len;
|
||||
IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n",
|
||||
fseq_ver->version);
|
||||
IWL_DEBUG_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n",
|
||||
fseq_ver->version);
|
||||
}
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_NUM_STATIONS:
|
||||
|
||||
@@ -160,23 +160,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
|
||||
* @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
|
||||
* @NVM_CHANNEL_VLP: client support connection to UHB VLP AP
|
||||
* @NVM_CHANNEL_AFC: client support connection to UHB AFC AP
|
||||
* @NVM_CHANNEL_VLP_AP_NOT_ALLOWED: UHB VLP AP not allowed,
|
||||
* Valid only when %NVM_CHANNEL_VLP is enabled.
|
||||
*/
|
||||
enum iwl_nvm_channel_flags {
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_UNIFORM = BIT(7),
|
||||
NVM_CHANNEL_20MHZ = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
NVM_CHANNEL_VLP = BIT(13),
|
||||
NVM_CHANNEL_AFC = BIT(14),
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_UNIFORM = BIT(7),
|
||||
NVM_CHANNEL_20MHZ = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
NVM_CHANNEL_VLP = BIT(13),
|
||||
NVM_CHANNEL_AFC = BIT(14),
|
||||
NVM_CHANNEL_VLP_AP_NOT_ALLOWED = BIT(15),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1044,6 +1047,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
|
||||
case IWL_CFG_RF_TYPE_GF:
|
||||
case IWL_CFG_RF_TYPE_FM:
|
||||
case IWL_CFG_RF_TYPE_WH:
|
||||
case IWL_CFG_RF_TYPE_PE:
|
||||
iftype_data->he_cap.he_cap_elem.phy_cap_info[9] |=
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
|
||||
if (!is_ap)
|
||||
@@ -1629,8 +1633,7 @@ IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
|
||||
|
||||
static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
int ch_idx, u16 nvm_flags,
|
||||
struct iwl_reg_capa reg_capa,
|
||||
const struct iwl_rf_cfg *cfg)
|
||||
struct iwl_reg_capa reg_capa)
|
||||
{
|
||||
u32 flags = NL80211_RRF_NO_HT40;
|
||||
|
||||
@@ -1685,10 +1688,12 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
}
|
||||
|
||||
/* Set the AP type for the UHB case. */
|
||||
if (nvm_flags & NVM_CHANNEL_VLP)
|
||||
flags |= NL80211_RRF_ALLOW_6GHZ_VLP_AP;
|
||||
else
|
||||
if (nvm_flags & NVM_CHANNEL_VLP) {
|
||||
if (!(nvm_flags & NVM_CHANNEL_VLP_AP_NOT_ALLOWED))
|
||||
flags |= NL80211_RRF_ALLOW_6GHZ_VLP_AP;
|
||||
} else {
|
||||
flags |= NL80211_RRF_NO_6GHZ_VLP_CLIENT;
|
||||
}
|
||||
|
||||
if (!(nvm_flags & NVM_CHANNEL_AFC))
|
||||
flags |= NL80211_RRF_NO_6GHZ_AFC_CLIENT;
|
||||
@@ -1815,8 +1820,8 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
|
||||
}
|
||||
|
||||
reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
|
||||
ch_flags, reg_capa,
|
||||
cfg);
|
||||
ch_flags,
|
||||
reg_capa);
|
||||
|
||||
/* we can't continue the same rule */
|
||||
if (ch_idx == 0 || prev_reg_rule_flags != reg_rule_flags ||
|
||||
|
||||
@@ -147,6 +147,8 @@ struct iwl_fw_error_dump_mode {
|
||||
* Op_mode needs to reset its internal state because the device did not
|
||||
* survive the system state transition. The firmware is no longer running,
|
||||
* etc...
|
||||
* @dump: Op_mode needs to collect the firmware dump upon this handler
|
||||
* being called.
|
||||
*/
|
||||
struct iwl_op_mode_ops {
|
||||
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
||||
@@ -174,6 +176,7 @@ struct iwl_op_mode_ops {
|
||||
enum iwl_fw_ini_time_point tp_id,
|
||||
union iwl_dbg_tlv_tp_data *tp_data);
|
||||
void (*device_powered_off)(struct iwl_op_mode *op_mode);
|
||||
void (*dump)(struct iwl_op_mode *op_mode);
|
||||
};
|
||||
|
||||
int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops);
|
||||
@@ -286,4 +289,11 @@ static inline void iwl_op_mode_device_powered_off(struct iwl_op_mode *op_mode)
|
||||
op_mode->ops->device_powered_off(op_mode);
|
||||
}
|
||||
|
||||
static inline void iwl_op_mode_dump(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
if (!op_mode || !op_mode->ops || !op_mode->ops->dump)
|
||||
return;
|
||||
op_mode->ops->dump(op_mode);
|
||||
}
|
||||
|
||||
#endif /* __iwl_op_mode_h__ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016 Intel Deutschland GmbH
|
||||
*/
|
||||
@@ -514,6 +514,14 @@ enum {
|
||||
#define WMAL_INDRCT_CMD(addr) \
|
||||
((WMAL_CMD_READ_BURST_ACCESS << WMAL_INDRCT_RD_CMD1_OPMOD_POS) | \
|
||||
((addr) & WMAL_INDRCT_RD_CMD1_BYTE_ADDRESS_MSK))
|
||||
#define WMAL_MRSPF_STTS 0xADFC24
|
||||
#define WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS 15
|
||||
#define WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_MSK 0x8000
|
||||
#define WMAL_TIMEOUT_VAL 0xA5A5A5A2
|
||||
#define WMAL_MRSPF_STTS_IS_FIFO1_NOT_EMPTY(val) \
|
||||
(((val) >> (WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS)) & \
|
||||
((WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_MSK) >> \
|
||||
(WMAL_MRSPF_STTS_FIFO1_NOT_EMPTY_POS)))
|
||||
|
||||
#define WFPM_LMAC1_PS_CTL_RW 0xA03380
|
||||
#define WFPM_LMAC2_PS_CTL_RW 0xA033C0
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include "iwl-fh.h"
|
||||
#include <linux/dmapool.h>
|
||||
#include "fw/api/commands.h"
|
||||
#include "pcie/internal.h"
|
||||
#include "iwl-context-info-v2.h"
|
||||
#include "pcie/gen1_2/internal.h"
|
||||
#include "pcie/iwl-context-info-v2.h"
|
||||
|
||||
struct iwl_trans_dev_restart_data {
|
||||
struct list_head list;
|
||||
@@ -497,7 +497,19 @@ IWL_EXPORT_SYMBOL(iwl_trans_read_mem);
|
||||
int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
|
||||
const void *buf, int dwords)
|
||||
{
|
||||
return iwl_trans_pcie_write_mem(trans, addr, buf, dwords);
|
||||
int offs, ret = 0;
|
||||
const u32 *vals = buf;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans)) {
|
||||
iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
|
||||
for (offs = 0; offs < dwords; offs++)
|
||||
iwl_write32(trans, HBUS_TARG_MEM_WDAT,
|
||||
vals ? vals[offs] : 0);
|
||||
iwl_trans_release_nic_access(trans);
|
||||
} else {
|
||||
ret = -EBUSY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_write_mem);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*/
|
||||
#include <net/gso.h>
|
||||
#include <linux/ieee80211.h>
|
||||
@@ -82,3 +82,114 @@ int iwl_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_tx_tso_segment);
|
||||
#endif /* CONFIG_INET */
|
||||
|
||||
static u32 iwl_div_by_db(u32 value, u8 db)
|
||||
{
|
||||
/*
|
||||
* 2^32 * 10**(i / 10) for i = [1, 10], skipping 0 and simply stopping
|
||||
* at 10 dB and looping instead of using a much larger table.
|
||||
*
|
||||
* Using 64 bit math is overkill, but means the helper does not require
|
||||
* a limit on the input range.
|
||||
*/
|
||||
static const u32 db_to_val[] = {
|
||||
0xcb59185e, 0xa1866ba8, 0x804dce7a, 0x65ea59fe, 0x50f44d89,
|
||||
0x404de61f, 0x331426af, 0x2892c18b, 0x203a7e5b, 0x1999999a,
|
||||
};
|
||||
|
||||
while (value && db > 0) {
|
||||
u8 change = min_t(u8, db, ARRAY_SIZE(db_to_val));
|
||||
|
||||
value = (((u64)value) * db_to_val[change - 1]) >> 32;
|
||||
|
||||
db -= change;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
s8 iwl_average_neg_dbm(const u8 *neg_dbm_values, u8 len)
|
||||
{
|
||||
int average_magnitude;
|
||||
u32 average_factor;
|
||||
int sum_magnitude = -128;
|
||||
u32 sum_factor = 0;
|
||||
int i, count = 0;
|
||||
|
||||
/*
|
||||
* To properly average the decibel values (signal values given in dBm)
|
||||
* we need to do the math in linear space. Doing a linear average of
|
||||
* dB (dBm) values is a bit annoying though due to the large range of
|
||||
* at least -10 to -110 dBm that will not fit into a 32 bit integer.
|
||||
*
|
||||
* A 64 bit integer should be sufficient, but then we still have the
|
||||
* problem that there are no directly usable utility functions
|
||||
* available.
|
||||
*
|
||||
* So, lets not deal with that and instead do much of the calculation
|
||||
* with a 16.16 fixed point integer along with a base in dBm. 16.16 bit
|
||||
* gives us plenty of head-room for adding up a few values and even
|
||||
* doing some math on it. And the tail should be accurate enough too
|
||||
* (1/2^16 is somewhere around -48 dB, so effectively zero).
|
||||
*
|
||||
* i.e. the real value of sum is:
|
||||
* sum = sum_factor / 2^16 * 10^(sum_magnitude / 10) mW
|
||||
*
|
||||
* However, that does mean we need to be able to bring two values to
|
||||
* a common base, so we need a helper for that.
|
||||
*
|
||||
* Note that this function takes an input with unsigned negative dBm
|
||||
* values but returns a signed dBm (i.e. a negative value).
|
||||
*/
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int val_magnitude;
|
||||
u32 val_factor;
|
||||
|
||||
/* Assume invalid */
|
||||
if (neg_dbm_values[i] == 0xff)
|
||||
continue;
|
||||
|
||||
val_factor = 0x10000;
|
||||
val_magnitude = -neg_dbm_values[i];
|
||||
|
||||
if (val_magnitude <= sum_magnitude) {
|
||||
u8 div_db = sum_magnitude - val_magnitude;
|
||||
|
||||
val_factor = iwl_div_by_db(val_factor, div_db);
|
||||
val_magnitude = sum_magnitude;
|
||||
} else {
|
||||
u8 div_db = val_magnitude - sum_magnitude;
|
||||
|
||||
sum_factor = iwl_div_by_db(sum_factor, div_db);
|
||||
sum_magnitude = val_magnitude;
|
||||
}
|
||||
|
||||
sum_factor += val_factor;
|
||||
count++;
|
||||
}
|
||||
|
||||
/* No valid noise measurement, return a very high noise level */
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
average_magnitude = sum_magnitude;
|
||||
average_factor = sum_factor / count;
|
||||
|
||||
/*
|
||||
* average_factor will be a number smaller than 1.0 (0x10000) at this
|
||||
* point. What we need to do now is to adjust average_magnitude so that
|
||||
* average_factor is between -0.5 dB and 0.5 dB.
|
||||
*
|
||||
* Just do -1 dB steps and find the point where
|
||||
* -0.5 dB * -i dB = 0x10000 * 10^(-0.5/10) / i dB
|
||||
* = div_by_db(0xe429, i)
|
||||
* is smaller than average_factor.
|
||||
*/
|
||||
for (i = 0; average_factor < iwl_div_by_db(0xe429, i); i++) {
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
return clamp(average_magnitude - i, -128, 0);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_average_neg_dbm);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_utils_h__
|
||||
#define __iwl_utils_h__
|
||||
@@ -53,4 +53,6 @@ u32 iwl_find_ie_offset(u8 *beacon, u8 eid, u32 frame_size)
|
||||
return ie - beacon;
|
||||
}
|
||||
|
||||
s8 iwl_average_neg_dbm(const u8 *neg_dbm_values, u8 len);
|
||||
|
||||
#endif /* __iwl_utils_h__ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021 - 2022 Intel Corporation
|
||||
* Copyright (C) 2021 - 2022, 2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __sap_h__
|
||||
@@ -340,12 +340,12 @@ enum iwl_sap_wifi_auth_type {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_sap_wifi_cipher_alg
|
||||
* @SAP_WIFI_CIPHER_ALG_NONE: TBD
|
||||
* @SAP_WIFI_CIPHER_ALG_TKIP: TBD
|
||||
* @SAP_WIFI_CIPHER_ALG_CCMP: TBD
|
||||
* @SAP_WIFI_CIPHER_ALG_GCMP: TBD
|
||||
* @SAP_WIFI_CIPHER_ALG_GCMP_256: TBD
|
||||
* enum iwl_sap_wifi_cipher_alg - MEI WiFi cipher algorithm IDs
|
||||
* @SAP_WIFI_CIPHER_ALG_NONE: No encryption
|
||||
* @SAP_WIFI_CIPHER_ALG_TKIP: TKIPO
|
||||
* @SAP_WIFI_CIPHER_ALG_CCMP: CCMP
|
||||
* @SAP_WIFI_CIPHER_ALG_GCMP: GCMP-128
|
||||
* @SAP_WIFI_CIPHER_ALG_GCMP_256: GCMP-256
|
||||
*/
|
||||
enum iwl_sap_wifi_cipher_alg {
|
||||
SAP_WIFI_CIPHER_ALG_NONE = IWL_MEI_CIPHER_NONE,
|
||||
@@ -601,7 +601,7 @@ enum iwl_sap_flex_filter_flags {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_sap_flex_filter -
|
||||
* struct iwl_sap_flex_filter - filter configuration
|
||||
* @src_port: Source port in network format.
|
||||
* @dst_port: Destination port in network format.
|
||||
* @flags: Flags and protocol, see &enum iwl_sap_flex_filter_flags.
|
||||
@@ -633,7 +633,7 @@ enum iwl_sap_ipv4_filter_flags {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_sap_ipv4_filter-
|
||||
* struct iwl_sap_ipv4_filter - IPv4 filter configuration
|
||||
* @ipv4_addr: The IP address to filer.
|
||||
* @flags: See &enum iwl_sap_ipv4_filter_flags.
|
||||
*/
|
||||
@@ -643,7 +643,7 @@ struct iwl_sap_ipv4_filter {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum iwl_sap_ipv6_filter_flags -
|
||||
* enum iwl_sap_ipv6_filter_flags - IPv6 filter flags
|
||||
* @SAP_IPV6_ADDR_FILTER_COPY: Pass packets to the host.
|
||||
* @SAP_IPV6_ADDR_FILTER_ENABLED: If false, the filter should be ignored.
|
||||
*/
|
||||
@@ -653,7 +653,7 @@ enum iwl_sap_ipv6_filter_flags {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_sap_ipv6_filter -
|
||||
* struct iwl_sap_ipv6_filter - IPv6 filter configuration
|
||||
* @addr_lo24: Lowest 24 bits of the IPv6 address.
|
||||
* @flags: See &enum iwl_sap_ipv6_filter_flags.
|
||||
*/
|
||||
@@ -663,7 +663,7 @@ struct iwl_sap_ipv6_filter {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum iwl_sap_icmpv6_filter_flags -
|
||||
* enum iwl_sap_icmpv6_filter_flags - ICMPv6 filter flags
|
||||
* @SAP_ICMPV6_FILTER_ENABLED: If false, the filter should be ignored.
|
||||
* @SAP_ICMPV6_FILTER_COPY: Pass packets to the host.
|
||||
*/
|
||||
@@ -673,8 +673,8 @@ enum iwl_sap_icmpv6_filter_flags {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_sap_vlan_filter_flags -
|
||||
* @SAP_VLAN_FILTER_VLAN_ID_MSK: TBD
|
||||
* enum iwl_sap_vlan_filter_flags - VLAN filter flags
|
||||
* @SAP_VLAN_FILTER_VLAN_ID_MSK: VLAN ID
|
||||
* @SAP_VLAN_FILTER_ENABLED: If false, the filter should be ignored.
|
||||
*/
|
||||
enum iwl_sap_vlan_filter_flags {
|
||||
@@ -751,7 +751,7 @@ struct iwl_sap_pldr_data {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum iwl_sap_pldr_status -
|
||||
* enum iwl_sap_pldr_status - product reset status
|
||||
* @SAP_PLDR_STATUS_SUCCESS: PLDR started/ended successfully
|
||||
* @SAP_PLDR_STATUS_FAILURE: PLDR failed to start/end
|
||||
*/
|
||||
|
||||
@@ -9,8 +9,4 @@ iwlmld-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
|
||||
iwlmld-$(CONFIG_IWLWIFI_LEDS) += led.o
|
||||
iwlmld-$(CONFIG_PM_SLEEP) += d3.o
|
||||
|
||||
# non-upstream things
|
||||
iwlmld-$(CONFIG_IWL_VENDOR_CMDS) += vendor-cmd.o
|
||||
iwlmld-$(CONFIG_IWLMVM_AX_SOFTAP_TESTMODE) += ax-softap-testmode.o
|
||||
|
||||
subdir-ccflags-y += -I$(src)/../
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user