mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
ath.git patches for v7.2 (PR #1)
For ath9k: - improve the GPIO interface. For ath12k: - replace dynamic memory allocation in WMI rx path - avoid buffer overread when configuring IRQs - code housekeeping -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCae9uIQAKCRAsFbugiYzL e6j9AQDl8svsSSmRgrw3IYVPlYi6W+XeY1hTFr7RR3AEkDQ8jgD+KbTQ2ogUJA2Q DLMnTKtbYczm3NLlza/75lbTDNkDpQs= =u5r4 -----END PGP SIGNATURE----- Merge tag 'ath-next-20260427' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath Jeff Johnson says: ================== ath.git patches for v7.2 (PR #1) For ath9k: - improve the GPIO interface. For ath12k: - replace dynamic memory allocation in WMI rx path - avoid buffer overread when configuring IRQs - code housekeeping ================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
334a70c454
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/gpio/generic.h>
|
||||
#include <linux/gpio/machine.h> /* For WLAN GPIOs */
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
|
@ -214,6 +215,56 @@ static const struct of_device_id ath79_gpio_of_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ATH9K_AHB)
|
||||
/*
|
||||
* This registers all of the ath79k GPIOs as descriptors to be picked
|
||||
* directly from the ATH79K wifi driver if the two are jitted together
|
||||
* in the same SoC.
|
||||
*/
|
||||
#define ATH79K_WIFI_DESCS 32
|
||||
static int ath79_gpio_register_wifi_descriptors(struct device *dev,
|
||||
const char *label)
|
||||
{
|
||||
struct gpiod_lookup_table *lookup;
|
||||
int i;
|
||||
|
||||
/* Create a gpiod lookup using gpiochip-local offsets + 1 for NULL */
|
||||
lookup = devm_kzalloc(dev,
|
||||
struct_size(lookup, table, ATH79K_WIFI_DESCS + 1),
|
||||
GFP_KERNEL);
|
||||
if (!lookup)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Ugly system-wide lookup for the NULL device: we know this
|
||||
* is already NULL but explicitly assign it here for people to
|
||||
* know what is going on. (Yes this is an ugly legacy hack, live
|
||||
* with it.)
|
||||
*/
|
||||
lookup->dev_id = NULL;
|
||||
|
||||
for (i = 0; i < ATH79K_WIFI_DESCS; i++) {
|
||||
lookup->table[i] =
|
||||
/*
|
||||
* Set the HW offset on the chip and the lookup
|
||||
* index to the same value, so looking up index 0
|
||||
* will get HW offset 0, index 1 HW offset 1 etc.
|
||||
*/
|
||||
GPIO_LOOKUP_IDX(label, i, "ath9k", i, GPIO_ACTIVE_HIGH);
|
||||
}
|
||||
|
||||
gpiod_add_lookup_table(lookup);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int ath79_gpio_register_wifi_descriptors(struct device *dev,
|
||||
const char *label)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_generic_chip_config config;
|
||||
|
|
@ -276,7 +327,11 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
|||
girq->handler = handle_simple_irq;
|
||||
}
|
||||
|
||||
return devm_gpiochip_add_data(dev, &ctrl->chip.gc, ctrl);
|
||||
err = devm_gpiochip_add_data(dev, &ctrl->chip.gc, ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ath79_gpio_register_wifi_descriptors(dev, ctrl->chip.gc.label);
|
||||
}
|
||||
|
||||
static struct platform_driver ath79_gpio_driver = {
|
||||
|
|
|
|||
|
|
@ -583,31 +583,36 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab)
|
|||
netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
|
||||
ath12k_ahb_ext_grp_napi_poll);
|
||||
|
||||
for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
|
||||
/* For TX ring, ensure that the ring mask and the
|
||||
* tcl_to_wbm_rbm_map point to the same ring number.
|
||||
*/
|
||||
for (j = 0; j < DP_TCL_NUM_RING_MAX; j++) {
|
||||
if (ring_mask->tx[i] &
|
||||
BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num)) {
|
||||
BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
|
||||
irq_grp->irqs[num_irq++] =
|
||||
wbm2host_tx_completions_ring1 - j;
|
||||
}
|
||||
}
|
||||
|
||||
if (ring_mask->rx[i] & BIT(j)) {
|
||||
for (j = 0; j < ATH12K_EXT_IRQ_NUM_MAX; j++) {
|
||||
if (ring_mask->rx[i] & BIT(j) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX) {
|
||||
irq_grp->irqs[num_irq++] =
|
||||
reo2host_destination_ring1 - j;
|
||||
}
|
||||
|
||||
if (ring_mask->rx_err[i] & BIT(j))
|
||||
if (ring_mask->rx_err[i] & BIT(j) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX)
|
||||
irq_grp->irqs[num_irq++] = reo2host_exception;
|
||||
|
||||
if (ring_mask->rx_wbm_rel[i] & BIT(j))
|
||||
if (ring_mask->rx_wbm_rel[i] & BIT(j) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX)
|
||||
irq_grp->irqs[num_irq++] = wbm2host_rx_release;
|
||||
|
||||
if (ring_mask->reo_status[i] & BIT(j))
|
||||
if (ring_mask->reo_status[i] & BIT(j) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX)
|
||||
irq_grp->irqs[num_irq++] = reo2host_status;
|
||||
|
||||
if (ring_mask->rx_mon_dest[i] & BIT(j))
|
||||
if (ring_mask->rx_mon_dest[i] & BIT(j) &&
|
||||
num_irq < ATH12K_EXT_IRQ_NUM_MAX)
|
||||
irq_grp->irqs[num_irq++] =
|
||||
rxdma2host_monitor_destination_mac1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2256,6 +2256,7 @@ void ath12k_core_deinit(struct ath12k_base *ab)
|
|||
void ath12k_core_free(struct ath12k_base *ab)
|
||||
{
|
||||
timer_delete_sync(&ab->rx_replenish_retry);
|
||||
ath12k_wmi_free();
|
||||
destroy_workqueue(ab->workqueue_aux);
|
||||
destroy_workqueue(ab->workqueue);
|
||||
kfree(ab);
|
||||
|
|
@ -2280,6 +2281,9 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
|
|||
if (!ab->workqueue_aux)
|
||||
goto err_free_wq;
|
||||
|
||||
if (ath12k_wmi_alloc() < 0)
|
||||
goto err_free_wq_aux;
|
||||
|
||||
mutex_init(&ab->core_lock);
|
||||
spin_lock_init(&ab->base_lock);
|
||||
init_completion(&ab->reset_complete);
|
||||
|
|
@ -2314,6 +2318,8 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
|
|||
|
||||
return ab;
|
||||
|
||||
err_free_wq_aux:
|
||||
destroy_workqueue(ab->workqueue_aux);
|
||||
err_free_wq:
|
||||
destroy_workqueue(ab->workqueue);
|
||||
err_sc_free:
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
|
||||
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
|
||||
int (*iter)(struct ath12k_base *ab, u16 tag, u16 len,
|
||||
const void *ptr, void *data),
|
||||
void *data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1523,7 +1523,7 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
|
|||
void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
|
||||
struct sk_buff *skb);
|
||||
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
|
||||
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
|
||||
int (*iter)(struct ath12k_base *ab, u16 tag, u16 len,
|
||||
const void *ptr, void *data),
|
||||
void *data);
|
||||
int ath12k_dp_tx_htt_h2t_ver_req_msg(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-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_HTC_H
|
||||
|
|
@ -301,7 +301,7 @@ struct ath12k_htc {
|
|||
u8 wmi_ep_count;
|
||||
};
|
||||
|
||||
int ath12k_htc_init(struct ath12k_base *ar);
|
||||
int ath12k_htc_init(struct ath12k_base *ab);
|
||||
int ath12k_htc_wait_target(struct ath12k_htc *htc);
|
||||
int ath12k_htc_start(struct ath12k_htc *htc);
|
||||
int ath12k_htc_connect_service(struct ath12k_htc *htc,
|
||||
|
|
@ -309,8 +309,8 @@ int ath12k_htc_connect_service(struct ath12k_htc *htc,
|
|||
struct ath12k_htc_svc_conn_resp *conn_resp);
|
||||
int ath12k_htc_send(struct ath12k_htc *htc, enum ath12k_htc_ep_id eid,
|
||||
struct sk_buff *packet);
|
||||
struct sk_buff *ath12k_htc_alloc_skb(struct ath12k_base *ar, int size);
|
||||
void ath12k_htc_rx_completion_handler(struct ath12k_base *ar,
|
||||
struct sk_buff *ath12k_htc_alloc_skb(struct ath12k_base *ab, int size);
|
||||
void ath12k_htc_rx_completion_handler(struct ath12k_base *ab,
|
||||
struct sk_buff *skb);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -559,7 +559,6 @@ struct hal_eht_sig_ofdma_cmn_eb1 {
|
|||
#define HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4 GENMASK_ULL(35, 27)
|
||||
#define HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5 GENMASK_ULL(44, 36)
|
||||
#define HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6 GENMASK_ULL(53, 45)
|
||||
#define HAL_RX_EHT_SIG_OFDMA_EB2_MCS GNEMASK_ULL(57, 54)
|
||||
|
||||
struct hal_eht_sig_ofdma_cmn_eb2 {
|
||||
__le64 info0;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/refcount.h>
|
||||
#include "core.h"
|
||||
#include "debugfs.h"
|
||||
#include "debug.h"
|
||||
|
|
@ -134,6 +136,10 @@ struct wmi_pdev_set_obss_bitmap_arg {
|
|||
const char *label;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(ath12k_wmi_mutex);
|
||||
static refcount_t ath12k_wmi_refcount;
|
||||
static void __percpu *ath12k_wmi_tb;
|
||||
|
||||
static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
|
||||
[WMI_TAG_ARRAY_BYTE] = { .min_len = 0 },
|
||||
[WMI_TAG_ARRAY_UINT32] = { .min_len = 0 },
|
||||
|
|
@ -289,29 +295,19 @@ static int ath12k_wmi_tlv_iter_parse(struct ath12k_base *ab, u16 tag, u16 len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath12k_wmi_tlv_parse(struct ath12k_base *ar, const void **tb,
|
||||
const void *ptr, size_t len)
|
||||
{
|
||||
return ath12k_wmi_tlv_iter(ar, ptr, len, ath12k_wmi_tlv_iter_parse,
|
||||
(void *)tb);
|
||||
}
|
||||
|
||||
static const void **
|
||||
ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab,
|
||||
struct sk_buff *skb, gfp_t gfp)
|
||||
ath12k_wmi_tlv_parse(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
const void **tb;
|
||||
int ret;
|
||||
|
||||
tb = kzalloc_objs(*tb, WMI_TAG_MAX, gfp);
|
||||
if (!tb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
tb = this_cpu_ptr(ath12k_wmi_tb);
|
||||
memset(tb, 0, WMI_TAG_MAX * sizeof(*tb));
|
||||
|
||||
ret = ath12k_wmi_tlv_parse(ab, tb, skb->data, skb->len);
|
||||
if (ret) {
|
||||
kfree(tb);
|
||||
ret = ath12k_wmi_tlv_iter(ab, skb->data, skb->len,
|
||||
ath12k_wmi_tlv_iter_parse, (void *)tb);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return tb;
|
||||
}
|
||||
|
|
@ -3911,9 +3907,10 @@ ath12k_wmi_obss_color_collision_event(struct ath12k_base *ab, struct sk_buff *sk
|
|||
const struct wmi_obss_color_collision_event *ev;
|
||||
struct ath12k_link_vif *arvif;
|
||||
u32 vdev_id, evt_type;
|
||||
const void **tb;
|
||||
u64 bitmap;
|
||||
|
||||
const void **tb __free(kfree) = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ath12k_warn(ab, "failed to parse OBSS color collision tlv %ld\n",
|
||||
PTR_ERR(tb));
|
||||
|
|
@ -5714,7 +5711,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -5724,13 +5721,11 @@ static int ath12k_pull_vdev_start_resp_tlv(struct ath12k_base *ab, struct sk_buf
|
|||
ev = tb[WMI_TAG_VDEV_START_RESPONSE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch vdev start resp ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
*vdev_rsp = *ev;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5809,7 +5804,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -5819,7 +5814,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch reg chan list ext update ev\n");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -5849,7 +5843,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
if (num_2g_reg_rules > MAX_REG_RULES || num_5g_reg_rules > MAX_REG_RULES) {
|
||||
ath12k_warn(ab, "Num reg rules for 2G/5G exceeds max limit (num_2g_reg_rules: %d num_5g_reg_rules: %d max_rules: %d)\n",
|
||||
num_2g_reg_rules, num_5g_reg_rules, MAX_REG_RULES);
|
||||
kfree(tb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -5859,7 +5852,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
if (num_6g_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
|
||||
ath12k_warn(ab, "Num 6G reg rules for AP mode(%d) exceeds max limit (num_6g_reg_rules_ap: %d, max_rules: %d)\n",
|
||||
i, num_6g_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
|
||||
kfree(tb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -5884,14 +5876,12 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
num_6g_reg_rules_cl[WMI_REG_VLP_AP][i] > MAX_6GHZ_REG_RULES) {
|
||||
ath12k_warn(ab, "Num 6g client reg rules exceeds max limit, for client(type: %d)\n",
|
||||
i);
|
||||
kfree(tb);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!total_reg_rules) {
|
||||
ath12k_warn(ab, "No reg rules available\n");
|
||||
kfree(tb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -5993,7 +5983,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
ext_wmi_reg_rule);
|
||||
|
||||
if (!reg_info->reg_rules_2g_ptr) {
|
||||
kfree(tb);
|
||||
ath12k_warn(ab, "Unable to Allocate memory for 2g rules\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -6027,7 +6016,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
ext_wmi_reg_rule);
|
||||
|
||||
if (!reg_info->reg_rules_5g_ptr) {
|
||||
kfree(tb);
|
||||
ath12k_warn(ab, "Unable to Allocate memory for 5g rules\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -6046,7 +6034,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
ext_wmi_reg_rule);
|
||||
|
||||
if (!reg_info->reg_rules_6g_ap_ptr[i]) {
|
||||
kfree(tb);
|
||||
ath12k_warn(ab, "Unable to Allocate memory for 6g ap rules\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -6061,7 +6048,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
ext_wmi_reg_rule);
|
||||
|
||||
if (!reg_info->reg_rules_6g_client_ptr[j][i]) {
|
||||
kfree(tb);
|
||||
ath12k_warn(ab, "Unable to Allocate memory for 6g client rules\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -6096,7 +6082,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
|
|||
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI, "processed regulatory ext channel list\n");
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6107,7 +6092,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6117,7 +6102,6 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
|
|||
ev = tb[WMI_TAG_PEER_DELETE_RESP_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch peer delete resp ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6127,7 +6111,6 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
|
|||
ether_addr_copy(peer_del_resp->peer_macaddr.addr,
|
||||
ev->peer_macaddr.addr);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6139,7 +6122,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6149,13 +6132,11 @@ static int ath12k_pull_vdev_del_resp_ev(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_VDEV_DELETE_RESP_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch vdev delete resp ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
*vdev_id = le32_to_cpu(ev->vdev_id);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6167,7 +6148,7 @@ static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab,
|
|||
const struct wmi_bcn_tx_status_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6177,14 +6158,12 @@ static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch bcn tx status ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
*vdev_id = le32_to_cpu(ev->vdev_id);
|
||||
*tx_status = le32_to_cpu(ev->tx_status);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6195,7 +6174,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6205,13 +6184,11 @@ static int ath12k_pull_vdev_stopped_param_tlv(struct ath12k_base *ab, struct sk_
|
|||
ev = tb[WMI_TAG_VDEV_STOPPED_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch vdev stop ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
*vdev_id = le32_to_cpu(ev->vdev_id);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6350,7 +6327,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6360,7 +6337,6 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch mgmt tx compl ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6370,7 +6346,6 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
|
|||
param->ppdu_id = ev->ppdu_id;
|
||||
param->ack_rssi = ev->ack_rssi;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6533,7 +6508,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6543,7 +6518,6 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
ev = tb[WMI_TAG_SCAN_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch scan ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6555,7 +6529,6 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
scan_evt_param->vdev_id = ev->vdev_id;
|
||||
scan_evt_param->tsf_timestamp = ev->tsf_timestamp;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6566,7 +6539,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6576,7 +6549,6 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
|
|||
ev = tb[WMI_TAG_PEER_STA_KICKOUT_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch peer sta kickout ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6584,7 +6556,6 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
|
|||
arg->reason = le32_to_cpu(ev->reason);
|
||||
arg->rssi = le32_to_cpu(ev->rssi);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6595,7 +6566,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6605,7 +6576,6 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
ev = tb[WMI_TAG_ROAM_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch roam ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6613,7 +6583,6 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
roam_ev->reason = ev->reason;
|
||||
roam_ev->rssi = ev->rssi;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6647,7 +6616,7 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
const struct wmi_chan_info_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6657,7 +6626,6 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
ev = tb[WMI_TAG_CHAN_INFO_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch chan info ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6674,7 +6642,6 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
ch_info_ev->mac_clk_mhz = ev->mac_clk_mhz;
|
||||
ch_info_ev->vdev_id = ev->vdev_id;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6686,7 +6653,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6696,7 +6663,6 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
ev = tb[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch pdev bss chan info ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6714,7 +6680,6 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
|
|||
bss_ch_info_ev->rx_bss_cycle_count_low = ev->rx_bss_cycle_count_low;
|
||||
bss_ch_info_ev->rx_bss_cycle_count_high = ev->rx_bss_cycle_count_high;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6726,7 +6691,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6736,7 +6701,6 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
|
|||
ev = tb[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch vdev install key compl ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
|
|
@ -6746,7 +6710,6 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
|
|||
arg->key_flags = le32_to_cpu(ev->key_flags);
|
||||
arg->status = le32_to_cpu(ev->status);
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6757,7 +6720,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6767,14 +6730,12 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
|
|||
ev = tb[WMI_TAG_PEER_ASSOC_CONF_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch peer assoc conf ev");
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
peer_assoc_conf->vdev_id = le32_to_cpu(ev->vdev_id);
|
||||
peer_assoc_conf->macaddr = ev->peer_macaddr.addr;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6792,7 +6753,7 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
|
|||
const void **tb;
|
||||
int ret, i;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -6801,7 +6762,6 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
|
|||
|
||||
ev = tb[WMI_TAG_11D_NEW_COUNTRY_EVENT];
|
||||
if (!ev) {
|
||||
kfree(tb);
|
||||
ath12k_warn(ab, "failed to fetch 11d new cc ev");
|
||||
return -EPROTO;
|
||||
}
|
||||
|
|
@ -6814,8 +6774,6 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
|
|||
ab->new_alpha2[0],
|
||||
ab->new_alpha2[1]);
|
||||
|
||||
kfree(tb);
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
|
|
@ -8557,7 +8515,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -8567,7 +8525,6 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch pdev ctl failsafe check ev");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8581,8 +8538,6 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
|
|||
if (ev->ctl_failsafe_status != 0)
|
||||
ath12k_warn(ab, "pdev ctl failsafe failure status %d",
|
||||
ev->ctl_failsafe_status);
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8654,7 +8609,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -8666,7 +8621,6 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
|
|||
|
||||
if (!ev || !vdev_ids) {
|
||||
ath12k_warn(ab, "failed to fetch pdev csa switch count ev");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8676,8 +8630,6 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
|
|||
ev->num_vdevs);
|
||||
|
||||
ath12k_wmi_process_csa_switch_count_event(ab, ev, vdev_ids);
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8689,7 +8641,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -8700,7 +8652,6 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
|
|||
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch pdev dfs radar detected ev");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8739,8 +8690,6 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
|
|||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
|
||||
|
|
@ -8751,7 +8700,7 @@ static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
|
|||
int ret;
|
||||
u16 length;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
|
|
@ -8762,14 +8711,11 @@ static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
|
|||
ev = tb[WMI_TAG_ARRAY_BYTE];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch ftm msg\n");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
length = skb->len - TLV_HDR_SIZE;
|
||||
ath12k_tm_process_event(ab, cmd_id, ev, length);
|
||||
kfree(tb);
|
||||
tb = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8782,7 +8728,7 @@ ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
|
|||
int temp;
|
||||
u32 pdev_id;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ath12k_warn(ab, "failed to parse tlv: %ld\n", PTR_ERR(tb));
|
||||
return;
|
||||
|
|
@ -8791,15 +8737,12 @@ ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch pdev temp ev\n");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
temp = a_sle32_to_cpu(ev->temp);
|
||||
pdev_id = le32_to_cpu(ev->pdev_id);
|
||||
|
||||
kfree(tb);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"pdev temperature ev temp %d pdev_id %u\n",
|
||||
temp, pdev_id);
|
||||
|
|
@ -8826,7 +8769,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab,
|
||||
|
|
@ -8838,15 +8781,12 @@ static void ath12k_fils_discovery_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_HOST_SWFDA_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch FILS discovery event\n");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
ath12k_warn(ab,
|
||||
"FILS discovery frame expected from host for vdev_id: %u, transmission scheduled at %u, next TBTT: %u\n",
|
||||
ev->vdev_id, ev->fils_tt, ev->tbtt);
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
|
||||
|
|
@ -8856,7 +8796,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab,
|
||||
|
|
@ -8869,7 +8809,6 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
|
|||
if (!ev) {
|
||||
ath12k_warn(ab,
|
||||
"failed to fetch probe response transmission status event");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8877,8 +8816,6 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
|
|||
ath12k_warn(ab,
|
||||
"Probe response transmission failed for vdev_id %u, status %u\n",
|
||||
ev->vdev_id, ev->tx_status);
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
|
||||
|
|
@ -8890,7 +8827,7 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
|
|||
struct ath12k *ar;
|
||||
int ret, vdev_id;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse P2P NoA TLV: %d\n", ret);
|
||||
|
|
@ -8900,10 +8837,8 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_P2P_NOA_EVENT];
|
||||
noa = tb[WMI_TAG_P2P_NOA_INFO];
|
||||
|
||||
if (!ev || !noa) {
|
||||
ret = -EPROTO;
|
||||
goto out;
|
||||
}
|
||||
if (!ev || !noa)
|
||||
return -EPROTO;
|
||||
|
||||
vdev_id = __le32_to_cpu(ev->vdev_id);
|
||||
|
||||
|
|
@ -8926,8 +8861,6 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
|
|||
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
kfree(tb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -8938,7 +8871,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, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -8946,10 +8879,8 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
ev = tb[WMI_TAG_RFKILL_EVENT];
|
||||
if (!ev) {
|
||||
kfree(tb);
|
||||
if (!ev)
|
||||
return;
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC,
|
||||
"wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
|
||||
|
|
@ -8962,7 +8893,6 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
|
|||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
queue_work(ab->workqueue, &ab->rfkill_work);
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8978,7 +8908,7 @@ static void ath12k_wmi_twt_enable_event(struct ath12k_base *ab,
|
|||
const struct wmi_twt_enable_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse wmi twt enable status event tlv: %d\n",
|
||||
|
|
@ -8989,15 +8919,12 @@ static void ath12k_wmi_twt_enable_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_TWT_ENABLE_COMPLETE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch twt enable wmi event\n");
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt enable event pdev id %u status %u\n",
|
||||
le32_to_cpu(ev->pdev_id),
|
||||
le32_to_cpu(ev->status));
|
||||
|
||||
exit:
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
|
||||
|
|
@ -9007,7 +8934,7 @@ static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
|
|||
const struct wmi_twt_disable_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse wmi twt disable status event tlv: %d\n",
|
||||
|
|
@ -9018,15 +8945,12 @@ static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_TWT_DISABLE_COMPLETE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch twt disable wmi event\n");
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt disable event pdev id %d status %u\n",
|
||||
le32_to_cpu(ev->pdev_id),
|
||||
le32_to_cpu(ev->status));
|
||||
|
||||
exit:
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static int ath12k_wmi_wow_wakeup_host_parse(struct ath12k_base *ab,
|
||||
|
|
@ -9099,7 +9023,7 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
|
|||
const void **tb;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
|
|
@ -9109,7 +9033,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_GTK_OFFLOAD_STATUS_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch gtk offload status ev");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9119,7 +9042,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
|
|||
rcu_read_unlock();
|
||||
ath12k_warn(ab, "failed to get arvif for vdev_id:%d\n",
|
||||
le32_to_cpu(ev->vdev_id));
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9135,8 +9057,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
|
|||
(void *)&replay_ctr_be, GFP_ATOMIC);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
|
||||
|
|
@ -9148,7 +9068,7 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
|
|||
const void **tb;
|
||||
int ret, i;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse mlo setup complete event tlv: %d\n",
|
||||
|
|
@ -9159,7 +9079,6 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
|
|||
ev = tb[WMI_TAG_MLO_SETUP_COMPLETE_EVENT];
|
||||
if (!ev) {
|
||||
ath12k_warn(ab, "failed to fetch mlo setup complete event\n");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -9178,14 +9097,11 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
|
|||
if (!ar) {
|
||||
ath12k_warn(ab, "invalid pdev_id %d status %u in setup complete event\n",
|
||||
ev->pdev_id, ev->status);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
ar->mlo_setup_status = le32_to_cpu(ev->status);
|
||||
complete(&ar->mlo_setup_done);
|
||||
|
||||
out:
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
|
||||
|
|
@ -9195,7 +9111,7 @@ static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
|
|||
const void **tb;
|
||||
int ret;
|
||||
|
||||
tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
|
||||
tb = ath12k_wmi_tlv_parse(ab, skb);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath12k_warn(ab, "failed to parse teardown complete event tlv: %d\n", ret);
|
||||
|
|
@ -9203,13 +9119,8 @@ static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
ev = tb[WMI_TAG_MLO_TEARDOWN_COMPLETE];
|
||||
if (!ev) {
|
||||
if (!ev)
|
||||
ath12k_warn(ab, "failed to fetch teardown complete event\n");
|
||||
kfree(tb);
|
||||
return;
|
||||
}
|
||||
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATH12K_DEBUGFS
|
||||
|
|
@ -11239,3 +11150,31 @@ int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
|
|||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_alloc(void)
|
||||
{
|
||||
guard(mutex)(&ath12k_wmi_mutex);
|
||||
|
||||
if (!ath12k_wmi_tb) {
|
||||
ath12k_wmi_tb = __alloc_percpu(WMI_TAG_MAX * sizeof(void *),
|
||||
__alignof__(void *));
|
||||
if (!ath12k_wmi_tb)
|
||||
return -ENOMEM;
|
||||
|
||||
refcount_set(&ath12k_wmi_refcount, 1);
|
||||
} else {
|
||||
refcount_inc(&ath12k_wmi_refcount);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath12k_wmi_free(void)
|
||||
{
|
||||
guard(mutex)(&ath12k_wmi_mutex);
|
||||
|
||||
if (refcount_dec_and_test(&ath12k_wmi_refcount)) {
|
||||
free_percpu(ath12k_wmi_tb);
|
||||
ath12k_wmi_tb = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6576,4 +6576,7 @@ int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
|
|||
struct ath12k_reg_tpc_power_info *param);
|
||||
int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
|
||||
struct wmi_mlo_link_set_active_arg *param);
|
||||
int ath12k_wmi_alloc(void);
|
||||
void ath12k_wmi_free(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include "hw.h"
|
||||
|
|
@ -2719,19 +2719,28 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, u32 gpio, u32 type)
|
|||
static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out,
|
||||
const char *label)
|
||||
{
|
||||
enum gpiod_flags flags = out ? GPIOD_OUT_LOW : GPIOD_IN;
|
||||
struct gpio_desc *gpiod;
|
||||
int err;
|
||||
|
||||
if (ah->caps.gpio_requested & BIT(gpio))
|
||||
if (ah->gpiods[gpio])
|
||||
return;
|
||||
|
||||
err = devm_gpio_request_one(ah->dev, gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label);
|
||||
/*
|
||||
* Obtains a system specific GPIO descriptor from another GPIO controller.
|
||||
* Ideally this should come from the device tree, this is a legacy code
|
||||
* path.
|
||||
*/
|
||||
gpiod = gpiod_get_index(NULL, "ath9k", gpio, flags);
|
||||
err = PTR_ERR_OR_ZERO(gpiod);
|
||||
if (err) {
|
||||
ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n",
|
||||
gpio, err);
|
||||
return;
|
||||
}
|
||||
|
||||
ah->caps.gpio_requested |= BIT(gpio);
|
||||
gpiod_set_consumer_name(gpiod, label);
|
||||
ah->gpiods[gpio] = gpiod;
|
||||
}
|
||||
|
||||
static void ath9k_hw_gpio_cfg_wmac(struct ath_hw *ah, u32 gpio, bool out,
|
||||
|
|
@ -2791,10 +2800,12 @@ void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio)
|
|||
if (!AR_SREV_SOC(ah))
|
||||
return;
|
||||
|
||||
WARN_ON(gpio >= ah->caps.num_gpio_pins);
|
||||
if (ah->gpiods[gpio]) {
|
||||
gpiod_put(ah->gpiods[gpio]);
|
||||
ah->gpiods[gpio] = NULL;
|
||||
}
|
||||
|
||||
if (ah->caps.gpio_requested & BIT(gpio))
|
||||
ah->caps.gpio_requested &= ~BIT(gpio);
|
||||
WARN_ON(gpio >= ah->caps.num_gpio_pins);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_gpio_free);
|
||||
|
||||
|
|
@ -2822,8 +2833,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
|
|||
val = REG_READ(ah, AR_GPIO_IN(ah)) & BIT(gpio);
|
||||
else
|
||||
val = MS_REG_READ(AR, gpio);
|
||||
} else if (BIT(gpio) & ah->caps.gpio_requested) {
|
||||
val = gpio_get_value(gpio) & BIT(gpio);
|
||||
} else if (ah->gpiods[gpio]) {
|
||||
val = gpiod_get_value(ah->gpiods[gpio]);
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
|
@ -2846,8 +2857,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
|
|||
AR7010_GPIO_OUT : AR_GPIO_IN_OUT(ah);
|
||||
|
||||
REG_RMW(ah, out_addr, val << gpio, BIT(gpio));
|
||||
} else if (BIT(gpio) & ah->caps.gpio_requested) {
|
||||
gpio_set_value(gpio, val);
|
||||
} else if (ah->gpiods[gpio]) {
|
||||
gpiod_set_value(ah->gpiods[gpio], val);
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
|
|
@ -302,7 +303,6 @@ struct ath9k_hw_capabilities {
|
|||
u8 max_rxchains;
|
||||
u8 num_gpio_pins;
|
||||
u32 gpio_mask;
|
||||
u32 gpio_requested;
|
||||
u8 rx_hp_qdepth;
|
||||
u8 rx_lp_qdepth;
|
||||
u8 rx_status_len;
|
||||
|
|
@ -783,6 +783,7 @@ struct ath_hw {
|
|||
struct ath9k_hw_capabilities caps;
|
||||
struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
|
||||
struct ath9k_channel *curchan;
|
||||
struct gpio_desc *gpiods[32];
|
||||
|
||||
union {
|
||||
struct ar5416_eeprom_def def;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user