diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/wmi.c | 303 |
1 files changed, 134 insertions, 169 deletions
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 8a65fa04b48d..34ab9631ff36 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/skbuff.h> #include <linux/ctype.h> @@ -238,8 +238,8 @@ static int ath11k_wmi_tlv_parse(struct ath11k_base *ar, const void **tb, (void *)tb); } -const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, - size_t len, gfp_t gfp) +const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, + struct sk_buff *skb, gfp_t gfp) { const void **tb; int ret; @@ -248,7 +248,7 @@ const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, if (!tb) return ERR_PTR(-ENOMEM); - ret = ath11k_wmi_tlv_parse(ab, tb, ptr, len); + ret = ath11k_wmi_tlv_parse(ab, tb, skb->data, skb->len); if (ret) { kfree(tb); return ERR_PTR(ret); @@ -2098,7 +2098,7 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, WMI_SCAN_EVENT_BSS_CHANNEL | WMI_SCAN_EVENT_FOREIGN_CHAN | WMI_SCAN_EVENT_DEQUEUED; - arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; + arg->scan_f_chan_stat_evnt = 1; if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE, ar->ab->wmi_ab.svc_map)) @@ -2379,6 +2379,70 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, return ret; } +int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, + u32 vdev_id, + struct ath11k_reg_tpc_power_info *param) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct wmi_vdev_set_tpc_power_cmd *cmd; + struct wmi_vdev_ch_power_info *ch; + struct sk_buff *skb; + struct wmi_tlv *tlv; + u8 *ptr; + int i, ret, len, array_len; + + array_len = sizeof(*ch) * param->num_pwr_levels; + len = sizeof(*cmd) + TLV_HDR_SIZE + array_len; + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + ptr = skb->data; + + cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_TPC_POWER_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->vdev_id = vdev_id; + cmd->psd_power = param->is_psd_power; + cmd->eirp_power = param->eirp_power; + cmd->power_type_6ghz = param->ap_power_type; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "tpc vdev id %d is psd power %d eirp power %d 6 ghz power type %d\n", + vdev_id, param->is_psd_power, param->eirp_power, param->ap_power_type); + + ptr += sizeof(*cmd); + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, array_len); + + ptr += TLV_HDR_SIZE; + ch = (struct wmi_vdev_ch_power_info *)ptr; + + for (i = 0; i < param->num_pwr_levels; i++, ch++) { + ch->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_VDEV_CH_POWER_INFO) | + FIELD_PREP(WMI_TLV_LEN, + sizeof(*ch) - TLV_HDR_SIZE); + + ch->chan_cfreq = param->chan_power_info[i].chan_cfreq; + ch->tx_power = param->chan_power_info[i].tx_power; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tpc chan freq %d TX power %d\n", + ch->chan_cfreq, ch->tx_power); + } + + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_TPC_POWER_CMDID); + if (ret) { + ath11k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n"); + dev_kfree_skb(skb); + return ret; + } + + return 0; +} + int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar, struct scan_cancel_param *param) { @@ -3930,7 +3994,7 @@ ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *sk struct ath11k_vif *arvif; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -3956,8 +4020,7 @@ ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *sk switch (ev->evt_type) { case WMI_BSS_COLOR_COLLISION_DETECTION: - ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap, - GFP_KERNEL); + ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap); ath11k_dbg(ab, ATH11K_DBG_WMI, "OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n", ev->vdev_id, ev->evt_type, ev->obss_color_bitmap); @@ -4749,6 +4812,14 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, soc->pdevs[0].pdev_id = 0; } + if (!soc->reg_info_store) { + soc->reg_info_store = kcalloc(soc->num_radios, + sizeof(*soc->reg_info_store), + GFP_ATOMIC); + if (!soc->reg_info_store) + return -ENOMEM; + } + return 0; } @@ -4786,6 +4857,7 @@ static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab) { kfree(ab->db_caps); ab->db_caps = NULL; + ab->num_db_cap = 0; } static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab, @@ -5003,7 +5075,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf const struct wmi_vdev_start_resp_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5028,6 +5100,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf vdev_rsp->mac_id = ev->mac_id; vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; + vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power; kfree(tb); return 0; @@ -5102,7 +5175,7 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n"); - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5278,7 +5351,7 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n"); - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5634,7 +5707,7 @@ static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff * const struct wmi_peer_delete_resp_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5666,7 +5739,7 @@ static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab, const struct wmi_vdev_delete_resp_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5686,15 +5759,15 @@ static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base *ab, return 0; } -static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab, void *evt_buf, - u32 len, u32 *vdev_id, - u32 *tx_status) +static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base *ab, + struct sk_buff *skb, + u32 *vdev_id, u32 *tx_status) { const void **tb; const struct wmi_bcn_tx_status_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5722,7 +5795,7 @@ static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base *ab, struct sk_ const struct wmi_vdev_stopped_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -5876,7 +5949,7 @@ static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab, const struct wmi_mgmt_tx_compl_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6052,7 +6125,7 @@ static int ath11k_pull_scan_ev(struct ath11k_base *ab, struct sk_buff *skb, const struct wmi_scan_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6085,7 +6158,7 @@ static int ath11k_pull_peer_sta_kickout_ev(struct ath11k_base *ab, struct sk_buf const struct wmi_peer_sta_kickout_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6112,7 +6185,7 @@ static int ath11k_pull_roam_ev(struct ath11k_base *ab, struct sk_buff *skb, const struct wmi_roam_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6153,14 +6226,14 @@ exit: return idx; } -static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, u8 *evt_buf, - u32 len, struct wmi_chan_info_event *ch_info_ev) +static int ath11k_pull_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb, + struct wmi_chan_info_event *ch_info_ev) { const void **tb; const struct wmi_chan_info_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, evt_buf, len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6199,7 +6272,7 @@ ath11k_pull_pdev_bss_chan_info_ev(struct ath11k_base *ab, struct sk_buff *skb, const struct wmi_pdev_bss_chan_info_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6239,7 +6312,7 @@ ath11k_pull_vdev_install_key_compl_ev(struct ath11k_base *ab, struct sk_buff *sk const struct wmi_vdev_install_key_compl_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6270,7 +6343,7 @@ static int ath11k_pull_peer_assoc_conf_ev(struct ath11k_base *ab, struct sk_buff const struct wmi_peer_assoc_conf_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -6995,7 +7068,7 @@ static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *s const void **tb; int ret, i; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -7060,32 +7133,15 @@ static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab, wake_up(&wmi->tx_ce_desc_wq); } -static bool ath11k_reg_is_world_alpha(char *alpha) -{ - if (alpha[0] == '0' && alpha[1] == '0') - return true; - - if (alpha[0] == 'n' && alpha[1] == 'a') - return true; - - return false; -} - -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - struct sk_buff *skb, +static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb, enum wmi_reg_chan_list_cmd_type id) { - struct cur_regulatory_info *reg_info = NULL; - struct ieee80211_regdomain *regd = NULL; - bool intersect = false; - int ret = 0, pdev_idx, i, j; - struct ath11k *ar; + struct cur_regulatory_info *reg_info; + int ret; reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); - if (!reg_info) { - ret = -ENOMEM; - goto fallback; - } + if (!reg_info) + return -ENOMEM; if (id == WMI_REG_CHAN_LIST_CC_ID) ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); @@ -7093,118 +7149,22 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); if (ret) { - ath11k_warn(ab, "failed to extract regulatory info from received event\n"); - goto fallback; - } - - ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); - - if (reg_info->status_code != REG_SET_CC_STATUS_PASS) { - /* In case of failure to set the requested ctry, - * fw retains the current regd. We print a failure info - * and return from here. - */ - ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n"); - goto mem_free; - } - - pdev_idx = reg_info->phy_id; - - /* Avoid default reg rule updates sent during FW recovery if - * it is already available - */ - spin_lock(&ab->base_lock); - if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) && - ab->default_regd[pdev_idx]) { - spin_unlock(&ab->base_lock); + ath11k_warn(ab, "failed to extract regulatory info\n"); goto mem_free; } - spin_unlock(&ab->base_lock); - if (pdev_idx >= ab->num_radios) { - /* Process the event for phy0 only if single_pdev_only - * is true. If pdev_idx is valid but not 0, discard the - * event. Otherwise, it goes to fallback. - */ - if (ab->hw_params.single_pdev_only && - pdev_idx < ab->hw_params.num_rxmda_per_pdev) - goto mem_free; - else - goto fallback; - } - - /* Avoid multiple overwrites to default regd, during core - * stop-start after mac registration. - */ - if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && - !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, - (char *)reg_info->alpha2, 2)) + ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP); + if (ret) { + ath11k_warn(ab, "failed to process regulatory info %d\n", ret); goto mem_free; - - /* Intersect new rules with default regd if a new country setting was - * requested, i.e a default regd was already set during initialization - * and the regd coming from this event has a valid country info. - */ - if (ab->default_regd[pdev_idx] && - !ath11k_reg_is_world_alpha((char *) - ab->default_regd[pdev_idx]->alpha2) && - !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) - intersect = true; - - regd = ath11k_reg_build_regd(ab, reg_info, intersect); - if (!regd) { - ath11k_warn(ab, "failed to build regd from reg_info\n"); - goto fallback; - } - - spin_lock(&ab->base_lock); - if (ab->default_regd[pdev_idx]) { - /* The initial rules from FW after WMI Init is to build - * the default regd. From then on, any rules updated for - * the pdev could be due to user reg changes. - * Free previously built regd before assigning the newly - * generated regd to ar. NULL pointer handling will be - * taken care by kfree itself. - */ - ar = ab->pdevs[pdev_idx].ar; - kfree(ab->new_regd[pdev_idx]); - ab->new_regd[pdev_idx] = regd; - queue_work(ab->workqueue, &ar->regd_update_work); - } else { - /* This regd would be applied during mac registration and is - * held constant throughout for regd intersection purpose - */ - ab->default_regd[pdev_idx] = regd; } - ab->dfs_region = reg_info->dfs_region; - spin_unlock(&ab->base_lock); - goto mem_free; + kfree(reg_info); + return 0; -fallback: - /* Fallback to older reg (by sending previous country setting - * again if fw has succeeded and we failed to process here. - * The Regdomain should be uniform across driver and fw. Since the - * FW has processed the command and sent a success status, we expect - * this function to succeed as well. If it doesn't, CTRY needs to be - * reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent. - */ - /* TODO: This is rare, but still should also be handled */ - WARN_ON(1); mem_free: - if (reg_info) { - kfree(reg_info->reg_rules_2ghz_ptr); - kfree(reg_info->reg_rules_5ghz_ptr); - if (reg_info->is_ext_reg_event) { - for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) - kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); - - for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) - for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) - kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]); - } - kfree(reg_info); - } + ath11k_reg_reset_info(reg_info); + kfree(reg_info); return ret; } @@ -7362,7 +7322,7 @@ static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff } ar->last_wmi_vdev_start_status = 0; - + ar->max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power; status = vdev_start_resp.status; if (WARN_ON_ONCE(status)) { @@ -7384,8 +7344,7 @@ static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *s struct ath11k_vif *arvif; u32 vdev_id, tx_status; - if (ath11k_pull_bcn_tx_status_ev(ab, skb->data, skb->len, - &vdev_id, &tx_status) != 0) { + if (ath11k_pull_bcn_tx_status_ev(ab, skb, &vdev_id, &tx_status) != 0) { ath11k_warn(ab, "failed to extract bcn tx status"); return; } @@ -7416,7 +7375,7 @@ static void ath11k_wmi_event_peer_sta_ps_state_chg(struct ath11k_base *ab, enum ath11k_wmi_peer_ps_state peer_previous_ps_state; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -7884,7 +7843,7 @@ static void ath11k_chan_info_event(struct ath11k_base *ab, struct sk_buff *skb) /* HW channel counters frequency value in hertz */ u32 cc_freq_hz = ab->cc_freq_hz; - if (ath11k_pull_chan_info_ev(ab, skb->data, skb->len, &ch_info_ev) != 0) { + if (ath11k_pull_chan_info_ev(ab, skb, &ch_info_ev) != 0) { ath11k_warn(ab, "failed to extract chan info event"); return; } @@ -8216,7 +8175,7 @@ static void ath11k_pdev_ctl_failsafe_check_event(struct ath11k_base *ab, const struct wmi_pdev_ctl_failsafe_chk_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -8267,7 +8226,7 @@ ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab, } if (arvif->is_up && arvif->vif->bss_conf.csa_active) - ieee80211_csa_finish(arvif->vif); + ieee80211_csa_finish(arvif->vif, 0); } rcu_read_unlock(); } @@ -8281,7 +8240,7 @@ ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base *ab, const u32 *vdev_ids; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -8315,7 +8274,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff struct ath11k *ar; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -8369,7 +8328,7 @@ ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab, const struct wmi_pdev_temperature_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -8409,7 +8368,7 @@ static void ath11k_fils_discovery_event(struct ath11k_base *ab, const struct wmi_fils_discovery_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, @@ -8441,7 +8400,7 @@ static void ath11k_probe_resp_tx_status_event(struct ath11k_base *ab, const struct wmi_probe_resp_tx_status_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, @@ -8567,7 +8526,7 @@ static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab, const struct wmi_twt_add_dialog_event *ev; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, @@ -8604,7 +8563,7 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab, u64 replay_ctr; int ret; - tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); if (IS_ERR(tb)) { ret = PTR_ERR(tb); ath11k_warn(ab, "failed to parse tlv: %d\n", ret); @@ -9793,3 +9752,9 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar, return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID); } + +bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar) +{ + return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, + ar->ab->wmi_ab.svc_map) && ar->supports_6ghz; +} |