ath.git patches for v6.9
We have new features for both ath11k and ath12k. ath12k is now under heavy refactoring in preparation for MLO support. Major changes: ath12k * refactoring in preparation for Multi-Link Operation (MLO) support * 1024 Block Ack window size support * provide firmware wmi logs via a trace event ath11k * 36 bit DMA mask support * support 6 GHz station power modes: Low Power Indoor (LPI), Standard Power) SP and Very Low Power (VLP) -----BEGIN PGP SIGNATURE----- iQFLBAABCgA1FiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmW49dUXHHF1aWNfa3Zh bG9AcXVpY2luYy5jb20ACgkQbhckVSbrbZsGagf+PmejP9HDXTB8RmL0exK79XyJ DDn2a1elnnUNwf1SLrRTVZ83dtoN2V48A4/xQUhNfjs7vDUvvRj/vbUx2pe3CGoJ 9qUMO2/U7KxfEb4wo+iib51lD4B00/QaQIqC/nKY6xc85GIdUEdIfMXyEN2OF0Zz BYEILiQtRdWYWmemesVv7goumpSEsReIdoETwMdVze8/geOluiy6UCBW7bh6BAi8 U9aaDEZuPfuvCWCWeCWNTN+xJNHSdLsdjSPZD+zq0jLHcuD1GmDJYQ5r67ZvUjM+ rS39DnJrDtTfiGMwIieGOy2zSCZZSVlyjFJuL9+P0X5N8A5057YIa+CZjeLCpw== =mU6W -----END PGP SIGNATURE----- Merge tag 'ath-next-20240130' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath ath.git patches for v6.9 We have new features for both ath11k and ath12k. ath12k is now under heavy refactoring in preparation for MLO support. Major changes: ath12k * refactoring in preparation for Multi-Link Operation (MLO) support * 1024 Block Ack window size support * provide firmware wmi logs via a trace event ath11k * 36 bit DMA mask support * support 6 GHz station power modes: Low Power Indoor (LPI), Standard Power) SP and Very Low Power (VLP)
This commit is contained in:
commit
6c76dd3a91
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -3613,7 +3613,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
||||
default:
|
||||
ath10k_err(ar, "unsupported core hardware revision %d\n",
|
||||
hw_rev);
|
||||
ret = -ENOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_mac;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: ISC */
|
||||
/*
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _COREDUMP_H_
|
||||
@ -13,7 +13,11 @@
|
||||
|
||||
/**
|
||||
* enum ath10k_fw_crash_dump_type - types of data in the dump file
|
||||
* @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
|
||||
* @ATH10K_FW_CRASH_DUMP_REGISTERS: Register crash dump in binary format
|
||||
* @ATH10K_FW_CRASH_DUMP_CE_DATA: Copy Engine crash dump data
|
||||
* @ATH10K_FW_CRASH_DUMP_RAM_DATA: RAM crash dump data, contains multiple
|
||||
* struct ath10k_dump_ram_data_hdr
|
||||
* @ATH10K_FW_CRASH_DUMP_MAX: Maximum enumeration
|
||||
*/
|
||||
enum ath10k_fw_crash_dump_type {
|
||||
ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
|
||||
|
@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
@ -381,7 +382,7 @@ static int ath10k_htt_verify_version(struct ath10k_htt *htt)
|
||||
htt->target_version_major != 3) {
|
||||
ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n",
|
||||
htt->target_version_major);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021, 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _HTT_H_
|
||||
@ -906,7 +906,7 @@ struct htt_data_tx_completion_ext {
|
||||
__le16 msdus_rssi[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @brief target -> host TX completion indication message definition
|
||||
*
|
||||
* @details
|
||||
@ -1474,15 +1474,19 @@ enum htt_q_depth_type {
|
||||
#define HTT_TX_Q_STATE_ENTRY_MULTIPLIER 0
|
||||
|
||||
/**
|
||||
* htt_q_state_conf - part of htt_frag_desc_bank_cfg for host q state config
|
||||
* struct htt_q_state_conf - part of htt_frag_desc_bank_cfg for host q state config
|
||||
*
|
||||
* Defines host q state format and behavior. See htt_q_state.
|
||||
*
|
||||
* @paddr: Queue physical address
|
||||
* @num_peers: Number of supported peers
|
||||
* @num_tids: Number of supported TIDs
|
||||
* @record_size: Defines the size of each host q entry in bytes. In practice
|
||||
* however firmware (at least 10.4.3-00191) ignores this host
|
||||
* configuration value and uses hardcoded value of 1.
|
||||
* @record_multiplier: This is valid only when q depth type is MSDUs. It
|
||||
* defines the exponent for the power of 2 multiplication.
|
||||
* @pad: struct padding for 32-bit alignment
|
||||
*/
|
||||
struct htt_q_state_conf {
|
||||
__le32 paddr;
|
||||
@ -1518,7 +1522,7 @@ struct htt_frag_desc_bank_cfg64 {
|
||||
#define HTT_TX_Q_STATE_ENTRY_EXP_LSB 6
|
||||
|
||||
/**
|
||||
* htt_q_state - shared between host and firmware via DMA
|
||||
* struct htt_q_state - shared between host and firmware via DMA
|
||||
*
|
||||
* This structure is used for the host to expose it's software queue state to
|
||||
* firmware so that its rate control can schedule fetch requests for optimized
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "mac.h"
|
||||
@ -4056,7 +4056,7 @@ static int ath10k_mac_tx(struct ath10k *ar,
|
||||
!(skb_cb->flags & ATH10K_SKB_F_RAW_TX)) {
|
||||
WARN_ON_ONCE(1);
|
||||
ieee80211_free_txskb(hw, skb);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7065,7 +7065,7 @@ static int ath10k_mac_set_tid_config(struct ath10k *ar, struct ieee80211_sta *st
|
||||
|
||||
if (sta) {
|
||||
if (!sta->wme)
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
@ -889,7 +889,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (WARN_ON_ONCE(!ar_pci->targ_cpu_to_ce_addr))
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar_pci->targ_cpu_to_ce_addr(ar, addr);
|
||||
}
|
||||
@ -2668,7 +2668,7 @@ static int ath10k_pci_safe_chip_reset(struct ath10k *ar)
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (!ar_pci->pci_soft_reset)
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar_pci->pci_soft_reset(ar);
|
||||
}
|
||||
@ -2808,7 +2808,7 @@ static int ath10k_pci_chip_reset(struct ath10k *ar)
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (WARN_ON(!ar_pci->pci_hard_reset))
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar_pci->pci_hard_reset(ar);
|
||||
}
|
||||
@ -3594,7 +3594,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, ATH10K_BUS_PCI,
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
@ -851,6 +852,10 @@ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
|
||||
if (!ev) {
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
arg->desc_id = ev->desc_id;
|
||||
arg->status = ev->status;
|
||||
@ -1347,7 +1352,7 @@ static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
arg->min_tx_power = ev->hw_min_tx_power;
|
||||
@ -2119,9 +2124,9 @@ static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar,
|
||||
case WMI_VDEV_SUBTYPE_MESH_11S:
|
||||
return WMI_TLV_VDEV_SUBTYPE_MESH_11S;
|
||||
case WMI_VDEV_SUBTYPE_MESH_NON_11S:
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _WMI_TLV_H
|
||||
#define _WMI_TLV_H
|
||||
@ -2343,7 +2343,7 @@ struct wmi_tlv_adaptive_qcs {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* wmi_tlv_tx_pause_id - firmware tx queue pause reason types
|
||||
* enum wmi_tlv_tx_pause_id - firmware tx queue pause reason types
|
||||
*
|
||||
* @WMI_TLV_TX_PAUSE_ID_MCC: used for by multi-channel firmware scheduler.
|
||||
* Only vdev_map is valid.
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
@ -6927,14 +6927,14 @@ void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs,
|
||||
ath10k_wmi_put_start_scan_tlvs(u8 *tlvs,
|
||||
const struct wmi_start_scan_arg *arg)
|
||||
{
|
||||
struct wmi_ie_data *ie;
|
||||
struct wmi_chan_list *channels;
|
||||
struct wmi_ssid_list *ssids;
|
||||
struct wmi_bssid_list *bssids;
|
||||
void *ptr = tlvs->tlvs;
|
||||
void *ptr = tlvs;
|
||||
int i;
|
||||
|
||||
if (arg->n_channels) {
|
||||
@ -7012,7 +7012,7 @@ ath10k_wmi_op_gen_start_scan(struct ath10k *ar,
|
||||
cmd = (struct wmi_start_scan_cmd *)skb->data;
|
||||
|
||||
ath10k_wmi_put_start_scan_common(&cmd->common, arg);
|
||||
ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
|
||||
ath10k_wmi_put_start_scan_tlvs(cmd->tlvs, arg);
|
||||
|
||||
cmd->burst_duration_ms = __cpu_to_le32(0);
|
||||
|
||||
@ -7041,7 +7041,7 @@ ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar,
|
||||
cmd = (struct wmi_10x_start_scan_cmd *)skb->data;
|
||||
|
||||
ath10k_wmi_put_start_scan_common(&cmd->common, arg);
|
||||
ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
|
||||
ath10k_wmi_put_start_scan_tlvs(cmd->tlvs, arg);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n");
|
||||
return skb;
|
||||
@ -8733,9 +8733,9 @@ int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
|
||||
return WMI_VDEV_SUBTYPE_LEGACY_PROXY_STA;
|
||||
case WMI_VDEV_SUBTYPE_MESH_11S:
|
||||
case WMI_VDEV_SUBTYPE_MESH_NON_11S:
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ath10k_wmi_10_2_4_op_get_vdev_subtype(struct ath10k *ar,
|
||||
@ -8755,9 +8755,9 @@ static int ath10k_wmi_10_2_4_op_get_vdev_subtype(struct ath10k *ar,
|
||||
case WMI_VDEV_SUBTYPE_MESH_11S:
|
||||
return WMI_VDEV_SUBTYPE_10_2_4_MESH_11S;
|
||||
case WMI_VDEV_SUBTYPE_MESH_NON_11S:
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
|
||||
@ -8779,7 +8779,7 @@ static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
|
||||
case WMI_VDEV_SUBTYPE_MESH_NON_11S:
|
||||
return WMI_VDEV_SUBTYPE_10_4_MESH_NON_11S;
|
||||
}
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
@ -8918,8 +8918,6 @@ ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
memset(skb->data, 0, sizeof(*cmd));
|
||||
|
||||
cmd = (struct wmi_10_4_tdls_peer_update_cmd *)skb->data;
|
||||
cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _WMI_H_
|
||||
@ -3008,8 +3008,11 @@ enum wmi_coex_version {
|
||||
* @WMI_10_4_TDLS_UAPSD_SLEEP_STA: TDLS sleep sta support enable/disable
|
||||
* @WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE: TDLS connection tracker in host
|
||||
* enable/disable
|
||||
* @WMI_10_4_TDLS_EXPLICIT_MODE_ONLY:Explicit TDLS mode enable/disable
|
||||
* @WMI_10_4_TDLS_EXPLICIT_MODE_ONLY: Explicit TDLS mode enable/disable
|
||||
* @WMI_10_4_TX_DATA_ACK_RSSI: Enable DATA ACK RSSI if firmware is capable
|
||||
* @WMI_10_4_EXT_PEER_TID_CONFIGS_SUPPORT: Firmware supports Extended Peer
|
||||
* TID configuration for QoS related settings
|
||||
* @WMI_10_4_REPORT_AIRTIME: Firmware supports transmit airtime reporting
|
||||
*/
|
||||
enum wmi_10_4_feature_mask {
|
||||
WMI_10_4_LTEU_SUPPORT = BIT(0),
|
||||
@ -3069,7 +3072,10 @@ struct host_memory_chunk {
|
||||
struct wmi_host_mem_chunks {
|
||||
__le32 count;
|
||||
/* some fw revisions require at least 1 chunk regardless of count */
|
||||
struct host_memory_chunk items[1];
|
||||
union {
|
||||
struct host_memory_chunk item;
|
||||
DECLARE_FLEX_ARRAY(struct host_memory_chunk, items);
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wmi_init_cmd {
|
||||
@ -3215,23 +3221,16 @@ struct wmi_start_scan_common {
|
||||
__le32 scan_ctrl_flags;
|
||||
} __packed;
|
||||
|
||||
struct wmi_start_scan_tlvs {
|
||||
/* TLV parameters. These includes channel list, ssid list, bssid list,
|
||||
* extra ies.
|
||||
*/
|
||||
u8 tlvs[0];
|
||||
} __packed;
|
||||
|
||||
struct wmi_start_scan_cmd {
|
||||
struct wmi_start_scan_common common;
|
||||
__le32 burst_duration_ms;
|
||||
struct wmi_start_scan_tlvs tlvs;
|
||||
u8 tlvs[];
|
||||
} __packed;
|
||||
|
||||
/* This is the definition from 10.X firmware branch */
|
||||
struct wmi_10x_start_scan_cmd {
|
||||
struct wmi_start_scan_common common;
|
||||
struct wmi_start_scan_tlvs tlvs;
|
||||
u8 tlvs[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_ssid_arg {
|
||||
@ -4260,13 +4259,6 @@ struct wmi_peer_sta_ps_state_chg_event {
|
||||
__le32 peer_ps_state;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_chanlist_update_event {
|
||||
/* number of channels */
|
||||
__le32 num_chan;
|
||||
/* array of channels */
|
||||
struct wmi_channel channel_list[1];
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_DEBUG_MESG (sizeof(u32) * 32)
|
||||
|
||||
struct wmi_debug_mesg_event {
|
||||
@ -5793,30 +5785,6 @@ struct wmi_bcn_prb_info {
|
||||
/* app IE */
|
||||
} __packed;
|
||||
|
||||
struct wmi_bcn_tmpl_cmd {
|
||||
/* unique id identifying the VDEV, generated by the caller */
|
||||
__le32 vdev_id;
|
||||
/* TIM IE offset from the beginning of the template. */
|
||||
__le32 tim_ie_offset;
|
||||
/* beacon probe capabilities and IEs */
|
||||
struct wmi_bcn_prb_info bcn_prb_info;
|
||||
/* beacon buffer length */
|
||||
__le32 buf_len;
|
||||
/* variable length data */
|
||||
u8 data[1];
|
||||
} __packed;
|
||||
|
||||
struct wmi_prb_tmpl_cmd {
|
||||
/* unique id identifying the VDEV, generated by the caller */
|
||||
__le32 vdev_id;
|
||||
/* beacon probe capabilities and IEs */
|
||||
struct wmi_bcn_prb_info bcn_prb_info;
|
||||
/* beacon buffer length */
|
||||
__le32 buf_len;
|
||||
/* Variable length data */
|
||||
u8 data[1];
|
||||
} __packed;
|
||||
|
||||
enum wmi_sta_ps_mode {
|
||||
/* enable power save for the given STA VDEV */
|
||||
WMI_STA_PS_MODE_DISABLED = 0,
|
||||
@ -7197,7 +7165,13 @@ struct wmi_tdls_peer_capabilities {
|
||||
__le32 is_peer_responder;
|
||||
__le32 pref_offchan_num;
|
||||
__le32 pref_offchan_bw;
|
||||
struct wmi_channel peer_chan_list[1];
|
||||
union {
|
||||
/* to match legacy implementation allocate room for
|
||||
* at least one record even if peer_chan_len is 0
|
||||
*/
|
||||
struct wmi_channel peer_chan_min_allocation;
|
||||
DECLARE_FLEX_ARRAY(struct wmi_channel, peer_chan_list);
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wmi_10_4_tdls_peer_update_cmd {
|
||||
|
@ -314,6 +314,43 @@ struct ath11k_rekey_data {
|
||||
bool enable_offload;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath11k_chan_power_info - TPE containing power info per channel chunk
|
||||
* @chan_cfreq: channel center freq (MHz)
|
||||
* e.g.
|
||||
* channel 37/20 MHz, it is 6135
|
||||
* channel 37/40 MHz, it is 6125
|
||||
* channel 37/80 MHz, it is 6145
|
||||
* channel 37/160 MHz, it is 6185
|
||||
* @tx_power: transmit power (dBm)
|
||||
*/
|
||||
struct ath11k_chan_power_info {
|
||||
u16 chan_cfreq;
|
||||
s8 tx_power;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath11k_reg_tpc_power_info - regulatory TPC power info
|
||||
* @is_psd_power: is PSD power or not
|
||||
* @eirp_power: Maximum EIRP power (dBm), valid only if power is PSD
|
||||
* @ap_power_type: type of power (SP/LPI/VLP)
|
||||
* @num_pwr_levels: number of power levels
|
||||
* @reg_max: Array of maximum TX power (dBm) per PSD value
|
||||
* @ap_constraint_power: AP constraint power (dBm)
|
||||
* @tpe: TPE values processed from TPE IE
|
||||
* @chan_power_info: power info to send to firmware
|
||||
*/
|
||||
struct ath11k_reg_tpc_power_info {
|
||||
bool is_psd_power;
|
||||
u8 eirp_power;
|
||||
enum wmi_reg_6ghz_ap_type ap_power_type;
|
||||
u8 num_pwr_levels;
|
||||
u8 reg_max[IEEE80211_MAX_NUM_PWR_LEVEL];
|
||||
u8 ap_constraint_power;
|
||||
s8 tpe[IEEE80211_MAX_NUM_PWR_LEVEL];
|
||||
struct ath11k_chan_power_info chan_power_info[IEEE80211_MAX_NUM_PWR_LEVEL];
|
||||
};
|
||||
|
||||
struct ath11k_vif {
|
||||
u32 vdev_id;
|
||||
enum wmi_vdev_type vdev_type;
|
||||
@ -368,6 +405,8 @@ struct ath11k_vif {
|
||||
struct ieee80211_chanctx_conf chanctx;
|
||||
struct ath11k_arp_ns_offload arp_ns_offload;
|
||||
struct ath11k_rekey_data rekey_data;
|
||||
|
||||
struct ath11k_reg_tpc_power_info reg_tpc_info;
|
||||
};
|
||||
|
||||
struct ath11k_vif_iter {
|
||||
@ -735,6 +774,7 @@ struct ath11k {
|
||||
/* protected by conf_mutex */
|
||||
bool ps_state_enable;
|
||||
bool ps_timekeeper_enable;
|
||||
s8 max_allowed_tx_power;
|
||||
};
|
||||
|
||||
struct ath11k_band_cap {
|
||||
@ -918,6 +958,7 @@ struct ath11k_base {
|
||||
* This may or may not be used during the runtime
|
||||
*/
|
||||
struct ieee80211_regdomain *new_regd[MAX_RADIOS];
|
||||
struct cur_regulatory_info *reg_info_store;
|
||||
|
||||
/* Current DFS Regulatory */
|
||||
enum ath11k_dfs_region dfs_region;
|
||||
|
@ -104,11 +104,14 @@ void ath11k_dp_srng_cleanup(struct ath11k_base *ab, struct dp_srng *ring)
|
||||
if (!ring->vaddr_unaligned)
|
||||
return;
|
||||
|
||||
if (ring->cached)
|
||||
if (ring->cached) {
|
||||
dma_unmap_single(ab->dev, ring->paddr_unaligned, ring->size,
|
||||
DMA_FROM_DEVICE);
|
||||
kfree(ring->vaddr_unaligned);
|
||||
else
|
||||
} else {
|
||||
dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
|
||||
ring->paddr_unaligned);
|
||||
}
|
||||
|
||||
ring->vaddr_unaligned = NULL;
|
||||
}
|
||||
@ -249,7 +252,18 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
|
||||
|
||||
if (cached) {
|
||||
ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL);
|
||||
ring->paddr_unaligned = virt_to_phys(ring->vaddr_unaligned);
|
||||
if (!ring->vaddr_unaligned)
|
||||
return -ENOMEM;
|
||||
|
||||
ring->paddr_unaligned = dma_map_single(ab->dev,
|
||||
ring->vaddr_unaligned,
|
||||
ring->size,
|
||||
DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(ab->dev, ring->paddr_unaligned)) {
|
||||
kfree(ring->vaddr_unaligned);
|
||||
ring->vaddr_unaligned = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
@ -103,7 +103,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
|
||||
if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
!ieee80211_is_data(hdr->frame_control)))
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1);
|
||||
|
||||
@ -1018,7 +1018,7 @@ int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab)
|
||||
if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
|
||||
ath11k_err(ab, "unsupported htt major version %d supported version is %d\n",
|
||||
dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -626,15 +626,30 @@ u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u32 *ath11k_hal_srng_dst_peek_with_dma(struct ath11k_base *ab,
|
||||
struct hal_srng *srng, dma_addr_t *paddr)
|
||||
{
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
||||
if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) {
|
||||
*paddr = srng->ring_base_paddr +
|
||||
sizeof(*srng->ring_base_vaddr) * srng->u.dst_ring.tp;
|
||||
return srng->ring_base_vaddr + srng->u.dst_ring.tp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ath11k_hal_srng_prefetch_desc(struct ath11k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
dma_addr_t desc_paddr;
|
||||
u32 *desc;
|
||||
|
||||
/* prefetch only if desc is available */
|
||||
desc = ath11k_hal_srng_dst_peek(ab, srng);
|
||||
desc = ath11k_hal_srng_dst_peek_with_dma(ab, srng, &desc_paddr);
|
||||
if (likely(desc)) {
|
||||
dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc),
|
||||
dma_sync_single_for_cpu(ab->dev, desc_paddr,
|
||||
(srng->entry_size * sizeof(u32)),
|
||||
DMA_FROM_DEVICE);
|
||||
prefetch(desc);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_HAL_H
|
||||
@ -674,6 +674,7 @@ struct hal_srng_config {
|
||||
* @HAL_RX_BUF_RBM_SW1_BM: For Tx completion -- returned to host
|
||||
* @HAL_RX_BUF_RBM_SW2_BM: For Tx completion -- returned to host
|
||||
* @HAL_RX_BUF_RBM_SW3_BM: For Rx release -- returned to host
|
||||
* @HAL_RX_BUF_RBM_SW4_BM: For Tx completion -- returned to host
|
||||
*/
|
||||
|
||||
enum hal_rx_buf_return_buf_manager {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
@ -246,7 +246,7 @@ int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng,
|
||||
case HAL_REO_CMD_UNBLOCK_CACHE:
|
||||
case HAL_REO_CMD_FLUSH_TIMEOUT_LIST:
|
||||
ath11k_warn(ab, "Unsupported reo command %d\n", type);
|
||||
ret = -ENOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
default:
|
||||
ath11k_warn(ab, "Unknown reo command %d\n", type);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_MAC_H
|
||||
@ -176,4 +176,7 @@ int ath11k_mac_wait_tx_complete(struct ath11k *ar);
|
||||
int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,
|
||||
enum wmi_sta_keepalive_method method,
|
||||
u32 interval);
|
||||
void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_chanctx_conf *ctx);
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/msi.h>
|
||||
@ -423,7 +423,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
|
||||
goto free_controller;
|
||||
} else {
|
||||
mhi_ctrl->iova_start = 0;
|
||||
mhi_ctrl->iova_stop = 0xFFFFFFFF;
|
||||
mhi_ctrl->iova_stop = ab_pci->dma_mask;
|
||||
}
|
||||
|
||||
mhi_ctrl->rddm_size = RDDM_DUMP_SIZE;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -18,7 +18,8 @@
|
||||
#include "qmi.h"
|
||||
|
||||
#define ATH11K_PCI_BAR_NUM 0
|
||||
#define ATH11K_PCI_DMA_MASK 32
|
||||
#define ATH11K_PCI_DMA_MASK 36
|
||||
#define ATH11K_PCI_COHERENT_DMA_MASK 32
|
||||
|
||||
#define TCSR_SOC_HW_VERSION 0x0224
|
||||
#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8)
|
||||
@ -526,14 +527,24 @@ static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)
|
||||
goto disable_device;
|
||||
}
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev,
|
||||
DMA_BIT_MASK(ATH11K_PCI_DMA_MASK));
|
||||
ret = dma_set_mask(&pdev->dev,
|
||||
DMA_BIT_MASK(ATH11K_PCI_DMA_MASK));
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to set pci dma mask to %d: %d\n",
|
||||
ATH11K_PCI_DMA_MASK, ret);
|
||||
goto release_region;
|
||||
}
|
||||
|
||||
ab_pci->dma_mask = DMA_BIT_MASK(ATH11K_PCI_DMA_MASK);
|
||||
|
||||
ret = dma_set_coherent_mask(&pdev->dev,
|
||||
DMA_BIT_MASK(ATH11K_PCI_COHERENT_DMA_MASK));
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to set pci coherent dma mask to %d: %d\n",
|
||||
ATH11K_PCI_COHERENT_DMA_MASK, ret);
|
||||
goto release_region;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
ab->mem_len = pci_resource_len(pdev, ATH11K_PCI_BAR_NUM);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _ATH11K_PCI_H
|
||||
#define _ATH11K_PCI_H
|
||||
@ -72,6 +72,7 @@ struct ath11k_pci {
|
||||
/* enum ath11k_pci_flags */
|
||||
unsigned long flags;
|
||||
u16 link_ctl;
|
||||
u64 dma_mask;
|
||||
};
|
||||
|
||||
static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
|
||||
|
@ -425,6 +425,11 @@ static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1,
|
||||
/* Use the flags of both the rules */
|
||||
new_rule->flags = rule1->flags | rule2->flags;
|
||||
|
||||
if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD))
|
||||
new_rule->psd = min_t(s8, rule1->psd, rule2->psd);
|
||||
else
|
||||
new_rule->flags &= ~NL80211_RRF_PSD;
|
||||
|
||||
/* To be safe, lts use the max cac timeout of both rules */
|
||||
new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
|
||||
rule2->dfs_cac_ms);
|
||||
@ -527,13 +532,14 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw)
|
||||
static void
|
||||
ath11k_reg_update_rule(struct ieee80211_reg_rule *reg_rule, u32 start_freq,
|
||||
u32 end_freq, u32 bw, u32 ant_gain, u32 reg_pwr,
|
||||
u32 reg_flags)
|
||||
s8 psd, u32 reg_flags)
|
||||
{
|
||||
reg_rule->freq_range.start_freq_khz = MHZ_TO_KHZ(start_freq);
|
||||
reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(end_freq);
|
||||
reg_rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw);
|
||||
reg_rule->power_rule.max_antenna_gain = DBI_TO_MBI(ant_gain);
|
||||
reg_rule->power_rule.max_eirp = DBM_TO_MBM(reg_pwr);
|
||||
reg_rule->psd = psd;
|
||||
reg_rule->flags = reg_flags;
|
||||
}
|
||||
|
||||
@ -563,7 +569,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
|
||||
reg_rule->start_freq,
|
||||
ETSI_WEATHER_RADAR_BAND_LOW, bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
@ -584,7 +590,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
|
||||
|
||||
ath11k_reg_update_rule(regd->reg_rules + i, start_freq,
|
||||
end_freq, bw, reg_rule->ant_gain,
|
||||
reg_rule->reg_power, flags);
|
||||
reg_rule->reg_power, reg_rule->psd_eirp, flags);
|
||||
|
||||
regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
|
||||
|
||||
@ -605,7 +611,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
|
||||
ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
reg_rule->end_freq, bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
@ -618,25 +624,68 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
|
||||
*rule_idx = i;
|
||||
}
|
||||
|
||||
enum wmi_reg_6ghz_ap_type
|
||||
ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
switch (power_type) {
|
||||
case IEEE80211_REG_LPI_AP:
|
||||
return WMI_REG_INDOOR_AP;
|
||||
case IEEE80211_REG_SP_AP:
|
||||
return WMI_REG_STANDARD_POWER_AP;
|
||||
case IEEE80211_REG_VLP_AP:
|
||||
return WMI_REG_VERY_LOW_POWER_AP;
|
||||
default:
|
||||
return WMI_REG_MAX_AP_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
struct ieee80211_regdomain *
|
||||
ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info, bool intersect)
|
||||
struct cur_regulatory_info *reg_info, bool intersect,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
|
||||
struct cur_reg_rule *reg_rule;
|
||||
struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
|
||||
u8 i = 0, j = 0, k = 0;
|
||||
u8 num_rules;
|
||||
u16 max_bw;
|
||||
u32 flags;
|
||||
u32 flags, reg_6ghz_number, max_bw_6ghz;
|
||||
char alpha2[3];
|
||||
|
||||
num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules;
|
||||
|
||||
/* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list.
|
||||
* This can be updated after complete 6 GHz regulatory support is added.
|
||||
*/
|
||||
if (reg_info->is_ext_reg_event)
|
||||
num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
if (vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
enum wmi_reg_6ghz_ap_type ap_type;
|
||||
|
||||
ap_type = ath11k_reg_ap_pwr_convert(power_type);
|
||||
|
||||
if (ap_type == WMI_REG_MAX_AP_TYPE)
|
||||
ap_type = WMI_REG_INDOOR_AP;
|
||||
|
||||
reg_6ghz_number = reg_info->num_6ghz_rules_client
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
|
||||
if (reg_6ghz_number == 0) {
|
||||
ap_type = WMI_REG_INDOOR_AP;
|
||||
reg_6ghz_number = reg_info->num_6ghz_rules_client
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
}
|
||||
|
||||
reg_rule_6ghz = reg_info->reg_rules_6ghz_client_ptr
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
max_bw_6ghz = reg_info->max_bw_6ghz_client
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
} else {
|
||||
reg_6ghz_number = reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
|
||||
reg_rule_6ghz =
|
||||
reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP];
|
||||
max_bw_6ghz = reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP];
|
||||
}
|
||||
|
||||
num_rules += reg_6ghz_number;
|
||||
}
|
||||
|
||||
if (!num_rules)
|
||||
goto ret;
|
||||
@ -683,14 +732,13 @@ ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
* per other BW rule flags we pass from here
|
||||
*/
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
} else if (reg_info->is_ext_reg_event &&
|
||||
reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] &&
|
||||
(k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) {
|
||||
reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] +
|
||||
k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw,
|
||||
reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
|
||||
} else if (reg_info->is_ext_reg_event && reg_6ghz_number &&
|
||||
k < reg_6ghz_number) {
|
||||
reg_rule = reg_rule_6ghz + k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz);
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
if (reg_rule->psd_flag)
|
||||
flags |= NL80211_RRF_PSD;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -702,7 +750,7 @@ ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
reg_rule->start_freq,
|
||||
reg_rule->end_freq, max_bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
/* Update dfs cac timeout if the dfs domain is ETSI and the
|
||||
* new rule covers weather radar band.
|
||||
@ -758,6 +806,159 @@ ret:
|
||||
return new_regd;
|
||||
}
|
||||
|
||||
static bool ath11k_reg_is_world_alpha(char *alpha)
|
||||
{
|
||||
if (alpha[0] == '0' && alpha[1] == '0')
|
||||
return true;
|
||||
|
||||
if (alpha[0] == 'n' && alpha[1] == 'a')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar)
|
||||
{
|
||||
struct ath11k_vif *arvif;
|
||||
|
||||
/* Currently each struct ath11k maps to one struct ieee80211_hw/wiphy
|
||||
* and one struct ieee80211_regdomain, so it could only store one group
|
||||
* reg rules. It means multi-interface concurrency in the same ath11k is
|
||||
* not support for the regdomain. So get the vdev type of the first entry
|
||||
* now. After concurrency support for the regdomain, this should change.
|
||||
*/
|
||||
arvif = list_first_entry_or_null(&ar->arvifs, struct ath11k_vif, list);
|
||||
if (arvif)
|
||||
return arvif->vdev_type;
|
||||
|
||||
return WMI_VDEV_TYPE_UNSPEC;
|
||||
}
|
||||
|
||||
int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info,
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
struct ieee80211_regdomain *regd;
|
||||
bool intersect = false;
|
||||
int pdev_idx;
|
||||
struct ath11k *ar;
|
||||
enum wmi_vdev_type vdev_type;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list");
|
||||
|
||||
if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
|
||||
/* In case of failure to set the requested ctry,
|
||||
* fw retains the current regd. We print a failure info
|
||||
* and return from here.
|
||||
*/
|
||||
ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev_idx = reg_info->phy_id;
|
||||
|
||||
/* Avoid default reg rule updates sent during FW recovery if
|
||||
* it is already available
|
||||
*/
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
|
||||
ab->default_regd[pdev_idx]) {
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
goto retfail;
|
||||
}
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
/* Process the event for phy0 only if single_pdev_only
|
||||
* is true. If pdev_idx is valid but not 0, discard the
|
||||
* event. Otherwise, it goes to fallback. In either case
|
||||
* ath11k_reg_reset_info() needs to be called to avoid
|
||||
* memory leak issue.
|
||||
*/
|
||||
ath11k_reg_reset_info(reg_info);
|
||||
|
||||
if (ab->hw_params.single_pdev_only &&
|
||||
pdev_idx < ab->hw_params.num_rxmda_per_pdev)
|
||||
return 0;
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Avoid multiple overwrites to default regd, during core
|
||||
* stop-start after mac registration.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
|
||||
(char *)reg_info->alpha2, 2))
|
||||
goto retfail;
|
||||
|
||||
/* Intersect new rules with default regd if a new country setting was
|
||||
* requested, i.e a default regd was already set during initialization
|
||||
* and the regd coming from this event has a valid country info.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] &&
|
||||
!ath11k_reg_is_world_alpha((char *)
|
||||
ab->default_regd[pdev_idx]->alpha2) &&
|
||||
!ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
|
||||
intersect = true;
|
||||
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
vdev_type = ath11k_reg_get_ar_vdev_type(ar);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"wmi handle chan list power type %d vdev type %d intersect %d\n",
|
||||
power_type, vdev_type, intersect);
|
||||
|
||||
regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type);
|
||||
if (!regd) {
|
||||
ath11k_warn(ab, "failed to build regd from reg_info\n");
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (power_type == IEEE80211_REG_UNSET_AP) {
|
||||
ath11k_reg_reset_info(&ab->reg_info_store[pdev_idx]);
|
||||
ab->reg_info_store[pdev_idx] = *reg_info;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
if (ab->default_regd[pdev_idx]) {
|
||||
/* The initial rules from FW after WMI Init is to build
|
||||
* the default regd. From then on, any rules updated for
|
||||
* the pdev could be due to user reg changes.
|
||||
* Free previously built regd before assigning the newly
|
||||
* generated regd to ar. NULL pointer handling will be
|
||||
* taken care by kfree itself.
|
||||
*/
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
kfree(ab->new_regd[pdev_idx]);
|
||||
ab->new_regd[pdev_idx] = regd;
|
||||
queue_work(ab->workqueue, &ar->regd_update_work);
|
||||
} else {
|
||||
/* This regd would be applied during mac registration and is
|
||||
* held constant throughout for regd intersection purpose
|
||||
*/
|
||||
ab->default_regd[pdev_idx] = regd;
|
||||
}
|
||||
ab->dfs_region = reg_info->dfs_region;
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
fallback:
|
||||
/* Fallback to older reg (by sending previous country setting
|
||||
* again if fw has succeeded and we failed to process here.
|
||||
* The Regdomain should be uniform across driver and fw. Since the
|
||||
* FW has processed the command and sent a success status, we expect
|
||||
* this function to succeed as well. If it doesn't, CTRY needs to be
|
||||
* reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent.
|
||||
*/
|
||||
/* TODO: This is rare, but still should also be handled */
|
||||
WARN_ON(1);
|
||||
|
||||
retfail:
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void ath11k_regd_update_work(struct work_struct *work)
|
||||
{
|
||||
struct ath11k *ar = container_of(work, struct ath11k,
|
||||
@ -781,10 +982,36 @@ void ath11k_reg_init(struct ath11k *ar)
|
||||
ar->hw->wiphy->reg_notifier = ath11k_reg_notifier;
|
||||
}
|
||||
|
||||
void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!reg_info)
|
||||
return;
|
||||
|
||||
kfree(reg_info->reg_rules_2ghz_ptr);
|
||||
kfree(reg_info->reg_rules_5ghz_ptr);
|
||||
|
||||
for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
|
||||
kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
|
||||
|
||||
for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++)
|
||||
kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]);
|
||||
}
|
||||
|
||||
memset(reg_info, 0, sizeof(*reg_info));
|
||||
}
|
||||
|
||||
void ath11k_reg_free(struct ath11k_base *ab)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++)
|
||||
ath11k_reg_reset_info(&ab->reg_info_store[i]);
|
||||
|
||||
kfree(ab->reg_info_store);
|
||||
ab->reg_info_store = NULL;
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_radios; i++) {
|
||||
kfree(ab->default_regd[i]);
|
||||
kfree(ab->new_regd[i]);
|
||||
|
@ -30,11 +30,20 @@ enum ath11k_dfs_region {
|
||||
|
||||
/* ATH11K Regulatory API's */
|
||||
void ath11k_reg_init(struct ath11k *ar);
|
||||
void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info);
|
||||
void ath11k_reg_free(struct ath11k_base *ab);
|
||||
void ath11k_regd_update_work(struct work_struct *work);
|
||||
struct ieee80211_regdomain *
|
||||
ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info, bool intersect);
|
||||
struct cur_regulatory_info *reg_info, bool intersect,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
int ath11k_regd_update(struct ath11k *ar);
|
||||
int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
|
||||
enum wmi_reg_6ghz_ap_type
|
||||
ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
|
||||
int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
|
||||
struct cur_regulatory_info *reg_info,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
|
||||
#endif
|
||||
|
@ -198,7 +198,7 @@ static void ath11k_tm_wmi_event_segmented(struct ath11k_base *ab, u32 cmd_id,
|
||||
u16 length;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse ftm event tlv: %d\n", ret);
|
||||
|
@ -238,8 +238,8 @@ static int ath11k_wmi_tlv_parse(struct ath11k_base *ar, const void **tb,
|
||||
(void *)tb);
|
||||
}
|
||||
|
||||
const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr,
|
||||
size_t len, gfp_t gfp)
|
||||
const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab,
|
||||
struct sk_buff *skb, gfp_t gfp)
|
||||
{
|
||||
const void **tb;
|
||||
int ret;
|
||||
@ -248,7 +248,7 @@ const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr,
|
||||
if (!tb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = ath11k_wmi_tlv_parse(ab, tb, ptr, len);
|
||||
ret = ath11k_wmi_tlv_parse(ab, tb, skb->data, skb->len);
|
||||
if (ret) {
|
||||
kfree(tb);
|
||||
return ERR_PTR(ret);
|
||||
@ -2379,6 +2379,70 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar,
|
||||
u32 vdev_id,
|
||||
struct ath11k_reg_tpc_power_info *param)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_vdev_set_tpc_power_cmd *cmd;
|
||||
struct wmi_vdev_ch_power_info *ch;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
u8 *ptr;
|
||||
int i, ret, len, array_len;
|
||||
|
||||
array_len = sizeof(*ch) * param->num_pwr_levels;
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + array_len;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
ptr = skb->data;
|
||||
|
||||
cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_TPC_POWER_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->psd_power = param->is_psd_power;
|
||||
cmd->eirp_power = param->eirp_power;
|
||||
cmd->power_type_6ghz = param->ap_power_type;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"tpc vdev id %d is psd power %d eirp power %d 6 ghz power type %d\n",
|
||||
vdev_id, param->is_psd_power, param->eirp_power, param->ap_power_type);
|
||||
|
||||
ptr += sizeof(*cmd);
|
||||
tlv = (struct wmi_tlv *)ptr;
|
||||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
|
||||
FIELD_PREP(WMI_TLV_LEN, array_len);
|
||||
|
||||
ptr += TLV_HDR_SIZE;
|
||||
ch = (struct wmi_vdev_ch_power_info *)ptr;
|
||||
|
||||
for (i = 0; i < param->num_pwr_levels; i++, ch++) {
|
||||
ch->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_VDEV_CH_POWER_INFO) |
|
||||
FIELD_PREP(WMI_TLV_LEN,
|
||||
sizeof(*ch) - TLV_HDR_SIZE);
|
||||
|
||||
ch->chan_cfreq = param->chan_power_info[i].chan_cfreq;
|
||||
ch->tx_power = param->chan_power_info[i].tx_power;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tpc chan freq %d TX power %d\n",
|
||||
ch->chan_cfreq, ch->tx_power);
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_TPC_POWER_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar,
|
||||
struct scan_cancel_param *param)
|
||||
{
|
||||
@ -3930,7 +3994,7 @@ ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *sk
|
||||
struct ath11k_vif *arvif;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4749,6 +4813,14 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc,
|
||||
soc->pdevs[0].pdev_id = 0;
|
||||
}
|
||||
|
||||
if (!soc->reg_info_store) {
|
||||
soc->reg_info_store = kcalloc(soc->num_radios,
|
||||
sizeof(*soc->reg_info_store),
|
||||
GFP_ATOMIC);
|
||||
if (!soc->reg_info_store)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5003,7 +5075,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf
|
||||
const struct wmi_vdev_start_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5028,6 +5100,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf
|
||||
vdev_rsp->mac_id = ev->mac_id;
|
||||
vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
|
||||
vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
|
||||
vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
@ -5102,7 +5175,7 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab,
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n");
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5278,7 +5351,7 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab,
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n");
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5634,7 +5707,7 @@ static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *
|
||||
const struct wmi_peer_delete_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5666,7 +5739,7 @@ static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab,
|
||||
const struct wmi_vdev_delete_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5686,15 +5759,15 @@ static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab, void *evt_buf,
|
||||
u32 len, u32 *vdev_id,
|
||||
u32 *tx_status)
|
||||
static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab,
|
||||
struct sk_buff *skb,
|
||||
u32 *vdev_id, u32 *tx_status)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_bcn_tx_status_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5722,7 +5795,7 @@ static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base *ab, struct sk_
|
||||
const struct wmi_vdev_stopped_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5876,7 +5949,7 @@ static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab,
|
||||
const struct wmi_mgmt_tx_compl_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6052,7 +6125,7 @@ static int ath11k_pull_scan_ev(struct ath11k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_scan_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6085,7 +6158,7 @@ static int ath11k_pull_peer_sta_kickout_ev(struct ath11k_base *ab, struct sk_buf
|
||||
const struct wmi_peer_sta_kickout_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6112,7 +6185,7 @@ static int ath11k_pull_roam_ev(struct ath11k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_roam_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6153,14 +6226,14 @@ exit:
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, u8 *evt_buf,
|
||||
u32 len, struct wmi_chan_info_event *ch_info_ev)
|
||||
static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb,
|
||||
struct wmi_chan_info_event *ch_info_ev)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_chan_info_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6199,7 +6272,7 @@ ath11k_pull_pdev_bss_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_pdev_bss_chan_info_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6239,7 +6312,7 @@ ath11k_pull_vdev_install_key_compl_ev(struct ath11k_base *ab, struct sk_buff *sk
|
||||
const struct wmi_vdev_install_key_compl_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6270,7 +6343,7 @@ static int ath11k_pull_peer_assoc_conf_ev(struct ath11k_base *ab, struct sk_buff
|
||||
const struct wmi_peer_assoc_conf_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6995,7 +7068,7 @@ static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *s
|
||||
const void **tb;
|
||||
int ret, i;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -7060,32 +7133,15 @@ static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab,
|
||||
wake_up(&wmi->tx_ce_desc_wq);
|
||||
}
|
||||
|
||||
static bool ath11k_reg_is_world_alpha(char *alpha)
|
||||
{
|
||||
if (alpha[0] == '0' && alpha[1] == '0')
|
||||
return true;
|
||||
|
||||
if (alpha[0] == 'n' && alpha[1] == 'a')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
|
||||
struct sk_buff *skb,
|
||||
static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb,
|
||||
enum wmi_reg_chan_list_cmd_type id)
|
||||
{
|
||||
struct cur_regulatory_info *reg_info = NULL;
|
||||
struct ieee80211_regdomain *regd = NULL;
|
||||
bool intersect = false;
|
||||
int ret = 0, pdev_idx, i, j;
|
||||
struct ath11k *ar;
|
||||
struct cur_regulatory_info *reg_info;
|
||||
int ret;
|
||||
|
||||
reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
|
||||
if (!reg_info) {
|
||||
ret = -ENOMEM;
|
||||
goto fallback;
|
||||
}
|
||||
if (!reg_info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (id == WMI_REG_CHAN_LIST_CC_ID)
|
||||
ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
|
||||
@ -7093,118 +7149,22 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
|
||||
ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to extract regulatory info from received event\n");
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id);
|
||||
|
||||
if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
|
||||
/* In case of failure to set the requested ctry,
|
||||
* fw retains the current regd. We print a failure info
|
||||
* and return from here.
|
||||
*/
|
||||
ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n");
|
||||
ath11k_warn(ab, "failed to extract regulatory info\n");
|
||||
goto mem_free;
|
||||
}
|
||||
|
||||
pdev_idx = reg_info->phy_id;
|
||||
|
||||
/* Avoid default reg rule updates sent during FW recovery if
|
||||
* it is already available
|
||||
*/
|
||||
spin_lock(&ab->base_lock);
|
||||
if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
|
||||
ab->default_regd[pdev_idx]) {
|
||||
spin_unlock(&ab->base_lock);
|
||||
ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to process regulatory info %d\n", ret);
|
||||
goto mem_free;
|
||||
}
|
||||
spin_unlock(&ab->base_lock);
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
/* Process the event for phy0 only if single_pdev_only
|
||||
* is true. If pdev_idx is valid but not 0, discard the
|
||||
* event. Otherwise, it goes to fallback.
|
||||
*/
|
||||
if (ab->hw_params.single_pdev_only &&
|
||||
pdev_idx < ab->hw_params.num_rxmda_per_pdev)
|
||||
goto mem_free;
|
||||
else
|
||||
goto fallback;
|
||||
}
|
||||
kfree(reg_info);
|
||||
return 0;
|
||||
|
||||
/* Avoid multiple overwrites to default regd, during core
|
||||
* stop-start after mac registration.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
|
||||
(char *)reg_info->alpha2, 2))
|
||||
goto mem_free;
|
||||
|
||||
/* Intersect new rules with default regd if a new country setting was
|
||||
* requested, i.e a default regd was already set during initialization
|
||||
* and the regd coming from this event has a valid country info.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] &&
|
||||
!ath11k_reg_is_world_alpha((char *)
|
||||
ab->default_regd[pdev_idx]->alpha2) &&
|
||||
!ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
|
||||
intersect = true;
|
||||
|
||||
regd = ath11k_reg_build_regd(ab, reg_info, intersect);
|
||||
if (!regd) {
|
||||
ath11k_warn(ab, "failed to build regd from reg_info\n");
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
spin_lock(&ab->base_lock);
|
||||
if (ab->default_regd[pdev_idx]) {
|
||||
/* The initial rules from FW after WMI Init is to build
|
||||
* the default regd. From then on, any rules updated for
|
||||
* the pdev could be due to user reg changes.
|
||||
* Free previously built regd before assigning the newly
|
||||
* generated regd to ar. NULL pointer handling will be
|
||||
* taken care by kfree itself.
|
||||
*/
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
kfree(ab->new_regd[pdev_idx]);
|
||||
ab->new_regd[pdev_idx] = regd;
|
||||
queue_work(ab->workqueue, &ar->regd_update_work);
|
||||
} else {
|
||||
/* This regd would be applied during mac registration and is
|
||||
* held constant throughout for regd intersection purpose
|
||||
*/
|
||||
ab->default_regd[pdev_idx] = regd;
|
||||
}
|
||||
ab->dfs_region = reg_info->dfs_region;
|
||||
spin_unlock(&ab->base_lock);
|
||||
|
||||
goto mem_free;
|
||||
|
||||
fallback:
|
||||
/* Fallback to older reg (by sending previous country setting
|
||||
* again if fw has succeeded and we failed to process here.
|
||||
* The Regdomain should be uniform across driver and fw. Since the
|
||||
* FW has processed the command and sent a success status, we expect
|
||||
* this function to succeed as well. If it doesn't, CTRY needs to be
|
||||
* reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent.
|
||||
*/
|
||||
/* TODO: This is rare, but still should also be handled */
|
||||
WARN_ON(1);
|
||||
mem_free:
|
||||
if (reg_info) {
|
||||
kfree(reg_info->reg_rules_2ghz_ptr);
|
||||
kfree(reg_info->reg_rules_5ghz_ptr);
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++)
|
||||
kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
|
||||
|
||||
for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++)
|
||||
for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++)
|
||||
kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]);
|
||||
}
|
||||
kfree(reg_info);
|
||||
}
|
||||
ath11k_reg_reset_info(reg_info);
|
||||
kfree(reg_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -7362,7 +7322,7 @@ static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff
|
||||
}
|
||||
|
||||
ar->last_wmi_vdev_start_status = 0;
|
||||
|
||||
ar->max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power;
|
||||
status = vdev_start_resp.status;
|
||||
|
||||
if (WARN_ON_ONCE(status)) {
|
||||
@ -7384,8 +7344,7 @@ static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *s
|
||||
struct ath11k_vif *arvif;
|
||||
u32 vdev_id, tx_status;
|
||||
|
||||
if (ath11k_pull_bcn_tx_status_ev(ab, skb->data, skb->len,
|
||||
&vdev_id, &tx_status) != 0) {
|
||||
if (ath11k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) {
|
||||
ath11k_warn(ab, "failed to extract bcn tx status");
|
||||
return;
|
||||
}
|
||||
@ -7416,7 +7375,7 @@ static void ath11k_wmi_event_peer_sta_ps_state_chg(struct ath11k_base *ab,
|
||||
enum ath11k_wmi_peer_ps_state peer_previous_ps_state;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -7884,7 +7843,7 @@ static void ath11k_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
/* HW channel counters frequency value in hertz */
|
||||
u32 cc_freq_hz = ab->cc_freq_hz;
|
||||
|
||||
if (ath11k_pull_chan_info_ev(ab, skb->data, skb->len, &ch_info_ev) != 0) {
|
||||
if (ath11k_pull_chan_info_ev(ab, skb, &ch_info_ev) != 0) {
|
||||
ath11k_warn(ab, "failed to extract chan info event");
|
||||
return;
|
||||
}
|
||||
@ -8216,7 +8175,7 @@ static void ath11k_pdev_ctl_failsafe_check_event(struct ath11k_base *ab,
|
||||
const struct wmi_pdev_ctl_failsafe_chk_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -8281,7 +8240,7 @@ ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base *ab,
|
||||
const u32 *vdev_ids;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -8315,7 +8274,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff
|
||||
struct ath11k *ar;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -8369,7 +8328,7 @@ ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab,
|
||||
const struct wmi_pdev_temperature_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -8409,7 +8368,7 @@ static void ath11k_fils_discovery_event(struct ath11k_base *ab,
|
||||
const struct wmi_fils_discovery_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab,
|
||||
@ -8441,7 +8400,7 @@ static void ath11k_probe_resp_tx_status_event(struct ath11k_base *ab,
|
||||
const struct wmi_probe_resp_tx_status_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab,
|
||||
@ -8567,7 +8526,7 @@ static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab,
|
||||
const struct wmi_twt_add_dialog_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab,
|
||||
@ -8604,7 +8563,7 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
|
||||
u64 replay_ctr;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -9793,3 +9752,9 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar,
|
||||
|
||||
return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
|
||||
}
|
||||
|
||||
bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar)
|
||||
{
|
||||
return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map) && ar->supports_6ghz;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ struct ath11k;
|
||||
struct ath11k_fw_stats;
|
||||
struct ath11k_fw_dbglog;
|
||||
struct ath11k_vif;
|
||||
struct ath11k_reg_tpc_power_info;
|
||||
|
||||
#define PSOC_HOST_MAX_NUM_SS (8)
|
||||
|
||||
@ -327,6 +328,22 @@ enum wmi_tlv_cmd_id {
|
||||
WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID,
|
||||
WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID,
|
||||
WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID,
|
||||
WMI_VDEV_SET_ARP_STAT_CMDID,
|
||||
WMI_VDEV_GET_ARP_STAT_CMDID,
|
||||
WMI_VDEV_GET_TX_POWER_CMDID,
|
||||
WMI_VDEV_LIMIT_OFFCHAN_CMDID,
|
||||
WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID,
|
||||
WMI_VDEV_CHAINMASK_CONFIG_CMDID,
|
||||
WMI_VDEV_GET_BCN_RECEPTION_STATS_CMDID,
|
||||
WMI_VDEV_GET_MWS_COEX_INFO_CMDID,
|
||||
WMI_VDEV_DELETE_ALL_PEER_CMDID,
|
||||
WMI_VDEV_BSS_MAX_IDLE_TIME_CMDID,
|
||||
WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID,
|
||||
WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID,
|
||||
WMI_VDEV_SET_PCL_CMDID,
|
||||
WMI_VDEV_GET_BIG_DATA_CMDID,
|
||||
WMI_VDEV_GET_BIG_DATA_P2_CMDID,
|
||||
WMI_VDEV_SET_TPC_POWER_CMDID,
|
||||
WMI_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_GRP_PEER),
|
||||
WMI_PEER_DELETE_CMDID,
|
||||
WMI_PEER_FLUSH_TIDS_CMDID,
|
||||
@ -1880,6 +1897,8 @@ enum wmi_tlv_tag {
|
||||
WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
|
||||
WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
|
||||
WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
|
||||
WMI_TAG_VDEV_SET_TPC_POWER_CMD = 0x3B5,
|
||||
WMI_TAG_VDEV_CH_POWER_INFO,
|
||||
WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8,
|
||||
WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD,
|
||||
WMI_TAG_MAX
|
||||
@ -2114,6 +2133,7 @@ enum wmi_tlv_service {
|
||||
/* The second 128 bits */
|
||||
WMI_MAX_EXT_SERVICE = 256,
|
||||
WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265,
|
||||
WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT = 280,
|
||||
WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
|
||||
WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326,
|
||||
WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN = 357,
|
||||
@ -3168,6 +3188,41 @@ struct wlan_ssid {
|
||||
u8 ssid[WLAN_SSID_MAX_LEN];
|
||||
};
|
||||
|
||||
struct wmi_vdev_ch_power_info {
|
||||
u32 tlv_header;
|
||||
|
||||
/* Channel center frequency (MHz) */
|
||||
u32 chan_cfreq;
|
||||
|
||||
/* Unit: dBm, either PSD/EIRP power for this frequency or
|
||||
* incremental for non-PSD BW
|
||||
*/
|
||||
u32 tx_power;
|
||||
} __packed;
|
||||
|
||||
struct wmi_vdev_set_tpc_power_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
|
||||
/* Value: 0 or 1, is PSD power or not */
|
||||
u32 psd_power;
|
||||
|
||||
/* Maximum EIRP power (dBm units), valid only if power is PSD */
|
||||
u32 eirp_power;
|
||||
|
||||
/* Type: WMI_6GHZ_REG_TYPE, used for halphy CTL lookup */
|
||||
u32 power_type_6ghz;
|
||||
|
||||
/* This fixed_param TLV is followed by the below TLVs:
|
||||
* num_pwr_levels of wmi_vdev_ch_power_info
|
||||
* For PSD power, it is the PSD/EIRP power of the frequency (20 MHz chunks).
|
||||
* For non-PSD power, the power values are for 20, 40, and till
|
||||
* BSS BW power levels.
|
||||
* The num_pwr_levels will be checked by sw how many elements present
|
||||
* in the variable-length array.
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
#define WMI_IE_BITMAP_SIZE 8
|
||||
|
||||
/* prefix used by scan requestor ids on the host */
|
||||
@ -4119,6 +4174,7 @@ struct wmi_vdev_start_resp_event {
|
||||
};
|
||||
u32 cfgd_tx_streams;
|
||||
u32 cfgd_rx_streams;
|
||||
s32 max_allowed_tx_power;
|
||||
} __packed;
|
||||
|
||||
/* VDEV start response status codes */
|
||||
@ -4951,6 +5007,7 @@ struct ath11k_targ_cap {
|
||||
};
|
||||
|
||||
enum wmi_vdev_type {
|
||||
WMI_VDEV_TYPE_UNSPEC = 0,
|
||||
WMI_VDEV_TYPE_AP = 1,
|
||||
WMI_VDEV_TYPE_STA = 2,
|
||||
WMI_VDEV_TYPE_IBSS = 3,
|
||||
@ -6295,8 +6352,8 @@ enum wmi_sta_keepalive_method {
|
||||
#define WMI_STA_KEEPALIVE_INTERVAL_DEFAULT 30
|
||||
#define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0
|
||||
|
||||
const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr,
|
||||
size_t len, gfp_t gfp);
|
||||
const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab,
|
||||
struct sk_buff *skb, gfp_t gfp);
|
||||
int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
|
||||
u32 cmd_id);
|
||||
struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
|
||||
@ -6479,5 +6536,9 @@ int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_va
|
||||
int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar);
|
||||
int ath11k_wmi_sta_keepalive(struct ath11k *ar,
|
||||
const struct wmi_sta_keepalive_arg *arg);
|
||||
bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar);
|
||||
int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar,
|
||||
u32 vdev_id,
|
||||
struct ath11k_reg_tpc_power_info *param);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -104,27 +104,66 @@ int ath12k_core_resume(struct ath12k_base *ab)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
|
||||
size_t name_len)
|
||||
static int __ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
|
||||
size_t name_len, bool with_variant,
|
||||
bool bus_type_mode)
|
||||
{
|
||||
/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
|
||||
char variant[9 + ATH12K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
|
||||
|
||||
if (ab->qmi.target.bdf_ext[0] != '\0')
|
||||
if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
|
||||
scnprintf(variant, sizeof(variant), ",variant=%s",
|
||||
ab->qmi.target.bdf_ext);
|
||||
|
||||
scnprintf(name, name_len,
|
||||
"bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
ath12k_bus_str(ab->hif.bus),
|
||||
ab->qmi.target.chip_id,
|
||||
ab->qmi.target.board_id, variant);
|
||||
switch (ab->id.bdf_search) {
|
||||
case ATH12K_BDF_SEARCH_BUS_AND_BOARD:
|
||||
if (bus_type_mode)
|
||||
scnprintf(name, name_len,
|
||||
"bus=%s",
|
||||
ath12k_bus_str(ab->hif.bus));
|
||||
else
|
||||
scnprintf(name, name_len,
|
||||
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
ath12k_bus_str(ab->hif.bus),
|
||||
ab->id.vendor, ab->id.device,
|
||||
ab->id.subsystem_vendor,
|
||||
ab->id.subsystem_device,
|
||||
ab->qmi.target.chip_id,
|
||||
ab->qmi.target.board_id,
|
||||
variant);
|
||||
break;
|
||||
default:
|
||||
scnprintf(name, name_len,
|
||||
"bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
ath12k_bus_str(ab->hif.bus),
|
||||
ab->qmi.target.chip_id,
|
||||
ab->qmi.target.board_id, variant);
|
||||
break;
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot using board name '%s'\n", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
|
||||
size_t name_len)
|
||||
{
|
||||
return __ath12k_core_create_board_name(ab, name, name_len, true, false);
|
||||
}
|
||||
|
||||
static int ath12k_core_create_fallback_board_name(struct ath12k_base *ab, char *name,
|
||||
size_t name_len)
|
||||
{
|
||||
return __ath12k_core_create_board_name(ab, name, name_len, false, false);
|
||||
}
|
||||
|
||||
static int ath12k_core_create_bus_type_board_name(struct ath12k_base *ab, char *name,
|
||||
size_t name_len)
|
||||
{
|
||||
return __ath12k_core_create_board_name(ab, name, name_len, false, true);
|
||||
}
|
||||
|
||||
const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab,
|
||||
const char *file)
|
||||
{
|
||||
@ -159,7 +198,9 @@ static int ath12k_core_parse_bd_ie_board(struct ath12k_base *ab,
|
||||
struct ath12k_board_data *bd,
|
||||
const void *buf, size_t buf_len,
|
||||
const char *boardname,
|
||||
int bd_ie_type)
|
||||
int ie_id,
|
||||
int name_id,
|
||||
int data_id)
|
||||
{
|
||||
const struct ath12k_fw_ie *hdr;
|
||||
bool name_match_found;
|
||||
@ -169,7 +210,7 @@ static int ath12k_core_parse_bd_ie_board(struct ath12k_base *ab,
|
||||
|
||||
name_match_found = false;
|
||||
|
||||
/* go through ATH12K_BD_IE_BOARD_ elements */
|
||||
/* go through ATH12K_BD_IE_BOARD_/ATH12K_BD_IE_REGDB_ elements */
|
||||
while (buf_len > sizeof(struct ath12k_fw_ie)) {
|
||||
hdr = buf;
|
||||
board_ie_id = le32_to_cpu(hdr->id);
|
||||
@ -180,48 +221,50 @@ static int ath12k_core_parse_bd_ie_board(struct ath12k_base *ab,
|
||||
buf += sizeof(*hdr);
|
||||
|
||||
if (buf_len < ALIGN(board_ie_len, 4)) {
|
||||
ath12k_err(ab, "invalid ATH12K_BD_IE_BOARD length: %zu < %zu\n",
|
||||
ath12k_err(ab, "invalid %s length: %zu < %zu\n",
|
||||
ath12k_bd_ie_type_str(ie_id),
|
||||
buf_len, ALIGN(board_ie_len, 4));
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (board_ie_id) {
|
||||
case ATH12K_BD_IE_BOARD_NAME:
|
||||
if (board_ie_id == name_id) {
|
||||
ath12k_dbg_dump(ab, ATH12K_DBG_BOOT, "board name", "",
|
||||
board_ie_data, board_ie_len);
|
||||
|
||||
if (board_ie_len != strlen(boardname))
|
||||
break;
|
||||
goto next;
|
||||
|
||||
ret = memcmp(board_ie_data, boardname, strlen(boardname));
|
||||
if (ret)
|
||||
break;
|
||||
goto next;
|
||||
|
||||
name_match_found = true;
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"boot found match for name '%s'",
|
||||
"boot found match %s for name '%s'",
|
||||
ath12k_bd_ie_type_str(ie_id),
|
||||
boardname);
|
||||
break;
|
||||
case ATH12K_BD_IE_BOARD_DATA:
|
||||
} else if (board_ie_id == data_id) {
|
||||
if (!name_match_found)
|
||||
/* no match found */
|
||||
break;
|
||||
goto next;
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"boot found board data for '%s'", boardname);
|
||||
"boot found %s for '%s'",
|
||||
ath12k_bd_ie_type_str(ie_id),
|
||||
boardname);
|
||||
|
||||
bd->data = board_ie_data;
|
||||
bd->len = board_ie_len;
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
default:
|
||||
ath12k_warn(ab, "unknown ATH12K_BD_IE_BOARD found: %d\n",
|
||||
} else {
|
||||
ath12k_warn(ab, "unknown %s id found: %d\n",
|
||||
ath12k_bd_ie_type_str(ie_id),
|
||||
board_ie_id);
|
||||
break;
|
||||
}
|
||||
|
||||
next:
|
||||
/* jump over the padding */
|
||||
board_ie_len = ALIGN(board_ie_len, 4);
|
||||
|
||||
@ -238,7 +281,10 @@ out:
|
||||
|
||||
static int ath12k_core_fetch_board_data_api_n(struct ath12k_base *ab,
|
||||
struct ath12k_board_data *bd,
|
||||
const char *boardname)
|
||||
const char *boardname,
|
||||
int ie_id_match,
|
||||
int name_id,
|
||||
int data_id)
|
||||
{
|
||||
size_t len, magic_len;
|
||||
const u8 *data;
|
||||
@ -303,22 +349,23 @@ static int ath12k_core_fetch_board_data_api_n(struct ath12k_base *ab,
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (ie_id) {
|
||||
case ATH12K_BD_IE_BOARD:
|
||||
if (ie_id == ie_id_match) {
|
||||
ret = ath12k_core_parse_bd_ie_board(ab, bd, data,
|
||||
ie_len,
|
||||
boardname,
|
||||
ATH12K_BD_IE_BOARD);
|
||||
ie_id_match,
|
||||
name_id,
|
||||
data_id);
|
||||
if (ret == -ENOENT)
|
||||
/* no match found, continue */
|
||||
break;
|
||||
goto next;
|
||||
else if (ret)
|
||||
/* there was an error, bail out */
|
||||
goto err;
|
||||
/* either found or error, so stop searching */
|
||||
goto out;
|
||||
}
|
||||
|
||||
next:
|
||||
/* jump over the padding */
|
||||
ie_len = ALIGN(ie_len, 4);
|
||||
|
||||
@ -328,8 +375,9 @@ static int ath12k_core_fetch_board_data_api_n(struct ath12k_base *ab,
|
||||
|
||||
out:
|
||||
if (!bd->data || !bd->len) {
|
||||
ath12k_err(ab,
|
||||
"failed to fetch board data for %s from %s\n",
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"failed to fetch %s for %s from %s\n",
|
||||
ath12k_bd_ie_type_str(ie_id_match),
|
||||
boardname, filepath);
|
||||
ret = -ENODATA;
|
||||
goto err;
|
||||
@ -356,28 +404,56 @@ int ath12k_core_fetch_board_data_api_1(struct ath12k_base *ab,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BOARD_NAME_SIZE 100
|
||||
#define BOARD_NAME_SIZE 200
|
||||
int ath12k_core_fetch_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd)
|
||||
{
|
||||
char boardname[BOARD_NAME_SIZE];
|
||||
char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
|
||||
char *filename, filepath[100];
|
||||
int bd_api;
|
||||
int ret;
|
||||
|
||||
ret = ath12k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
|
||||
filename = ATH12K_BOARD_API2_FILE;
|
||||
|
||||
ret = ath12k_core_create_board_name(ab, boardname, sizeof(boardname));
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to create board name: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bd_api = 2;
|
||||
ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname);
|
||||
ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname,
|
||||
ATH12K_BD_IE_BOARD,
|
||||
ATH12K_BD_IE_BOARD_NAME,
|
||||
ATH12K_BD_IE_BOARD_DATA);
|
||||
if (!ret)
|
||||
goto success;
|
||||
|
||||
ret = ath12k_core_create_fallback_board_name(ab, fallback_boardname,
|
||||
sizeof(fallback_boardname));
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to create fallback board name: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
|
||||
ATH12K_BD_IE_BOARD,
|
||||
ATH12K_BD_IE_BOARD_NAME,
|
||||
ATH12K_BD_IE_BOARD_DATA);
|
||||
if (!ret)
|
||||
goto success;
|
||||
|
||||
bd_api = 1;
|
||||
ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_DEFAULT_BOARD_FILE);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
|
||||
ath12k_core_create_firmware_path(ab, filename,
|
||||
filepath, sizeof(filepath));
|
||||
ath12k_err(ab, "failed to fetch board data for %s from %s\n",
|
||||
boardname, filepath);
|
||||
if (memcmp(boardname, fallback_boardname, strlen(boardname)))
|
||||
ath12k_err(ab, "failed to fetch board data for %s from %s\n",
|
||||
fallback_boardname, filepath);
|
||||
|
||||
ath12k_err(ab, "failed to fetch board.bin from %s\n",
|
||||
ab->hw_params->fw.dir);
|
||||
return ret;
|
||||
}
|
||||
@ -387,6 +463,52 @@ success:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd)
|
||||
{
|
||||
char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE];
|
||||
int ret;
|
||||
|
||||
ret = ath12k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
|
||||
if (ret) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"failed to create board name for regdb: %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname,
|
||||
ATH12K_BD_IE_REGDB,
|
||||
ATH12K_BD_IE_REGDB_NAME,
|
||||
ATH12K_BD_IE_REGDB_DATA);
|
||||
if (!ret)
|
||||
goto exit;
|
||||
|
||||
ret = ath12k_core_create_bus_type_board_name(ab, default_boardname,
|
||||
BOARD_NAME_SIZE);
|
||||
if (ret) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"failed to create default board name for regdb: %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = ath12k_core_fetch_board_data_api_n(ab, bd, default_boardname,
|
||||
ATH12K_BD_IE_REGDB,
|
||||
ATH12K_BD_IE_REGDB_NAME,
|
||||
ATH12K_BD_IE_REGDB_DATA);
|
||||
if (!ret)
|
||||
goto exit;
|
||||
|
||||
ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_REGDB_FILE_NAME);
|
||||
if (ret)
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to fetch %s from %s\n",
|
||||
ATH12K_REGDB_FILE_NAME, ab->hw_params->fw.dir);
|
||||
|
||||
exit:
|
||||
if (!ret)
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "fetched regdb\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath12k_core_stop(struct ath12k_base *ab)
|
||||
{
|
||||
if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
|
||||
@ -592,8 +714,6 @@ static int ath12k_core_start(struct ath12k_base *ab,
|
||||
|
||||
ath12k_dp_cc_config(ab);
|
||||
|
||||
ath12k_dp_pdev_pre_alloc(ab);
|
||||
|
||||
ret = ath12k_dp_rx_pdev_reo_setup(ab);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
|
||||
@ -759,6 +879,7 @@ static void ath12k_rfkill_work(struct work_struct *work)
|
||||
{
|
||||
struct ath12k_base *ab = container_of(work, struct ath12k_base, rfkill_work);
|
||||
struct ath12k *ar;
|
||||
struct ieee80211_hw *hw;
|
||||
bool rfkill_radio_on;
|
||||
int i;
|
||||
|
||||
@ -771,8 +892,9 @@ static void ath12k_rfkill_work(struct work_struct *work)
|
||||
if (!ar)
|
||||
continue;
|
||||
|
||||
hw = ath12k_ar_to_hw(ar);
|
||||
ath12k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
|
||||
wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
|
||||
wiphy_rfkill_set_hw_state(hw->wiphy, !rfkill_radio_on);
|
||||
}
|
||||
}
|
||||
|
||||
@ -801,6 +923,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k *ar;
|
||||
struct ath12k_pdev *pdev;
|
||||
struct ath12k_hw *ah;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
@ -810,13 +933,20 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
|
||||
if (ab->is_reset)
|
||||
set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
||||
|
||||
for (i = 0; i < ab->num_hw; i++) {
|
||||
if (!ab->ah[i])
|
||||
continue;
|
||||
|
||||
ah = ab->ah[i];
|
||||
ieee80211_stop_queues(ah->hw);
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
if (!ar || ar->state == ATH12K_STATE_OFF)
|
||||
continue;
|
||||
|
||||
ieee80211_stop_queues(ar->hw);
|
||||
ath12k_mac_drain_tx(ar);
|
||||
complete(&ar->scan.started);
|
||||
complete(&ar->scan.completed);
|
||||
@ -856,7 +986,7 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
|
||||
case ATH12K_STATE_ON:
|
||||
ar->state = ATH12K_STATE_RESTARTING;
|
||||
ath12k_core_halt(ar);
|
||||
ieee80211_restart_hw(ar->hw);
|
||||
ieee80211_restart_hw(ath12k_ar_to_hw(ar));
|
||||
break;
|
||||
case ATH12K_STATE_OFF:
|
||||
ath12k_warn(ab,
|
||||
@ -1054,6 +1184,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
|
||||
|
||||
ab->dev = dev;
|
||||
ab->hif.bus = bus;
|
||||
ab->qmi.num_radios = U8_MAX;
|
||||
|
||||
return ab;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_CORE_H
|
||||
@ -55,6 +55,11 @@
|
||||
#define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ)
|
||||
#define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ)
|
||||
|
||||
enum ath12k_bdf_search {
|
||||
ATH12K_BDF_SEARCH_DEFAULT,
|
||||
ATH12K_BDF_SEARCH_BUS_AND_BOARD,
|
||||
};
|
||||
|
||||
enum wme_ac {
|
||||
WME_AC_BE,
|
||||
WME_AC_BK,
|
||||
@ -420,7 +425,7 @@ struct ath12k_sta {
|
||||
};
|
||||
|
||||
#define ATH12K_MIN_5G_FREQ 4150
|
||||
#define ATH12K_MIN_6G_FREQ 5945
|
||||
#define ATH12K_MIN_6G_FREQ 5925
|
||||
#define ATH12K_MAX_6G_FREQ 7115
|
||||
#define ATH12K_NUM_CHANS 100
|
||||
#define ATH12K_MAX_5G_CHAN 173
|
||||
@ -468,7 +473,7 @@ struct ath12k_per_peer_tx_stats {
|
||||
struct ath12k {
|
||||
struct ath12k_base *ab;
|
||||
struct ath12k_pdev *pdev;
|
||||
struct ieee80211_hw *hw;
|
||||
struct ath12k_hw *ah;
|
||||
struct ath12k_wmi_pdev *wmi;
|
||||
struct ath12k_pdev_dp dp;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
@ -532,6 +537,7 @@ struct ath12k {
|
||||
/* pdev_idx starts from 0 whereas pdev->pdev_id starts with 1 */
|
||||
u8 pdev_idx;
|
||||
u8 lmac_id;
|
||||
u8 hw_link_id;
|
||||
|
||||
struct completion peer_assoc_done;
|
||||
struct completion peer_delete_done;
|
||||
@ -591,6 +597,13 @@ struct ath12k {
|
||||
int monitor_vdev_id;
|
||||
};
|
||||
|
||||
struct ath12k_hw {
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
u8 num_radio;
|
||||
struct ath12k radio[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
struct ath12k_band_cap {
|
||||
u32 phy_id;
|
||||
u32 max_bw_supported;
|
||||
@ -724,6 +737,16 @@ struct ath12k_base {
|
||||
u8 fw_pdev_count;
|
||||
|
||||
struct ath12k_pdev __rcu *pdevs_active[MAX_RADIOS];
|
||||
|
||||
/* Holds information of wiphy (hw) registration.
|
||||
*
|
||||
* In Multi/Single Link Operation case, all pdevs are registered as
|
||||
* a single wiphy. In other (legacy/Non-MLO) cases, each pdev is
|
||||
* registered as separate wiphys.
|
||||
*/
|
||||
struct ath12k_hw *ah[MAX_RADIOS];
|
||||
u8 num_hw;
|
||||
|
||||
struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS];
|
||||
unsigned long long free_vdev_map;
|
||||
unsigned long long free_vdev_stats_id_map;
|
||||
@ -793,10 +816,23 @@ struct ath12k_base {
|
||||
/* true means radio is on */
|
||||
bool rfkill_radio_on;
|
||||
|
||||
struct {
|
||||
enum ath12k_bdf_search bdf_search;
|
||||
u32 vendor;
|
||||
u32 device;
|
||||
u32 subsystem_vendor;
|
||||
u32 subsystem_device;
|
||||
} id;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
struct ath12k_pdev_map {
|
||||
struct ath12k_base *ab;
|
||||
u8 pdev_idx;
|
||||
};
|
||||
|
||||
int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab);
|
||||
int ath12k_core_pre_init(struct ath12k_base *ab);
|
||||
int ath12k_core_init(struct ath12k_base *ath12k);
|
||||
@ -810,6 +846,7 @@ int ath12k_core_fetch_board_data_api_1(struct ath12k_base *ab,
|
||||
int ath12k_core_fetch_bdf(struct ath12k_base *ath12k,
|
||||
struct ath12k_board_data *bd);
|
||||
void ath12k_core_free_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd);
|
||||
int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd);
|
||||
int ath12k_core_check_dt(struct ath12k_base *ath12k);
|
||||
int ath12k_core_check_smbios(struct ath12k_base *ab);
|
||||
void ath12k_core_halt(struct ath12k *ar);
|
||||
@ -882,4 +919,18 @@ static inline const char *ath12k_bus_str(enum ath12k_bus bus)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static inline struct ath12k_hw *ath12k_hw_to_ah(struct ieee80211_hw *hw)
|
||||
{
|
||||
return hw->priv;
|
||||
}
|
||||
|
||||
static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah)
|
||||
{
|
||||
return ah->radio;
|
||||
}
|
||||
|
||||
static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar)
|
||||
{
|
||||
return ar->ah->hw;
|
||||
}
|
||||
#endif /* _CORE_H_ */
|
||||
|
@ -150,7 +150,7 @@ struct ath12k_pdev_dp {
|
||||
|
||||
#define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */
|
||||
|
||||
#define DP_BA_WIN_SZ_MAX 256
|
||||
#define DP_BA_WIN_SZ_MAX 1024
|
||||
|
||||
#define DP_TCL_NUM_RING_MAX 4
|
||||
|
||||
@ -170,6 +170,7 @@ struct ath12k_pdev_dp {
|
||||
#define DP_REO_CMD_RING_SIZE 128
|
||||
#define DP_REO_STATUS_RING_SIZE 2048
|
||||
#define DP_RXDMA_BUF_RING_SIZE 4096
|
||||
#define DP_RX_MAC_BUF_RING_SIZE 2048
|
||||
#define DP_RXDMA_REFILL_RING_SIZE 2048
|
||||
#define DP_RXDMA_ERR_DST_RING_SIZE 1024
|
||||
#define DP_RXDMA_MON_STATUS_RING_SIZE 1024
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "dp_mon.h"
|
||||
@ -1130,7 +1130,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
|
||||
!(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
|
||||
rx_status->flag |= RX_FLAG_8023;
|
||||
|
||||
ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
||||
ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi);
|
||||
}
|
||||
|
||||
static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, u32 mac_id,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
@ -2458,7 +2458,7 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
|
||||
!(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
|
||||
rx_status->flag |= RX_FLAG_8023;
|
||||
|
||||
ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
||||
ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi);
|
||||
}
|
||||
|
||||
static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
|
||||
@ -2844,7 +2844,7 @@ mic_fail:
|
||||
ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);
|
||||
ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
|
||||
HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);
|
||||
ieee80211_rx(ar->hw, msdu);
|
||||
ieee80211_rx(ath12k_ar_to_hw(ar), msdu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -4086,7 +4086,7 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
||||
ret = ath12k_dp_srng_setup(ab,
|
||||
&dp->rx_mac_buf_ring[i],
|
||||
HAL_RXDMA_BUF, 1,
|
||||
i, 1024);
|
||||
i, DP_RX_MAC_BUF_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to setup rx_mac_buf_ring %d\n",
|
||||
i);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
@ -151,7 +151,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
!ieee80211_is_data(hdr->frame_control))
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);
|
||||
|
||||
@ -401,7 +401,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
||||
}
|
||||
}
|
||||
|
||||
ieee80211_tx_status_skb(ar->hw, msdu);
|
||||
ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -498,7 +498,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
||||
* Might end up reporting it out-of-band from HTT stats.
|
||||
*/
|
||||
|
||||
ieee80211_tx_status_skb(ar->hw, msdu);
|
||||
ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
@ -837,7 +837,7 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)
|
||||
if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
|
||||
ath12k_err(ab, "unsupported htt major version %d supported version is %d\n",
|
||||
dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2500,13 +2500,13 @@ struct hal_rx_reo_queue {
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE BIT(30)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG BIT(31)
|
||||
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE GENMASK(7, 0)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE GENMASK(9, 8)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SVLD BIT(10)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SSN GENMASK(22, 11)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR BIT(23)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR BIT(24)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_VALID BIT(25)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE GENMASK(9, 0)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE GENMASK(11, 10)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SVLD BIT(12)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SSN GENMASK(24, 13)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR BIT(25)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR BIT(26)
|
||||
#define HAL_REO_UPD_RX_QUEUE_INFO2_PN_VALID BIT(27)
|
||||
|
||||
struct hal_reo_update_rx_queue {
|
||||
struct hal_reo_cmd_hdr cmd;
|
||||
@ -2517,6 +2517,12 @@ struct hal_reo_update_rx_queue {
|
||||
__le32 pn[4];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_reo_queue_1k {
|
||||
struct hal_desc_header desc_hdr;
|
||||
__le32 rx_bitmap_1023_288[23];
|
||||
__le32 reserved[8];
|
||||
} __packed;
|
||||
|
||||
#define HAL_REO_UNBLOCK_CACHE_INFO0_UNBLK_CACHE BIT(0)
|
||||
#define HAL_REO_UNBLOCK_CACHE_INFO0_RESOURCE_IDX GENMASK(2, 1)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
@ -247,7 +247,7 @@ int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
case HAL_REO_CMD_UNBLOCK_CACHE:
|
||||
case HAL_REO_CMD_FLUSH_TIMEOUT_LIST:
|
||||
ath12k_warn(ab, "Unsupported reo command %d\n", type);
|
||||
ret = -ENOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
default:
|
||||
ath12k_warn(ab, "Unknown reo command %d\n", type);
|
||||
@ -688,23 +688,28 @@ void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab,
|
||||
|
||||
u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)
|
||||
{
|
||||
u32 num_ext_desc;
|
||||
u32 num_ext_desc, num_1k_desc = 0;
|
||||
|
||||
if (ba_window_size <= 1) {
|
||||
if (tid != HAL_DESC_REO_NON_QOS_TID)
|
||||
num_ext_desc = 1;
|
||||
else
|
||||
num_ext_desc = 0;
|
||||
|
||||
} else if (ba_window_size <= 105) {
|
||||
num_ext_desc = 1;
|
||||
} else if (ba_window_size <= 210) {
|
||||
num_ext_desc = 2;
|
||||
} else {
|
||||
} else if (ba_window_size <= 256) {
|
||||
num_ext_desc = 3;
|
||||
} else {
|
||||
num_ext_desc = 10;
|
||||
num_1k_desc = 1;
|
||||
}
|
||||
|
||||
return sizeof(struct hal_rx_reo_queue) +
|
||||
(num_ext_desc * sizeof(struct hal_rx_reo_queue_ext));
|
||||
(num_ext_desc * sizeof(struct hal_rx_reo_queue_ext)) +
|
||||
(num_1k_desc * sizeof(struct hal_rx_reo_queue_1k));
|
||||
}
|
||||
|
||||
void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,
|
||||
|
@ -914,6 +914,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0,
|
||||
|
||||
.def_num_link = 0,
|
||||
.max_mlo_peer = 256,
|
||||
},
|
||||
{
|
||||
.name = "wcn7850 hw2.0",
|
||||
@ -978,6 +981,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.rfkill_on_level = 1,
|
||||
|
||||
.rddm_size = 0x780000,
|
||||
|
||||
.def_num_link = 2,
|
||||
.max_mlo_peer = 32,
|
||||
},
|
||||
{
|
||||
.name = "qcn9274 hw2.0",
|
||||
@ -1040,6 +1046,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0,
|
||||
|
||||
.def_num_link = 0,
|
||||
.max_mlo_peer = 256,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -192,6 +192,9 @@ struct ath12k_hw_params {
|
||||
u32 rfkill_on_level;
|
||||
|
||||
u32 rddm_size;
|
||||
|
||||
u8 def_num_link;
|
||||
u16 max_mlo_peer;
|
||||
};
|
||||
|
||||
struct ath12k_hw_ops {
|
||||
@ -242,10 +245,16 @@ enum ath12k_bd_ie_board_type {
|
||||
ATH12K_BD_IE_BOARD_DATA = 1,
|
||||
};
|
||||
|
||||
enum ath12k_bd_ie_regdb_type {
|
||||
ATH12K_BD_IE_REGDB_NAME = 0,
|
||||
ATH12K_BD_IE_REGDB_DATA = 1,
|
||||
};
|
||||
|
||||
enum ath12k_bd_ie_type {
|
||||
/* contains sub IEs of enum ath12k_bd_ie_board_type */
|
||||
ATH12K_BD_IE_BOARD = 0,
|
||||
ATH12K_BD_IE_BOARD_EXT = 1,
|
||||
/* contains sub IEs of enum ath12k_bd_ie_regdb_type */
|
||||
ATH12K_BD_IE_REGDB = 1,
|
||||
};
|
||||
|
||||
struct ath12k_hw_regs {
|
||||
@ -315,6 +324,18 @@ struct ath12k_hw_regs {
|
||||
u32 hal_reo_status_ring_base;
|
||||
};
|
||||
|
||||
static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case ATH12K_BD_IE_BOARD:
|
||||
return "board data";
|
||||
case ATH12K_BD_IE_REGDB:
|
||||
return "regdb data";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int ath12k_hw_init(struct ath12k_base *ab);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_MAC_H
|
||||
@ -12,6 +12,8 @@
|
||||
|
||||
struct ath12k;
|
||||
struct ath12k_base;
|
||||
struct ath12k_hw;
|
||||
struct ath12k_pdev_map;
|
||||
|
||||
struct ath12k_generic_iter {
|
||||
struct ath12k *ar;
|
||||
|
@ -1310,6 +1310,15 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
|
||||
goto err_free_core;
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor, pdev->subsystem_device);
|
||||
|
||||
ab->id.vendor = pdev->vendor;
|
||||
ab->id.device = pdev->device;
|
||||
ab->id.subsystem_vendor = pdev->subsystem_vendor;
|
||||
ab->id.subsystem_device = pdev->subsystem_device;
|
||||
|
||||
switch (pci_dev->device) {
|
||||
case QCN9274_DEVICE_ID:
|
||||
ab_pci->msi_config = &ath12k_msi_config[0];
|
||||
@ -1333,6 +1342,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
|
||||
}
|
||||
break;
|
||||
case WCN7850_DEVICE_ID:
|
||||
ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
|
||||
ab_pci->msi_config = &ath12k_msi_config[0];
|
||||
ab->static_window_map = false;
|
||||
ab_pci->pci_ops = &ath12k_pci_ops_wcn7850;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/elf.h>
|
||||
@ -17,7 +17,7 @@
|
||||
#define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08
|
||||
#define ATH12K_QMI_MAX_CHUNK_SIZE 2097152
|
||||
|
||||
static struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -61,7 +61,7 @@ static struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
@ -511,7 +511,7 @@ static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -528,7 +528,68 @@ static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_phy_cap_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
|
||||
num_phy_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
|
||||
num_phy),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
|
||||
board_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
|
||||
board_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
@ -753,7 +814,7 @@ static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -789,7 +850,7 @@ static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -821,7 +882,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -863,7 +924,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
@ -890,7 +951,7 @@ static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -930,7 +991,7 @@ static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
@ -957,7 +1018,7 @@ static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -975,7 +1036,7 @@ static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
@ -983,7 +1044,7 @@ static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1009,7 +1070,7 @@ static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1026,7 +1087,7 @@ static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1042,7 +1103,7 @@ static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1068,7 +1129,7 @@ static struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1094,7 +1155,7 @@ static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -1348,7 +1409,7 @@ static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1483,7 +1544,7 @@ static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -1501,7 +1562,7 @@ static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1525,7 +1586,7 @@ static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -1542,7 +1603,7 @@ static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1595,7 +1656,7 @@ static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1630,7 +1691,7 @@ static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_2_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1654,7 +1715,7 @@ static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1671,7 +1732,7 @@ static struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
@ -1706,7 +1767,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -1724,7 +1785,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
@ -1862,7 +1923,7 @@ static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@ -1879,22 +1940,78 @@ static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
},
|
||||
};
|
||||
|
||||
static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
|
||||
static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
},
|
||||
};
|
||||
|
||||
static void ath12k_host_cap_parse_mlo(struct qmi_wlanfw_host_cap_req_msg_v01 *req)
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
|
||||
enable_fwlog_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
|
||||
enable_fwlog),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static void ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
|
||||
struct qmi_wlanfw_host_cap_req_msg_v01 *req)
|
||||
{
|
||||
struct wlfw_host_mlo_chip_info_s_v01 *info;
|
||||
u8 hw_link_id = 0;
|
||||
int i;
|
||||
|
||||
if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"skip QMI MLO cap due to invalid num_radio %d\n",
|
||||
ab->qmi.num_radios);
|
||||
return;
|
||||
}
|
||||
|
||||
req->mlo_capable_valid = 1;
|
||||
req->mlo_capable = 1;
|
||||
req->mlo_chip_id_valid = 1;
|
||||
@ -1905,28 +2022,31 @@ static void ath12k_host_cap_parse_mlo(struct qmi_wlanfw_host_cap_req_msg_v01 *re
|
||||
/* Max peer number generally won't change for the same device
|
||||
* but needs to be synced with host driver.
|
||||
*/
|
||||
req->max_mlo_peer = 32;
|
||||
req->max_mlo_peer = ab->hw_params->max_mlo_peer;
|
||||
req->mlo_num_chips_valid = 1;
|
||||
req->mlo_num_chips = 1;
|
||||
|
||||
info = &req->mlo_chip_info[0];
|
||||
info->chip_id = 0;
|
||||
info->num_local_links = ab->qmi.num_radios;
|
||||
|
||||
for (i = 0; i < info->num_local_links; i++) {
|
||||
info->hw_link_id[i] = hw_link_id;
|
||||
info->valid_mlo_link_id[i] = 1;
|
||||
|
||||
hw_link_id++;
|
||||
}
|
||||
|
||||
req->mlo_chip_info_valid = 1;
|
||||
req->mlo_chip_info[0].chip_id = 0;
|
||||
req->mlo_chip_info[0].num_local_links = 2;
|
||||
req->mlo_chip_info[0].hw_link_id[0] = 0;
|
||||
req->mlo_chip_info[0].hw_link_id[1] = 1;
|
||||
req->mlo_chip_info[0].valid_mlo_link_id[0] = 1;
|
||||
req->mlo_chip_info[0].valid_mlo_link_id[1] = 1;
|
||||
}
|
||||
|
||||
static int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_host_cap_req_msg_v01 req;
|
||||
struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_host_cap_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req.num_clients_valid = 1;
|
||||
req.num_clients = 1;
|
||||
req.mem_cfg_mode = ab->qmi.target_mem_mode;
|
||||
@ -1963,10 +2083,10 @@ static int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
|
||||
*/
|
||||
req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
|
||||
req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
|
||||
|
||||
ath12k_host_cap_parse_mlo(&req);
|
||||
}
|
||||
|
||||
ath12k_host_cap_parse_mlo(ab, &req);
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
|
||||
if (ret < 0)
|
||||
@ -1977,6 +2097,7 @@ static int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
|
||||
QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
@ -1996,6 +2117,59 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_phy_cap_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret;
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
QMI_WLANFW_PHY_CAP_REQ_V01,
|
||||
QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_phy_cap_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "failed to send phy capability request: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!resp.num_phy_valid) {
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ab->qmi.num_radios = resp.num_phy;
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI, "phy capability resp valid %d num_phy %d valid %d board_id %d\n",
|
||||
resp.num_phy_valid, resp.num_phy,
|
||||
resp.board_id_valid, resp.board_id);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
/* If PHY capability not advertised then rely on default num link */
|
||||
ab->qmi.num_radios = ab->hw_params->def_num_link;
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"no valid response from PHY capability, choose default num_phy %d\n",
|
||||
ab->qmi.num_radios);
|
||||
}
|
||||
|
||||
static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_ind_register_req_msg_v01 *req;
|
||||
@ -2040,6 +2214,7 @@ static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
|
||||
QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_ind_register_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@ -2068,8 +2243,8 @@ resp_out:
|
||||
static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0, i;
|
||||
bool delayed;
|
||||
|
||||
@ -2077,8 +2252,6 @@ static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
/* Some targets by default request a block of big contiguous
|
||||
* DMA memory, it's hard to allocate from kernel. So host returns
|
||||
* failure to firmware and firmware then request multiple blocks of
|
||||
@ -2088,7 +2261,6 @@ static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
|
||||
delayed = true;
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
|
||||
ab->qmi.mem_seg_count);
|
||||
memset(req, 0, sizeof(*req));
|
||||
} else {
|
||||
delayed = false;
|
||||
req->mem_seg_len = ab->qmi.mem_seg_count;
|
||||
@ -2114,6 +2286,7 @@ static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
|
||||
QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@ -2208,17 +2381,14 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
|
||||
|
||||
static int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_cap_req_msg_v01 req;
|
||||
struct qmi_wlanfw_cap_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_cap_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_cap_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
|
||||
int ret = 0;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
|
||||
if (ret < 0)
|
||||
@ -2229,6 +2399,7 @@ static int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
|
||||
QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_cap_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@ -2310,8 +2481,8 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
|
||||
const u8 *data, u32 len, u8 type)
|
||||
{
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
const u8 *temp = data;
|
||||
int ret;
|
||||
u32 remaining = len;
|
||||
@ -2319,7 +2490,6 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
while (remaining) {
|
||||
req->valid = 1;
|
||||
@ -2423,8 +2593,7 @@ static int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab,
|
||||
|
||||
break;
|
||||
case ATH12K_QMI_BDF_TYPE_REGDB:
|
||||
ret = ath12k_core_fetch_board_data_api_1(ab, &bd,
|
||||
ATH12K_REGDB_FILE_NAME);
|
||||
ret = ath12k_core_fetch_regdb(ab, &bd);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "qmi failed to load regdb bin:\n");
|
||||
goto out;
|
||||
@ -2546,14 +2715,11 @@ static void ath12k_qmi_m3_free(struct ath12k_base *ab)
|
||||
static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
|
||||
struct qmi_wlanfw_m3_info_req_msg_v01 req;
|
||||
struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_m3_info_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
ret = ath12k_qmi_m3_load(ab);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to load m3 firmware: %d", ret);
|
||||
@ -2573,6 +2739,7 @@ static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
|
||||
QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
|
||||
qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@ -2597,14 +2764,11 @@ out:
|
||||
static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
|
||||
u32 mode)
|
||||
{
|
||||
struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
|
||||
struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req.mode = mode;
|
||||
req.hw_debug_valid = 1;
|
||||
req.hw_debug = 0;
|
||||
@ -2619,6 +2783,7 @@ static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
|
||||
QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
|
||||
mode, ret);
|
||||
goto out;
|
||||
@ -2649,10 +2814,10 @@ out:
|
||||
static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
|
||||
struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {};
|
||||
struct ce_pipe_config *ce_cfg;
|
||||
struct service_to_pipe *svc_cfg;
|
||||
struct qmi_txn txn = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0, pipe_num;
|
||||
|
||||
ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
|
||||
@ -2662,8 +2827,6 @@ static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req->host_version_valid = 1;
|
||||
strscpy(req->host_version, ATH12K_HOST_VERSION_STRING,
|
||||
sizeof(req->host_version));
|
||||
@ -2710,6 +2873,7 @@ static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
|
||||
QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@ -2733,6 +2897,49 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
|
||||
struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
|
||||
struct qmi_txn txn;
|
||||
int ret;
|
||||
|
||||
req.enable_fwlog_valid = true;
|
||||
req.enable_fwlog = 1;
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01,
|
||||
QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
|
||||
resp.resp.result, resp.resp.error);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath12k_qmi_firmware_stop(struct ath12k_base *ab)
|
||||
{
|
||||
int ret;
|
||||
@ -2749,6 +2956,12 @@ int ath12k_qmi_firmware_start(struct ath12k_base *ab,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ath12k_qmi_wlanfw_wlan_ini_send(ab);
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab);
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
|
||||
@ -2792,6 +3005,8 @@ static int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi)
|
||||
struct ath12k_base *ab = qmi->ab;
|
||||
int ret;
|
||||
|
||||
ath12k_qmi_phy_cap_send(ab);
|
||||
|
||||
ret = ath12k_qmi_fw_ind_register_send(ab);
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_QMI_H
|
||||
@ -141,6 +141,7 @@ struct ath12k_qmi {
|
||||
u32 target_mem_mode;
|
||||
bool target_mem_delayed;
|
||||
u8 cal_done;
|
||||
u8 num_radios;
|
||||
struct target_info target;
|
||||
struct m3_mem_region m3_mem;
|
||||
unsigned int service_ins_id;
|
||||
@ -251,6 +252,22 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN 0
|
||||
#define QMI_WLANFW_PHY_CAP_REQ_V01 0x0057
|
||||
#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN 18
|
||||
#define QMI_WLANFW_PHY_CAP_RESP_V01 0x0057
|
||||
|
||||
struct qmi_wlanfw_phy_cap_req_msg_v01 {
|
||||
};
|
||||
|
||||
struct qmi_wlanfw_phy_cap_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
u8 num_phy_valid;
|
||||
u8 num_phy;
|
||||
u8 board_id_valid;
|
||||
u32 board_id;
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN 54
|
||||
#define QMI_WLANFW_IND_REGISTER_REQ_V01 0x0020
|
||||
#define QMI_WLANFW_IND_REGISTER_RESP_MSG_V01_MAX_LEN 18
|
||||
@ -559,6 +576,21 @@ struct qmi_wlanfw_wlan_cfg_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01 0x002F
|
||||
#define ATH12K_QMI_WLANFW_WLAN_INI_RESP_V01 0x002F
|
||||
#define QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN 7
|
||||
#define QMI_WLANFW_WLAN_INI_RESP_MSG_V01_MAX_LEN 7
|
||||
|
||||
struct qmi_wlanfw_wlan_ini_req_msg_v01 {
|
||||
/* Must be set to true if enable_fwlog is being passed */
|
||||
u8 enable_fwlog_valid;
|
||||
u8 enable_fwlog;
|
||||
};
|
||||
|
||||
struct qmi_wlanfw_wlan_ini_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
int ath12k_qmi_firmware_start(struct ath12k_base *ab,
|
||||
u32 mode);
|
||||
void ath12k_qmi_firmware_stop(struct ath12k_base *ab);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/rtnetlink.h>
|
||||
#include "core.h"
|
||||
@ -48,7 +48,8 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct ath12k_wmi_init_country_arg arg;
|
||||
struct ath12k *ar = hw->priv;
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
struct ath12k *ar = ath12k_ah_to_ar(ah);
|
||||
int ret;
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_REG,
|
||||
@ -95,7 +96,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar)
|
||||
struct ieee80211_supported_band **bands;
|
||||
struct ath12k_wmi_scan_chan_list_arg *arg;
|
||||
struct ieee80211_channel *channel;
|
||||
struct ieee80211_hw *hw = ar->hw;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ath12k_wmi_channel_arg *ch;
|
||||
enum nl80211_band band;
|
||||
int num_channels = 0;
|
||||
@ -103,7 +104,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar)
|
||||
|
||||
bands = hw->wiphy->bands;
|
||||
for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
||||
if (!bands[band])
|
||||
if (!(ar->mac.sbands[band].channels && bands[band]))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < bands[band]->n_channels; i++) {
|
||||
@ -129,7 +130,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar)
|
||||
ch = arg->channel;
|
||||
|
||||
for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
||||
if (!bands[band])
|
||||
if (!(ar->mac.sbands[band].channels && bands[band]))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < bands[band]->n_channels; i++) {
|
||||
@ -199,7 +200,7 @@ static void ath12k_copy_regd(struct ieee80211_regdomain *regd_orig,
|
||||
|
||||
int ath12k_regd_update(struct ath12k *ar, bool init)
|
||||
{
|
||||
struct ieee80211_hw *hw = ar->hw;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ieee80211_regdomain *regd, *regd_copy = NULL;
|
||||
int ret, regd_len, pdev_id;
|
||||
struct ath12k_base *ab;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
@ -140,6 +140,33 @@ TRACE_EVENT(ath12k_htt_rxdesc,
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath12k_wmi_diag,
|
||||
TP_PROTO(struct ath12k_base *ab, const void *data, size_t len),
|
||||
|
||||
TP_ARGS(ab, data, len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ab->dev))
|
||||
__string(driver, dev_driver_string(ab->dev))
|
||||
__field(u16, len)
|
||||
__dynamic_array(u8, data, len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ab->dev));
|
||||
__assign_str(driver, dev_driver_string(ab->dev));
|
||||
__entry->len = len;
|
||||
memcpy(__get_dynamic_array(data), data, len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s %s tlv diag len %d",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->len
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
|
||||
|
||||
/* we don't want to use include/trace/events */
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ctype.h>
|
||||
@ -359,8 +359,8 @@ static int ath12k_wmi_tlv_parse(struct ath12k_base *ar, const void **tb,
|
||||
}
|
||||
|
||||
static const void **
|
||||
ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab, const void *ptr,
|
||||
size_t len, gfp_t gfp)
|
||||
ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab,
|
||||
struct sk_buff *skb, gfp_t gfp)
|
||||
{
|
||||
const void **tb;
|
||||
int ret;
|
||||
@ -369,7 +369,7 @@ ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab, const void *ptr,
|
||||
if (!tb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = ath12k_wmi_tlv_parse(ab, tb, ptr, len);
|
||||
ret = ath12k_wmi_tlv_parse(ab, tb, skb->data, skb->len);
|
||||
if (ret) {
|
||||
kfree(tb);
|
||||
return ERR_PTR(ret);
|
||||
@ -4374,7 +4374,7 @@ static int ath12k_pull_vdev_start_resp_tlv(struct ath12k_base *ab, struct sk_buf
|
||||
const struct wmi_vdev_start_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4452,7 +4452,7 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI, "processing regulatory ext channel list\n");
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4738,7 +4738,7 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
|
||||
const struct wmi_peer_delete_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4770,7 +4770,7 @@ static int ath12k_pull_vdev_del_resp_ev(struct ath12k_base *ab,
|
||||
const struct wmi_vdev_delete_resp_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4790,15 +4790,15 @@ static int ath12k_pull_vdev_del_resp_ev(struct ath12k_base *ab,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab, void *evt_buf,
|
||||
u32 len, u32 *vdev_id,
|
||||
u32 *tx_status)
|
||||
static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab,
|
||||
struct sk_buff *skb,
|
||||
u32 *vdev_id, u32 *tx_status)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_bcn_tx_status_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4826,7 +4826,7 @@ static int ath12k_pull_vdev_stopped_param_tlv(struct ath12k_base *ab, struct sk_
|
||||
const struct wmi_vdev_stopped_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -4948,7 +4948,7 @@ static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id,
|
||||
if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status)
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
||||
ieee80211_tx_status_irqsafe(ar->hw, msdu);
|
||||
ieee80211_tx_status_irqsafe(ath12k_ar_to_hw(ar), msdu);
|
||||
|
||||
num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx);
|
||||
|
||||
@ -4970,7 +4970,7 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
|
||||
const struct wmi_mgmt_tx_compl_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5076,6 +5076,8 @@ static void ath12k_wmi_event_scan_bss_chan(struct ath12k *ar)
|
||||
|
||||
static void ath12k_wmi_event_scan_foreign_chan(struct ath12k *ar, u32 freq)
|
||||
{
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
switch (ar->scan.state) {
|
||||
@ -5087,7 +5089,7 @@ static void ath12k_wmi_event_scan_foreign_chan(struct ath12k *ar, u32 freq)
|
||||
break;
|
||||
case ATH12K_SCAN_RUNNING:
|
||||
case ATH12K_SCAN_ABORTING:
|
||||
ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq);
|
||||
ar->scan_channel = ieee80211_get_channel(hw->wiphy, freq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -5141,7 +5143,7 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_scan_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5174,7 +5176,7 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
|
||||
const struct wmi_peer_sta_kickout_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5201,7 +5203,7 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_roam_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5226,13 +5228,14 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
static int freq_to_idx(struct ath12k *ar, int freq)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
int band, ch, idx = 0;
|
||||
|
||||
for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
|
||||
if (!ar->mac.sbands[band].channels)
|
||||
continue;
|
||||
|
||||
sband = ar->hw->wiphy->bands[band];
|
||||
sband = hw->wiphy->bands[band];
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
@ -5245,14 +5248,14 @@ exit:
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, u8 *evt_buf,
|
||||
u32 len, struct wmi_chan_info_event *ch_info_ev)
|
||||
static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
struct wmi_chan_info_event *ch_info_ev)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_chan_info_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5291,7 +5294,7 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_pdev_bss_chan_info_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5331,7 +5334,7 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
|
||||
const struct wmi_vdev_install_key_compl_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5362,7 +5365,7 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
|
||||
const struct wmi_peer_assoc_conf_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5384,13 +5387,13 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
|
||||
}
|
||||
|
||||
static int
|
||||
ath12k_pull_pdev_temp_ev(struct ath12k_base *ab, u8 *evt_buf,
|
||||
u32 len, const struct wmi_pdev_temperature_event *ev)
|
||||
ath12k_pull_pdev_temp_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
||||
const struct wmi_pdev_temperature_event *ev)
|
||||
{
|
||||
const void **tb;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -5725,8 +5728,7 @@ static void ath12k_bcn_tx_status_event(struct ath12k_base *ab, struct sk_buff *s
|
||||
{
|
||||
u32 vdev_id, tx_status;
|
||||
|
||||
if (ath12k_pull_bcn_tx_status_ev(ab, skb->data, skb->len,
|
||||
&vdev_id, &tx_status) != 0) {
|
||||
if (ath12k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) {
|
||||
ath12k_warn(ab, "failed to extract bcn tx status");
|
||||
return;
|
||||
}
|
||||
@ -5864,7 +5866,7 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
status->freq, status->band, status->signal,
|
||||
status->rate_idx);
|
||||
|
||||
ieee80211_rx_ni(ar->hw, skb);
|
||||
ieee80211_rx_ni(ath12k_ar_to_hw(ar), skb);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
@ -6037,7 +6039,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sta = ieee80211_find_sta_by_ifaddr(ar->hw,
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr, NULL);
|
||||
if (!sta) {
|
||||
ath12k_warn(ab, "Spurious quick kickout for STA %pM\n",
|
||||
@ -6110,7 +6112,7 @@ static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
/* HW channel counters frequency value in hertz */
|
||||
u32 cc_freq_hz = ab->cc_freq_hz;
|
||||
|
||||
if (ath12k_pull_chan_info_ev(ab, skb->data, skb->len, &ch_info_ev) != 0) {
|
||||
if (ath12k_pull_chan_info_ev(ab, skb, &ch_info_ev) != 0) {
|
||||
ath12k_warn(ab, "failed to extract chan info event");
|
||||
return;
|
||||
}
|
||||
@ -6395,7 +6397,7 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
|
||||
const struct wmi_pdev_ctl_failsafe_chk_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6460,7 +6462,7 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
|
||||
const u32 *vdev_ids;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6494,7 +6496,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
|
||||
struct ath12k *ar;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6531,7 +6533,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
|
||||
if (ar->dfs_block_radar_events)
|
||||
ath12k_info(ab, "DFS Radar detected, but ignored as requested\n");
|
||||
else
|
||||
ieee80211_radar_detected(ar->hw);
|
||||
ieee80211_radar_detected(ath12k_ar_to_hw(ar));
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
@ -6546,7 +6548,7 @@ ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
|
||||
struct ath12k *ar;
|
||||
struct wmi_pdev_temperature_event ev = {0};
|
||||
|
||||
if (ath12k_pull_pdev_temp_ev(ab, skb->data, skb->len, &ev) != 0) {
|
||||
if (ath12k_pull_pdev_temp_ev(ab, skb, &ev) != 0) {
|
||||
ath12k_warn(ab, "failed to extract pdev temperature event");
|
||||
return;
|
||||
}
|
||||
@ -6573,7 +6575,7 @@ static void ath12k_fils_discovery_event(struct ath12k_base *ab,
|
||||
const struct wmi_fils_discovery_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab,
|
||||
@ -6603,7 +6605,7 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
|
||||
const struct wmi_probe_resp_tx_status_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab,
|
||||
@ -6635,7 +6637,7 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
|
||||
const void **tb;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
@ -6662,6 +6664,12 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_wmi_diag_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
trace_ath12k_wmi_diag(ab, skb->data, skb->len);
|
||||
}
|
||||
|
||||
static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
@ -6772,6 +6780,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
case WMI_VDEV_DELETE_RESP_EVENTID:
|
||||
ath12k_vdev_delete_resp_event(ab, skb);
|
||||
break;
|
||||
case WMI_DIAG_EVENTID:
|
||||
ath12k_wmi_diag_event(ab, skb);
|
||||
break;
|
||||
/* TODO: Add remaining events */
|
||||
default:
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI, "Unknown eventid: 0x%x\n", id);
|
||||
|
@ -144,7 +144,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath_ahb_remove(struct platform_device *pdev)
|
||||
static void ath_ahb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
|
||||
|
||||
@ -155,13 +155,11 @@ static int ath_ahb_remove(struct platform_device *pdev)
|
||||
free_irq(sc->irq, sc);
|
||||
ieee80211_free_hw(sc->hw);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ath_ahb_driver = {
|
||||
.probe = ath_ahb_probe,
|
||||
.remove = ath_ahb_remove,
|
||||
.remove_new = ath_ahb_remove,
|
||||
.driver = {
|
||||
.name = "ath9k",
|
||||
},
|
||||
|
@ -643,7 +643,7 @@ static void ath_ant_try_scan(struct ath_ant_comb *antcomb,
|
||||
conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
} else if (antcomb->rssi_sub >
|
||||
antcomb->rssi_lna1) {
|
||||
antcomb->rssi_lna2) {
|
||||
/* set to A-B */
|
||||
conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
|
@ -851,8 +851,6 @@
|
||||
#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN 0x0000000e
|
||||
#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE1 0x9934
|
||||
#define AR_PHY_POWER_TX_RATE2 0x9938
|
||||
#define AR_PHY_POWER_TX_RATE_MAX 0x993c
|
||||
#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
@ -1041,13 +1039,6 @@
|
||||
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001
|
||||
|
||||
/*
|
||||
* AGC 3 Register Map
|
||||
*/
|
||||
#define AR_AGC3_BASE 0xce00
|
||||
|
||||
#define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180)
|
||||
|
||||
/* GLB Registers */
|
||||
#define AR_GLB_BASE 0x20000
|
||||
#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE)
|
||||
|
@ -17,10 +17,6 @@
|
||||
#ifndef REG_AIC_H
|
||||
#define REG_AIC_H
|
||||
|
||||
#define AR_SM_BASE 0xa200
|
||||
#define AR_SM1_BASE 0xb200
|
||||
#define AR_AGC_BASE 0x9e00
|
||||
|
||||
#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0)
|
||||
#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
|
||||
#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
|
||||
|
Loading…
x
Reference in New Issue
Block a user