summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKalle Valo <kvalo@kernel.org>2023-09-28 19:27:58 +0300
committerKalle Valo <kvalo@kernel.org>2023-09-28 19:27:58 +0300
commit9896f0608f9fe0b49badd2fd6ae76ec761c70624 (patch)
treeaf9583577c751ff3c61fa5952c2d625a6f4a5e95 /drivers
parent6016f0cb02f4de005d7829da959e774447ff40fb (diff)
parent9e61589ac3c2d23c528d3ffd44604d98553ea1cb (diff)
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v6.7. Major changes: ath12k * WCN7850: enable 320 MHz channels in 6 GHz band * WCN7850: hardware rfkill support * WCN7850: enable IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS to make scan faster ath11k * add chip id board name while searching board-2.bin
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c16
-rw-r--r--drivers/net/wireless/ath/ath11k/core.c108
-rw-r--r--drivers/net/wireless/ath/ath11k/core.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c23
-rw-r--r--drivers/net/wireless/ath/ath11k/hal.c8
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.c31
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.h18
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_tx.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c58
-rw-r--r--drivers/net/wireless/ath/ath11k/mhi.c1
-rw-r--r--drivers/net/wireless/ath/ath11k/pci.c24
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.c28
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.c8
-rw-r--r--drivers/net/wireless/ath/ath12k/core.c60
-rw-r--r--drivers/net/wireless/ath/ath12k/core.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.c1
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_mon.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_rx.c30
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_tx.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/hal.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/hw.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c133
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/peer.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/rx_desc.h91
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.c93
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.h25
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c6
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c20
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.h2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/testmode.c2
46 files changed, 661 insertions, 265 deletions
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 19f61225a708..43e0db78d42b 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -256,7 +256,7 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
/* always bulk-out a multiple of 4 bytes */
xferlen = (sizeof(struct ar5523_cmd_hdr) + ilen + 3) & ~3;
- hdr = (struct ar5523_cmd_hdr *)cmd->buf_tx;
+ hdr = cmd->buf_tx;
memset(hdr, 0, sizeof(struct ar5523_cmd_hdr));
hdr->len = cpu_to_be32(xferlen);
hdr->code = cpu_to_be32(code);
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index 666ce384a1d8..27367bd64e95 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -110,7 +110,7 @@ struct ath10k_ce_ring {
struct ce_desc_64 *shadow_base;
/* keep last */
- void *per_transfer_context[];
+ void *per_transfer_context[] __counted_by(nentries);
};
struct ath10k_ce_pipe {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index f9518e1c9903..fe89bc61e531 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -1140,7 +1140,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
- memcpy(data, *ath10k_gstrings_stats,
+ memcpy(data, ath10k_gstrings_stats,
sizeof(ath10k_gstrings_stats));
}
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 7b24297146e7..c80470e8886a 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -880,8 +880,7 @@ enum htt_data_tx_status {
HTT_DATA_TX_STATUS_OK = 0,
HTT_DATA_TX_STATUS_DISCARD = 1,
HTT_DATA_TX_STATUS_NO_ACK = 2,
- HTT_DATA_TX_STATUS_POSTPONE = 3, /* HL only */
- HTT_DATA_TX_STATUS_DOWNLOAD_FAIL = 128
+ HTT_DATA_TX_STATUS_POSTPONE = 3 /* HL only */
};
enum htt_data_tx_flags {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 438b0caaceb7..b261d6371c0f 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2964,7 +2964,6 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
break;
case HTT_DATA_TX_STATUS_DISCARD:
case HTT_DATA_TX_STATUS_POSTPONE:
- case HTT_DATA_TX_STATUS_DOWNLOAD_FAIL:
tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
break;
default:
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index bd603feb7953..be4d4536aaa8 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -796,20 +796,16 @@ static int ath10k_htt_send_frag_desc_bank_cfg_64(struct ath10k_htt *htt)
return 0;
}
-static void ath10k_htt_fill_rx_desc_offset_32(struct ath10k_hw_params *hw, void *rx_ring)
+static void ath10k_htt_fill_rx_desc_offset_32(struct ath10k_hw_params *hw,
+ struct htt_rx_ring_setup_ring32 *rx_ring)
{
- struct htt_rx_ring_setup_ring32 *ring =
- (struct htt_rx_ring_setup_ring32 *)rx_ring;
-
- ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
+ ath10k_htt_rx_desc_get_offsets(hw, &rx_ring->offsets);
}
-static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw, void *rx_ring)
+static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw,
+ struct htt_rx_ring_setup_ring64 *rx_ring)
{
- struct htt_rx_ring_setup_ring64 *ring =
- (struct htt_rx_ring_setup_ring64 *)rx_ring;
-
- ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
+ ath10k_htt_rx_desc_get_offsets(hw, &rx_ring->offsets);
}
static int ath10k_htt_send_rx_ring_cfg_32(struct ath10k_htt *htt)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index fc7c4564a715..c3a0dd15d8ea 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -985,9 +985,15 @@ int ath11k_core_check_dt(struct ath11k_base *ab)
return 0;
}
+enum ath11k_bdf_name_type {
+ ATH11K_BDF_NAME_FULL,
+ ATH11K_BDF_NAME_BUS_NAME,
+ ATH11K_BDF_NAME_CHIP_ID,
+};
+
static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
size_t name_len, bool with_variant,
- bool bus_type_mode)
+ enum ath11k_bdf_name_type name_type)
{
/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
@@ -998,11 +1004,8 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
switch (ab->id.bdf_search) {
case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
- if (bus_type_mode)
- scnprintf(name, name_len,
- "bus=%s",
- ath11k_bus_str(ab->hif.bus));
- else
+ switch (name_type) {
+ case ATH11K_BDF_NAME_FULL:
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",
ath11k_bus_str(ab->hif.bus),
@@ -1012,6 +1015,19 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
ab->qmi.target.chip_id,
ab->qmi.target.board_id,
variant);
+ break;
+ case ATH11K_BDF_NAME_BUS_NAME:
+ scnprintf(name, name_len,
+ "bus=%s",
+ ath11k_bus_str(ab->hif.bus));
+ break;
+ case ATH11K_BDF_NAME_CHIP_ID:
+ scnprintf(name, name_len,
+ "bus=%s,qmi-chip-id=%d",
+ ath11k_bus_str(ab->hif.bus),
+ ab->qmi.target.chip_id);
+ break;
+ }
break;
default:
scnprintf(name, name_len,
@@ -1030,19 +1046,29 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
- return __ath11k_core_create_board_name(ab, name, name_len, true, false);
+ return __ath11k_core_create_board_name(ab, name, name_len, true,
+ ATH11K_BDF_NAME_FULL);
}
static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
- return __ath11k_core_create_board_name(ab, name, name_len, false, false);
+ return __ath11k_core_create_board_name(ab, name, name_len, false,
+ ATH11K_BDF_NAME_FULL);
}
static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
- return __ath11k_core_create_board_name(ab, name, name_len, false, true);
+ return __ath11k_core_create_board_name(ab, name, name_len, false,
+ ATH11K_BDF_NAME_BUS_NAME);
+}
+
+static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name,
+ size_t name_len)
+{
+ return __ath11k_core_create_board_name(ab, name, name_len, false,
+ ATH11K_BDF_NAME_CHIP_ID);
}
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
@@ -1289,16 +1315,21 @@ int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
#define BOARD_NAME_SIZE 200
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
{
- char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
+ char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL;
char *filename, filepath[100];
- int ret;
+ int ret = 0;
filename = ATH11K_BOARD_API2_FILE;
+ boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
+ if (!boardname) {
+ ret = -ENOMEM;
+ goto exit;
+ }
- ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
+ ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
if (ret) {
ath11k_err(ab, "failed to create board name: %d", ret);
- return ret;
+ goto exit;
}
ab->bd_api = 2;
@@ -1307,13 +1338,19 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ATH11K_BD_IE_BOARD_NAME,
ATH11K_BD_IE_BOARD_DATA);
if (!ret)
- goto success;
+ goto exit;
+
+ fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
+ if (!fallback_boardname) {
+ ret = -ENOMEM;
+ goto exit;
+ }
ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
- sizeof(fallback_boardname));
+ BOARD_NAME_SIZE);
if (ret) {
ath11k_err(ab, "failed to create fallback board name: %d", ret);
- return ret;
+ goto exit;
}
ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
@@ -1321,7 +1358,28 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ATH11K_BD_IE_BOARD_NAME,
ATH11K_BD_IE_BOARD_DATA);
if (!ret)
- goto success;
+ goto exit;
+
+ chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
+ if (!chip_id_boardname) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = ath11k_core_create_chip_id_board_name(ab, chip_id_boardname,
+ BOARD_NAME_SIZE);
+ if (ret) {
+ ath11k_err(ab, "failed to create chip id board name: %d", ret);
+ goto exit;
+ }
+
+ ret = ath11k_core_fetch_board_data_api_n(ab, bd, chip_id_boardname,
+ ATH11K_BD_IE_BOARD,
+ ATH11K_BD_IE_BOARD_NAME,
+ ATH11K_BD_IE_BOARD_DATA);
+
+ if (!ret)
+ goto exit;
ab->bd_api = 1;
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
@@ -1334,14 +1392,22 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
fallback_boardname, filepath);
+ ath11k_err(ab, "failed to fetch board data for %s from %s\n",
+ chip_id_boardname, filepath);
+
ath11k_err(ab, "failed to fetch board.bin from %s\n",
ab->hw_params.fw.dir);
- return ret;
}
-success:
- ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
- return 0;
+exit:
+ kfree(boardname);
+ kfree(fallback_boardname);
+ kfree(chip_id_boardname);
+
+ if (!ret)
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
+
+ return ret;
}
int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index b04447762483..650972f9d146 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -901,8 +901,6 @@ struct ath11k_base {
struct list_head peers;
wait_queue_head_t peer_mapping_wq;
u8 mac_addr[ETH_ALEN];
- bool wmi_ready;
- u32 wlan_init_status;
int irq_num[ATH11K_IRQ_NUM_MAX];
struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
struct ath11k_targ_cap target_caps;
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index d070bcb3fe24..a7252b52555c 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -1009,7 +1009,7 @@ void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif)
static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx)
{
- struct ath11k_base *ab = (struct ath11k_base *)ctx;
+ struct ath11k_base *ab = ctx;
struct sk_buff *msdu = skb;
dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 62bc98852f0f..9de849f09620 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1256,7 +1256,7 @@ static int ath11k_htt_tlv_ppdu_stats_parse(struct ath11k_base *ab,
int cur_user;
u16 peer_id;
- ppdu_info = (struct htt_ppdu_stats_info *)data;
+ ppdu_info = data;
switch (tag) {
case HTT_PPDU_STATS_TAG_COMMON:
@@ -1388,9 +1388,6 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
bool is_ampdu = false;
- if (!usr_stats)
- return;
-
if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
return;
@@ -4489,8 +4486,7 @@ int ath11k_dp_rx_monitor_link_desc_return(struct ath11k *ar,
src_srng_desc = ath11k_hal_srng_src_get_next_entry(ar->ab, hal_srng);
if (src_srng_desc) {
- struct ath11k_buffer_addr *src_desc =
- (struct ath11k_buffer_addr *)src_srng_desc;
+ struct ath11k_buffer_addr *src_desc = src_srng_desc;
*src_desc = *((struct ath11k_buffer_addr *)p_last_buf_addr_info);
} else {
@@ -4509,8 +4505,7 @@ void ath11k_dp_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,
u8 *rbm,
void **pp_buf_addr_info)
{
- struct hal_rx_msdu_link *msdu_link =
- (struct hal_rx_msdu_link *)rx_msdu_link_desc;
+ struct hal_rx_msdu_link *msdu_link = rx_msdu_link_desc;
struct ath11k_buffer_addr *buf_addr_info;
buf_addr_info = (struct ath11k_buffer_addr *)&msdu_link->buf_addr_info;
@@ -4551,7 +4546,7 @@ static void ath11k_hal_rx_msdu_list_get(struct ath11k *ar,
u32 first = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1);
u8 tmp = 0;
- msdu_link = (struct hal_rx_msdu_link *)msdu_link_desc;
+ msdu_link = msdu_link_desc;
msdu_details = &msdu_link->msdu_link[0];
for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) {
@@ -4648,8 +4643,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id,
bool is_frag, is_first_msdu;
bool drop_mpdu = false;
struct ath11k_skb_rxcb *rxcb;
- struct hal_reo_entrance_ring *ent_desc =
- (struct hal_reo_entrance_ring *)ring_entry;
+ struct hal_reo_entrance_ring *ent_desc = ring_entry;
int buf_id;
u32 rx_link_buf_info[2];
u8 rbm;
@@ -5097,13 +5091,6 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
mon_dst_srng = &ar->ab->hal.srng_list[ring_id];
- if (!mon_dst_srng) {
- ath11k_warn(ar->ab,
- "HAL Monitor Destination Ring Init Failed -- %p",
- mon_dst_srng);
- return;
- }
-
spin_lock_bh(&pmon->mon_lock);
ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c
index 0a99aa7ddbf4..23f3af8e372d 100644
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -571,7 +571,7 @@ u32 ath11k_hal_ce_get_desc_size(enum hal_ce_desc type)
void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
u8 byte_swap_data)
{
- struct hal_ce_srng_src_desc *desc = (struct hal_ce_srng_src_desc *)buf;
+ struct hal_ce_srng_src_desc *desc = buf;
desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
desc->buffer_addr_info =
@@ -586,8 +586,7 @@ void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
{
- struct hal_ce_srng_dest_desc *desc =
- (struct hal_ce_srng_dest_desc *)buf;
+ struct hal_ce_srng_dest_desc *desc = buf;
desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
desc->buffer_addr_info =
@@ -597,8 +596,7 @@ void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
u32 ath11k_hal_ce_dst_status_get_length(void *buf)
{
- struct hal_ce_srng_dst_status_desc *desc =
- (struct hal_ce_srng_dst_status_desc *)buf;
+ struct hal_ce_srng_dst_status_desc *desc = buf;
u32 len;
len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c
index e5ed5efb139e..41946795d620 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -265,7 +265,7 @@ out:
void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
u32 cookie, u8 manager)
{
- struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
+ struct ath11k_buffer_addr *binfo = desc;
u32 paddr_lo, paddr_hi;
paddr_lo = lower_32_bits(paddr);
@@ -279,7 +279,7 @@ void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
u32 *cookie, u8 *rbm)
{
- struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
+ struct ath11k_buffer_addr *binfo = desc;
*paddr =
(((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) |
@@ -292,7 +292,7 @@ void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
u32 *msdu_cookies,
enum hal_rx_buf_return_buf_manager *rbm)
{
- struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc;
+ struct hal_rx_msdu_link *link = link_desc;
struct hal_rx_msdu_details *msdu;
int i;
@@ -699,7 +699,7 @@ u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)
void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
u32 start_seq, enum hal_pn_type type)
{
- struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr;
+ struct hal_rx_reo_queue *qdesc = vaddr;
struct hal_rx_reo_queue_ext *ext_desc;
memset(qdesc, 0, sizeof(*qdesc));
@@ -809,27 +809,25 @@ static inline void
ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
struct hal_rx_user_status *rx_user_status)
{
- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
+ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
- rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->rsvd2[10]);
+ rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info10);
}
static inline void
ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
struct hal_rx_user_status *rx_user_status)
{
- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
+ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->mpdu_ok_byte_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT,
- __le32_to_cpu(ppdu_end_user->rsvd2[6]));
+ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,
+ __le32_to_cpu(ppdu_end_user->info8));
rx_user_status->mpdu_err_byte_count =
- FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT,
- __le32_to_cpu(ppdu_end_user->rsvd2[8]));
+ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT,
+ __le32_to_cpu(ppdu_end_user->info9));
}
static inline void
@@ -903,8 +901,8 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX,
__le32_to_cpu(eu_stats->info2));
ppdu_info->tid =
- ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP,
- __le32_to_cpu(eu_stats->info6))) - 1;
+ ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP,
+ __le32_to_cpu(eu_stats->info7))) - 1;
ppdu_info->tcp_msdu_count =
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT,
__le32_to_cpu(eu_stats->info4));
@@ -1540,8 +1538,7 @@ void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr,
u32 *sw_cookie, void **pp_buf_addr,
u8 *rbm, u32 *msdu_cnt)
{
- struct hal_reo_entrance_ring *reo_ent_ring =
- (struct hal_reo_entrance_ring *)rx_desc;
+ struct hal_reo_entrance_ring *reo_ent_ring = rx_desc;
struct ath11k_buffer_addr *buf_addr_info;
struct rx_mpdu_desc *rx_mpdu_desc_info_details;
diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.h b/drivers/net/wireless/ath/ath11k/hal_rx.h
index 61bd8416c4fd..472a52cf5889 100644
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
@@ -149,7 +149,7 @@ struct hal_rx_mon_ppdu_info {
u8 beamformed;
u8 rssi_comb;
u8 rssi_chain_pri20[HAL_RX_MAX_NSS];
- u8 tid;
+ u16 tid;
u16 ht_flags;
u16 vht_flags;
u16 he_flags;
@@ -219,11 +219,11 @@ struct hal_rx_ppdu_start {
#define HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT GENMASK(15, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT GENMASK(31, 16)
-#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0)
-#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16)
+#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP GENMASK(15, 0)
+#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_EOSP_BITMAP GENMASK(31, 16)
-#define HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
-#define HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
+#define HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
+#define HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
struct hal_rx_ppdu_end_user_stats {
__le32 rsvd0[2];
@@ -236,7 +236,13 @@ struct hal_rx_ppdu_end_user_stats {
__le32 info4;
__le32 info5;
__le32 info6;
- __le32 rsvd2[11];
+ __le32 info7;
+ __le32 rsvd2[4];
+ __le32 info8;
+ __le32 rsvd3;
+ __le32 info9;
+ __le32 rsvd4[2];
+ __le32 info10;
} __packed;
struct hal_rx_ppdu_end_user_stats_ext {
diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.c b/drivers/net/wireless/ath/ath11k/hal_tx.c
index d1b0e36e04a9..b919df6ce743 100644
--- a/drivers/net/wireless/ath/ath11k/hal_tx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_tx.c
@@ -37,7 +37,7 @@ static const u8 dscp_tid_map[DSCP_TID_MAP_TBL_ENTRY_SIZE] = {
void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
struct hal_tx_info *ti)
{
- struct hal_tcl_data_cmd *tcl_cmd = (struct hal_tcl_data_cmd *)cmd;
+ struct hal_tcl_data_cmd *tcl_cmd = cmd;
tcl_cmd->buf_addr_info.info0 =
FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr);
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 6ed036b51dba..20b04723daec 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6970,8 +6970,8 @@ err:
static int ath11k_mac_vif_unref(int buf_id, void *skb, void *ctx)
{
- struct ieee80211_vif *vif = (struct ieee80211_vif *)ctx;
- struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);
+ struct ieee80211_vif *vif = ctx;
+ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
if (skb_cb->vif == vif)
skb_cb->vif = NULL;
@@ -7913,12 +7913,14 @@ ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
static bool
ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
+ struct ath11k_vif *arvif,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask,
int *nss)
{
struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
+ const struct ieee80211_sta_he_cap *he_cap;
u16 he_mcs_map = 0;
u8 ht_nss_mask = 0;
u8 vht_nss_mask = 0;
@@ -7949,7 +7951,11 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
return false;
}
- he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap));
+ he_cap = ieee80211_get_he_iftype_cap_vif(sband, arvif->vif);
+ if (!he_cap)
+ return false;
+
+ he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(he_cap));
for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
if (mask->control[band].he_mcs[i] == 0)
@@ -8365,7 +8371,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
ieee80211_iterate_stations_atomic(ar->hw,
ath11k_mac_disable_peer_fixed_rate,
arvif);
- } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, band, mask,
+ } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,
&single_nss)) {
rate = WMI_FIXED_RATE_NONE;
nss = single_nss;
@@ -8908,7 +8914,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
{
struct ath11k *ar = hw->priv;
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
- struct scan_req_params arg;
+ struct scan_req_params *arg;
int ret;
u32 scan_time_msec;
@@ -8940,27 +8946,31 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
- memset(&arg, 0, sizeof(arg));
- ath11k_wmi_start_scan_init(ar, &arg);
- arg.num_chan = 1;
- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
- GFP_KERNEL);
- if (!arg.chan_list) {
+ arg = kzalloc(sizeof(*arg), GFP_KERNEL);
+ if (!arg) {
ret = -ENOMEM;
goto exit;
}
+ ath11k_wmi_start_scan_init(ar, arg);
+ arg->num_chan = 1;
+ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
+ GFP_KERNEL);
+ if (!arg->chan_list) {
+ ret = -ENOMEM;
+ goto free_arg;
+ }
- arg.vdev_id = arvif->vdev_id;
- arg.scan_id = ATH11K_SCAN_ID;
- arg.chan_list[0] = chan->center_freq;
- arg.dwell_time_active = scan_time_msec;
- arg.dwell_time_passive = scan_time_msec;
- arg.max_scan_time = scan_time_msec;
- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
- arg.scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
- arg.burst_duration = duration;
-
- ret = ath11k_start_scan(ar, &arg);
+ arg->vdev_id = arvif->vdev_id;
+ arg->scan_id = ATH11K_SCAN_ID;
+ arg->chan_list[0] = chan->center_freq;
+ arg->dwell_time_active = scan_time_msec;
+ arg->dwell_time_passive = scan_time_msec;
+ arg->max_scan_time = scan_time_msec;
+ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
+ arg->scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
+ arg->burst_duration = duration;
+
+ ret = ath11k_start_scan(ar, arg);
if (ret) {
ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
@@ -8986,7 +8996,9 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
ret = 0;
free_chan_list:
- kfree(arg.chan_list);
+ kfree(arg->chan_list);
+free_arg:
+ kfree(arg);
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index 3ac689f1def4..721dd9702f95 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -333,6 +333,7 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
ath11k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
break;
case MHI_CB_EE_RDDM:
+ ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n");
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
break;
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 9573bd959cac..aa049593f9b5 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -852,10 +852,16 @@ unsupported_wcn6855_soc:
if (ret)
goto err_pci_disable_msi;
+ ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
+ if (ret) {
+ ath11k_err(ab, "failed to set irq affinity %d\n", ret);
+ goto err_pci_disable_msi;
+ }
+
ret = ath11k_mhi_register(ab_pci);
if (ret) {
ath11k_err(ab, "failed to register mhi: %d\n", ret);
- goto err_pci_disable_msi;
+ goto err_irq_affinity_cleanup;
}
ret = ath11k_hal_srng_init(ab);
@@ -876,12 +882,6 @@ unsupported_wcn6855_soc:
goto err_ce_free;
}
- ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
- if (ret) {
- ath11k_err(ab, "failed to set irq affinity %d\n", ret);
- goto err_free_irq;
- }
-
/* kernel may allocate a dummy vector before request_irq and
* then allocate a real vector when request_irq is called.
* So get msi_data here again to avoid spurious interrupt
@@ -890,20 +890,17 @@ unsupported_wcn6855_soc:
ret = ath11k_pci_config_msi_data(ab_pci);
if (ret) {
ath11k_err(ab, "failed to config msi_data: %d\n", ret);
- goto err_irq_affinity_cleanup;
+ goto err_free_irq;
}
ret = ath11k_core_init(ab);
if (ret) {
ath11k_err(ab, "failed to init core: %d\n", ret);
- goto err_irq_affinity_cleanup;
+ goto err_free_irq;
}
ath11k_qmi_fwreset_from_cold_boot(ab);
return 0;
-err_irq_affinity_cleanup:
- ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
-
err_free_irq:
ath11k_pcic_free_irq(ab);
@@ -916,6 +913,9 @@ err_hal_srng_deinit:
err_mhi_unregister:
ath11k_mhi_unregister(ab_pci);
+err_irq_affinity_cleanup:
+ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
err_pci_disable_msi:
ath11k_pci_free_msi(ab_pci);
diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c
index 705868198df4..0b7b7122cc05 100644
--- a/drivers/net/wireless/ath/ath11k/spectral.c
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
@@ -382,16 +382,11 @@ static ssize_t ath11k_write_file_spectral_count(struct file *file,
{
struct ath11k *ar = file->private_data;
unsigned long val;
- char buf[32];
- ssize_t len;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
+ ssize_t ret;
- buf[len] = '\0';
- if (kstrtoul(buf, 0, &val))
- return -EINVAL;
+ ret = kstrtoul_from_user(user_buf, count, 0, &val);
+ if (ret)
+ return ret;
if (val > ATH11K_SPECTRAL_SCAN_COUNT_MAX)
return -EINVAL;
@@ -437,16 +432,11 @@ static ssize_t ath11k_write_file_spectral_bins(struct file *file,
{
struct ath11k *ar = file->private_data;
unsigned long val;
- char buf[32];
- ssize_t len;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
+ ssize_t ret;
- buf[len] = '\0';
- if (kstrtoul(buf, 0, &val))
- return -EINVAL;
+ ret = kstrtoul_from_user(user_buf, count, 0, &val);
+ if (ret)
+ return ret;
if (val < ATH11K_SPECTRAL_MIN_BINS ||
val > ar->ab->hw_params.spectral.max_fft_bins)
@@ -598,7 +588,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
return -EINVAL;
}
- tlv = (struct spectral_tlv *)data;
+ tlv = data;
tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header));
/* convert Dword into bytes */
tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 23ad6825e5be..e93601fe7bcb 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -2281,7 +2281,7 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
- tmp_ptr = (u32 *)ptr;
+ tmp_ptr = ptr;
for (i = 0; i < params->num_chan; ++i)
tmp_ptr[i] = params->chan_list[i];
@@ -4148,7 +4148,7 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
ptr += TLV_HDR_SIZE + len;
if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
- hw_mode = (struct wmi_pdev_set_hw_mode_cmd_param *)ptr;
+ hw_mode = ptr;
hw_mode->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_PDEV_SET_HW_MODE_CMD) |
FIELD_PREP(WMI_TLV_LEN,
@@ -4168,7 +4168,7 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
len = sizeof(*band_to_mac);
for (idx = 0; idx < param->num_band_to_mac; idx++) {
- band_to_mac = (void *)ptr;
+ band_to_mac = ptr;
band_to_mac->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_PDEV_BAND_TO_MAC) |
@@ -7222,14 +7222,12 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
memset(&fixed_param, 0, sizeof(fixed_param));
memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
min_t(u16, sizeof(fixed_param), len));
- ab->wlan_init_status = fixed_param.ready_event_min.status;
rdy_parse->num_extra_mac_addr =
fixed_param.ready_event_min.num_extra_mac_addr;
ether_addr_copy(ab->mac_addr,
fixed_param.ready_event_min.mac_addr.addr);
ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
- ab->wmi_ready = true;
break;
case WMI_TAG_ARRAY_FIXED_STRUCT:
addr_list = (struct wmi_mac_addr *)ptr;
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 3df8059d5512..9a9a471ff130 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -19,6 +19,27 @@ unsigned int ath12k_debug_mask;
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
+static int ath12k_core_rfkill_config(struct ath12k_base *ab)
+{
+ struct ath12k *ar;
+ int ret = 0, i;
+
+ if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL))
+ return 0;
+
+ for (i = 0; i < ab->num_radios; i++) {
+ ar = ab->pdevs[i].ar;
+
+ ret = ath12k_mac_rfkill_config(ar);
+ if (ret && ret != -EOPNOTSUPP) {
+ ath12k_warn(ab, "failed to configure rfkill: %d", ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
int ath12k_core_suspend(struct ath12k_base *ab)
{
int ret;
@@ -603,6 +624,13 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
goto err_core_stop;
}
ath12k_hif_irq_enable(ab);
+
+ ret = ath12k_core_rfkill_config(ab);
+ if (ret && ret != -EOPNOTSUPP) {
+ ath12k_err(ab, "failed to config rfkill: %d\n", ret);
+ goto err_core_stop;
+ }
+
mutex_unlock(&ab->core_lock);
return 0;
@@ -655,6 +683,27 @@ err_hal_srng_deinit:
return ret;
}
+static void ath12k_rfkill_work(struct work_struct *work)
+{
+ struct ath12k_base *ab = container_of(work, struct ath12k_base, rfkill_work);
+ struct ath12k *ar;
+ bool rfkill_radio_on;
+ int i;
+
+ spin_lock_bh(&ab->base_lock);
+ rfkill_radio_on = ab->rfkill_radio_on;
+ spin_unlock_bh(&ab->base_lock);
+
+ for (i = 0; i < ab->num_radios; i++) {
+ ar = ab->pdevs[i].ar;
+ if (!ar)
+ continue;
+
+ ath12k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
+ wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
+ }
+}
+
void ath12k_core_halt(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
@@ -668,6 +717,7 @@ void ath12k_core_halt(struct ath12k *ar)
ath12k_mac_peer_cleanup_all(ar);
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
+ cancel_work_sync(&ab->rfkill_work);
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
synchronize_rcu();
@@ -685,6 +735,9 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ab->stats.fw_crash_counter++;
spin_unlock_bh(&ab->base_lock);
+ if (ab->is_reset)
+ set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
+
for (i = 0; i < ab->num_radios; i++) {
pdev = &ab->pdevs[i];
ar = pdev->ar;
@@ -823,6 +876,8 @@ static void ath12k_core_reset(struct work_struct *work)
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset starting\n");
ab->is_reset = true;
+ atomic_set(&ab->recovery_start_count, 0);
+ reinit_completion(&ab->recovery_start);
atomic_set(&ab->recovery_count, 0);
ath12k_core_pre_reconfigure_recovery(ab);
@@ -830,9 +885,6 @@ static void ath12k_core_reset(struct work_struct *work)
reinit_completion(&ab->reconfigure_complete);
ath12k_core_post_reconfigure_recovery(ab);
- reinit_completion(&ab->recovery_start);
- atomic_set(&ab->recovery_start_count, 0);
-
ath12k_dbg(ab, ATH12K_DBG_BOOT, "waiting recovery start...\n");
time_left = wait_for_completion_timeout(&ab->recovery_start,
@@ -922,6 +974,8 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
INIT_WORK(&ab->restart_work, ath12k_core_restart);
INIT_WORK(&ab->reset_work, ath12k_core_reset);
+ INIT_WORK(&ab->rfkill_work, ath12k_rfkill_work);
+
timer_setup(&ab->rx_replenish_retry, ath12k_ce_rx_replenish_retry, 0);
init_completion(&ab->htc_suspend);
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index d873b573dac6..3f5f0471f640 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -771,6 +771,10 @@ struct ath12k_base {
u64 fw_soc_drop_count;
bool static_window_map;
+ struct work_struct rfkill_work;
+ /* true means radio is on */
+ bool rfkill_radio_on;
+
/* must be last */
u8 drv_priv[] __aligned(sizeof(void *));
};
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index f933896f2a68..6893466f61f0 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -38,6 +38,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
crypto_free_shash(peer->tfm_mmic);
+ peer->dp_setup_done = false;
spin_unlock_bh(&ab->base_lock);
}
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index f1e57e98bdc6..1698a7712494 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -13,8 +13,7 @@
static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,
struct hal_rx_user_status *rx_user_status)
{
- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
+ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->ul_ofdma_user_v0_word0 =
__le32_to_cpu(ppdu_end_user->usr_resp_ref);
@@ -23,13 +22,12 @@ static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,
}
static void
-ath12k_dp_mon_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
+ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats,
+ void *ppduinfo,
struct hal_rx_user_status *rx_user_status)
{
- struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
- (struct hal_rx_ppdu_end_user_stats *)rx_tlv;
- u32 mpdu_ok_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_ok_cnt);
- u32 mpdu_err_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_err_cnt);
+ u32 mpdu_ok_byte_count = __le32_to_cpu(stats->mpdu_ok_cnt);
+ u32 mpdu_err_byte_count = __le32_to_cpu(stats->mpdu_err_cnt);
rx_user_status->mpdu_ok_byte_count =
u32_get_bits(mpdu_ok_byte_count,
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index e6e64d437c47..39ef3c0d2e65 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -1555,6 +1555,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
+ if (len > (skb->len - struct_size(msg, data, 0))) {
+ ath12k_warn(ab,
+ "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
+ len, skb->len);
+ return -EINVAL;
+ }
+
pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
ppdu_id = le32_to_cpu(msg->ppdu_id);
@@ -1583,6 +1590,16 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
goto exit;
}
+ if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
+ spin_unlock_bh(&ar->data_lock);
+ ath12k_warn(ab,
+ "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
+ ppdu_info->ppdu_stats.common.num_users,
+ HTT_PPDU_STATS_MAX_USERS);
+ ret = -EINVAL;
+ goto exit;
+ }
+
/* back up data rate tlv for all peers */
if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
(ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
@@ -2748,6 +2765,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
}
peer->tfm_mmic = tfm;
+ peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);
return 0;
@@ -3214,6 +3232,14 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
ret = -ENOENT;
goto out_unlock;
}
+
+ if (!peer->dp_setup_done) {
+ ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
+ peer->addr, peer_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
rx_tid = &peer->rx_tid[tid];
if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
@@ -3229,7 +3255,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
goto out_unlock;
}
- if (frag_no > __fls(rx_tid->rx_frag_bitmap))
+ if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap)))
__skb_queue_tail(&rx_tid->rx_frags, msdu);
else
ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu);
@@ -3730,7 +3756,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
continue;
}
- desc_info = (struct ath12k_rx_desc_info *)err_info.rx_desc;
+ desc_info = err_info.rx_desc;
/* retry manual desc retrieval if hw cc is not done */
if (!desc_info) {
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 8874c815d7fa..f5e0f5426226 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -106,11 +106,10 @@ static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *
return desc;
}
-static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd,
+static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
+ struct hal_tx_msdu_ext_desc *tcl_ext_cmd,
struct hal_tx_info *ti)
{
- struct hal_tx_msdu_ext_desc *tcl_ext_cmd = (struct hal_tx_msdu_ext_desc *)cmd;
-
tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr,
HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO);
tcl_ext_cmd->info1 = le32_encode_bits(0x0,
@@ -330,8 +329,11 @@ tcl_ring_sel:
fail_unmap_dma:
dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
- dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
- sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);
+
+ if (skb_cb->paddr_ext_desc)
+ dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+ sizeof(struct hal_tx_msdu_ext_desc),
+ DMA_TO_DEVICE);
fail_remove_tx_buf:
ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index e7a150e7158e..eca86fc25a60 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -385,13 +385,13 @@ static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
- RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
+ RX_MSDU_END_QCN9274_INFO12_MIMO_SS_BITMAP);
}
static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
return le16_get_bits(desc->u.qcn9274.msdu_end.info5,
- RX_MSDU_END_INFO5_TID);
+ RX_MSDU_END_QCN9274_INFO5_TID);
}
static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
@@ -819,13 +819,13 @@ static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
- RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
+ RX_MSDU_END_WCN7850_INFO12_MIMO_SS_BITMAP);
}
static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
- return le16_get_bits(desc->u.wcn7850.msdu_end.info5,
- RX_MSDU_END_INFO5_TID);
+ return le32_get_bits(desc->u.wcn7850.mpdu_start.info2,
+ RX_MPDU_START_INFO2_TID);
}
static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
@@ -837,7 +837,7 @@ static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,
struct hal_rx_desc *ldesc)
{
memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end,
- sizeof(struct rx_msdu_end_qcn9274));
+ sizeof(struct rx_msdu_end_wcn7850));
}
static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)
diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
index 5991cc91cd00..f69649f58e82 100644
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -907,6 +907,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
+
+ .rfkill_pin = 0,
+ .rfkill_cfg = 0,
+ .rfkill_on_level = 0,
},
{
.name = "wcn7850 hw2.0",
@@ -964,6 +968,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
BIT(CNSS_PCIE_PERST_NO_PULL_V01),
+
+ .rfkill_pin = 48,
+ .rfkill_cfg = 0,
+ .rfkill_on_level = 1,
},
{
.name = "qcn9274 hw2.0",
@@ -1019,6 +1027,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
+
+ .rfkill_pin = 0,
+ .rfkill_cfg = 0,
+ .rfkill_on_level = 0,
},
};
diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
index e6c4223c283c..1b4912bf57ad 100644
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -186,6 +186,10 @@ struct ath12k_hw_params {
const struct hal_ops *hal_ops;
u64 qmi_cnss_feature_bitmap;
+
+ u32 rfkill_pin;
+ u32 rfkill_cfg;
+ u32 rfkill_on_level;
};
struct ath12k_hw_ops {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 24113709972d..d4a2f82612b6 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -2525,7 +2525,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BEACON) {
param_id = WMI_PDEV_PARAM_BEACON_TX_MODE;
- param_value = WMI_BEACON_STAGGERED_MODE;
+ param_value = WMI_BEACON_BURST_MODE;
ret = ath12k_wmi_pdev_set_param(ar, param_id,
param_value, ar->pdev->pdev_id);
if (ret)
@@ -2533,7 +2533,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
arvif->vdev_id);
else
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
- "Set staggered beacon mode for VDEV: %d\n",
+ "Set burst beacon mode for VDEV: %d\n",
arvif->vdev_id);
ret = ath12k_mac_setup_bcn_tmpl(arvif);
@@ -2761,9 +2761,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
- if (changed & BSS_CHANGED_FILS_DISCOVERY ||
- changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
- ath12k_mac_fils_discovery(arvif, info);
+ ath12k_mac_fils_discovery(arvif, info);
if (changed & BSS_CHANGED_EHT_PUNCTURING)
arvif->punct_bitmap = info->eht_puncturing;
@@ -2780,18 +2778,21 @@ void __ath12k_mac_scan_finish(struct ath12k *ar)
break;
case ATH12K_SCAN_RUNNING:
case ATH12K_SCAN_ABORTING:
+ if (ar->scan.is_roc && ar->scan.roc_notify)
+ ieee80211_remain_on_channel_expired(ar->hw);
+ fallthrough;
+ case ATH12K_SCAN_STARTING:
if (!ar->scan.is_roc) {
struct cfg80211_scan_info info = {
- .aborted = (ar->scan.state ==
- ATH12K_SCAN_ABORTING),
+ .aborted = ((ar->scan.state ==
+ ATH12K_SCAN_ABORTING) ||
+ (ar->scan.state ==
+ ATH12K_SCAN_STARTING)),
};
ieee80211_scan_completed(ar->hw, &info);
- } else if (ar->scan.roc_notify) {
- ieee80211_remain_on_channel_expired(ar->hw);
}
- fallthrough;
- case ATH12K_SCAN_STARTING:
+
ar->scan.state = ATH12K_SCAN_IDLE;
ar->scan_channel = NULL;
ar->scan.roc_freq = 0;
@@ -5108,6 +5109,63 @@ err:
return ret;
}
+int ath12k_mac_rfkill_config(struct ath12k *ar)
+{
+ struct ath12k_base *ab = ar->ab;
+ u32 param;
+ int ret;
+
+ if (ab->hw_params->rfkill_pin == 0)
+ return -EOPNOTSUPP;
+
+ ath12k_dbg(ab, ATH12K_DBG_MAC,
+ "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d",
+ ab->hw_params->rfkill_pin, ab->hw_params->rfkill_cfg,
+ ab->hw_params->rfkill_on_level);
+
+ param = u32_encode_bits(ab->hw_params->rfkill_on_level,
+ WMI_RFKILL_CFG_RADIO_LEVEL) |
+ u32_encode_bits(ab->hw_params->rfkill_pin,
+ WMI_RFKILL_CFG_GPIO_PIN_NUM) |
+ u32_encode_bits(ab->hw_params->rfkill_cfg,
+ WMI_RFKILL_CFG_PIN_AS_GPIO);
+
+ ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_HW_RFKILL_CONFIG,
+ param, ar->pdev->pdev_id);
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to set rfkill config 0x%x: %d\n",
+ param, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable)
+{
+ enum wmi_rfkill_enable_radio param;
+ int ret;
+
+ if (enable)
+ param = WMI_RFKILL_ENABLE_RADIO_ON;
+ else
+ param = WMI_RFKILL_ENABLE_RADIO_OFF;
+
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac %d rfkill enable %d",
+ ar->pdev_idx, param);
+
+ ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RFKILL_ENABLE,
+ param, ar->pdev->pdev_id);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to set rfkill enable param %d: %d\n",
+ param, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
{
struct ath12k *ar = hw->priv;
@@ -5128,6 +5186,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
+ cancel_work_sync(&ar->ab->rfkill_work);
spin_lock_bh(&ar->data_lock);
list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {
@@ -5790,12 +5849,13 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
static int
ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
- const struct cfg80211_chan_def *chandef,
+ struct ieee80211_chanctx_conf *ctx,
bool restart)
{
struct ath12k *ar = arvif->ar;
struct ath12k_base *ab = ar->ab;
struct wmi_vdev_start_req_arg arg = {};
+ const struct cfg80211_chan_def *chandef = &ctx->def;
int he_support = arvif->vif->bss_conf.he_support;
int ret;
@@ -5829,6 +5889,8 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
/* For now allow DFS for AP mode */
arg.chan_radar = !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
+ arg.freq2_radar = ctx->radar_enabled;
+
arg.passive = arg.chan_radar;
spin_lock_bh(&ab->base_lock);
@@ -5936,15 +5998,15 @@ err:
}
static int ath12k_mac_vdev_start(struct ath12k_vif *arvif,
- const struct cfg80211_chan_def *chandef)
+ struct ieee80211_chanctx_conf *ctx)
{
- return ath12k_mac_vdev_start_restart(arvif, chandef, false);
+ return ath12k_mac_vdev_start_restart(arvif, ctx, false);
}
static int ath12k_mac_vdev_restart(struct ath12k_vif *arvif,
- const struct cfg80211_chan_def *chandef)
+ struct ieee80211_chanctx_conf *ctx)
{
- return ath12k_mac_vdev_start_restart(arvif, chandef, true);
+ return ath12k_mac_vdev_start_restart(arvif, ctx, true);
}
struct ath12k_mac_change_chanctx_arg {
@@ -6039,13 +6101,28 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
if (WARN_ON(!arvif->is_started))
continue;
- if (WARN_ON(!arvif->is_up))
- continue;
+ /* Firmware expect vdev_restart only if vdev is up.
+ * If vdev is down then it expect vdev_stop->vdev_start.
+ */
+ if (arvif->is_up) {
+ ret = ath12k_mac_vdev_restart(arvif, vifs[i].new_ctx);
+ if (ret) {
+ ath12k_warn(ab, "failed to restart vdev %d: %d\n",
+ arvif->vdev_id, ret);
+ continue;
+ }
+ } else {
+ ret = ath12k_mac_vdev_stop(arvif);
+ if (ret) {
+ ath12k_warn(ab, "failed to stop vdev %d: %d\n",
+ arvif->vdev_id, ret);
+ continue;
+ }
- ret = ath12k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def);
- if (ret) {
- ath12k_warn(ab, "failed to restart vdev %d: %d\n",
- arvif->vdev_id, ret);
+ ret = ath12k_mac_vdev_start(arvif, vifs[i].new_ctx);
+ if (ret)
+ ath12k_warn(ab, "failed to start vdev %d: %d\n",
+ arvif->vdev_id, ret);
continue;
}
@@ -6118,7 +6195,8 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw,
if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
goto unlock;
- if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH)
+ if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH ||
+ changed & IEEE80211_CHANCTX_CHANGE_RADAR)
ath12k_mac_update_active_vif_chan(ar, ctx);
/* TODO: Recalc radar detection */
@@ -6138,7 +6216,7 @@ static int ath12k_start_vdev_delay(struct ieee80211_hw *hw,
if (WARN_ON(arvif->is_started))
return -EBUSY;
- ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx.def);
+ ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx);
if (ret) {
ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
arvif->vdev_id, vif->addr,
@@ -6218,7 +6296,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
goto out;
}
- ret = ath12k_mac_vdev_start(arvif, &ctx->def);
+ ret = ath12k_mac_vdev_start(arvif, ctx);
if (ret) {
ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
arvif->vdev_id, vif->addr,
@@ -7231,6 +7309,11 @@ static int __ath12k_mac_register(struct ath12k *ar)
ar->hw->wiphy->interface_modes = ab->hw_params->interface_modes;
+ if (ar->hw->wiphy->bands[NL80211_BAND_2GHZ] &&
+ ar->hw->wiphy->bands[NL80211_BAND_5GHZ] &&
+ ar->hw->wiphy->bands[NL80211_BAND_6GHZ])
+ ieee80211_hw_set(ar->hw, SINGLE_SCAN_ON_ALL_BANDS);
+
ieee80211_hw_set(ar->hw, SIGNAL_DBM);
ieee80211_hw_set(ar->hw, SUPPORTS_PS);
ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index 7b16b70df4fa..59b4e8f5eee0 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -73,4 +73,6 @@ int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw);
enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw);
enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher);
+int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable);
+int ath12k_mac_rfkill_config(struct ath12k *ar);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h
index b296dc0e2f67..c6edb24cbedd 100644
--- a/drivers/net/wireless/ath/ath12k/peer.h
+++ b/drivers/net/wireless/ath/ath12k/peer.h
@@ -44,6 +44,9 @@ struct ath12k_peer {
struct ppdu_user_delayba ppdu_stats_delayba;
bool delayba_flag;
bool is_authorized;
+
+ /* protected by ab->data_lock */
+ bool dp_setup_done;
};
void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id);
diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/rx_desc.h
index bfa87cb8d021..c4058abc516e 100644
--- a/drivers/net/wireless/ath/ath12k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath12k/rx_desc.h
@@ -627,17 +627,18 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO5_SA_IDX_TIMEOUT BIT(0)
#define RX_MSDU_END_INFO5_DA_IDX_TIMEOUT BIT(1)
-#define RX_MSDU_END_INFO5_TO_DS BIT(2)
-#define RX_MSDU_END_INFO5_TID GENMASK(6, 3)
#define RX_MSDU_END_INFO5_SA_IS_VALID BIT(7)
#define RX_MSDU_END_INFO5_DA_IS_VALID BIT(8)
#define RX_MSDU_END_INFO5_DA_IS_MCBC BIT(9)
#define RX_MSDU_END_INFO5_L3_HDR_PADDING GENMASK(11, 10)
#define RX_MSDU_END_INFO5_FIRST_MSDU BIT(12)
#define RX_MSDU_END_INFO5_LAST_MSDU BIT(13)
-#define RX_MSDU_END_INFO5_FROM_DS BIT(14)
#define RX_MSDU_END_INFO5_IP_CHKSUM_FAIL_COPY BIT(15)
+#define RX_MSDU_END_QCN9274_INFO5_TO_DS BIT(2)
+#define RX_MSDU_END_QCN9274_INFO5_TID GENMASK(6, 3)
+#define RX_MSDU_END_QCN9274_INFO5_FROM_DS BIT(14)
+
#define RX_MSDU_END_INFO6_MSDU_DROP BIT(0)
#define RX_MSDU_END_INFO6_REO_DEST_IND GENMASK(5, 1)
#define RX_MSDU_END_INFO6_FLOW_IDX GENMASK(25, 6)
@@ -650,14 +651,15 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO7_AGGR_COUNT GENMASK(7, 0)
#define RX_MSDU_END_INFO7_FLOW_AGGR_CONTN BIT(8)
#define RX_MSDU_END_INFO7_FISA_TIMEOUT BIT(9)
-#define RX_MSDU_END_INFO7_TCPUDP_CSUM_FAIL_CPY BIT(10)
-#define RX_MSDU_END_INFO7_MSDU_LIMIT_ERROR BIT(11)
-#define RX_MSDU_END_INFO7_FLOW_IDX_TIMEOUT BIT(12)
-#define RX_MSDU_END_INFO7_FLOW_IDX_INVALID BIT(13)
-#define RX_MSDU_END_INFO7_CCE_MATCH BIT(14)
-#define RX_MSDU_END_INFO7_AMSDU_PARSER_ERR BIT(15)
-#define RX_MSDU_END_INFO8_KEY_ID GENMASK(7, 0)
+#define RX_MSDU_END_QCN9274_INFO7_TCPUDP_CSUM_FAIL_CPY BIT(10)
+#define RX_MSDU_END_QCN9274_INFO7_MSDU_LIMIT_ERROR BIT(11)
+#define RX_MSDU_END_QCN9274_INFO7_FLOW_IDX_TIMEOUT BIT(12)
+#define RX_MSDU_END_QCN9274_INFO7_FLOW_IDX_INVALID BIT(13)
+#define RX_MSDU_END_QCN9274_INFO7_CCE_MATCH BIT(14)
+#define RX_MSDU_END_QCN9274_INFO7_AMSDU_PARSER_ERR BIT(15)
+
+#define RX_MSDU_END_QCN9274_INFO8_KEY_ID GENMASK(7, 0)
#define RX_MSDU_END_INFO9_SERVICE_CODE GENMASK(14, 6)
#define RX_MSDU_END_INFO9_PRIORITY_VALID BIT(15)
@@ -698,8 +700,9 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO12_RATE_MCS GENMASK(17, 14)
#define RX_MSDU_END_INFO12_RECV_BW GENMASK(20, 18)
#define RX_MSDU_END_INFO12_RECEPTION_TYPE GENMASK(23, 21)
-#define RX_MSDU_END_INFO12_MIMO_SS_BITMAP GENMASK(30, 24)
-#define RX_MSDU_END_INFO12_MIMO_DONE_COPY BIT(31)
+
+#define RX_MSDU_END_QCN9274_INFO12_MIMO_SS_BITMAP GENMASK(30, 24)
+#define RX_MSDU_END_QCN9274_INFO12_MIMO_DONE_COPY BIT(31)
#define RX_MSDU_END_INFO13_FIRST_MPDU BIT(0)
#define RX_MSDU_END_INFO13_MCAST_BCAST BIT(2)
@@ -714,7 +717,6 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO13_EOSP BIT(11)
#define RX_MSDU_END_INFO13_A_MSDU_ERROR BIT(12)
#define RX_MSDU_END_INFO13_ORDER BIT(14)
-#define RX_MSDU_END_INFO13_WIFI_PARSER_ERR BIT(15)
#define RX_MSDU_END_INFO13_OVERFLOW_ERR BIT(16)
#define RX_MSDU_END_INFO13_MSDU_LEN_ERR BIT(17)
#define RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL BIT(18)
@@ -732,6 +734,8 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO13_UNDECRYPT_FRAME_ERR BIT(30)
#define RX_MSDU_END_INFO13_FCS_ERR BIT(31)
+#define RX_MSDU_END_QCN9274_INFO13_WIFI_PARSER_ERR BIT(15)
+
#define RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE GENMASK(12, 10)
#define RX_MSDU_END_INFO14_RX_BITMAP_NOT_UPDED BIT(13)
#define RX_MSDU_END_INFO14_MSDU_DONE BIT(31)
@@ -782,6 +786,65 @@ struct rx_msdu_end_qcn9274 {
__le32 info14;
} __packed;
+/* These macro definitions are only used for WCN7850 */
+#define RX_MSDU_END_WCN7850_INFO2_KEY_ID BIT(7, 0)
+
+#define RX_MSDU_END_WCN7850_INFO5_MSDU_LIMIT_ERR BIT(2)
+#define RX_MSDU_END_WCN7850_INFO5_IDX_TIMEOUT BIT(3)
+#define RX_MSDU_END_WCN7850_INFO5_IDX_INVALID BIT(4)
+#define RX_MSDU_END_WCN7850_INFO5_WIFI_PARSE_ERR BIT(5)
+#define RX_MSDU_END_WCN7850_INFO5_AMSDU_PARSER_ERR BIT(6)
+#define RX_MSDU_END_WCN7850_INFO5_TCPUDP_CSUM_FAIL_CPY BIT(14)
+
+#define RX_MSDU_END_WCN7850_INFO12_MIMO_SS_BITMAP GENMASK(31, 24)
+
+#define RX_MSDU_END_WCN7850_INFO13_FRAGMENT_FLAG BIT(13)
+#define RX_MSDU_END_WCN7850_INFO13_CCE_MATCH BIT(15)
+
+struct rx_msdu_end_wcn7850 {
+ __le16 info0;
+ __le16 phy_ppdu_id;
+ __le16 ip_hdr_cksum;
+ __le16 info1;
+ __le16 info2;
+ __le16 cumulative_l3_checksum;
+ __le32 rule_indication0;
+ __le32 rule_indication1;
+ __le16 info3;
+ __le16 l3_type;
+ __le32 ipv6_options_crc;
+ __le32 tcp_seq_num;
+ __le32 tcp_ack_num;
+ __le16 info4;
+ __le16 window_size;
+ __le16 tcp_udp_chksum;
+ __le16 info5;
+ __le16 sa_idx;
+ __le16 da_idx_or_sw_peer_id;
+ __le32 info6;
+ __le32 fse_metadata;
+ __le16 cce_metadata;
+ __le16 sa_sw_peer_id;
+ __le16 info7;
+ __le16 rsvd0;
+ __le16 cumulative_l4_checksum;
+ __le16 cumulative_ip_length;
+ __le32 info9;
+ __le32 info10;
+ __le32 info11;
+ __le32 toeplitz_hash_2_or_4;
+ __le32 flow_id_toeplitz;
+ __le32 info12;
+ __le32 ppdu_start_timestamp_31_0;
+ __le32 ppdu_start_timestamp_63_32;
+ __le32 phy_meta_data;
+ __le16 vlan_ctag_ci;
+ __le16 vlan_stag_ci;
+ __le32 rsvd[3];
+ __le32 info13;
+ __le32 info14;
+} __packed;
+
/* rx_msdu_end
*
* rxpcu_mpdu_filter_in_category
@@ -1410,7 +1473,7 @@ struct rx_pkt_hdr_tlv {
struct hal_rx_desc_wcn7850 {
__le64 msdu_end_tag;
- struct rx_msdu_end_qcn9274 msdu_end;
+ struct rx_msdu_end_wcn7850 msdu_end;
u8 rx_padding0[RX_BE_PADDING0_BYTES];
__le64 mpdu_start_tag;
struct rx_mpdu_start_qcn9274 mpdu_start;
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index ef0f3cf35cfd..80b3d51387b8 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -152,6 +152,8 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_service_available_event) },
[WMI_TAG_PEER_ASSOC_CONF_EVENT] = {
.min_len = sizeof(struct wmi_peer_assoc_conf_event) },
+ [WMI_TAG_RFKILL_EVENT] = {
+ .min_len = sizeof(struct wmi_rfkill_state_change_event) },
[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT] = {
.min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) },
[WMI_TAG_HOST_SWFDA_EVENT] = {
@@ -3876,6 +3878,12 @@ static int ath12k_wmi_ext_hal_reg_caps(struct ath12k_base *soc,
ath12k_warn(soc, "failed to extract reg cap %d\n", i);
return ret;
}
+
+ if (reg_cap.phy_id >= MAX_RADIOS) {
+ ath12k_warn(soc, "unexpected phy id %u\n", reg_cap.phy_id);
+ return -EINVAL;
+ }
+
soc->hal_reg_cap[reg_cap.phy_id] = reg_cap;
}
return 0;
@@ -4153,14 +4161,22 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
__le32 cap_info_internal)
{
struct ath12k_band_cap *cap_band = &pdev->cap.band[band];
+ u32 support_320mhz;
u8 i;
+ if (band == NL80211_BAND_6GHZ)
+ support_320mhz = cap_band->eht_cap_phy_info[0] &
+ IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+
for (i = 0; i < WMI_MAX_EHTCAP_MAC_SIZE; i++)
cap_band->eht_cap_mac_info[i] = le32_to_cpu(cap_mac_info[i]);
for (i = 0; i < WMI_MAX_EHTCAP_PHY_SIZE; i++)
cap_band->eht_cap_phy_info[i] = le32_to_cpu(cap_phy_info[i]);
+ if (band == NL80211_BAND_6GHZ)
+ cap_band->eht_cap_phy_info[0] |= support_320mhz;
+
cap_band->eht_mcs_20_only = le32_to_cpu(supp_mcs[0]);
cap_band->eht_mcs_80 = le32_to_cpu(supp_mcs[1]);
if (band != NL80211_BAND_2GHZ) {
@@ -4182,10 +4198,19 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
const struct ath12k_wmi_caps_ext_params *caps,
struct ath12k_pdev *pdev)
{
- u32 bands;
+ struct ath12k_band_cap *cap_band;
+ u32 bands, support_320mhz;
int i;
if (ab->hw_params->single_pdev_only) {
+ if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) {
+ support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) &
+ IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+ cap_band = &pdev->cap.band[NL80211_BAND_6GHZ];
+ cap_band->eht_cap_phy_info[0] |= support_320mhz;
+ return 0;
+ }
+
for (i = 0; i < ab->fw_pdev_count; i++) {
struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i];
@@ -4241,7 +4266,8 @@ static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag,
return -EPROTO;
if (ab->hw_params->single_pdev_only) {
- if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id))
+ if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id) &&
+ caps->hw_mode_id != WMI_HOST_HW_MODE_SINGLE)
return 0;
} else {
for (i = 0; i < ab->num_radios; i++) {
@@ -5395,7 +5421,13 @@ static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab,
static bool ath12k_reg_is_world_alpha(char *alpha)
{
- return alpha[0] == '0' && alpha[1] == '0';
+ if (alpha[0] == '0' && alpha[1] == '0')
+ return true;
+
+ if (alpha[0] == 'n' && alpha[1] == 'a')
+ return true;
+
+ return false;
}
static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb)
@@ -5867,8 +5899,9 @@ exit:
rcu_read_unlock();
}
-static struct ath12k *ath12k_get_ar_on_scan_abort(struct ath12k_base *ab,
- u32 vdev_id)
+static struct ath12k *ath12k_get_ar_on_scan_state(struct ath12k_base *ab,
+ u32 vdev_id,
+ enum ath12k_scan_state state)
{
int i;
struct ath12k_pdev *pdev;
@@ -5880,7 +5913,7 @@ static struct ath12k *ath12k_get_ar_on_scan_abort(struct ath12k_base *ab,
ar = pdev->ar;
spin_lock_bh(&ar->data_lock);
- if (ar->scan.state == ATH12K_SCAN_ABORTING &&
+ if (ar->scan.state == state &&
ar->scan.vdev_id == vdev_id) {
spin_unlock_bh(&ar->data_lock);
return ar;
@@ -5910,10 +5943,15 @@ static void ath12k_scan_event(struct ath12k_base *ab, struct sk_buff *skb)
* aborting scan's vdev id matches this event info.
*/
if (le32_to_cpu(scan_ev.event_type) == WMI_SCAN_EVENT_COMPLETED &&
- le32_to_cpu(scan_ev.reason) == WMI_SCAN_REASON_CANCELLED)
- ar = ath12k_get_ar_on_scan_abort(ab, le32_to_cpu(scan_ev.vdev_id));
- else
+ le32_to_cpu(scan_ev.reason) == WMI_SCAN_REASON_CANCELLED) {
+ ar = ath12k_get_ar_on_scan_state(ab, le32_to_cpu(scan_ev.vdev_id),
+ ATH12K_SCAN_ABORTING);
+ if (!ar)
+ ar = ath12k_get_ar_on_scan_state(ab, le32_to_cpu(scan_ev.vdev_id),
+ ATH12K_SCAN_RUNNING);
+ } else {
ar = ath12k_mac_get_ar_by_vdev_id(ab, le32_to_cpu(scan_ev.vdev_id));
+ }
if (!ar) {
ath12k_warn(ab, "Received scan event for unknown vdev");
@@ -6580,6 +6618,40 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
kfree(tb);
}
+static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ const struct wmi_rfkill_state_change_event *ev;
+ const void **tb;
+ int ret;
+
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
+ if (IS_ERR(tb)) {
+ ret = PTR_ERR(tb);
+ ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
+ return;
+ }
+
+ ev = tb[WMI_TAG_RFKILL_EVENT];
+ if (!ev) {
+ kfree(tb);
+ return;
+ }
+
+ ath12k_dbg(ab, ATH12K_DBG_MAC,
+ "wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
+ le32_to_cpu(ev->gpio_pin_num),
+ le32_to_cpu(ev->int_type),
+ le32_to_cpu(ev->radio_state));
+
+ spin_lock_bh(&ab->base_lock);
+ ab->rfkill_radio_on = (ev->radio_state == cpu_to_le32(WMI_RFKILL_RADIO_STATE_ON));
+ spin_unlock_bh(&ab->base_lock);
+
+ queue_work(ab->workqueue, &ab->rfkill_work);
+ kfree(tb);
+}
+
static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd_hdr;
@@ -6672,6 +6744,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID:
ath12k_probe_resp_tx_status_event(ab, skb);
break;
+ case WMI_RFKILL_STATE_CHANGE_EVENTID:
+ ath12k_rfkill_state_change_event(ab, skb);
+ break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index c75a6fa1f7e0..965755b4cbfd 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -4793,6 +4793,31 @@ struct ath12k_wmi_base {
#define ATH12K_FW_STATS_BUF_SIZE (1024 * 1024)
+enum wmi_sys_cap_info_flags {
+ WMI_SYS_CAP_INFO_RXTX_LED = BIT(0),
+ WMI_SYS_CAP_INFO_RFKILL = BIT(1),
+};
+
+#define WMI_RFKILL_CFG_GPIO_PIN_NUM GENMASK(5, 0)
+#define WMI_RFKILL_CFG_RADIO_LEVEL BIT(6)
+#define WMI_RFKILL_CFG_PIN_AS_GPIO GENMASK(10, 7)
+
+enum wmi_rfkill_enable_radio {
+ WMI_RFKILL_ENABLE_RADIO_ON = 0,
+ WMI_RFKILL_ENABLE_RADIO_OFF = 1,
+};
+
+enum wmi_rfkill_radio_state {
+ WMI_RFKILL_RADIO_STATE_OFF = 1,
+ WMI_RFKILL_RADIO_STATE_ON = 2,
+};
+
+struct wmi_rfkill_state_change_event {
+ __le32 gpio_pin_num;
+ __le32 int_type;
+ __le32 radio_state;
+} __packed;
+
void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
struct ath12k_wmi_resource_config_arg *config);
void ath12k_wmi_init_wcn7850(struct ath12k_base *ab,
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index c59c14483177..597d1f916dfd 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -230,13 +230,13 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
}
static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
{
- struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+ struct ath5k_hw *ah = hw_priv;
return ath5k_hw_reg_read(ah, reg_offset);
}
static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
{
- struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+ struct ath5k_hw *ah = hw_priv;
ath5k_hw_reg_write(ah, val, reg_offset);
}
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 86b8cb975b1a..b51fce5ae260 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -54,7 +54,7 @@ MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
/* return bus cachesize in 4B word units */
static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
{
- struct ath5k_hw *ah = (struct ath5k_hw *) common->priv;
+ struct ath5k_hw *ah = common->priv;
u8 u8tmp;
pci_read_config_byte(ah->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
@@ -76,7 +76,7 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
static bool
ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
{
- struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
+ struct ath5k_hw *ah = common->ah;
u32 status, timeout;
/*
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d3aa9e7a37c2..8f9fe23e9755 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -852,14 +852,14 @@ void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)
void ath6kl_wakeup_event(void *dev)
{
- struct ath6kl *ar = (struct ath6kl *) dev;
+ struct ath6kl *ar = dev;
wake_up(&ar->event_wq);
}
void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
{
- struct ath6kl *ar = (struct ath6kl *) devt;
+ struct ath6kl *ar = devt;
ar->tx_pwr = tx_pwr;
wake_up(&ar->event_wq);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index a56fab6232a9..80e66acc5cf6 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -708,7 +708,7 @@ void ath6kl_tx_complete(struct htc_target *target,
packet->endpoint >= ENDPOINT_MAX))
continue;
- ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
+ ath6kl_cookie = packet->pkt_cntxt;
if (WARN_ON_ONCE(!ath6kl_cookie))
continue;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a29c11f944a5..6274d1624261 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -766,10 +766,10 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
}
}
-static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
+static u32 ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- int ret;
+ u32 ret;
if (IS_CHAN_2GHZ(chan)) {
if (IS_CHAN_HT40(chan))
@@ -791,7 +791,7 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
return ret;
}
-static int ar9561_hw_get_modes_txgain_index(struct ath_hw *ah,
+static u32 ar9561_hw_get_modes_txgain_index(struct ath_hw *ah,
struct ath9k_channel *chan)
{
if (IS_CHAN_2GHZ(chan)) {
@@ -916,7 +916,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
* TXGAIN initvals.
*/
if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
- int modes_txgain_index = 1;
+ u32 modes_txgain_index = 1;
if (AR_SREV_9550(ah))
modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan);
@@ -925,9 +925,6 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
modes_txgain_index =
ar9561_hw_get_modes_txgain_index(ah, chan);
- if (modes_txgain_index < 0)
- return -EINVAL;
-
REG_WRITE_ARRAY(&ah->iniModesTxGain, modes_txgain_index,
regWrites);
} else {
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9bc57c5a89bf..a0376a6787b8 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1293,7 +1293,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
- memcpy(data, *ath9k_gstrings_stats,
+ memcpy(data, ath9k_gstrings_stats,
sizeof(ath9k_gstrings_stats));
}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index e5414435b141..90cfe39aa433 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1481,31 +1481,31 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
{
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
struct htc_target *htc_handle = hif_dev->htc_handle;
- int ret;
const struct firmware *fw;
+ int ret;
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
if (ret)
return ret;
- if (hif_dev->flags & HIF_USB_READY) {
- /* request cached firmware during suspend/resume cycle */
- ret = request_firmware(&fw, hif_dev->fw_name,
- &hif_dev->udev->dev);
- if (ret)
- goto fail_resume;
-
- hif_dev->fw_data = fw->data;
- hif_dev->fw_size = fw->size;
- ret = ath9k_hif_usb_download_fw(hif_dev);
- release_firmware(fw);
- if (ret)
- goto fail_resume;
- } else {
- ath9k_hif_usb_dealloc_urbs(hif_dev);
- return -EIO;
+ if (!(hif_dev->flags & HIF_USB_READY)) {
+ ret = -EIO;
+ goto fail_resume;
}
+ /* request cached firmware during suspend/resume cycle */
+ ret = request_firmware(&fw, hif_dev->fw_name,
+ &hif_dev->udev->dev);
+ if (ret)
+ goto fail_resume;
+
+ hif_dev->fw_data = fw->data;
+ hif_dev->fw_size = fw->size;
+ ret = ath9k_hif_usb_download_fw(hif_dev);
+ release_firmware(fw);
+ if (ret)
+ goto fail_resume;
+
mdelay(100);
ret = ath9k_htc_resume(htc_handle);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index c549ff3abcdc..278ddc713fdc 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -423,7 +423,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
- memcpy(data, *ath9k_htc_gstrings_stats,
+ memcpy(data, ath9k_htc_gstrings_stats,
sizeof(ath9k_htc_gstrings_stats));
}
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 9013f056eecb..d405a4c34059 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -180,7 +180,7 @@ static int wcn36xx_dxe_init_descs(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *wc
if (!wcn_ch->cpu_addr)
return -ENOMEM;
- cur_dxe = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr;
+ cur_dxe = wcn_ch->cpu_addr;
cur_ctl = wcn_ch->head_blk_ctl;
for (i = 0; i < wcn_ch->desc_num; i++) {
@@ -453,7 +453,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
{
- struct wcn36xx *wcn = (struct wcn36xx *)dev;
+ struct wcn36xx *wcn = dev;
int int_src, int_reason;
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src);
@@ -541,7 +541,7 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev)
{
- struct wcn36xx *wcn = (struct wcn36xx *)dev;
+ struct wcn36xx *wcn = dev;
wcn36xx_dxe_rx_frame(wcn);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 17e1919d1cd8..2cf86fc3f8fe 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -576,7 +576,7 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
if (len < sizeof(*rsp))
return -EIO;
- rsp = (struct wcn36xx_hal_mac_start_rsp_msg *)buf;
+ rsp = buf;
if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->start_rsp_params.status)
return -EIO;
@@ -1025,7 +1025,7 @@ static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len)
ret = wcn36xx_smd_rsp_status_check(buf, len);
if (ret)
return ret;
- rsp = (struct wcn36xx_hal_switch_channel_rsp_msg *)buf;
+ rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL, "channel switched to: %d, status: %d\n",
rsp->channel_number, rsp->status);
return ret;
@@ -1072,7 +1072,7 @@ static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len,
if (ret)
return ret;
- rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf;
+ rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n",
rsp->header.len);
@@ -1131,7 +1131,7 @@ static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
{
struct wcn36xx_hal_update_scan_params_resp *rsp;
- rsp = (struct wcn36xx_hal_update_scan_params_resp *)buf;
+ rsp = buf;
/* Remove the PNO version bit */
rsp->status &= (~(WCN36XX_FW_MSG_PNO_VERSION_MASK));
@@ -1198,7 +1198,7 @@ static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
- rsp = (struct wcn36xx_hal_add_sta_self_rsp_msg *)buf;
+ rsp = buf;
if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
wcn36xx_warn("hal add sta self failure: %d\n",
@@ -1316,7 +1316,7 @@ static int wcn36xx_smd_join_rsp(void *buf, size_t len)
if (wcn36xx_smd_rsp_status_check(buf, len))
return -EIO;
- rsp = (struct wcn36xx_hal_join_rsp_msg *)buf;
+ rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL,
"hal rsp join status %d tx_mgmt_power %d\n",
@@ -1481,7 +1481,7 @@ static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
- rsp = (struct wcn36xx_hal_config_sta_rsp_msg *)buf;
+ rsp = buf;
params = &rsp->params;
if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
@@ -1849,7 +1849,7 @@ static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
- rsp = (struct wcn36xx_hal_config_bss_rsp_msg *)buf;
+ rsp = buf;
params = &rsp->bss_rsp_params;
if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
@@ -2476,7 +2476,7 @@ static int wcn36xx_smd_add_ba_session_rsp(void *buf, int len, u8 *session)
if (len < sizeof(*rsp))
return -EINVAL;
- rsp = (struct wcn36xx_hal_add_ba_session_rsp_msg *)buf;
+ rsp = buf;
if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS)
return rsp->status;
@@ -2654,7 +2654,7 @@ static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba
if (len < sizeof(*rsp))
return -EINVAL;
- rsp = (struct wcn36xx_hal_trigger_ba_rsp_msg *) buf;
+ rsp = buf;
if (rsp->candidate_cnt < 1)
return rsp->status ? rsp->status : -EINVAL;
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index cf15cde2a364..2c1ed9e570bf 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -47,7 +47,7 @@ struct wcn36xx_fw_msg_status_rsp {
struct wcn36xx_hal_ind_msg {
struct list_head list;
size_t msg_len;
- u8 msg[];
+ u8 msg[] __counted_by(msg_len);
};
struct wcn36xx;
diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.c b/drivers/net/wireless/ath/wcn36xx/testmode.c
index 7ae14b4d2d0e..e5142c052985 100644
--- a/drivers/net/wireless/ath/wcn36xx/testmode.c
+++ b/drivers/net/wireless/ath/wcn36xx/testmode.c
@@ -53,7 +53,7 @@ static int wcn36xx_tm_cmd_ptt(struct wcn36xx *wcn, struct ieee80211_vif *vif,
buf = nla_data(tb[WCN36XX_TM_ATTR_DATA]);
buf_len = nla_len(tb[WCN36XX_TM_ATTR_DATA]);
- msg = (struct ftm_rsp_msg *)buf;
+ msg = buf;
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
"testmode cmd wmi msg_id 0x%04X msg_len %d buf %pK buf_len %d\n",