1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
6 #include <linux/skbuff.h>
7 #include <linux/ctype.h>
8 #include <net/mac80211.h>
9 #include <net/cfg80211.h>
10 #include <linux/completion.h>
11 #include <linux/if_ether.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/uuid.h>
15 #include <linux/time.h>
25 struct wmi_tlv_policy
{
29 struct wmi_tlv_svc_ready_parse
{
30 bool wmi_svc_bitmap_done
;
33 struct wmi_tlv_dma_ring_caps_parse
{
34 struct wmi_dma_ring_capabilities
*dma_ring_caps
;
38 struct wmi_tlv_svc_rdy_ext_parse
{
39 struct ath11k_service_ext_param param
;
40 struct wmi_soc_mac_phy_hw_mode_caps
*hw_caps
;
41 struct wmi_hw_mode_capabilities
*hw_mode_caps
;
44 struct wmi_hw_mode_capabilities pref_hw_mode_caps
;
45 struct wmi_mac_phy_capabilities
*mac_phy_caps
;
47 struct wmi_soc_hal_reg_capabilities
*soc_hal_reg_caps
;
48 struct wmi_hal_reg_capabilities_ext
*ext_hal_reg_caps
;
49 u32 n_ext_hal_reg_caps
;
50 struct wmi_tlv_dma_ring_caps_parse dma_caps_parse
;
53 bool ext_hal_reg_done
;
54 bool mac_phy_chainmask_combo_done
;
55 bool mac_phy_chainmask_cap_done
;
56 bool oem_dma_ring_cap_done
;
57 bool dma_ring_cap_done
;
60 struct wmi_tlv_svc_rdy_ext2_parse
{
61 struct wmi_tlv_dma_ring_caps_parse dma_caps_parse
;
62 bool dma_ring_cap_done
;
65 struct wmi_tlv_rdy_parse
{
66 u32 num_extra_mac_addr
;
69 struct wmi_tlv_dma_buf_release_parse
{
70 struct ath11k_wmi_dma_buf_release_fixed_param fixed
;
71 struct wmi_dma_buf_release_entry
*buf_entry
;
72 struct wmi_dma_buf_release_meta_data
*meta_data
;
79 struct wmi_tlv_fw_stats_parse
{
80 const struct wmi_stats_event
*ev
;
81 const struct wmi_per_chain_rssi_stats
*rssi
;
82 struct ath11k_fw_stats
*stats
;
87 struct wmi_tlv_mgmt_rx_parse
{
88 const struct wmi_mgmt_rx_hdr
*fixed
;
93 static const struct wmi_tlv_policy wmi_tlv_policies
[] = {
96 [WMI_TAG_ARRAY_UINT32
]
98 [WMI_TAG_SERVICE_READY_EVENT
]
99 = { .min_len
= sizeof(struct wmi_service_ready_event
) },
100 [WMI_TAG_SERVICE_READY_EXT_EVENT
]
101 = { .min_len
= sizeof(struct wmi_service_ready_ext_event
) },
102 [WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS
]
103 = { .min_len
= sizeof(struct wmi_soc_mac_phy_hw_mode_caps
) },
104 [WMI_TAG_SOC_HAL_REG_CAPABILITIES
]
105 = { .min_len
= sizeof(struct wmi_soc_hal_reg_capabilities
) },
106 [WMI_TAG_VDEV_START_RESPONSE_EVENT
]
107 = { .min_len
= sizeof(struct wmi_vdev_start_resp_event
) },
108 [WMI_TAG_PEER_DELETE_RESP_EVENT
]
109 = { .min_len
= sizeof(struct wmi_peer_delete_resp_event
) },
110 [WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT
]
111 = { .min_len
= sizeof(struct wmi_bcn_tx_status_event
) },
112 [WMI_TAG_VDEV_STOPPED_EVENT
]
113 = { .min_len
= sizeof(struct wmi_vdev_stopped_event
) },
114 [WMI_TAG_REG_CHAN_LIST_CC_EVENT
]
115 = { .min_len
= sizeof(struct wmi_reg_chan_list_cc_event
) },
116 [WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT
]
117 = { .min_len
= sizeof(struct wmi_reg_chan_list_cc_ext_event
) },
118 [WMI_TAG_MGMT_RX_HDR
]
119 = { .min_len
= sizeof(struct wmi_mgmt_rx_hdr
) },
120 [WMI_TAG_MGMT_TX_COMPL_EVENT
]
121 = { .min_len
= sizeof(struct wmi_mgmt_tx_compl_event
) },
123 = { .min_len
= sizeof(struct wmi_scan_event
) },
124 [WMI_TAG_PEER_STA_KICKOUT_EVENT
]
125 = { .min_len
= sizeof(struct wmi_peer_sta_kickout_event
) },
127 = { .min_len
= sizeof(struct wmi_roam_event
) },
128 [WMI_TAG_CHAN_INFO_EVENT
]
129 = { .min_len
= sizeof(struct wmi_chan_info_event
) },
130 [WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT
]
131 = { .min_len
= sizeof(struct wmi_pdev_bss_chan_info_event
) },
132 [WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT
]
133 = { .min_len
= sizeof(struct wmi_vdev_install_key_compl_event
) },
134 [WMI_TAG_READY_EVENT
] = {
135 .min_len
= sizeof(struct wmi_ready_event_min
) },
136 [WMI_TAG_SERVICE_AVAILABLE_EVENT
]
137 = {.min_len
= sizeof(struct wmi_service_available_event
) },
138 [WMI_TAG_PEER_ASSOC_CONF_EVENT
]
139 = { .min_len
= sizeof(struct wmi_peer_assoc_conf_event
) },
140 [WMI_TAG_STATS_EVENT
]
141 = { .min_len
= sizeof(struct wmi_stats_event
) },
142 [WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT
]
143 = { .min_len
= sizeof(struct wmi_pdev_ctl_failsafe_chk_event
) },
144 [WMI_TAG_HOST_SWFDA_EVENT
] = {
145 .min_len
= sizeof(struct wmi_fils_discovery_event
) },
146 [WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT
] = {
147 .min_len
= sizeof(struct wmi_probe_resp_tx_status_event
) },
148 [WMI_TAG_VDEV_DELETE_RESP_EVENT
] = {
149 .min_len
= sizeof(struct wmi_vdev_delete_resp_event
) },
150 [WMI_TAG_OBSS_COLOR_COLLISION_EVT
] = {
151 .min_len
= sizeof(struct wmi_obss_color_collision_event
) },
152 [WMI_TAG_11D_NEW_COUNTRY_EVENT
] = {
153 .min_len
= sizeof(struct wmi_11d_new_cc_ev
) },
154 [WMI_TAG_PER_CHAIN_RSSI_STATS
] = {
155 .min_len
= sizeof(struct wmi_per_chain_rssi_stats
) },
156 [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT
] = {
157 .min_len
= sizeof(struct wmi_twt_add_dialog_event
) },
158 [WMI_TAG_P2P_NOA_INFO
] = {
159 .min_len
= sizeof(struct ath11k_wmi_p2p_noa_info
) },
160 [WMI_TAG_P2P_NOA_EVENT
] = {
161 .min_len
= sizeof(struct wmi_p2p_noa_event
) },
164 #define PRIMAP(_hw_mode_) \
165 [_hw_mode_] = _hw_mode_##_PRI
167 static const int ath11k_hw_mode_pri_map
[] = {
168 PRIMAP(WMI_HOST_HW_MODE_SINGLE
),
169 PRIMAP(WMI_HOST_HW_MODE_DBS
),
170 PRIMAP(WMI_HOST_HW_MODE_SBS_PASSIVE
),
171 PRIMAP(WMI_HOST_HW_MODE_SBS
),
172 PRIMAP(WMI_HOST_HW_MODE_DBS_SBS
),
173 PRIMAP(WMI_HOST_HW_MODE_DBS_OR_SBS
),
175 PRIMAP(WMI_HOST_HW_MODE_MAX
),
179 ath11k_wmi_tlv_iter(struct ath11k_base
*ab
, const void *ptr
, size_t len
,
180 int (*iter
)(struct ath11k_base
*ab
, u16 tag
, u16 len
,
181 const void *ptr
, void *data
),
184 const void *begin
= ptr
;
185 const struct wmi_tlv
*tlv
;
186 u16 tlv_tag
, tlv_len
;
190 if (len
< sizeof(*tlv
)) {
191 ath11k_err(ab
, "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
192 ptr
- begin
, len
, sizeof(*tlv
));
197 tlv_tag
= FIELD_GET(WMI_TLV_TAG
, tlv
->header
);
198 tlv_len
= FIELD_GET(WMI_TLV_LEN
, tlv
->header
);
203 ath11k_err(ab
, "wmi tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
204 tlv_tag
, ptr
- begin
, len
, tlv_len
);
208 if (tlv_tag
< ARRAY_SIZE(wmi_tlv_policies
) &&
209 wmi_tlv_policies
[tlv_tag
].min_len
&&
210 wmi_tlv_policies
[tlv_tag
].min_len
> tlv_len
) {
211 ath11k_err(ab
, "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n",
212 tlv_tag
, ptr
- begin
, tlv_len
,
213 wmi_tlv_policies
[tlv_tag
].min_len
);
217 ret
= iter(ab
, tlv_tag
, tlv_len
, ptr
, data
);
228 static int ath11k_wmi_tlv_iter_parse(struct ath11k_base
*ab
, u16 tag
, u16 len
,
229 const void *ptr
, void *data
)
231 const void **tb
= data
;
233 if (tag
< WMI_TAG_MAX
)
239 static int ath11k_wmi_tlv_parse(struct ath11k_base
*ar
, const void **tb
,
240 const void *ptr
, size_t len
)
242 return ath11k_wmi_tlv_iter(ar
, ptr
, len
, ath11k_wmi_tlv_iter_parse
,
246 const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base
*ab
,
247 struct sk_buff
*skb
, gfp_t gfp
)
252 tb
= kcalloc(WMI_TAG_MAX
, sizeof(*tb
), gfp
);
254 return ERR_PTR(-ENOMEM
);
256 ret
= ath11k_wmi_tlv_parse(ab
, tb
, skb
->data
, skb
->len
);
265 static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi
*wmi
, struct sk_buff
*skb
,
268 struct ath11k_skb_cb
*skb_cb
= ATH11K_SKB_CB(skb
);
269 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
270 struct wmi_cmd_hdr
*cmd_hdr
;
274 if (skb_push(skb
, sizeof(struct wmi_cmd_hdr
)) == NULL
)
277 cmd
|= FIELD_PREP(WMI_CMD_HDR_CMD_ID
, cmd_id
);
279 cmd_hdr
= (struct wmi_cmd_hdr
*)skb
->data
;
280 cmd_hdr
->cmd_id
= cmd
;
282 trace_ath11k_wmi_cmd(ab
, cmd_id
, skb
->data
, skb
->len
);
284 memset(skb_cb
, 0, sizeof(*skb_cb
));
285 ret
= ath11k_htc_send(&ab
->htc
, wmi
->eid
, skb
);
293 skb_pull(skb
, sizeof(struct wmi_cmd_hdr
));
297 int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi
*wmi
, struct sk_buff
*skb
,
300 struct ath11k_wmi_base
*wmi_ab
= wmi
->wmi_ab
;
301 int ret
= -EOPNOTSUPP
;
302 struct ath11k_base
*ab
= wmi_ab
->ab
;
306 if (ab
->hw_params
.credit_flow
) {
307 wait_event_timeout(wmi_ab
->tx_credits_wq
, ({
308 ret
= ath11k_wmi_cmd_send_nowait(wmi
, skb
, cmd_id
);
310 if (ret
&& test_bit(ATH11K_FLAG_CRASH_FLUSH
,
311 &wmi_ab
->ab
->dev_flags
))
315 }), WMI_SEND_TIMEOUT_HZ
);
317 wait_event_timeout(wmi
->tx_ce_desc_wq
, ({
318 ret
= ath11k_wmi_cmd_send_nowait(wmi
, skb
, cmd_id
);
320 if (ret
&& test_bit(ATH11K_FLAG_CRASH_FLUSH
,
321 &wmi_ab
->ab
->dev_flags
))
325 }), WMI_SEND_TIMEOUT_HZ
);
329 ath11k_warn(wmi_ab
->ab
, "wmi command %d timeout\n", cmd_id
);
332 ath11k_warn(wmi_ab
->ab
, "ce desc not available for wmi command %d\n",
338 static int ath11k_pull_svc_ready_ext(struct ath11k_pdev_wmi
*wmi_handle
,
340 struct ath11k_service_ext_param
*param
)
342 const struct wmi_service_ready_ext_event
*ev
= ptr
;
347 /* Move this to host based bitmap */
348 param
->default_conc_scan_config_bits
= ev
->default_conc_scan_config_bits
;
349 param
->default_fw_config_bits
= ev
->default_fw_config_bits
;
350 param
->he_cap_info
= ev
->he_cap_info
;
351 param
->mpdu_density
= ev
->mpdu_density
;
352 param
->max_bssid_rx_filters
= ev
->max_bssid_rx_filters
;
353 memcpy(¶m
->ppet
, &ev
->ppet
, sizeof(param
->ppet
));
359 ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi
*wmi_handle
,
360 struct wmi_soc_mac_phy_hw_mode_caps
*hw_caps
,
361 struct wmi_hw_mode_capabilities
*wmi_hw_mode_caps
,
362 struct wmi_soc_hal_reg_capabilities
*hal_reg_caps
,
363 struct wmi_mac_phy_capabilities
*wmi_mac_phy_caps
,
364 u8 hw_mode_id
, u8 phy_id
,
365 struct ath11k_pdev
*pdev
)
367 struct wmi_mac_phy_capabilities
*mac_phy_caps
;
368 struct ath11k_base
*ab
= wmi_handle
->wmi_ab
->ab
;
369 struct ath11k_band_cap
*cap_band
;
370 struct ath11k_pdev_cap
*pdev_cap
= &pdev
->cap
;
372 u32 hw_idx
, phy_idx
= 0;
374 if (!hw_caps
|| !wmi_hw_mode_caps
|| !hal_reg_caps
)
377 for (hw_idx
= 0; hw_idx
< hw_caps
->num_hw_modes
; hw_idx
++) {
378 if (hw_mode_id
== wmi_hw_mode_caps
[hw_idx
].hw_mode_id
)
381 phy_map
= wmi_hw_mode_caps
[hw_idx
].phy_id_map
;
388 if (hw_idx
== hw_caps
->num_hw_modes
)
392 if (phy_id
>= hal_reg_caps
->num_phy
)
395 mac_phy_caps
= wmi_mac_phy_caps
+ phy_idx
;
397 pdev
->pdev_id
= mac_phy_caps
->pdev_id
;
398 pdev_cap
->supported_bands
|= mac_phy_caps
->supported_bands
;
399 pdev_cap
->ampdu_density
= mac_phy_caps
->ampdu_density
;
400 ab
->target_pdev_ids
[ab
->target_pdev_count
].supported_bands
=
401 mac_phy_caps
->supported_bands
;
402 ab
->target_pdev_ids
[ab
->target_pdev_count
].pdev_id
= mac_phy_caps
->pdev_id
;
403 ab
->target_pdev_count
++;
405 if (!(mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_2G_CAP
) &&
406 !(mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_5G_CAP
))
409 /* Take non-zero tx/rx chainmask. If tx/rx chainmask differs from
410 * band to band for a single radio, need to see how this should be
413 if (mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_2G_CAP
) {
414 pdev_cap
->tx_chain_mask
= mac_phy_caps
->tx_chain_mask_2g
;
415 pdev_cap
->rx_chain_mask
= mac_phy_caps
->rx_chain_mask_2g
;
418 if (mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_5G_CAP
) {
419 pdev_cap
->vht_cap
= mac_phy_caps
->vht_cap_info_5g
;
420 pdev_cap
->vht_mcs
= mac_phy_caps
->vht_supp_mcs_5g
;
421 pdev_cap
->he_mcs
= mac_phy_caps
->he_supp_mcs_5g
;
422 pdev_cap
->tx_chain_mask
= mac_phy_caps
->tx_chain_mask_5g
;
423 pdev_cap
->rx_chain_mask
= mac_phy_caps
->rx_chain_mask_5g
;
424 pdev_cap
->nss_ratio_enabled
=
425 WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps
->nss_ratio
);
426 pdev_cap
->nss_ratio_info
=
427 WMI_NSS_RATIO_INFO_GET(mac_phy_caps
->nss_ratio
);
430 /* tx/rx chainmask reported from fw depends on the actual hw chains used,
431 * For example, for 4x4 capable macphys, first 4 chains can be used for first
432 * mac and the remaining 4 chains can be used for the second mac or vice-versa.
433 * In this case, tx/rx chainmask 0xf will be advertised for first mac and 0xf0
434 * will be advertised for second mac or vice-versa. Compute the shift value
435 * for tx/rx chainmask which will be used to advertise supported ht/vht rates to
438 pdev_cap
->tx_chain_mask_shift
=
439 find_first_bit((unsigned long *)&pdev_cap
->tx_chain_mask
, 32);
440 pdev_cap
->rx_chain_mask_shift
=
441 find_first_bit((unsigned long *)&pdev_cap
->rx_chain_mask
, 32);
443 if (mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_2G_CAP
) {
444 cap_band
= &pdev_cap
->band
[NL80211_BAND_2GHZ
];
445 cap_band
->phy_id
= mac_phy_caps
->phy_id
;
446 cap_band
->max_bw_supported
= mac_phy_caps
->max_bw_supported_2g
;
447 cap_band
->ht_cap_info
= mac_phy_caps
->ht_cap_info_2g
;
448 cap_band
->he_cap_info
[0] = mac_phy_caps
->he_cap_info_2g
;
449 cap_band
->he_cap_info
[1] = mac_phy_caps
->he_cap_info_2g_ext
;
450 cap_band
->he_mcs
= mac_phy_caps
->he_supp_mcs_2g
;
451 memcpy(cap_band
->he_cap_phy_info
, &mac_phy_caps
->he_cap_phy_info_2g
,
452 sizeof(u32
) * PSOC_HOST_MAX_PHY_SIZE
);
453 memcpy(&cap_band
->he_ppet
, &mac_phy_caps
->he_ppet2g
,
454 sizeof(struct ath11k_ppe_threshold
));
457 if (mac_phy_caps
->supported_bands
& WMI_HOST_WLAN_5G_CAP
) {
458 cap_band
= &pdev_cap
->band
[NL80211_BAND_5GHZ
];
459 cap_band
->phy_id
= mac_phy_caps
->phy_id
;
460 cap_band
->max_bw_supported
= mac_phy_caps
->max_bw_supported_5g
;
461 cap_band
->ht_cap_info
= mac_phy_caps
->ht_cap_info_5g
;
462 cap_band
->he_cap_info
[0] = mac_phy_caps
->he_cap_info_5g
;
463 cap_band
->he_cap_info
[1] = mac_phy_caps
->he_cap_info_5g_ext
;
464 cap_band
->he_mcs
= mac_phy_caps
->he_supp_mcs_5g
;
465 memcpy(cap_band
->he_cap_phy_info
, &mac_phy_caps
->he_cap_phy_info_5g
,
466 sizeof(u32
) * PSOC_HOST_MAX_PHY_SIZE
);
467 memcpy(&cap_band
->he_ppet
, &mac_phy_caps
->he_ppet5g
,
468 sizeof(struct ath11k_ppe_threshold
));
470 cap_band
= &pdev_cap
->band
[NL80211_BAND_6GHZ
];
471 cap_band
->max_bw_supported
= mac_phy_caps
->max_bw_supported_5g
;
472 cap_band
->ht_cap_info
= mac_phy_caps
->ht_cap_info_5g
;
473 cap_band
->he_cap_info
[0] = mac_phy_caps
->he_cap_info_5g
;
474 cap_band
->he_cap_info
[1] = mac_phy_caps
->he_cap_info_5g_ext
;
475 cap_band
->he_mcs
= mac_phy_caps
->he_supp_mcs_5g
;
476 memcpy(cap_band
->he_cap_phy_info
, &mac_phy_caps
->he_cap_phy_info_5g
,
477 sizeof(u32
) * PSOC_HOST_MAX_PHY_SIZE
);
478 memcpy(&cap_band
->he_ppet
, &mac_phy_caps
->he_ppet5g
,
479 sizeof(struct ath11k_ppe_threshold
));
486 ath11k_pull_reg_cap_svc_rdy_ext(struct ath11k_pdev_wmi
*wmi_handle
,
487 struct wmi_soc_hal_reg_capabilities
*reg_caps
,
488 struct wmi_hal_reg_capabilities_ext
*wmi_ext_reg_cap
,
490 struct ath11k_hal_reg_capabilities_ext
*param
)
492 struct wmi_hal_reg_capabilities_ext
*ext_reg_cap
;
494 if (!reg_caps
|| !wmi_ext_reg_cap
)
497 if (phy_idx
>= reg_caps
->num_phy
)
500 ext_reg_cap
= &wmi_ext_reg_cap
[phy_idx
];
502 param
->phy_id
= ext_reg_cap
->phy_id
;
503 param
->eeprom_reg_domain
= ext_reg_cap
->eeprom_reg_domain
;
504 param
->eeprom_reg_domain_ext
=
505 ext_reg_cap
->eeprom_reg_domain_ext
;
506 param
->regcap1
= ext_reg_cap
->regcap1
;
507 param
->regcap2
= ext_reg_cap
->regcap2
;
508 /* check if param->wireless_mode is needed */
509 param
->low_2ghz_chan
= ext_reg_cap
->low_2ghz_chan
;
510 param
->high_2ghz_chan
= ext_reg_cap
->high_2ghz_chan
;
511 param
->low_5ghz_chan
= ext_reg_cap
->low_5ghz_chan
;
512 param
->high_5ghz_chan
= ext_reg_cap
->high_5ghz_chan
;
517 static int ath11k_pull_service_ready_tlv(struct ath11k_base
*ab
,
519 struct ath11k_targ_cap
*cap
)
521 const struct wmi_service_ready_event
*ev
= evt_buf
;
524 ath11k_err(ab
, "%s: failed by NULL param\n",
529 cap
->phy_capability
= ev
->phy_capability
;
530 cap
->max_frag_entry
= ev
->max_frag_entry
;
531 cap
->num_rf_chains
= ev
->num_rf_chains
;
532 cap
->ht_cap_info
= ev
->ht_cap_info
;
533 cap
->vht_cap_info
= ev
->vht_cap_info
;
534 cap
->vht_supp_mcs
= ev
->vht_supp_mcs
;
535 cap
->hw_min_tx_power
= ev
->hw_min_tx_power
;
536 cap
->hw_max_tx_power
= ev
->hw_max_tx_power
;
537 cap
->sys_cap_info
= ev
->sys_cap_info
;
538 cap
->min_pkt_size_enable
= ev
->min_pkt_size_enable
;
539 cap
->max_bcn_ie_size
= ev
->max_bcn_ie_size
;
540 cap
->max_num_scan_channels
= ev
->max_num_scan_channels
;
541 cap
->max_supported_macs
= ev
->max_supported_macs
;
542 cap
->wmi_fw_sub_feat_caps
= ev
->wmi_fw_sub_feat_caps
;
543 cap
->txrx_chainmask
= ev
->txrx_chainmask
;
544 cap
->default_dbs_hw_mode_index
= ev
->default_dbs_hw_mode_index
;
545 cap
->num_msdu_desc
= ev
->num_msdu_desc
;
550 /* Save the wmi_service_bitmap into a linear bitmap. The wmi_services in
551 * wmi_service ready event are advertised in b0-b3 (LSB 4-bits) of each
554 static void ath11k_wmi_service_bitmap_copy(struct ath11k_pdev_wmi
*wmi
,
555 const u32
*wmi_svc_bm
)
559 for (i
= 0, j
= 0; i
< WMI_SERVICE_BM_SIZE
&& j
< WMI_MAX_SERVICE
; i
++) {
561 if (wmi_svc_bm
[i
] & BIT(j
% WMI_SERVICE_BITS_IN_SIZE32
))
562 set_bit(j
, wmi
->wmi_ab
->svc_map
);
563 } while (++j
% WMI_SERVICE_BITS_IN_SIZE32
);
567 static int ath11k_wmi_tlv_svc_rdy_parse(struct ath11k_base
*ab
, u16 tag
, u16 len
,
568 const void *ptr
, void *data
)
570 struct wmi_tlv_svc_ready_parse
*svc_ready
= data
;
571 struct ath11k_pdev_wmi
*wmi_handle
= &ab
->wmi_ab
.wmi
[0];
575 case WMI_TAG_SERVICE_READY_EVENT
:
576 if (ath11k_pull_service_ready_tlv(ab
, ptr
, &ab
->target_caps
))
580 case WMI_TAG_ARRAY_UINT32
:
581 if (!svc_ready
->wmi_svc_bitmap_done
) {
582 expect_len
= WMI_SERVICE_BM_SIZE
* sizeof(u32
);
583 if (len
< expect_len
) {
584 ath11k_warn(ab
, "invalid len %d for the tag 0x%x\n",
589 ath11k_wmi_service_bitmap_copy(wmi_handle
, ptr
);
591 svc_ready
->wmi_svc_bitmap_done
= true;
601 static int ath11k_service_ready_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
603 struct wmi_tlv_svc_ready_parse svc_ready
= { };
606 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
607 ath11k_wmi_tlv_svc_rdy_parse
,
610 ath11k_warn(ab
, "failed to parse tlv %d\n", ret
);
614 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event service ready");
619 struct sk_buff
*ath11k_wmi_alloc_skb(struct ath11k_wmi_base
*wmi_ab
, u32 len
)
622 struct ath11k_base
*ab
= wmi_ab
->ab
;
623 u32 round_len
= roundup(len
, 4);
625 skb
= ath11k_htc_alloc_skb(ab
, WMI_SKB_HEADROOM
+ round_len
);
629 skb_reserve(skb
, WMI_SKB_HEADROOM
);
630 if (!IS_ALIGNED((unsigned long)skb
->data
, 4))
631 ath11k_warn(ab
, "unaligned WMI skb data\n");
633 skb_put(skb
, round_len
);
634 memset(skb
->data
, 0, round_len
);
639 static u32
ath11k_wmi_mgmt_get_freq(struct ath11k
*ar
,
640 struct ieee80211_tx_info
*info
)
642 struct ath11k_base
*ab
= ar
->ab
;
645 if (ab
->hw_params
.support_off_channel_tx
&&
647 (info
->flags
& IEEE80211_TX_CTL_TX_OFFCHAN
))
648 freq
= ar
->scan
.roc_freq
;
653 int ath11k_wmi_mgmt_send(struct ath11k
*ar
, u32 vdev_id
, u32 buf_id
,
654 struct sk_buff
*frame
)
656 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
657 struct ieee80211_tx_info
*info
= IEEE80211_SKB_CB(frame
);
658 struct wmi_mgmt_send_cmd
*cmd
;
659 struct wmi_tlv
*frame_tlv
;
664 buf_len
= frame
->len
< WMI_MGMT_SEND_DOWNLD_LEN
?
665 frame
->len
: WMI_MGMT_SEND_DOWNLD_LEN
;
667 len
= sizeof(*cmd
) + sizeof(*frame_tlv
) + roundup(buf_len
, 4);
669 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
673 cmd
= (struct wmi_mgmt_send_cmd
*)skb
->data
;
674 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_MGMT_TX_SEND_CMD
) |
675 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
676 cmd
->vdev_id
= vdev_id
;
677 cmd
->desc_id
= buf_id
;
678 cmd
->chanfreq
= ath11k_wmi_mgmt_get_freq(ar
, info
);
679 cmd
->paddr_lo
= lower_32_bits(ATH11K_SKB_CB(frame
)->paddr
);
680 cmd
->paddr_hi
= upper_32_bits(ATH11K_SKB_CB(frame
)->paddr
);
681 cmd
->frame_len
= frame
->len
;
682 cmd
->buf_len
= buf_len
;
683 cmd
->tx_params_valid
= 0;
685 frame_tlv
= (struct wmi_tlv
*)(skb
->data
+ sizeof(*cmd
));
686 frame_tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
687 FIELD_PREP(WMI_TLV_LEN
, buf_len
);
689 memcpy(frame_tlv
->value
, frame
->data
, buf_len
);
691 ath11k_ce_byte_swap(frame_tlv
->value
, buf_len
);
693 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_MGMT_TX_SEND_CMDID
);
696 "failed to submit WMI_MGMT_TX_SEND_CMDID cmd\n");
700 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd mgmt tx send");
705 int ath11k_wmi_vdev_create(struct ath11k
*ar
, u8
*macaddr
,
706 struct vdev_create_params
*param
)
708 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
709 struct wmi_vdev_create_cmd
*cmd
;
711 struct wmi_vdev_txrx_streams
*txrx_streams
;
716 /* It can be optimized my sending tx/rx chain configuration
717 * only for supported bands instead of always sending it for
720 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+
721 (WMI_NUM_SUPPORTED_BAND_MAX
* sizeof(*txrx_streams
));
723 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
727 cmd
= (struct wmi_vdev_create_cmd
*)skb
->data
;
728 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_CREATE_CMD
) |
729 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
731 cmd
->vdev_id
= param
->if_id
;
732 cmd
->vdev_type
= param
->type
;
733 cmd
->vdev_subtype
= param
->subtype
;
734 cmd
->num_cfg_txrx_streams
= WMI_NUM_SUPPORTED_BAND_MAX
;
735 cmd
->pdev_id
= param
->pdev_id
;
736 cmd
->mbssid_flags
= param
->mbssid_flags
;
737 cmd
->mbssid_tx_vdev_id
= param
->mbssid_tx_vdev_id
;
739 ether_addr_copy(cmd
->vdev_macaddr
.addr
, macaddr
);
741 ptr
= skb
->data
+ sizeof(*cmd
);
742 len
= WMI_NUM_SUPPORTED_BAND_MAX
* sizeof(*txrx_streams
);
745 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
746 FIELD_PREP(WMI_TLV_LEN
, len
);
750 len
= sizeof(*txrx_streams
);
751 txrx_streams
->tlv_header
=
752 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_TXRX_STREAMS
) |
753 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
754 txrx_streams
->band
= WMI_TPC_CHAINMASK_CONFIG_BAND_2G
;
755 txrx_streams
->supported_tx_streams
=
756 param
->chains
[NL80211_BAND_2GHZ
].tx
;
757 txrx_streams
->supported_rx_streams
=
758 param
->chains
[NL80211_BAND_2GHZ
].rx
;
761 txrx_streams
->tlv_header
=
762 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_TXRX_STREAMS
) |
763 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
764 txrx_streams
->band
= WMI_TPC_CHAINMASK_CONFIG_BAND_5G
;
765 txrx_streams
->supported_tx_streams
=
766 param
->chains
[NL80211_BAND_5GHZ
].tx
;
767 txrx_streams
->supported_rx_streams
=
768 param
->chains
[NL80211_BAND_5GHZ
].rx
;
770 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_CREATE_CMDID
);
773 "failed to submit WMI_VDEV_CREATE_CMDID\n");
777 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
778 "cmd vdev create id %d type %d subtype %d macaddr %pM pdevid %d\n",
779 param
->if_id
, param
->type
, param
->subtype
,
780 macaddr
, param
->pdev_id
);
785 int ath11k_wmi_vdev_delete(struct ath11k
*ar
, u8 vdev_id
)
787 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
788 struct wmi_vdev_delete_cmd
*cmd
;
792 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
796 cmd
= (struct wmi_vdev_delete_cmd
*)skb
->data
;
797 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_DELETE_CMD
) |
798 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
799 cmd
->vdev_id
= vdev_id
;
801 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_DELETE_CMDID
);
803 ath11k_warn(ar
->ab
, "failed to submit WMI_VDEV_DELETE_CMDID\n");
807 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd vdev delete id %d\n", vdev_id
);
812 int ath11k_wmi_vdev_stop(struct ath11k
*ar
, u8 vdev_id
)
814 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
815 struct wmi_vdev_stop_cmd
*cmd
;
819 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
823 cmd
= (struct wmi_vdev_stop_cmd
*)skb
->data
;
825 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_STOP_CMD
) |
826 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
827 cmd
->vdev_id
= vdev_id
;
829 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_STOP_CMDID
);
831 ath11k_warn(ar
->ab
, "failed to submit WMI_VDEV_STOP cmd\n");
835 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd vdev stop id 0x%x\n", vdev_id
);
840 int ath11k_wmi_vdev_down(struct ath11k
*ar
, u8 vdev_id
)
842 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
843 struct wmi_vdev_down_cmd
*cmd
;
847 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
851 cmd
= (struct wmi_vdev_down_cmd
*)skb
->data
;
853 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_DOWN_CMD
) |
854 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
855 cmd
->vdev_id
= vdev_id
;
857 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_DOWN_CMDID
);
859 ath11k_warn(ar
->ab
, "failed to submit WMI_VDEV_DOWN cmd\n");
863 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd vdev down id 0x%x\n", vdev_id
);
868 static void ath11k_wmi_put_wmi_channel(struct wmi_channel
*chan
,
869 struct wmi_vdev_start_req_arg
*arg
)
871 u32 center_freq1
= arg
->channel
.band_center_freq1
;
873 memset(chan
, 0, sizeof(*chan
));
875 chan
->mhz
= arg
->channel
.freq
;
876 chan
->band_center_freq1
= arg
->channel
.band_center_freq1
;
878 if (arg
->channel
.mode
== MODE_11AX_HE160
) {
879 if (arg
->channel
.freq
> arg
->channel
.band_center_freq1
)
880 chan
->band_center_freq1
= center_freq1
+ 40;
882 chan
->band_center_freq1
= center_freq1
- 40;
884 chan
->band_center_freq2
= arg
->channel
.band_center_freq1
;
886 } else if ((arg
->channel
.mode
== MODE_11AC_VHT80_80
) ||
887 (arg
->channel
.mode
== MODE_11AX_HE80_80
)) {
888 chan
->band_center_freq2
= arg
->channel
.band_center_freq2
;
890 chan
->band_center_freq2
= 0;
893 chan
->info
|= FIELD_PREP(WMI_CHAN_INFO_MODE
, arg
->channel
.mode
);
894 if (arg
->channel
.passive
)
895 chan
->info
|= WMI_CHAN_INFO_PASSIVE
;
896 if (arg
->channel
.allow_ibss
)
897 chan
->info
|= WMI_CHAN_INFO_ADHOC_ALLOWED
;
898 if (arg
->channel
.allow_ht
)
899 chan
->info
|= WMI_CHAN_INFO_ALLOW_HT
;
900 if (arg
->channel
.allow_vht
)
901 chan
->info
|= WMI_CHAN_INFO_ALLOW_VHT
;
902 if (arg
->channel
.allow_he
)
903 chan
->info
|= WMI_CHAN_INFO_ALLOW_HE
;
904 if (arg
->channel
.ht40plus
)
905 chan
->info
|= WMI_CHAN_INFO_HT40_PLUS
;
906 if (arg
->channel
.chan_radar
)
907 chan
->info
|= WMI_CHAN_INFO_DFS
;
908 if (arg
->channel
.freq2_radar
)
909 chan
->info
|= WMI_CHAN_INFO_DFS_FREQ2
;
911 chan
->reg_info_1
= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR
,
912 arg
->channel
.max_power
) |
913 FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR
,
914 arg
->channel
.max_reg_power
);
916 chan
->reg_info_2
= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX
,
917 arg
->channel
.max_antenna_gain
) |
918 FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR
,
919 arg
->channel
.max_power
);
922 int ath11k_wmi_vdev_start(struct ath11k
*ar
, struct wmi_vdev_start_req_arg
*arg
,
925 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
926 struct wmi_vdev_start_request_cmd
*cmd
;
928 struct wmi_channel
*chan
;
933 if (WARN_ON(arg
->ssid_len
> sizeof(cmd
->ssid
.ssid
)))
936 len
= sizeof(*cmd
) + sizeof(*chan
) + TLV_HDR_SIZE
;
938 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
942 cmd
= (struct wmi_vdev_start_request_cmd
*)skb
->data
;
943 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
944 WMI_TAG_VDEV_START_REQUEST_CMD
) |
945 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
946 cmd
->vdev_id
= arg
->vdev_id
;
947 cmd
->beacon_interval
= arg
->bcn_intval
;
948 cmd
->bcn_tx_rate
= arg
->bcn_tx_rate
;
949 cmd
->dtim_period
= arg
->dtim_period
;
950 cmd
->num_noa_descriptors
= arg
->num_noa_descriptors
;
951 cmd
->preferred_rx_streams
= arg
->pref_rx_streams
;
952 cmd
->preferred_tx_streams
= arg
->pref_tx_streams
;
953 cmd
->cac_duration_ms
= arg
->cac_duration_ms
;
954 cmd
->regdomain
= arg
->regdomain
;
955 cmd
->he_ops
= arg
->he_ops
;
956 cmd
->mbssid_flags
= arg
->mbssid_flags
;
957 cmd
->mbssid_tx_vdev_id
= arg
->mbssid_tx_vdev_id
;
961 cmd
->ssid
.ssid_len
= arg
->ssid_len
;
962 memcpy(cmd
->ssid
.ssid
, arg
->ssid
, arg
->ssid_len
);
964 if (arg
->hidden_ssid
)
965 cmd
->flags
|= WMI_VDEV_START_HIDDEN_SSID
;
966 if (arg
->pmf_enabled
)
967 cmd
->flags
|= WMI_VDEV_START_PMF_ENABLED
;
970 cmd
->flags
|= WMI_VDEV_START_LDPC_RX_ENABLED
;
971 if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED
, &ar
->ab
->dev_flags
))
972 cmd
->flags
|= WMI_VDEV_START_HW_ENCRYPTION_DISABLED
;
974 ptr
= skb
->data
+ sizeof(*cmd
);
977 ath11k_wmi_put_wmi_channel(chan
, arg
);
979 chan
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_CHANNEL
) |
980 FIELD_PREP(WMI_TLV_LEN
,
981 sizeof(*chan
) - TLV_HDR_SIZE
);
982 ptr
+= sizeof(*chan
);
985 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
986 FIELD_PREP(WMI_TLV_LEN
, 0);
988 /* Note: This is a nested TLV containing:
989 * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
995 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
996 WMI_VDEV_RESTART_REQUEST_CMDID
);
998 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
999 WMI_VDEV_START_REQUEST_CMDID
);
1001 ath11k_warn(ar
->ab
, "failed to submit vdev_%s cmd\n",
1002 restart
? "restart" : "start");
1006 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd vdev %s id 0x%x freq 0x%x mode 0x%x\n",
1007 restart
? "restart" : "start", arg
->vdev_id
,
1008 arg
->channel
.freq
, arg
->channel
.mode
);
1013 int ath11k_wmi_vdev_up(struct ath11k
*ar
, u32 vdev_id
, u32 aid
, const u8
*bssid
,
1014 u8
*tx_bssid
, u32 nontx_profile_idx
, u32 nontx_profile_cnt
)
1016 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1017 struct wmi_vdev_up_cmd
*cmd
;
1018 struct ieee80211_bss_conf
*bss_conf
;
1019 struct ath11k_vif
*arvif
;
1020 struct sk_buff
*skb
;
1023 arvif
= ath11k_mac_get_arvif(ar
, vdev_id
);
1025 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1029 cmd
= (struct wmi_vdev_up_cmd
*)skb
->data
;
1031 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_UP_CMD
) |
1032 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1033 cmd
->vdev_id
= vdev_id
;
1034 cmd
->vdev_assoc_id
= aid
;
1036 ether_addr_copy(cmd
->vdev_bssid
.addr
, bssid
);
1038 cmd
->nontx_profile_idx
= nontx_profile_idx
;
1039 cmd
->nontx_profile_cnt
= nontx_profile_cnt
;
1041 ether_addr_copy(cmd
->tx_vdev_bssid
.addr
, tx_bssid
);
1043 if (arvif
&& arvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
1044 bss_conf
= &arvif
->vif
->bss_conf
;
1046 if (bss_conf
->nontransmitted
) {
1047 ether_addr_copy(cmd
->tx_vdev_bssid
.addr
,
1048 bss_conf
->transmitter_bssid
);
1049 cmd
->nontx_profile_idx
= bss_conf
->bssid_index
;
1050 cmd
->nontx_profile_cnt
= bss_conf
->bssid_indicator
;
1054 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_UP_CMDID
);
1056 ath11k_warn(ar
->ab
, "failed to submit WMI_VDEV_UP cmd\n");
1060 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1061 "cmd vdev up id 0x%x assoc id %d bssid %pM\n",
1062 vdev_id
, aid
, bssid
);
1067 int ath11k_wmi_send_peer_create_cmd(struct ath11k
*ar
,
1068 struct peer_create_params
*param
)
1070 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1071 struct wmi_peer_create_cmd
*cmd
;
1072 struct sk_buff
*skb
;
1075 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1079 cmd
= (struct wmi_peer_create_cmd
*)skb
->data
;
1080 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PEER_CREATE_CMD
) |
1081 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1083 ether_addr_copy(cmd
->peer_macaddr
.addr
, param
->peer_addr
);
1084 cmd
->peer_type
= param
->peer_type
;
1085 cmd
->vdev_id
= param
->vdev_id
;
1087 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PEER_CREATE_CMDID
);
1089 ath11k_warn(ar
->ab
, "failed to submit WMI_PEER_CREATE cmd\n");
1093 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1094 "cmd peer create vdev_id %d peer_addr %pM\n",
1095 param
->vdev_id
, param
->peer_addr
);
1100 int ath11k_wmi_send_peer_delete_cmd(struct ath11k
*ar
,
1101 const u8
*peer_addr
, u8 vdev_id
)
1103 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1104 struct wmi_peer_delete_cmd
*cmd
;
1105 struct sk_buff
*skb
;
1108 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1112 cmd
= (struct wmi_peer_delete_cmd
*)skb
->data
;
1113 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PEER_DELETE_CMD
) |
1114 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1116 ether_addr_copy(cmd
->peer_macaddr
.addr
, peer_addr
);
1117 cmd
->vdev_id
= vdev_id
;
1119 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PEER_DELETE_CMDID
);
1121 ath11k_warn(ar
->ab
, "failed to send WMI_PEER_DELETE cmd\n");
1125 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1126 "cmd peer delete vdev_id %d peer_addr %pM\n",
1127 vdev_id
, peer_addr
);
1132 int ath11k_wmi_send_pdev_set_regdomain(struct ath11k
*ar
,
1133 struct pdev_set_regdomain_params
*param
)
1135 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1136 struct wmi_pdev_set_regdomain_cmd
*cmd
;
1137 struct sk_buff
*skb
;
1140 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1144 cmd
= (struct wmi_pdev_set_regdomain_cmd
*)skb
->data
;
1145 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1146 WMI_TAG_PDEV_SET_REGDOMAIN_CMD
) |
1147 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1149 cmd
->reg_domain
= param
->current_rd_in_use
;
1150 cmd
->reg_domain_2g
= param
->current_rd_2g
;
1151 cmd
->reg_domain_5g
= param
->current_rd_5g
;
1152 cmd
->conformance_test_limit_2g
= param
->ctl_2g
;
1153 cmd
->conformance_test_limit_5g
= param
->ctl_5g
;
1154 cmd
->dfs_domain
= param
->dfs_domain
;
1155 cmd
->pdev_id
= param
->pdev_id
;
1157 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_SET_REGDOMAIN_CMDID
);
1160 "failed to send WMI_PDEV_SET_REGDOMAIN cmd\n");
1164 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1165 "cmd pdev regd rd %d rd2g %d rd5g %d domain %d pdev id %d\n",
1166 param
->current_rd_in_use
, param
->current_rd_2g
,
1167 param
->current_rd_5g
, param
->dfs_domain
, param
->pdev_id
);
1172 int ath11k_wmi_set_peer_param(struct ath11k
*ar
, const u8
*peer_addr
,
1173 u32 vdev_id
, u32 param_id
, u32 param_val
)
1175 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1176 struct wmi_peer_set_param_cmd
*cmd
;
1177 struct sk_buff
*skb
;
1180 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1184 cmd
= (struct wmi_peer_set_param_cmd
*)skb
->data
;
1185 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PEER_SET_PARAM_CMD
) |
1186 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1187 ether_addr_copy(cmd
->peer_macaddr
.addr
, peer_addr
);
1188 cmd
->vdev_id
= vdev_id
;
1189 cmd
->param_id
= param_id
;
1190 cmd
->param_value
= param_val
;
1192 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PEER_SET_PARAM_CMDID
);
1194 ath11k_warn(ar
->ab
, "failed to send WMI_PEER_SET_PARAM cmd\n");
1198 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1199 "cmd peer set param vdev %d peer 0x%pM set param %d value %d\n",
1200 vdev_id
, peer_addr
, param_id
, param_val
);
1205 int ath11k_wmi_send_peer_flush_tids_cmd(struct ath11k
*ar
,
1206 u8 peer_addr
[ETH_ALEN
],
1207 struct peer_flush_params
*param
)
1209 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1210 struct wmi_peer_flush_tids_cmd
*cmd
;
1211 struct sk_buff
*skb
;
1214 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1218 cmd
= (struct wmi_peer_flush_tids_cmd
*)skb
->data
;
1219 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PEER_FLUSH_TIDS_CMD
) |
1220 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1222 ether_addr_copy(cmd
->peer_macaddr
.addr
, peer_addr
);
1223 cmd
->peer_tid_bitmap
= param
->peer_tid_bitmap
;
1224 cmd
->vdev_id
= param
->vdev_id
;
1226 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PEER_FLUSH_TIDS_CMDID
);
1229 "failed to send WMI_PEER_FLUSH_TIDS cmd\n");
1233 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1234 "cmd peer flush tids vdev_id %d peer_addr %pM tids %08x\n",
1235 param
->vdev_id
, peer_addr
, param
->peer_tid_bitmap
);
1240 int ath11k_wmi_peer_rx_reorder_queue_setup(struct ath11k
*ar
,
1241 int vdev_id
, const u8
*addr
,
1242 dma_addr_t paddr
, u8 tid
,
1243 u8 ba_window_size_valid
,
1246 struct wmi_peer_reorder_queue_setup_cmd
*cmd
;
1247 struct sk_buff
*skb
;
1250 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, sizeof(*cmd
));
1254 cmd
= (struct wmi_peer_reorder_queue_setup_cmd
*)skb
->data
;
1255 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1256 WMI_TAG_REORDER_QUEUE_SETUP_CMD
) |
1257 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1259 ether_addr_copy(cmd
->peer_macaddr
.addr
, addr
);
1260 cmd
->vdev_id
= vdev_id
;
1262 cmd
->queue_ptr_lo
= lower_32_bits(paddr
);
1263 cmd
->queue_ptr_hi
= upper_32_bits(paddr
);
1264 cmd
->queue_no
= tid
;
1265 cmd
->ba_window_size_valid
= ba_window_size_valid
;
1266 cmd
->ba_window_size
= ba_window_size
;
1268 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
,
1269 WMI_PEER_REORDER_QUEUE_SETUP_CMDID
);
1272 "failed to send WMI_PEER_REORDER_QUEUE_SETUP\n");
1276 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1277 "cmd peer reorder queue setup addr %pM vdev_id %d tid %d\n",
1278 addr
, vdev_id
, tid
);
1284 ath11k_wmi_rx_reord_queue_remove(struct ath11k
*ar
,
1285 struct rx_reorder_queue_remove_params
*param
)
1287 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1288 struct wmi_peer_reorder_queue_remove_cmd
*cmd
;
1289 struct sk_buff
*skb
;
1292 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1296 cmd
= (struct wmi_peer_reorder_queue_remove_cmd
*)skb
->data
;
1297 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1298 WMI_TAG_REORDER_QUEUE_REMOVE_CMD
) |
1299 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1301 ether_addr_copy(cmd
->peer_macaddr
.addr
, param
->peer_macaddr
);
1302 cmd
->vdev_id
= param
->vdev_id
;
1303 cmd
->tid_mask
= param
->peer_tid_bitmap
;
1305 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
1306 WMI_PEER_REORDER_QUEUE_REMOVE_CMDID
);
1309 "failed to send WMI_PEER_REORDER_QUEUE_REMOVE_CMDID");
1313 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1314 "cmd peer reorder queue remove peer_macaddr %pM vdev_id %d tid_map %d",
1315 param
->peer_macaddr
, param
->vdev_id
, param
->peer_tid_bitmap
);
1320 int ath11k_wmi_pdev_set_param(struct ath11k
*ar
, u32 param_id
,
1321 u32 param_value
, u8 pdev_id
)
1323 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1324 struct wmi_pdev_set_param_cmd
*cmd
;
1325 struct sk_buff
*skb
;
1328 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1332 cmd
= (struct wmi_pdev_set_param_cmd
*)skb
->data
;
1333 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_SET_PARAM_CMD
) |
1334 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1335 cmd
->pdev_id
= pdev_id
;
1336 cmd
->param_id
= param_id
;
1337 cmd
->param_value
= param_value
;
1339 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_SET_PARAM_CMDID
);
1341 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_SET_PARAM cmd\n");
1345 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1346 "cmd pdev set param %d pdev id %d value %d\n",
1347 param_id
, pdev_id
, param_value
);
1352 int ath11k_wmi_pdev_set_ps_mode(struct ath11k
*ar
, int vdev_id
,
1353 enum wmi_sta_ps_mode psmode
)
1355 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1356 struct wmi_pdev_set_ps_mode_cmd
*cmd
;
1357 struct sk_buff
*skb
;
1360 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1364 cmd
= (struct wmi_pdev_set_ps_mode_cmd
*)skb
->data
;
1365 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_STA_POWERSAVE_MODE_CMD
) |
1366 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1367 cmd
->vdev_id
= vdev_id
;
1368 cmd
->sta_ps_mode
= psmode
;
1370 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_STA_POWERSAVE_MODE_CMDID
);
1372 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_SET_PARAM cmd\n");
1376 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1377 "cmd sta powersave mode psmode %d vdev id %d\n",
1383 int ath11k_wmi_pdev_suspend(struct ath11k
*ar
, u32 suspend_opt
,
1386 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1387 struct wmi_pdev_suspend_cmd
*cmd
;
1388 struct sk_buff
*skb
;
1391 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1395 cmd
= (struct wmi_pdev_suspend_cmd
*)skb
->data
;
1397 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_SUSPEND_CMD
) |
1398 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1400 cmd
->suspend_opt
= suspend_opt
;
1401 cmd
->pdev_id
= pdev_id
;
1403 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_SUSPEND_CMDID
);
1405 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_SUSPEND cmd\n");
1409 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1410 "cmd pdev suspend pdev_id %d\n", pdev_id
);
1415 int ath11k_wmi_pdev_resume(struct ath11k
*ar
, u32 pdev_id
)
1417 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1418 struct wmi_pdev_resume_cmd
*cmd
;
1419 struct sk_buff
*skb
;
1422 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1426 cmd
= (struct wmi_pdev_resume_cmd
*)skb
->data
;
1428 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_RESUME_CMD
) |
1429 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1430 cmd
->pdev_id
= pdev_id
;
1432 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_RESUME_CMDID
);
1434 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_RESUME cmd\n");
1438 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1439 "cmd pdev resume pdev id %d\n", pdev_id
);
1444 /* TODO FW Support for the cmd is not available yet.
1445 * Can be tested once the command and corresponding
1446 * event is implemented in FW
1448 int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k
*ar
,
1449 enum wmi_bss_chan_info_req_type type
)
1451 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1452 struct wmi_pdev_bss_chan_info_req_cmd
*cmd
;
1453 struct sk_buff
*skb
;
1456 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1460 cmd
= (struct wmi_pdev_bss_chan_info_req_cmd
*)skb
->data
;
1462 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1463 WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST
) |
1464 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1465 cmd
->req_type
= type
;
1466 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
1468 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
1469 WMI_PDEV_BSS_CHAN_INFO_REQUEST_CMDID
);
1472 "failed to send WMI_PDEV_BSS_CHAN_INFO_REQUEST cmd\n");
1476 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1477 "cmd pdev bss chan info request type %d\n", type
);
1482 int ath11k_wmi_send_set_ap_ps_param_cmd(struct ath11k
*ar
, u8
*peer_addr
,
1483 struct ap_ps_params
*param
)
1485 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1486 struct wmi_ap_ps_peer_cmd
*cmd
;
1487 struct sk_buff
*skb
;
1490 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1494 cmd
= (struct wmi_ap_ps_peer_cmd
*)skb
->data
;
1495 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_AP_PS_PEER_CMD
) |
1496 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1498 cmd
->vdev_id
= param
->vdev_id
;
1499 ether_addr_copy(cmd
->peer_macaddr
.addr
, peer_addr
);
1500 cmd
->param
= param
->param
;
1501 cmd
->value
= param
->value
;
1503 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_AP_PS_PEER_PARAM_CMDID
);
1506 "failed to send WMI_AP_PS_PEER_PARAM_CMDID\n");
1510 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1511 "cmd ap ps peer param vdev id %d peer %pM param %d value %d\n",
1512 param
->vdev_id
, peer_addr
, param
->param
, param
->value
);
1517 int ath11k_wmi_set_sta_ps_param(struct ath11k
*ar
, u32 vdev_id
,
1518 u32 param
, u32 param_value
)
1520 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1521 struct wmi_sta_powersave_param_cmd
*cmd
;
1522 struct sk_buff
*skb
;
1525 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1529 cmd
= (struct wmi_sta_powersave_param_cmd
*)skb
->data
;
1530 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1531 WMI_TAG_STA_POWERSAVE_PARAM_CMD
) |
1532 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1534 cmd
->vdev_id
= vdev_id
;
1536 cmd
->value
= param_value
;
1538 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_STA_POWERSAVE_PARAM_CMDID
);
1540 ath11k_warn(ar
->ab
, "failed to send WMI_STA_POWERSAVE_PARAM_CMDID");
1544 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1545 "cmd set powersave param vdev_id %d param %d value %d\n",
1546 vdev_id
, param
, param_value
);
1551 int ath11k_wmi_force_fw_hang_cmd(struct ath11k
*ar
, u32 type
, u32 delay_time_ms
)
1553 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1554 struct wmi_force_fw_hang_cmd
*cmd
;
1555 struct sk_buff
*skb
;
1560 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
1564 cmd
= (struct wmi_force_fw_hang_cmd
*)skb
->data
;
1565 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_FORCE_FW_HANG_CMD
) |
1566 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
1569 cmd
->delay_time_ms
= delay_time_ms
;
1571 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_FORCE_FW_HANG_CMDID
);
1574 ath11k_warn(ar
->ab
, "Failed to send WMI_FORCE_FW_HANG_CMDID");
1578 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd force fw hang");
1583 int ath11k_wmi_vdev_set_param_cmd(struct ath11k
*ar
, u32 vdev_id
,
1584 u32 param_id
, u32 param_value
)
1586 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1587 struct wmi_vdev_set_param_cmd
*cmd
;
1588 struct sk_buff
*skb
;
1591 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1595 cmd
= (struct wmi_vdev_set_param_cmd
*)skb
->data
;
1596 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_SET_PARAM_CMD
) |
1597 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1599 cmd
->vdev_id
= vdev_id
;
1600 cmd
->param_id
= param_id
;
1601 cmd
->param_value
= param_value
;
1603 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_SET_PARAM_CMDID
);
1606 "failed to send WMI_VDEV_SET_PARAM_CMDID\n");
1610 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1611 "cmd vdev set param vdev 0x%x param %d value %d\n",
1612 vdev_id
, param_id
, param_value
);
1617 int ath11k_wmi_send_stats_request_cmd(struct ath11k
*ar
,
1618 struct stats_request_params
*param
)
1620 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1621 struct wmi_request_stats_cmd
*cmd
;
1622 struct sk_buff
*skb
;
1625 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1629 cmd
= (struct wmi_request_stats_cmd
*)skb
->data
;
1630 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_REQUEST_STATS_CMD
) |
1631 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1633 cmd
->stats_id
= param
->stats_id
;
1634 cmd
->vdev_id
= param
->vdev_id
;
1635 cmd
->pdev_id
= param
->pdev_id
;
1637 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_REQUEST_STATS_CMDID
);
1639 ath11k_warn(ar
->ab
, "failed to send WMI_REQUEST_STATS cmd\n");
1643 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1644 "cmd request stats 0x%x vdev id %d pdev id %d\n",
1645 param
->stats_id
, param
->vdev_id
, param
->pdev_id
);
1650 int ath11k_wmi_send_pdev_temperature_cmd(struct ath11k
*ar
)
1652 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1653 struct wmi_get_pdev_temperature_cmd
*cmd
;
1654 struct sk_buff
*skb
;
1657 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1661 cmd
= (struct wmi_get_pdev_temperature_cmd
*)skb
->data
;
1662 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_GET_TEMPERATURE_CMD
) |
1663 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1664 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
1666 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_GET_TEMPERATURE_CMDID
);
1668 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_GET_TEMPERATURE cmd\n");
1672 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1673 "cmd pdev get temperature for pdev_id %d\n", ar
->pdev
->pdev_id
);
1678 int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k
*ar
,
1679 u32 vdev_id
, u32 bcn_ctrl_op
)
1681 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1682 struct wmi_bcn_offload_ctrl_cmd
*cmd
;
1683 struct sk_buff
*skb
;
1686 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
1690 cmd
= (struct wmi_bcn_offload_ctrl_cmd
*)skb
->data
;
1691 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1692 WMI_TAG_BCN_OFFLOAD_CTRL_CMD
) |
1693 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1695 cmd
->vdev_id
= vdev_id
;
1696 cmd
->bcn_ctrl_op
= bcn_ctrl_op
;
1698 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_BCN_OFFLOAD_CTRL_CMDID
);
1701 "failed to send WMI_BCN_OFFLOAD_CTRL_CMDID\n");
1705 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1706 "cmd bcn offload ctrl vdev id %d ctrl_op %d\n",
1707 vdev_id
, bcn_ctrl_op
);
1712 int ath11k_wmi_p2p_go_bcn_ie(struct ath11k
*ar
, u32 vdev_id
,
1715 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1716 struct wmi_p2p_go_set_beacon_ie_cmd
*cmd
;
1717 size_t p2p_ie_len
, aligned_len
;
1718 struct wmi_tlv
*tlv
;
1719 struct sk_buff
*skb
;
1722 p2p_ie_len
= p2p_ie
[1] + 2;
1723 aligned_len
= roundup(p2p_ie_len
, 4);
1725 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ aligned_len
;
1727 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
1731 cmd
= (struct wmi_p2p_go_set_beacon_ie_cmd
*)skb
->data
;
1732 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_P2P_GO_SET_BEACON_IE
) |
1733 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1734 cmd
->vdev_id
= vdev_id
;
1735 cmd
->ie_buf_len
= p2p_ie_len
;
1737 tlv
= (struct wmi_tlv
*)cmd
->tlv
;
1738 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
1739 FIELD_PREP(WMI_TLV_LEN
, aligned_len
);
1740 memcpy(tlv
->value
, p2p_ie
, p2p_ie_len
);
1742 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_P2P_GO_SET_BEACON_IE
);
1744 ath11k_warn(ar
->ab
, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
1751 int ath11k_wmi_bcn_tmpl(struct ath11k
*ar
, u32 vdev_id
,
1752 struct ieee80211_mutable_offsets
*offs
,
1753 struct sk_buff
*bcn
, u32 ema_params
)
1755 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1756 struct wmi_bcn_tmpl_cmd
*cmd
;
1757 struct wmi_bcn_prb_info
*bcn_prb_info
;
1758 struct wmi_tlv
*tlv
;
1759 struct sk_buff
*skb
;
1762 size_t aligned_len
= roundup(bcn
->len
, 4);
1763 struct ieee80211_vif
*vif
;
1764 struct ath11k_vif
*arvif
= ath11k_mac_get_arvif(ar
, vdev_id
);
1767 ath11k_warn(ar
->ab
, "failed to find arvif with vdev id %d\n", vdev_id
);
1773 len
= sizeof(*cmd
) + sizeof(*bcn_prb_info
) + TLV_HDR_SIZE
+ aligned_len
;
1775 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
1779 cmd
= (struct wmi_bcn_tmpl_cmd
*)skb
->data
;
1780 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_BCN_TMPL_CMD
) |
1781 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1782 cmd
->vdev_id
= vdev_id
;
1783 cmd
->tim_ie_offset
= offs
->tim_offset
;
1785 if (vif
->bss_conf
.csa_active
) {
1786 cmd
->csa_switch_count_offset
= offs
->cntdwn_counter_offs
[0];
1787 cmd
->ext_csa_switch_count_offset
= offs
->cntdwn_counter_offs
[1];
1790 cmd
->buf_len
= bcn
->len
;
1791 cmd
->mbssid_ie_offset
= offs
->mbssid_off
;
1792 cmd
->ema_params
= ema_params
;
1794 ptr
= skb
->data
+ sizeof(*cmd
);
1797 len
= sizeof(*bcn_prb_info
);
1798 bcn_prb_info
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1799 WMI_TAG_BCN_PRB_INFO
) |
1800 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
1801 bcn_prb_info
->caps
= 0;
1802 bcn_prb_info
->erp
= 0;
1804 ptr
+= sizeof(*bcn_prb_info
);
1807 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
1808 FIELD_PREP(WMI_TLV_LEN
, aligned_len
);
1809 memcpy(tlv
->value
, bcn
->data
, bcn
->len
);
1811 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_BCN_TMPL_CMDID
);
1813 ath11k_warn(ar
->ab
, "failed to send WMI_BCN_TMPL_CMDID\n");
1817 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd bcn tmpl");
1822 int ath11k_wmi_vdev_install_key(struct ath11k
*ar
,
1823 struct wmi_vdev_install_key_arg
*arg
)
1825 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1826 struct wmi_vdev_install_key_cmd
*cmd
;
1827 struct wmi_tlv
*tlv
;
1828 struct sk_buff
*skb
;
1830 int key_len_aligned
= roundup(arg
->key_len
, sizeof(uint32_t));
1832 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ key_len_aligned
;
1834 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
1838 cmd
= (struct wmi_vdev_install_key_cmd
*)skb
->data
;
1839 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_INSTALL_KEY_CMD
) |
1840 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1841 cmd
->vdev_id
= arg
->vdev_id
;
1842 ether_addr_copy(cmd
->peer_macaddr
.addr
, arg
->macaddr
);
1843 cmd
->key_idx
= arg
->key_idx
;
1844 cmd
->key_flags
= arg
->key_flags
;
1845 cmd
->key_cipher
= arg
->key_cipher
;
1846 cmd
->key_len
= arg
->key_len
;
1847 cmd
->key_txmic_len
= arg
->key_txmic_len
;
1848 cmd
->key_rxmic_len
= arg
->key_rxmic_len
;
1850 if (arg
->key_rsc_counter
)
1851 memcpy(&cmd
->key_rsc_counter
, &arg
->key_rsc_counter
,
1852 sizeof(struct wmi_key_seq_counter
));
1854 tlv
= (struct wmi_tlv
*)(skb
->data
+ sizeof(*cmd
));
1855 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
1856 FIELD_PREP(WMI_TLV_LEN
, key_len_aligned
);
1858 memcpy(tlv
->value
, (u8
*)arg
->key_data
, key_len_aligned
);
1860 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_INSTALL_KEY_CMDID
);
1863 "failed to send WMI_VDEV_INSTALL_KEY cmd\n");
1867 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
1868 "cmd vdev install key idx %d cipher %d len %d\n",
1869 arg
->key_idx
, arg
->key_cipher
, arg
->key_len
);
1875 ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd
*cmd
,
1876 struct peer_assoc_params
*param
,
1877 bool hw_crypto_disabled
)
1879 cmd
->peer_flags
= 0;
1881 if (param
->is_wme_set
) {
1882 if (param
->qos_flag
)
1883 cmd
->peer_flags
|= WMI_PEER_QOS
;
1884 if (param
->apsd_flag
)
1885 cmd
->peer_flags
|= WMI_PEER_APSD
;
1887 cmd
->peer_flags
|= WMI_PEER_HT
;
1889 cmd
->peer_flags
|= WMI_PEER_40MHZ
;
1891 cmd
->peer_flags
|= WMI_PEER_80MHZ
;
1893 cmd
->peer_flags
|= WMI_PEER_160MHZ
;
1895 /* Typically if STBC is enabled for VHT it should be enabled
1898 if (param
->stbc_flag
)
1899 cmd
->peer_flags
|= WMI_PEER_STBC
;
1901 /* Typically if LDPC is enabled for VHT it should be enabled
1904 if (param
->ldpc_flag
)
1905 cmd
->peer_flags
|= WMI_PEER_LDPC
;
1907 if (param
->static_mimops_flag
)
1908 cmd
->peer_flags
|= WMI_PEER_STATIC_MIMOPS
;
1909 if (param
->dynamic_mimops_flag
)
1910 cmd
->peer_flags
|= WMI_PEER_DYN_MIMOPS
;
1911 if (param
->spatial_mux_flag
)
1912 cmd
->peer_flags
|= WMI_PEER_SPATIAL_MUX
;
1913 if (param
->vht_flag
)
1914 cmd
->peer_flags
|= WMI_PEER_VHT
;
1916 cmd
->peer_flags
|= WMI_PEER_HE
;
1917 if (param
->twt_requester
)
1918 cmd
->peer_flags
|= WMI_PEER_TWT_REQ
;
1919 if (param
->twt_responder
)
1920 cmd
->peer_flags
|= WMI_PEER_TWT_RESP
;
1923 /* Suppress authorization for all AUTH modes that need 4-way handshake
1924 * (during re-association).
1925 * Authorization will be done for these modes on key installation.
1927 if (param
->auth_flag
)
1928 cmd
->peer_flags
|= WMI_PEER_AUTH
;
1929 if (param
->need_ptk_4_way
) {
1930 cmd
->peer_flags
|= WMI_PEER_NEED_PTK_4_WAY
;
1931 if (!hw_crypto_disabled
&& param
->is_assoc
)
1932 cmd
->peer_flags
&= ~WMI_PEER_AUTH
;
1934 if (param
->need_gtk_2_way
)
1935 cmd
->peer_flags
|= WMI_PEER_NEED_GTK_2_WAY
;
1936 /* safe mode bypass the 4-way handshake */
1937 if (param
->safe_mode_enabled
)
1938 cmd
->peer_flags
&= ~(WMI_PEER_NEED_PTK_4_WAY
|
1939 WMI_PEER_NEED_GTK_2_WAY
);
1941 if (param
->is_pmf_enabled
)
1942 cmd
->peer_flags
|= WMI_PEER_PMF
;
1944 /* Disable AMSDU for station transmit, if user configures it */
1945 /* Disable AMSDU for AP transmit to 11n Stations, if user configures
1947 * if (param->amsdu_disable) Add after FW support
1950 /* Target asserts if node is marked HT and all MCS is set to 0.
1951 * Mark the node as non-HT if all the mcs rates are disabled through
1954 if (param
->peer_ht_rates
.num_rates
== 0)
1955 cmd
->peer_flags
&= ~WMI_PEER_HT
;
1958 int ath11k_wmi_send_peer_assoc_cmd(struct ath11k
*ar
,
1959 struct peer_assoc_params
*param
)
1961 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
1962 struct wmi_peer_assoc_complete_cmd
*cmd
;
1963 struct wmi_vht_rate_set
*mcs
;
1964 struct wmi_he_rate_set
*he_mcs
;
1965 struct sk_buff
*skb
;
1966 struct wmi_tlv
*tlv
;
1968 u32 peer_legacy_rates_align
;
1969 u32 peer_ht_rates_align
;
1972 peer_legacy_rates_align
= roundup(param
->peer_legacy_rates
.num_rates
,
1974 peer_ht_rates_align
= roundup(param
->peer_ht_rates
.num_rates
,
1977 len
= sizeof(*cmd
) +
1978 TLV_HDR_SIZE
+ (peer_legacy_rates_align
* sizeof(u8
)) +
1979 TLV_HDR_SIZE
+ (peer_ht_rates_align
* sizeof(u8
)) +
1980 sizeof(*mcs
) + TLV_HDR_SIZE
+
1981 (sizeof(*he_mcs
) * param
->peer_he_mcs_count
);
1983 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
1990 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
1991 WMI_TAG_PEER_ASSOC_COMPLETE_CMD
) |
1992 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
1994 cmd
->vdev_id
= param
->vdev_id
;
1996 cmd
->peer_new_assoc
= param
->peer_new_assoc
;
1997 cmd
->peer_associd
= param
->peer_associd
;
1999 ath11k_wmi_copy_peer_flags(cmd
, param
,
2000 test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED
,
2001 &ar
->ab
->dev_flags
));
2003 ether_addr_copy(cmd
->peer_macaddr
.addr
, param
->peer_mac
);
2005 cmd
->peer_rate_caps
= param
->peer_rate_caps
;
2006 cmd
->peer_caps
= param
->peer_caps
;
2007 cmd
->peer_listen_intval
= param
->peer_listen_intval
;
2008 cmd
->peer_ht_caps
= param
->peer_ht_caps
;
2009 cmd
->peer_max_mpdu
= param
->peer_max_mpdu
;
2010 cmd
->peer_mpdu_density
= param
->peer_mpdu_density
;
2011 cmd
->peer_vht_caps
= param
->peer_vht_caps
;
2012 cmd
->peer_phymode
= param
->peer_phymode
;
2014 /* Update 11ax capabilities */
2015 cmd
->peer_he_cap_info
= param
->peer_he_cap_macinfo
[0];
2016 cmd
->peer_he_cap_info_ext
= param
->peer_he_cap_macinfo
[1];
2017 cmd
->peer_he_cap_info_internal
= param
->peer_he_cap_macinfo_internal
;
2018 cmd
->peer_he_caps_6ghz
= param
->peer_he_caps_6ghz
;
2019 cmd
->peer_he_ops
= param
->peer_he_ops
;
2020 memcpy(&cmd
->peer_he_cap_phy
, ¶m
->peer_he_cap_phyinfo
,
2021 sizeof(param
->peer_he_cap_phyinfo
));
2022 memcpy(&cmd
->peer_ppet
, ¶m
->peer_ppet
,
2023 sizeof(param
->peer_ppet
));
2025 /* Update peer legacy rate information */
2026 ptr
+= sizeof(*cmd
);
2029 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
2030 FIELD_PREP(WMI_TLV_LEN
, peer_legacy_rates_align
);
2032 ptr
+= TLV_HDR_SIZE
;
2034 cmd
->num_peer_legacy_rates
= param
->peer_legacy_rates
.num_rates
;
2035 memcpy(ptr
, param
->peer_legacy_rates
.rates
,
2036 param
->peer_legacy_rates
.num_rates
);
2038 /* Update peer HT rate information */
2039 ptr
+= peer_legacy_rates_align
;
2042 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
2043 FIELD_PREP(WMI_TLV_LEN
, peer_ht_rates_align
);
2044 ptr
+= TLV_HDR_SIZE
;
2045 cmd
->num_peer_ht_rates
= param
->peer_ht_rates
.num_rates
;
2046 memcpy(ptr
, param
->peer_ht_rates
.rates
,
2047 param
->peer_ht_rates
.num_rates
);
2050 ptr
+= peer_ht_rates_align
;
2054 mcs
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VHT_RATE_SET
) |
2055 FIELD_PREP(WMI_TLV_LEN
, sizeof(*mcs
) - TLV_HDR_SIZE
);
2057 cmd
->peer_nss
= param
->peer_nss
;
2059 /* Update bandwidth-NSS mapping */
2060 cmd
->peer_bw_rxnss_override
= 0;
2061 cmd
->peer_bw_rxnss_override
|= param
->peer_bw_rxnss_override
;
2063 if (param
->vht_capable
) {
2064 mcs
->rx_max_rate
= param
->rx_max_rate
;
2065 mcs
->rx_mcs_set
= param
->rx_mcs_set
;
2066 mcs
->tx_max_rate
= param
->tx_max_rate
;
2067 mcs
->tx_mcs_set
= param
->tx_mcs_set
;
2071 cmd
->peer_he_mcs
= param
->peer_he_mcs_count
;
2072 cmd
->min_data_rate
= param
->min_data_rate
;
2074 ptr
+= sizeof(*mcs
);
2076 len
= param
->peer_he_mcs_count
* sizeof(*he_mcs
);
2079 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
2080 FIELD_PREP(WMI_TLV_LEN
, len
);
2081 ptr
+= TLV_HDR_SIZE
;
2083 /* Loop through the HE rate set */
2084 for (i
= 0; i
< param
->peer_he_mcs_count
; i
++) {
2086 he_mcs
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
2087 WMI_TAG_HE_RATE_SET
) |
2088 FIELD_PREP(WMI_TLV_LEN
,
2089 sizeof(*he_mcs
) - TLV_HDR_SIZE
);
2091 he_mcs
->rx_mcs_set
= param
->peer_he_tx_mcs_set
[i
];
2092 he_mcs
->tx_mcs_set
= param
->peer_he_rx_mcs_set
[i
];
2093 ptr
+= sizeof(*he_mcs
);
2096 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_PEER_ASSOC_CMDID
);
2099 "failed to send WMI_PEER_ASSOC_CMDID\n");
2103 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2104 "cmd peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x\n",
2105 cmd
->vdev_id
, cmd
->peer_associd
, param
->peer_mac
,
2106 cmd
->peer_flags
, cmd
->peer_rate_caps
, cmd
->peer_caps
,
2107 cmd
->peer_listen_intval
, cmd
->peer_ht_caps
,
2108 cmd
->peer_max_mpdu
, cmd
->peer_nss
, cmd
->peer_phymode
,
2109 cmd
->peer_mpdu_density
,
2110 cmd
->peer_vht_caps
, cmd
->peer_he_cap_info
,
2111 cmd
->peer_he_ops
, cmd
->peer_he_cap_info_ext
,
2112 cmd
->peer_he_cap_phy
[0], cmd
->peer_he_cap_phy
[1],
2113 cmd
->peer_he_cap_phy
[2],
2114 cmd
->peer_bw_rxnss_override
);
2119 void ath11k_wmi_start_scan_init(struct ath11k
*ar
,
2120 struct scan_req_params
*arg
)
2122 /* setup commonly used values */
2123 arg
->scan_req_id
= 1;
2124 if (ar
->state_11d
== ATH11K_11D_PREPARING
)
2125 arg
->scan_priority
= WMI_SCAN_PRIORITY_MEDIUM
;
2127 arg
->scan_priority
= WMI_SCAN_PRIORITY_LOW
;
2128 arg
->dwell_time_active
= 50;
2129 arg
->dwell_time_active_2g
= 0;
2130 arg
->dwell_time_passive
= 150;
2131 arg
->dwell_time_active_6g
= 40;
2132 arg
->dwell_time_passive_6g
= 30;
2133 arg
->min_rest_time
= 50;
2134 arg
->max_rest_time
= 500;
2135 arg
->repeat_probe_time
= 0;
2136 arg
->probe_spacing_time
= 0;
2138 arg
->max_scan_time
= 20000;
2139 arg
->probe_delay
= 5;
2140 arg
->notify_scan_events
= WMI_SCAN_EVENT_STARTED
|
2141 WMI_SCAN_EVENT_COMPLETED
|
2142 WMI_SCAN_EVENT_BSS_CHANNEL
|
2143 WMI_SCAN_EVENT_FOREIGN_CHAN
|
2144 WMI_SCAN_EVENT_DEQUEUED
;
2145 arg
->scan_f_chan_stat_evnt
= 1;
2147 if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE
,
2148 ar
->ab
->wmi_ab
.svc_map
))
2149 arg
->scan_ctrl_flags_ext
|=
2150 WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE
;
2154 /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be
2155 * ZEROs in probe request
2157 eth_broadcast_addr(arg
->bssid_list
[0].addr
);
2161 ath11k_wmi_copy_scan_event_cntrl_flags(struct wmi_start_scan_cmd
*cmd
,
2162 struct scan_req_params
*param
)
2164 /* Scan events subscription */
2165 if (param
->scan_ev_started
)
2166 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_STARTED
;
2167 if (param
->scan_ev_completed
)
2168 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_COMPLETED
;
2169 if (param
->scan_ev_bss_chan
)
2170 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_BSS_CHANNEL
;
2171 if (param
->scan_ev_foreign_chan
)
2172 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_FOREIGN_CHAN
;
2173 if (param
->scan_ev_dequeued
)
2174 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_DEQUEUED
;
2175 if (param
->scan_ev_preempted
)
2176 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_PREEMPTED
;
2177 if (param
->scan_ev_start_failed
)
2178 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_START_FAILED
;
2179 if (param
->scan_ev_restarted
)
2180 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_RESTARTED
;
2181 if (param
->scan_ev_foreign_chn_exit
)
2182 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT
;
2183 if (param
->scan_ev_suspended
)
2184 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_SUSPENDED
;
2185 if (param
->scan_ev_resumed
)
2186 cmd
->notify_scan_events
|= WMI_SCAN_EVENT_RESUMED
;
2188 /** Set scan control flags */
2189 cmd
->scan_ctrl_flags
= 0;
2190 if (param
->scan_f_passive
)
2191 cmd
->scan_ctrl_flags
|= WMI_SCAN_FLAG_PASSIVE
;
2192 if (param
->scan_f_strict_passive_pch
)
2193 cmd
->scan_ctrl_flags
|= WMI_SCAN_FLAG_STRICT_PASSIVE_ON_PCHN
;
2194 if (param
->scan_f_promisc_mode
)
2195 cmd
->scan_ctrl_flags
|= WMI_SCAN_FILTER_PROMISCUOS
;
2196 if (param
->scan_f_capture_phy_err
)
2197 cmd
->scan_ctrl_flags
|= WMI_SCAN_CAPTURE_PHY_ERROR
;
2198 if (param
->scan_f_half_rate
)
2199 cmd
->scan_ctrl_flags
|= WMI_SCAN_FLAG_HALF_RATE_SUPPORT
;
2200 if (param
->scan_f_quarter_rate
)
2201 cmd
->scan_ctrl_flags
|= WMI_SCAN_FLAG_QUARTER_RATE_SUPPORT
;
2202 if (param
->scan_f_cck_rates
)
2203 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_CCK_RATES
;
2204 if (param
->scan_f_ofdm_rates
)
2205 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_OFDM_RATES
;
2206 if (param
->scan_f_chan_stat_evnt
)
2207 cmd
->scan_ctrl_flags
|= WMI_SCAN_CHAN_STAT_EVENT
;
2208 if (param
->scan_f_filter_prb_req
)
2209 cmd
->scan_ctrl_flags
|= WMI_SCAN_FILTER_PROBE_REQ
;
2210 if (param
->scan_f_bcast_probe
)
2211 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_BCAST_PROBE_REQ
;
2212 if (param
->scan_f_offchan_mgmt_tx
)
2213 cmd
->scan_ctrl_flags
|= WMI_SCAN_OFFCHAN_MGMT_TX
;
2214 if (param
->scan_f_offchan_data_tx
)
2215 cmd
->scan_ctrl_flags
|= WMI_SCAN_OFFCHAN_DATA_TX
;
2216 if (param
->scan_f_force_active_dfs_chn
)
2217 cmd
->scan_ctrl_flags
|= WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS
;
2218 if (param
->scan_f_add_tpc_ie_in_probe
)
2219 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ
;
2220 if (param
->scan_f_add_ds_ie_in_probe
)
2221 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ
;
2222 if (param
->scan_f_add_spoofed_mac_in_probe
)
2223 cmd
->scan_ctrl_flags
|= WMI_SCAN_ADD_SPOOF_MAC_IN_PROBE_REQ
;
2224 if (param
->scan_f_add_rand_seq_in_probe
)
2225 cmd
->scan_ctrl_flags
|= WMI_SCAN_RANDOM_SEQ_NO_IN_PROBE_REQ
;
2226 if (param
->scan_f_en_ie_whitelist_in_probe
)
2227 cmd
->scan_ctrl_flags
|=
2228 WMI_SCAN_ENABLE_IE_WHTELIST_IN_PROBE_REQ
;
2230 /* for adaptive scan mode using 3 bits (21 - 23 bits) */
2231 WMI_SCAN_SET_DWELL_MODE(cmd
->scan_ctrl_flags
,
2232 param
->adaptive_dwell_time_mode
);
2234 cmd
->scan_ctrl_flags_ext
= param
->scan_ctrl_flags_ext
;
2237 int ath11k_wmi_send_scan_start_cmd(struct ath11k
*ar
,
2238 struct scan_req_params
*params
)
2240 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2241 struct wmi_start_scan_cmd
*cmd
;
2242 struct wmi_ssid
*ssid
= NULL
;
2243 struct wmi_mac_addr
*bssid
;
2244 struct sk_buff
*skb
;
2245 struct wmi_tlv
*tlv
;
2249 u16 extraie_len_with_pad
= 0;
2250 struct hint_short_ssid
*s_ssid
= NULL
;
2251 struct hint_bssid
*hint_bssid
= NULL
;
2255 len
+= TLV_HDR_SIZE
;
2256 if (params
->num_chan
)
2257 len
+= params
->num_chan
* sizeof(u32
);
2259 len
+= TLV_HDR_SIZE
;
2260 if (params
->num_ssids
)
2261 len
+= params
->num_ssids
* sizeof(*ssid
);
2263 len
+= TLV_HDR_SIZE
;
2264 if (params
->num_bssid
)
2265 len
+= sizeof(*bssid
) * params
->num_bssid
;
2267 len
+= TLV_HDR_SIZE
;
2268 if (params
->extraie
.len
&& params
->extraie
.len
<= 0xFFFF)
2269 extraie_len_with_pad
=
2270 roundup(params
->extraie
.len
, sizeof(u32
));
2271 len
+= extraie_len_with_pad
;
2273 if (params
->num_hint_bssid
)
2274 len
+= TLV_HDR_SIZE
+
2275 params
->num_hint_bssid
* sizeof(struct hint_bssid
);
2277 if (params
->num_hint_s_ssid
)
2278 len
+= TLV_HDR_SIZE
+
2279 params
->num_hint_s_ssid
* sizeof(struct hint_short_ssid
);
2281 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
2288 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_START_SCAN_CMD
) |
2289 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2291 cmd
->scan_id
= params
->scan_id
;
2292 cmd
->scan_req_id
= params
->scan_req_id
;
2293 cmd
->vdev_id
= params
->vdev_id
;
2294 cmd
->scan_priority
= params
->scan_priority
;
2295 cmd
->notify_scan_events
= params
->notify_scan_events
;
2297 ath11k_wmi_copy_scan_event_cntrl_flags(cmd
, params
);
2299 cmd
->dwell_time_active
= params
->dwell_time_active
;
2300 cmd
->dwell_time_active_2g
= params
->dwell_time_active_2g
;
2301 cmd
->dwell_time_passive
= params
->dwell_time_passive
;
2302 cmd
->dwell_time_active_6g
= params
->dwell_time_active_6g
;
2303 cmd
->dwell_time_passive_6g
= params
->dwell_time_passive_6g
;
2304 cmd
->min_rest_time
= params
->min_rest_time
;
2305 cmd
->max_rest_time
= params
->max_rest_time
;
2306 cmd
->repeat_probe_time
= params
->repeat_probe_time
;
2307 cmd
->probe_spacing_time
= params
->probe_spacing_time
;
2308 cmd
->idle_time
= params
->idle_time
;
2309 cmd
->max_scan_time
= params
->max_scan_time
;
2310 cmd
->probe_delay
= params
->probe_delay
;
2311 cmd
->burst_duration
= params
->burst_duration
;
2312 cmd
->num_chan
= params
->num_chan
;
2313 cmd
->num_bssid
= params
->num_bssid
;
2314 cmd
->num_ssids
= params
->num_ssids
;
2315 cmd
->ie_len
= params
->extraie
.len
;
2316 cmd
->n_probes
= params
->n_probes
;
2317 ether_addr_copy(cmd
->mac_addr
.addr
, params
->mac_addr
.addr
);
2318 ether_addr_copy(cmd
->mac_mask
.addr
, params
->mac_mask
.addr
);
2320 ptr
+= sizeof(*cmd
);
2322 len
= params
->num_chan
* sizeof(u32
);
2325 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_UINT32
) |
2326 FIELD_PREP(WMI_TLV_LEN
, len
);
2327 ptr
+= TLV_HDR_SIZE
;
2330 for (i
= 0; i
< params
->num_chan
; ++i
)
2331 tmp_ptr
[i
] = params
->chan_list
[i
];
2335 len
= params
->num_ssids
* sizeof(*ssid
);
2337 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_FIXED_STRUCT
) |
2338 FIELD_PREP(WMI_TLV_LEN
, len
);
2340 ptr
+= TLV_HDR_SIZE
;
2342 if (params
->num_ssids
) {
2344 for (i
= 0; i
< params
->num_ssids
; ++i
) {
2345 ssid
->ssid_len
= params
->ssid
[i
].length
;
2346 memcpy(ssid
->ssid
, params
->ssid
[i
].ssid
,
2347 params
->ssid
[i
].length
);
2352 ptr
+= (params
->num_ssids
* sizeof(*ssid
));
2353 len
= params
->num_bssid
* sizeof(*bssid
);
2355 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_FIXED_STRUCT
) |
2356 FIELD_PREP(WMI_TLV_LEN
, len
);
2358 ptr
+= TLV_HDR_SIZE
;
2361 if (params
->num_bssid
) {
2362 for (i
= 0; i
< params
->num_bssid
; ++i
) {
2363 ether_addr_copy(bssid
->addr
,
2364 params
->bssid_list
[i
].addr
);
2369 ptr
+= params
->num_bssid
* sizeof(*bssid
);
2371 len
= extraie_len_with_pad
;
2373 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
2374 FIELD_PREP(WMI_TLV_LEN
, len
);
2375 ptr
+= TLV_HDR_SIZE
;
2377 if (extraie_len_with_pad
)
2378 memcpy(ptr
, params
->extraie
.ptr
,
2379 params
->extraie
.len
);
2381 ptr
+= extraie_len_with_pad
;
2383 if (params
->num_hint_s_ssid
) {
2384 len
= params
->num_hint_s_ssid
* sizeof(struct hint_short_ssid
);
2386 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_FIXED_STRUCT
) |
2387 FIELD_PREP(WMI_TLV_LEN
, len
);
2388 ptr
+= TLV_HDR_SIZE
;
2390 for (i
= 0; i
< params
->num_hint_s_ssid
; ++i
) {
2391 s_ssid
->freq_flags
= params
->hint_s_ssid
[i
].freq_flags
;
2392 s_ssid
->short_ssid
= params
->hint_s_ssid
[i
].short_ssid
;
2398 if (params
->num_hint_bssid
) {
2399 len
= params
->num_hint_bssid
* sizeof(struct hint_bssid
);
2401 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_FIXED_STRUCT
) |
2402 FIELD_PREP(WMI_TLV_LEN
, len
);
2403 ptr
+= TLV_HDR_SIZE
;
2405 for (i
= 0; i
< params
->num_hint_bssid
; ++i
) {
2406 hint_bssid
->freq_flags
=
2407 params
->hint_bssid
[i
].freq_flags
;
2408 ether_addr_copy(¶ms
->hint_bssid
[i
].bssid
.addr
[0],
2409 &hint_bssid
->bssid
.addr
[0]);
2414 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
2415 WMI_START_SCAN_CMDID
);
2417 ath11k_warn(ar
->ab
, "failed to send WMI_START_SCAN_CMDID\n");
2421 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd start scan");
2426 int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k
*ar
,
2428 struct ath11k_reg_tpc_power_info
*param
)
2430 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2431 struct wmi_vdev_set_tpc_power_cmd
*cmd
;
2432 struct wmi_vdev_ch_power_info
*ch
;
2433 struct sk_buff
*skb
;
2434 struct wmi_tlv
*tlv
;
2436 int i
, ret
, len
, array_len
;
2438 array_len
= sizeof(*ch
) * param
->num_pwr_levels
;
2439 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ array_len
;
2441 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
2447 cmd
= (struct wmi_vdev_set_tpc_power_cmd
*)ptr
;
2448 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_VDEV_SET_TPC_POWER_CMD
) |
2449 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2450 cmd
->vdev_id
= vdev_id
;
2451 cmd
->psd_power
= param
->is_psd_power
;
2452 cmd
->eirp_power
= param
->eirp_power
;
2453 cmd
->power_type_6ghz
= param
->ap_power_type
;
2455 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2456 "tpc vdev id %d is psd power %d eirp power %d 6 ghz power type %d\n",
2457 vdev_id
, param
->is_psd_power
, param
->eirp_power
, param
->ap_power_type
);
2459 ptr
+= sizeof(*cmd
);
2460 tlv
= (struct wmi_tlv
*)ptr
;
2461 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
2462 FIELD_PREP(WMI_TLV_LEN
, array_len
);
2464 ptr
+= TLV_HDR_SIZE
;
2465 ch
= (struct wmi_vdev_ch_power_info
*)ptr
;
2467 for (i
= 0; i
< param
->num_pwr_levels
; i
++, ch
++) {
2468 ch
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
2469 WMI_TAG_VDEV_CH_POWER_INFO
) |
2470 FIELD_PREP(WMI_TLV_LEN
,
2471 sizeof(*ch
) - TLV_HDR_SIZE
);
2473 ch
->chan_cfreq
= param
->chan_power_info
[i
].chan_cfreq
;
2474 ch
->tx_power
= param
->chan_power_info
[i
].tx_power
;
2476 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tpc chan freq %d TX power %d\n",
2477 ch
->chan_cfreq
, ch
->tx_power
);
2480 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_VDEV_SET_TPC_POWER_CMDID
);
2482 ath11k_warn(ar
->ab
, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n");
2490 int ath11k_wmi_send_scan_stop_cmd(struct ath11k
*ar
,
2491 struct scan_cancel_param
*param
)
2493 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2494 struct wmi_stop_scan_cmd
*cmd
;
2495 struct sk_buff
*skb
;
2498 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2502 cmd
= (struct wmi_stop_scan_cmd
*)skb
->data
;
2504 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_STOP_SCAN_CMD
) |
2505 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2507 cmd
->vdev_id
= param
->vdev_id
;
2508 cmd
->requestor
= param
->requester
;
2509 cmd
->scan_id
= param
->scan_id
;
2510 cmd
->pdev_id
= param
->pdev_id
;
2511 /* stop the scan with the corresponding scan_id */
2512 if (param
->req_type
== WLAN_SCAN_CANCEL_PDEV_ALL
) {
2513 /* Cancelling all scans */
2514 cmd
->req_type
= WMI_SCAN_STOP_ALL
;
2515 } else if (param
->req_type
== WLAN_SCAN_CANCEL_VDEV_ALL
) {
2516 /* Cancelling VAP scans */
2517 cmd
->req_type
= WMI_SCN_STOP_VAP_ALL
;
2518 } else if (param
->req_type
== WLAN_SCAN_CANCEL_SINGLE
) {
2519 /* Cancelling specific scan */
2520 cmd
->req_type
= WMI_SCAN_STOP_ONE
;
2522 ath11k_warn(ar
->ab
, "invalid scan cancel param %d",
2528 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
2529 WMI_STOP_SCAN_CMDID
);
2531 ath11k_warn(ar
->ab
, "failed to send WMI_STOP_SCAN_CMDID\n");
2535 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd stop scan");
2540 int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k
*ar
,
2541 struct scan_chan_list_params
*chan_list
)
2543 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2544 struct wmi_scan_chan_list_cmd
*cmd
;
2545 struct sk_buff
*skb
;
2546 struct wmi_channel
*chan_info
;
2547 struct channel_param
*tchan_info
;
2548 struct wmi_tlv
*tlv
;
2551 u16 num_send_chans
, num_sends
= 0, max_chan_limit
= 0;
2554 tchan_info
= chan_list
->ch_param
;
2555 while (chan_list
->nallchans
) {
2556 len
= sizeof(*cmd
) + TLV_HDR_SIZE
;
2557 max_chan_limit
= (wmi
->wmi_ab
->max_msg_len
[ar
->pdev_idx
] - len
) /
2560 if (chan_list
->nallchans
> max_chan_limit
)
2561 num_send_chans
= max_chan_limit
;
2563 num_send_chans
= chan_list
->nallchans
;
2565 chan_list
->nallchans
-= num_send_chans
;
2566 len
+= sizeof(*chan_info
) * num_send_chans
;
2568 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
2572 cmd
= (struct wmi_scan_chan_list_cmd
*)skb
->data
;
2573 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_SCAN_CHAN_LIST_CMD
) |
2574 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2575 cmd
->pdev_id
= chan_list
->pdev_id
;
2576 cmd
->num_scan_chans
= num_send_chans
;
2578 cmd
->flags
|= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG
;
2580 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2581 "no.of chan = %d len = %d pdev_id = %d num_sends = %d\n",
2582 num_send_chans
, len
, cmd
->pdev_id
, num_sends
);
2584 ptr
= skb
->data
+ sizeof(*cmd
);
2586 len
= sizeof(*chan_info
) * num_send_chans
;
2588 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
2589 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
2590 ptr
+= TLV_HDR_SIZE
;
2592 for (i
= 0; i
< num_send_chans
; ++i
) {
2594 memset(chan_info
, 0, sizeof(*chan_info
));
2595 len
= sizeof(*chan_info
);
2596 chan_info
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
2598 FIELD_PREP(WMI_TLV_LEN
,
2599 len
- TLV_HDR_SIZE
);
2601 reg1
= &chan_info
->reg_info_1
;
2602 reg2
= &chan_info
->reg_info_2
;
2603 chan_info
->mhz
= tchan_info
->mhz
;
2604 chan_info
->band_center_freq1
= tchan_info
->cfreq1
;
2605 chan_info
->band_center_freq2
= tchan_info
->cfreq2
;
2607 if (tchan_info
->is_chan_passive
)
2608 chan_info
->info
|= WMI_CHAN_INFO_PASSIVE
;
2609 if (tchan_info
->allow_he
)
2610 chan_info
->info
|= WMI_CHAN_INFO_ALLOW_HE
;
2611 else if (tchan_info
->allow_vht
)
2612 chan_info
->info
|= WMI_CHAN_INFO_ALLOW_VHT
;
2613 else if (tchan_info
->allow_ht
)
2614 chan_info
->info
|= WMI_CHAN_INFO_ALLOW_HT
;
2615 if (tchan_info
->half_rate
)
2616 chan_info
->info
|= WMI_CHAN_INFO_HALF_RATE
;
2617 if (tchan_info
->quarter_rate
)
2618 chan_info
->info
|= WMI_CHAN_INFO_QUARTER_RATE
;
2619 if (tchan_info
->psc_channel
)
2620 chan_info
->info
|= WMI_CHAN_INFO_PSC
;
2621 if (tchan_info
->dfs_set
)
2622 chan_info
->info
|= WMI_CHAN_INFO_DFS
;
2624 chan_info
->info
|= FIELD_PREP(WMI_CHAN_INFO_MODE
,
2625 tchan_info
->phy_mode
);
2626 *reg1
|= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR
,
2627 tchan_info
->minpower
);
2628 *reg1
|= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR
,
2629 tchan_info
->maxpower
);
2630 *reg1
|= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR
,
2631 tchan_info
->maxregpower
);
2632 *reg1
|= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS
,
2633 tchan_info
->reg_class_id
);
2634 *reg2
|= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX
,
2635 tchan_info
->antennamax
);
2636 *reg2
|= FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR
,
2637 tchan_info
->maxregpower
);
2639 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2640 "chan scan list chan[%d] = %u, chan_info->info %8x\n",
2641 i
, chan_info
->mhz
, chan_info
->info
);
2643 ptr
+= sizeof(*chan_info
);
2648 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_SCAN_CHAN_LIST_CMDID
);
2650 ath11k_warn(ar
->ab
, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
2655 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd scan chan list channels %d",
2664 int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k
*ar
, u32 vdev_id
,
2665 struct wmi_wmm_params_all_arg
*param
)
2667 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2668 struct wmi_vdev_set_wmm_params_cmd
*cmd
;
2669 struct wmi_wmm_params
*wmm_param
;
2670 struct wmi_wmm_params_arg
*wmi_wmm_arg
;
2671 struct sk_buff
*skb
;
2674 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2678 cmd
= (struct wmi_vdev_set_wmm_params_cmd
*)skb
->data
;
2679 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
2680 WMI_TAG_VDEV_SET_WMM_PARAMS_CMD
) |
2681 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2683 cmd
->vdev_id
= vdev_id
;
2684 cmd
->wmm_param_type
= 0;
2686 for (ac
= 0; ac
< WME_NUM_AC
; ac
++) {
2689 wmi_wmm_arg
= ¶m
->ac_be
;
2692 wmi_wmm_arg
= ¶m
->ac_bk
;
2695 wmi_wmm_arg
= ¶m
->ac_vi
;
2698 wmi_wmm_arg
= ¶m
->ac_vo
;
2702 wmm_param
= (struct wmi_wmm_params
*)&cmd
->wmm_params
[ac
];
2703 wmm_param
->tlv_header
=
2704 FIELD_PREP(WMI_TLV_TAG
,
2705 WMI_TAG_VDEV_SET_WMM_PARAMS_CMD
) |
2706 FIELD_PREP(WMI_TLV_LEN
,
2707 sizeof(*wmm_param
) - TLV_HDR_SIZE
);
2709 wmm_param
->aifs
= wmi_wmm_arg
->aifs
;
2710 wmm_param
->cwmin
= wmi_wmm_arg
->cwmin
;
2711 wmm_param
->cwmax
= wmi_wmm_arg
->cwmax
;
2712 wmm_param
->txoplimit
= wmi_wmm_arg
->txop
;
2713 wmm_param
->acm
= wmi_wmm_arg
->acm
;
2714 wmm_param
->no_ack
= wmi_wmm_arg
->no_ack
;
2716 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2717 "wmm set ac %d aifs %d cwmin %d cwmax %d txop %d acm %d no_ack %d\n",
2718 ac
, wmm_param
->aifs
, wmm_param
->cwmin
,
2719 wmm_param
->cwmax
, wmm_param
->txoplimit
,
2720 wmm_param
->acm
, wmm_param
->no_ack
);
2722 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
2723 WMI_VDEV_SET_WMM_PARAMS_CMDID
);
2726 "failed to send WMI_VDEV_SET_WMM_PARAMS_CMDID");
2730 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd vdev set wmm params");
2735 int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k
*ar
,
2738 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2739 struct wmi_dfs_phyerr_offload_cmd
*cmd
;
2740 struct sk_buff
*skb
;
2743 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2747 cmd
= (struct wmi_dfs_phyerr_offload_cmd
*)skb
->data
;
2749 FIELD_PREP(WMI_TLV_TAG
,
2750 WMI_TAG_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMD
) |
2751 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2753 cmd
->pdev_id
= pdev_id
;
2755 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
2756 WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE_CMDID
);
2759 "failed to send WMI_PDEV_DFS_PHYERR_OFFLOAD_ENABLE cmd\n");
2763 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2764 "cmd pdev dfs phyerr offload enable pdev id %d\n", pdev_id
);
2769 int ath11k_wmi_delba_send(struct ath11k
*ar
, u32 vdev_id
, const u8
*mac
,
2770 u32 tid
, u32 initiator
, u32 reason
)
2772 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2773 struct wmi_delba_send_cmd
*cmd
;
2774 struct sk_buff
*skb
;
2777 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2781 cmd
= (struct wmi_delba_send_cmd
*)skb
->data
;
2782 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_DELBA_SEND_CMD
) |
2783 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2784 cmd
->vdev_id
= vdev_id
;
2785 ether_addr_copy(cmd
->peer_macaddr
.addr
, mac
);
2787 cmd
->initiator
= initiator
;
2788 cmd
->reasoncode
= reason
;
2790 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_DELBA_SEND_CMDID
);
2794 "failed to send WMI_DELBA_SEND_CMDID cmd\n");
2798 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2799 "cmd delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
2800 vdev_id
, mac
, tid
, initiator
, reason
);
2805 int ath11k_wmi_addba_set_resp(struct ath11k
*ar
, u32 vdev_id
, const u8
*mac
,
2806 u32 tid
, u32 status
)
2808 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2809 struct wmi_addba_setresponse_cmd
*cmd
;
2810 struct sk_buff
*skb
;
2813 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2817 cmd
= (struct wmi_addba_setresponse_cmd
*)skb
->data
;
2819 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ADDBA_SETRESPONSE_CMD
) |
2820 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2821 cmd
->vdev_id
= vdev_id
;
2822 ether_addr_copy(cmd
->peer_macaddr
.addr
, mac
);
2824 cmd
->statuscode
= status
;
2826 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_ADDBA_SET_RESP_CMDID
);
2830 "failed to send WMI_ADDBA_SET_RESP_CMDID cmd\n");
2834 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2835 "cmd addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
2836 vdev_id
, mac
, tid
, status
);
2841 int ath11k_wmi_addba_send(struct ath11k
*ar
, u32 vdev_id
, const u8
*mac
,
2842 u32 tid
, u32 buf_size
)
2844 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2845 struct wmi_addba_send_cmd
*cmd
;
2846 struct sk_buff
*skb
;
2849 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2853 cmd
= (struct wmi_addba_send_cmd
*)skb
->data
;
2854 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ADDBA_SEND_CMD
) |
2855 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2856 cmd
->vdev_id
= vdev_id
;
2857 ether_addr_copy(cmd
->peer_macaddr
.addr
, mac
);
2859 cmd
->buffersize
= buf_size
;
2861 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_ADDBA_SEND_CMDID
);
2865 "failed to send WMI_ADDBA_SEND_CMDID cmd\n");
2869 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2870 "cmd addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
2871 vdev_id
, mac
, tid
, buf_size
);
2876 int ath11k_wmi_addba_clear_resp(struct ath11k
*ar
, u32 vdev_id
, const u8
*mac
)
2878 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2879 struct wmi_addba_clear_resp_cmd
*cmd
;
2880 struct sk_buff
*skb
;
2883 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2887 cmd
= (struct wmi_addba_clear_resp_cmd
*)skb
->data
;
2889 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ADDBA_CLEAR_RESP_CMD
) |
2890 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2891 cmd
->vdev_id
= vdev_id
;
2892 ether_addr_copy(cmd
->peer_macaddr
.addr
, mac
);
2894 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_ADDBA_CLEAR_RESP_CMDID
);
2898 "failed to send WMI_ADDBA_CLEAR_RESP_CMDID cmd\n");
2902 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
2903 "cmd addba clear resp vdev_id 0x%X mac_addr %pM\n",
2909 int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k
*ar
, u8
*addr
, u8 enable
)
2911 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2912 struct wmi_pdev_pktlog_filter_cmd
*cmd
;
2913 struct wmi_pdev_pktlog_filter_info
*info
;
2914 struct sk_buff
*skb
;
2915 struct wmi_tlv
*tlv
;
2919 len
= sizeof(*cmd
) + sizeof(*info
) + TLV_HDR_SIZE
;
2920 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
2924 cmd
= (struct wmi_pdev_pktlog_filter_cmd
*)skb
->data
;
2926 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD
) |
2927 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2929 cmd
->pdev_id
= DP_HW2SW_MACID(ar
->pdev
->pdev_id
);
2931 cmd
->enable
= enable
;
2933 ptr
= skb
->data
+ sizeof(*cmd
);
2936 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
2937 FIELD_PREP(WMI_TLV_LEN
, sizeof(*info
));
2939 ptr
+= TLV_HDR_SIZE
;
2942 ether_addr_copy(info
->peer_macaddr
.addr
, addr
);
2943 info
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO
) |
2944 FIELD_PREP(WMI_TLV_LEN
,
2945 sizeof(*info
) - TLV_HDR_SIZE
);
2947 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
2948 WMI_PDEV_PKTLOG_FILTER_CMDID
);
2950 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
2954 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd pdev pktlog filter");
2960 ath11k_wmi_send_init_country_cmd(struct ath11k
*ar
,
2961 struct wmi_init_country_params init_cc_params
)
2963 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
2964 struct wmi_init_country_cmd
*cmd
;
2965 struct sk_buff
*skb
;
2968 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
2972 cmd
= (struct wmi_init_country_cmd
*)skb
->data
;
2974 FIELD_PREP(WMI_TLV_TAG
,
2975 WMI_TAG_SET_INIT_COUNTRY_CMD
) |
2976 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
2978 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
2980 switch (init_cc_params
.flags
) {
2982 cmd
->init_cc_type
= WMI_COUNTRY_INFO_TYPE_ALPHA
;
2983 memcpy((u8
*)&cmd
->cc_info
.alpha2
,
2984 init_cc_params
.cc_info
.alpha2
, 3);
2987 cmd
->init_cc_type
= WMI_COUNTRY_INFO_TYPE_COUNTRY_CODE
;
2988 cmd
->cc_info
.country_code
= init_cc_params
.cc_info
.country_code
;
2991 cmd
->init_cc_type
= WMI_COUNTRY_INFO_TYPE_REGDOMAIN
;
2992 cmd
->cc_info
.regdom_id
= init_cc_params
.cc_info
.regdom_id
;
2995 ath11k_warn(ar
->ab
, "unknown cc params flags: 0x%x",
2996 init_cc_params
.flags
);
3001 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3002 WMI_SET_INIT_COUNTRY_CMDID
);
3005 "failed to send WMI_SET_INIT_COUNTRY CMD :%d\n",
3010 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd set init country");
3019 int ath11k_wmi_send_set_current_country_cmd(struct ath11k
*ar
,
3020 struct wmi_set_current_country_params
*param
)
3022 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3023 struct wmi_set_current_country_cmd
*cmd
;
3024 struct sk_buff
*skb
;
3027 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
3031 cmd
= (struct wmi_set_current_country_cmd
*)skb
->data
;
3033 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_SET_CURRENT_COUNTRY_CMD
) |
3034 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3036 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3037 memcpy(&cmd
->new_alpha2
, ¶m
->alpha2
, 3);
3039 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_SET_CURRENT_COUNTRY_CMDID
);
3042 "failed to send WMI_SET_CURRENT_COUNTRY_CMDID: %d\n", ret
);
3046 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3047 "cmd set current country pdev id %d alpha2 %c%c\n",
3056 ath11k_wmi_send_thermal_mitigation_param_cmd(struct ath11k
*ar
,
3057 struct thermal_mitigation_params
*param
)
3059 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3060 struct wmi_therm_throt_config_request_cmd
*cmd
;
3061 struct wmi_therm_throt_level_config_info
*lvl_conf
;
3062 struct wmi_tlv
*tlv
;
3063 struct sk_buff
*skb
;
3066 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+
3067 THERMAL_LEVELS
* sizeof(struct wmi_therm_throt_level_config_info
);
3069 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3073 cmd
= (struct wmi_therm_throt_config_request_cmd
*)skb
->data
;
3075 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_THERM_THROT_CONFIG_REQUEST
) |
3076 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3078 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3079 cmd
->enable
= param
->enable
;
3080 cmd
->dc
= param
->dc
;
3081 cmd
->dc_per_event
= param
->dc_per_event
;
3082 cmd
->therm_throt_levels
= THERMAL_LEVELS
;
3084 tlv
= (struct wmi_tlv
*)(skb
->data
+ sizeof(*cmd
));
3085 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
3086 FIELD_PREP(WMI_TLV_LEN
,
3088 sizeof(struct wmi_therm_throt_level_config_info
)));
3090 lvl_conf
= (struct wmi_therm_throt_level_config_info
*)(skb
->data
+
3093 for (i
= 0; i
< THERMAL_LEVELS
; i
++) {
3094 lvl_conf
->tlv_header
=
3095 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_THERM_THROT_LEVEL_CONFIG_INFO
) |
3096 FIELD_PREP(WMI_TLV_LEN
, sizeof(*lvl_conf
) - TLV_HDR_SIZE
);
3098 lvl_conf
->temp_lwm
= param
->levelconf
[i
].tmplwm
;
3099 lvl_conf
->temp_hwm
= param
->levelconf
[i
].tmphwm
;
3100 lvl_conf
->dc_off_percent
= param
->levelconf
[i
].dcoffpercent
;
3101 lvl_conf
->prio
= param
->levelconf
[i
].priority
;
3105 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_THERM_THROT_SET_CONF_CMDID
);
3107 ath11k_warn(ar
->ab
, "failed to send THERM_THROT_SET_CONF cmd\n");
3111 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3112 "cmd therm throt set conf pdev_id %d enable %d dc %d dc_per_event %x levels %d\n",
3113 ar
->pdev
->pdev_id
, param
->enable
, param
->dc
,
3114 param
->dc_per_event
, THERMAL_LEVELS
);
3119 int ath11k_wmi_send_11d_scan_start_cmd(struct ath11k
*ar
,
3120 struct wmi_11d_scan_start_params
*param
)
3122 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3123 struct wmi_11d_scan_start_cmd
*cmd
;
3124 struct sk_buff
*skb
;
3127 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
3131 cmd
= (struct wmi_11d_scan_start_cmd
*)skb
->data
;
3133 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_11D_SCAN_START_CMD
) |
3134 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3136 cmd
->vdev_id
= param
->vdev_id
;
3137 cmd
->scan_period_msec
= param
->scan_period_msec
;
3138 cmd
->start_interval_msec
= param
->start_interval_msec
;
3140 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_11D_SCAN_START_CMDID
);
3143 "failed to send WMI_11D_SCAN_START_CMDID: %d\n", ret
);
3147 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3148 "cmd 11d scan start vdev id %d period %d ms internal %d ms\n",
3150 cmd
->scan_period_msec
,
3151 cmd
->start_interval_msec
);
3156 int ath11k_wmi_send_11d_scan_stop_cmd(struct ath11k
*ar
, u32 vdev_id
)
3158 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3159 struct wmi_11d_scan_stop_cmd
*cmd
;
3160 struct sk_buff
*skb
;
3163 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
3167 cmd
= (struct wmi_11d_scan_stop_cmd
*)skb
->data
;
3169 FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_11D_SCAN_STOP_CMD
) |
3170 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3172 cmd
->vdev_id
= vdev_id
;
3174 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_11D_SCAN_STOP_CMDID
);
3177 "failed to send WMI_11D_SCAN_STOP_CMDID: %d\n", ret
);
3181 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3182 "cmd 11d scan stop vdev id %d\n",
3188 int ath11k_wmi_pdev_pktlog_enable(struct ath11k
*ar
, u32 pktlog_filter
)
3190 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3191 struct wmi_pktlog_enable_cmd
*cmd
;
3192 struct sk_buff
*skb
;
3195 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
3199 cmd
= (struct wmi_pktlog_enable_cmd
*)skb
->data
;
3201 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_PKTLOG_ENABLE_CMD
) |
3202 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3204 cmd
->pdev_id
= DP_HW2SW_MACID(ar
->pdev
->pdev_id
);
3205 cmd
->evlist
= pktlog_filter
;
3206 cmd
->enable
= ATH11K_WMI_PKTLOG_ENABLE_FORCE
;
3208 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3209 WMI_PDEV_PKTLOG_ENABLE_CMDID
);
3211 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
3215 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd pdev pktlog enable");
3220 int ath11k_wmi_pdev_pktlog_disable(struct ath11k
*ar
)
3222 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3223 struct wmi_pktlog_disable_cmd
*cmd
;
3224 struct sk_buff
*skb
;
3227 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, sizeof(*cmd
));
3231 cmd
= (struct wmi_pktlog_disable_cmd
*)skb
->data
;
3233 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_PKTLOG_DISABLE_CMD
) |
3234 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3236 cmd
->pdev_id
= DP_HW2SW_MACID(ar
->pdev
->pdev_id
);
3238 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3239 WMI_PDEV_PKTLOG_DISABLE_CMDID
);
3241 ath11k_warn(ar
->ab
, "failed to send WMI_PDEV_PKTLOG_ENABLE_CMDID\n");
3245 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd pdev pktlog disable");
3250 void ath11k_wmi_fill_default_twt_params(struct wmi_twt_enable_params
*twt_params
)
3252 twt_params
->sta_cong_timer_ms
= ATH11K_TWT_DEF_STA_CONG_TIMER_MS
;
3253 twt_params
->default_slot_size
= ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE
;
3254 twt_params
->congestion_thresh_setup
= ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP
;
3255 twt_params
->congestion_thresh_teardown
=
3256 ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN
;
3257 twt_params
->congestion_thresh_critical
=
3258 ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL
;
3259 twt_params
->interference_thresh_teardown
=
3260 ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN
;
3261 twt_params
->interference_thresh_setup
=
3262 ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP
;
3263 twt_params
->min_no_sta_setup
= ATH11K_TWT_DEF_MIN_NO_STA_SETUP
;
3264 twt_params
->min_no_sta_teardown
= ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN
;
3265 twt_params
->no_of_bcast_mcast_slots
= ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS
;
3266 twt_params
->min_no_twt_slots
= ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS
;
3267 twt_params
->max_no_sta_twt
= ATH11K_TWT_DEF_MAX_NO_STA_TWT
;
3268 twt_params
->mode_check_interval
= ATH11K_TWT_DEF_MODE_CHECK_INTERVAL
;
3269 twt_params
->add_sta_slot_interval
= ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL
;
3270 twt_params
->remove_sta_slot_interval
=
3271 ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL
;
3272 /* TODO add MBSSID support */
3273 twt_params
->mbss_support
= 0;
3276 int ath11k_wmi_send_twt_enable_cmd(struct ath11k
*ar
, u32 pdev_id
,
3277 struct wmi_twt_enable_params
*params
)
3279 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3280 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3281 struct wmi_twt_enable_params_cmd
*cmd
;
3282 struct sk_buff
*skb
;
3287 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3291 cmd
= (struct wmi_twt_enable_params_cmd
*)skb
->data
;
3292 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_TWT_ENABLE_CMD
) |
3293 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3294 cmd
->pdev_id
= pdev_id
;
3295 cmd
->sta_cong_timer_ms
= params
->sta_cong_timer_ms
;
3296 cmd
->default_slot_size
= params
->default_slot_size
;
3297 cmd
->congestion_thresh_setup
= params
->congestion_thresh_setup
;
3298 cmd
->congestion_thresh_teardown
= params
->congestion_thresh_teardown
;
3299 cmd
->congestion_thresh_critical
= params
->congestion_thresh_critical
;
3300 cmd
->interference_thresh_teardown
= params
->interference_thresh_teardown
;
3301 cmd
->interference_thresh_setup
= params
->interference_thresh_setup
;
3302 cmd
->min_no_sta_setup
= params
->min_no_sta_setup
;
3303 cmd
->min_no_sta_teardown
= params
->min_no_sta_teardown
;
3304 cmd
->no_of_bcast_mcast_slots
= params
->no_of_bcast_mcast_slots
;
3305 cmd
->min_no_twt_slots
= params
->min_no_twt_slots
;
3306 cmd
->max_no_sta_twt
= params
->max_no_sta_twt
;
3307 cmd
->mode_check_interval
= params
->mode_check_interval
;
3308 cmd
->add_sta_slot_interval
= params
->add_sta_slot_interval
;
3309 cmd
->remove_sta_slot_interval
= params
->remove_sta_slot_interval
;
3310 cmd
->mbss_support
= params
->mbss_support
;
3312 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_ENABLE_CMDID
);
3314 ath11k_warn(ab
, "Failed to send WMI_TWT_ENABLE_CMDID");
3319 ar
->twt_enabled
= 1;
3321 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "cmd twt enable");
3327 ath11k_wmi_send_twt_disable_cmd(struct ath11k
*ar
, u32 pdev_id
)
3329 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3330 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3331 struct wmi_twt_disable_params_cmd
*cmd
;
3332 struct sk_buff
*skb
;
3337 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3341 cmd
= (struct wmi_twt_disable_params_cmd
*)skb
->data
;
3342 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_TWT_DISABLE_CMD
) |
3343 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3344 cmd
->pdev_id
= pdev_id
;
3346 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_DISABLE_CMDID
);
3348 ath11k_warn(ab
, "Failed to send WMI_TWT_DISABLE_CMDID");
3353 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "cmd twt disable");
3355 ar
->twt_enabled
= 0;
3360 int ath11k_wmi_send_twt_add_dialog_cmd(struct ath11k
*ar
,
3361 struct wmi_twt_add_dialog_params
*params
)
3363 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3364 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3365 struct wmi_twt_add_dialog_params_cmd
*cmd
;
3366 struct sk_buff
*skb
;
3371 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3375 cmd
= (struct wmi_twt_add_dialog_params_cmd
*)skb
->data
;
3376 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_TWT_ADD_DIALOG_CMD
) |
3377 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3379 cmd
->vdev_id
= params
->vdev_id
;
3380 ether_addr_copy(cmd
->peer_macaddr
.addr
, params
->peer_macaddr
);
3381 cmd
->dialog_id
= params
->dialog_id
;
3382 cmd
->wake_intvl_us
= params
->wake_intvl_us
;
3383 cmd
->wake_intvl_mantis
= params
->wake_intvl_mantis
;
3384 cmd
->wake_dura_us
= params
->wake_dura_us
;
3385 cmd
->sp_offset_us
= params
->sp_offset_us
;
3386 cmd
->flags
= params
->twt_cmd
;
3387 if (params
->flag_bcast
)
3388 cmd
->flags
|= WMI_TWT_ADD_DIALOG_FLAG_BCAST
;
3389 if (params
->flag_trigger
)
3390 cmd
->flags
|= WMI_TWT_ADD_DIALOG_FLAG_TRIGGER
;
3391 if (params
->flag_flow_type
)
3392 cmd
->flags
|= WMI_TWT_ADD_DIALOG_FLAG_FLOW_TYPE
;
3393 if (params
->flag_protection
)
3394 cmd
->flags
|= WMI_TWT_ADD_DIALOG_FLAG_PROTECTION
;
3396 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_ADD_DIALOG_CMDID
);
3399 "failed to send wmi command to add twt dialog: %d",
3405 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3406 "cmd twt add dialog vdev %u dialog id %u wake interval %u mantissa %u wake duration %u service period offset %u flags 0x%x\n",
3407 cmd
->vdev_id
, cmd
->dialog_id
, cmd
->wake_intvl_us
,
3408 cmd
->wake_intvl_mantis
, cmd
->wake_dura_us
, cmd
->sp_offset_us
,
3414 int ath11k_wmi_send_twt_del_dialog_cmd(struct ath11k
*ar
,
3415 struct wmi_twt_del_dialog_params
*params
)
3417 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3418 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3419 struct wmi_twt_del_dialog_params_cmd
*cmd
;
3420 struct sk_buff
*skb
;
3425 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3429 cmd
= (struct wmi_twt_del_dialog_params_cmd
*)skb
->data
;
3430 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_TWT_DEL_DIALOG_CMD
) |
3431 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3433 cmd
->vdev_id
= params
->vdev_id
;
3434 ether_addr_copy(cmd
->peer_macaddr
.addr
, params
->peer_macaddr
);
3435 cmd
->dialog_id
= params
->dialog_id
;
3437 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_DEL_DIALOG_CMDID
);
3440 "failed to send wmi command to delete twt dialog: %d",
3446 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3447 "cmd twt del dialog vdev %u dialog id %u\n",
3448 cmd
->vdev_id
, cmd
->dialog_id
);
3453 int ath11k_wmi_send_twt_pause_dialog_cmd(struct ath11k
*ar
,
3454 struct wmi_twt_pause_dialog_params
*params
)
3456 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3457 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3458 struct wmi_twt_pause_dialog_params_cmd
*cmd
;
3459 struct sk_buff
*skb
;
3464 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3468 cmd
= (struct wmi_twt_pause_dialog_params_cmd
*)skb
->data
;
3469 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3470 WMI_TAG_TWT_PAUSE_DIALOG_CMD
) |
3471 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3473 cmd
->vdev_id
= params
->vdev_id
;
3474 ether_addr_copy(cmd
->peer_macaddr
.addr
, params
->peer_macaddr
);
3475 cmd
->dialog_id
= params
->dialog_id
;
3477 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_PAUSE_DIALOG_CMDID
);
3480 "failed to send wmi command to pause twt dialog: %d",
3486 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3487 "cmd twt pause dialog vdev %u dialog id %u\n",
3488 cmd
->vdev_id
, cmd
->dialog_id
);
3493 int ath11k_wmi_send_twt_resume_dialog_cmd(struct ath11k
*ar
,
3494 struct wmi_twt_resume_dialog_params
*params
)
3496 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3497 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3498 struct wmi_twt_resume_dialog_params_cmd
*cmd
;
3499 struct sk_buff
*skb
;
3504 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3508 cmd
= (struct wmi_twt_resume_dialog_params_cmd
*)skb
->data
;
3509 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3510 WMI_TAG_TWT_RESUME_DIALOG_CMD
) |
3511 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3513 cmd
->vdev_id
= params
->vdev_id
;
3514 ether_addr_copy(cmd
->peer_macaddr
.addr
, params
->peer_macaddr
);
3515 cmd
->dialog_id
= params
->dialog_id
;
3516 cmd
->sp_offset_us
= params
->sp_offset_us
;
3517 cmd
->next_twt_size
= params
->next_twt_size
;
3519 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_TWT_RESUME_DIALOG_CMDID
);
3522 "failed to send wmi command to resume twt dialog: %d",
3528 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3529 "cmd twt resume dialog vdev %u dialog id %u service period offset %u next twt subfield size %u\n",
3530 cmd
->vdev_id
, cmd
->dialog_id
, cmd
->sp_offset_us
,
3531 cmd
->next_twt_size
);
3537 ath11k_wmi_send_obss_spr_cmd(struct ath11k
*ar
, u32 vdev_id
,
3538 struct ieee80211_he_obss_pd
*he_obss_pd
)
3540 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3541 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3542 struct wmi_obss_spatial_reuse_params_cmd
*cmd
;
3543 struct sk_buff
*skb
;
3548 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3552 cmd
= (struct wmi_obss_spatial_reuse_params_cmd
*)skb
->data
;
3553 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3554 WMI_TAG_OBSS_SPATIAL_REUSE_SET_CMD
) |
3555 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3556 cmd
->vdev_id
= vdev_id
;
3557 cmd
->enable
= he_obss_pd
->enable
;
3558 cmd
->obss_min
= he_obss_pd
->min_offset
;
3559 cmd
->obss_max
= he_obss_pd
->max_offset
;
3561 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3562 WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID
);
3565 "Failed to send WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID");
3570 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "cmd pdev obss pd spatial reuse");
3576 ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3578 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3579 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3580 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3581 struct sk_buff
*skb
;
3586 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3590 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3591 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3592 WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD
) |
3593 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3594 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3595 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3597 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3598 WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID
);
3601 "failed to send WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID");
3606 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3607 "cmd pdev set srg bss color bitmap pdev_id %d bss color bitmap %08x %08x\n",
3608 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3614 ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3616 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3617 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3618 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3619 struct sk_buff
*skb
;
3624 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3628 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3630 FIELD_PREP(WMI_TLV_TAG
,
3631 WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD
) |
3632 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3633 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3634 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3636 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3637 WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID
);
3640 "failed to send WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID");
3645 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3646 "cmd pdev set srg partial bssid bitmap pdev_id %d partial bssid bitmap %08x %08x\n",
3647 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3653 ath11k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3655 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3656 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3657 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3658 struct sk_buff
*skb
;
3663 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3667 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3669 FIELD_PREP(WMI_TLV_TAG
,
3670 WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD
) |
3671 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3672 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3673 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3675 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3676 WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID
);
3679 "failed to send WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
3684 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3685 "cmd pdev set srg obsscolor enable pdev_id %d bss color enable bitmap %08x %08x\n",
3686 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3692 ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3694 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3695 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3696 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3697 struct sk_buff
*skb
;
3702 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3706 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3708 FIELD_PREP(WMI_TLV_TAG
,
3709 WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD
) |
3710 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3711 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3712 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3714 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3715 WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID
);
3718 "failed to send WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
3723 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3724 "cmd pdev set srg obss bssid enable bitmap pdev_id %d bssid enable bitmap %08x %08x\n",
3725 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3731 ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3733 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3734 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3735 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3736 struct sk_buff
*skb
;
3741 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3745 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3747 FIELD_PREP(WMI_TLV_TAG
,
3748 WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD
) |
3749 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3750 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3751 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3753 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3754 WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID
);
3757 "failed to send WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
3762 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3763 "cmd pdev set non srg obss color enable bitmap pdev_id %d bss color enable bitmap %08x %08x\n",
3764 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3770 ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k
*ar
, u32
*bitmap
)
3772 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3773 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3774 struct wmi_pdev_obss_pd_bitmap_cmd
*cmd
;
3775 struct sk_buff
*skb
;
3780 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3784 cmd
= (struct wmi_pdev_obss_pd_bitmap_cmd
*)skb
->data
;
3786 FIELD_PREP(WMI_TLV_TAG
,
3787 WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD
) |
3788 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3789 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
3790 memcpy(cmd
->bitmap
, bitmap
, sizeof(cmd
->bitmap
));
3792 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3793 WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID
);
3796 "failed to send WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
3801 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3802 "cmd pdev set non srg obss bssid enable bitmap pdev_id %d bssid enable bitmap %08x %08x\n",
3803 cmd
->pdev_id
, cmd
->bitmap
[0], cmd
->bitmap
[1]);
3809 ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k
*ar
, u32 vdev_id
,
3810 u8 bss_color
, u32 period
,
3813 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3814 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3815 struct wmi_obss_color_collision_cfg_params_cmd
*cmd
;
3816 struct sk_buff
*skb
;
3821 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3825 cmd
= (struct wmi_obss_color_collision_cfg_params_cmd
*)skb
->data
;
3826 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3827 WMI_TAG_OBSS_COLOR_COLLISION_DET_CONFIG
) |
3828 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3829 cmd
->vdev_id
= vdev_id
;
3830 cmd
->evt_type
= enable
? ATH11K_OBSS_COLOR_COLLISION_DETECTION
:
3831 ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE
;
3832 cmd
->current_bss_color
= bss_color
;
3833 cmd
->detection_period_ms
= period
;
3834 cmd
->scan_period_ms
= ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS
;
3835 cmd
->free_slot_expiry_time_ms
= 0;
3838 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3839 WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID
);
3841 ath11k_warn(ab
, "Failed to send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID");
3846 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3847 "cmd obss color collision det config id %d type %d bss_color %d detect_period %d scan_period %d\n",
3848 cmd
->vdev_id
, cmd
->evt_type
, cmd
->current_bss_color
,
3849 cmd
->detection_period_ms
, cmd
->scan_period_ms
);
3854 int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k
*ar
, u32 vdev_id
,
3857 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
3858 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
3859 struct wmi_bss_color_change_enable_params_cmd
*cmd
;
3860 struct sk_buff
*skb
;
3865 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
3869 cmd
= (struct wmi_bss_color_change_enable_params_cmd
*)skb
->data
;
3870 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_BSS_COLOR_CHANGE_ENABLE
) |
3871 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3872 cmd
->vdev_id
= vdev_id
;
3873 cmd
->enable
= enable
? 1 : 0;
3875 ret
= ath11k_wmi_cmd_send(wmi
, skb
,
3876 WMI_BSS_COLOR_CHANGE_ENABLE_CMDID
);
3878 ath11k_warn(ab
, "Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
3883 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3884 "cmd bss color change enable id %d enable %d\n",
3885 cmd
->vdev_id
, cmd
->enable
);
3890 int ath11k_wmi_fils_discovery_tmpl(struct ath11k
*ar
, u32 vdev_id
,
3891 struct sk_buff
*tmpl
)
3893 struct wmi_tlv
*tlv
;
3894 struct sk_buff
*skb
;
3898 struct wmi_fils_discovery_tmpl_cmd
*cmd
;
3900 aligned_len
= roundup(tmpl
->len
, 4);
3901 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ aligned_len
;
3903 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3904 "vdev %i set FILS discovery template\n", vdev_id
);
3906 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
3910 cmd
= (struct wmi_fils_discovery_tmpl_cmd
*)skb
->data
;
3911 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3912 WMI_TAG_FILS_DISCOVERY_TMPL_CMD
) |
3913 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3914 cmd
->vdev_id
= vdev_id
;
3915 cmd
->buf_len
= tmpl
->len
;
3916 ptr
= skb
->data
+ sizeof(*cmd
);
3919 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
3920 FIELD_PREP(WMI_TLV_LEN
, aligned_len
);
3921 memcpy(tlv
->value
, tmpl
->data
, tmpl
->len
);
3923 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_FILS_DISCOVERY_TMPL_CMDID
);
3926 "WMI vdev %i failed to send FILS discovery template command\n",
3932 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd fils discovery tmpl");
3937 int ath11k_wmi_probe_resp_tmpl(struct ath11k
*ar
, u32 vdev_id
,
3938 struct sk_buff
*tmpl
)
3940 struct wmi_probe_tmpl_cmd
*cmd
;
3941 struct wmi_bcn_prb_info
*probe_info
;
3942 struct wmi_tlv
*tlv
;
3943 struct sk_buff
*skb
;
3946 size_t aligned_len
= roundup(tmpl
->len
, 4);
3948 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
3949 "vdev %i set probe response template\n", vdev_id
);
3951 len
= sizeof(*cmd
) + sizeof(*probe_info
) + TLV_HDR_SIZE
+ aligned_len
;
3953 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
3957 cmd
= (struct wmi_probe_tmpl_cmd
*)skb
->data
;
3958 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PRB_TMPL_CMD
) |
3959 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
3960 cmd
->vdev_id
= vdev_id
;
3961 cmd
->buf_len
= tmpl
->len
;
3963 ptr
= skb
->data
+ sizeof(*cmd
);
3966 len
= sizeof(*probe_info
);
3967 probe_info
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
3968 WMI_TAG_BCN_PRB_INFO
) |
3969 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
3970 probe_info
->caps
= 0;
3971 probe_info
->erp
= 0;
3973 ptr
+= sizeof(*probe_info
);
3976 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
3977 FIELD_PREP(WMI_TLV_LEN
, aligned_len
);
3978 memcpy(tlv
->value
, tmpl
->data
, tmpl
->len
);
3980 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_PRB_TMPL_CMDID
);
3983 "WMI vdev %i failed to send probe response template command\n",
3989 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd ");
3994 int ath11k_wmi_fils_discovery(struct ath11k
*ar
, u32 vdev_id
, u32 interval
,
3995 bool unsol_bcast_probe_resp_enabled
)
3997 struct sk_buff
*skb
;
3999 struct wmi_fils_discovery_cmd
*cmd
;
4001 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
4002 "vdev %i set %s interval to %u TU\n",
4003 vdev_id
, unsol_bcast_probe_resp_enabled
?
4004 "unsolicited broadcast probe response" : "FILS discovery",
4008 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
4012 cmd
= (struct wmi_fils_discovery_cmd
*)skb
->data
;
4013 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ENABLE_FILS_CMD
) |
4014 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
4015 cmd
->vdev_id
= vdev_id
;
4016 cmd
->interval
= interval
;
4017 cmd
->config
= unsol_bcast_probe_resp_enabled
;
4019 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_ENABLE_FILS_CMDID
);
4022 "WMI vdev %i failed to send FILS discovery enable/disable command\n",
4028 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd enable fils");
4034 ath11k_wmi_obss_color_collision_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
4037 const struct wmi_obss_color_collision_event
*ev
;
4038 struct ath11k_vif
*arvif
;
4041 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
4044 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
4048 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event obss color collision");
4052 ev
= tb
[WMI_TAG_OBSS_COLOR_COLLISION_EVT
];
4054 ath11k_warn(ab
, "failed to fetch obss color collision ev");
4058 arvif
= ath11k_mac_get_arvif_by_vdev_id(ab
, ev
->vdev_id
);
4060 ath11k_warn(ab
, "failed to find arvif with vedv id %d in obss_color_collision_event\n",
4065 switch (ev
->evt_type
) {
4066 case WMI_BSS_COLOR_COLLISION_DETECTION
:
4067 ieee80211_obss_color_collision_notify(arvif
->vif
, ev
->obss_color_bitmap
,
4069 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
4070 "OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n",
4071 ev
->vdev_id
, ev
->evt_type
, ev
->obss_color_bitmap
);
4073 case WMI_BSS_COLOR_COLLISION_DISABLE
:
4074 case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY
:
4075 case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE
:
4078 ath11k_warn(ab
, "received unknown obss color collision detection event\n");
4087 ath11k_fill_band_to_mac_param(struct ath11k_base
*soc
,
4088 struct wmi_host_pdev_band_to_mac
*band_to_mac
)
4091 struct ath11k_hal_reg_capabilities_ext
*hal_reg_cap
;
4092 struct ath11k_pdev
*pdev
;
4094 for (i
= 0; i
< soc
->num_radios
; i
++) {
4095 pdev
= &soc
->pdevs
[i
];
4096 hal_reg_cap
= &soc
->hal_reg_cap
[i
];
4097 band_to_mac
[i
].pdev_id
= pdev
->pdev_id
;
4099 switch (pdev
->cap
.supported_bands
) {
4100 case WMI_HOST_WLAN_2G_5G_CAP
:
4101 band_to_mac
[i
].start_freq
= hal_reg_cap
->low_2ghz_chan
;
4102 band_to_mac
[i
].end_freq
= hal_reg_cap
->high_5ghz_chan
;
4104 case WMI_HOST_WLAN_2G_CAP
:
4105 band_to_mac
[i
].start_freq
= hal_reg_cap
->low_2ghz_chan
;
4106 band_to_mac
[i
].end_freq
= hal_reg_cap
->high_2ghz_chan
;
4108 case WMI_HOST_WLAN_5G_CAP
:
4109 band_to_mac
[i
].start_freq
= hal_reg_cap
->low_5ghz_chan
;
4110 band_to_mac
[i
].end_freq
= hal_reg_cap
->high_5ghz_chan
;
4119 ath11k_wmi_copy_resource_config(struct wmi_resource_config
*wmi_cfg
,
4120 struct target_resource_config
*tg_cfg
)
4122 wmi_cfg
->num_vdevs
= tg_cfg
->num_vdevs
;
4123 wmi_cfg
->num_peers
= tg_cfg
->num_peers
;
4124 wmi_cfg
->num_offload_peers
= tg_cfg
->num_offload_peers
;
4125 wmi_cfg
->num_offload_reorder_buffs
= tg_cfg
->num_offload_reorder_buffs
;
4126 wmi_cfg
->num_peer_keys
= tg_cfg
->num_peer_keys
;
4127 wmi_cfg
->num_tids
= tg_cfg
->num_tids
;
4128 wmi_cfg
->ast_skid_limit
= tg_cfg
->ast_skid_limit
;
4129 wmi_cfg
->tx_chain_mask
= tg_cfg
->tx_chain_mask
;
4130 wmi_cfg
->rx_chain_mask
= tg_cfg
->rx_chain_mask
;
4131 wmi_cfg
->rx_timeout_pri
[0] = tg_cfg
->rx_timeout_pri
[0];
4132 wmi_cfg
->rx_timeout_pri
[1] = tg_cfg
->rx_timeout_pri
[1];
4133 wmi_cfg
->rx_timeout_pri
[2] = tg_cfg
->rx_timeout_pri
[2];
4134 wmi_cfg
->rx_timeout_pri
[3] = tg_cfg
->rx_timeout_pri
[3];
4135 wmi_cfg
->rx_decap_mode
= tg_cfg
->rx_decap_mode
;
4136 wmi_cfg
->scan_max_pending_req
= tg_cfg
->scan_max_pending_req
;
4137 wmi_cfg
->bmiss_offload_max_vdev
= tg_cfg
->bmiss_offload_max_vdev
;
4138 wmi_cfg
->roam_offload_max_vdev
= tg_cfg
->roam_offload_max_vdev
;
4139 wmi_cfg
->roam_offload_max_ap_profiles
=
4140 tg_cfg
->roam_offload_max_ap_profiles
;
4141 wmi_cfg
->num_mcast_groups
= tg_cfg
->num_mcast_groups
;
4142 wmi_cfg
->num_mcast_table_elems
= tg_cfg
->num_mcast_table_elems
;
4143 wmi_cfg
->mcast2ucast_mode
= tg_cfg
->mcast2ucast_mode
;
4144 wmi_cfg
->tx_dbg_log_size
= tg_cfg
->tx_dbg_log_size
;
4145 wmi_cfg
->num_wds_entries
= tg_cfg
->num_wds_entries
;
4146 wmi_cfg
->dma_burst_size
= tg_cfg
->dma_burst_size
;
4147 wmi_cfg
->mac_aggr_delim
= tg_cfg
->mac_aggr_delim
;
4148 wmi_cfg
->rx_skip_defrag_timeout_dup_detection_check
=
4149 tg_cfg
->rx_skip_defrag_timeout_dup_detection_check
;
4150 wmi_cfg
->vow_config
= tg_cfg
->vow_config
;
4151 wmi_cfg
->gtk_offload_max_vdev
= tg_cfg
->gtk_offload_max_vdev
;
4152 wmi_cfg
->num_msdu_desc
= tg_cfg
->num_msdu_desc
;
4153 wmi_cfg
->max_frag_entries
= tg_cfg
->max_frag_entries
;
4154 wmi_cfg
->num_tdls_vdevs
= tg_cfg
->num_tdls_vdevs
;
4155 wmi_cfg
->num_tdls_conn_table_entries
=
4156 tg_cfg
->num_tdls_conn_table_entries
;
4157 wmi_cfg
->beacon_tx_offload_max_vdev
=
4158 tg_cfg
->beacon_tx_offload_max_vdev
;
4159 wmi_cfg
->num_multicast_filter_entries
=
4160 tg_cfg
->num_multicast_filter_entries
;
4161 wmi_cfg
->num_wow_filters
= tg_cfg
->num_wow_filters
;
4162 wmi_cfg
->num_keep_alive_pattern
= tg_cfg
->num_keep_alive_pattern
;
4163 wmi_cfg
->keep_alive_pattern_size
= tg_cfg
->keep_alive_pattern_size
;
4164 wmi_cfg
->max_tdls_concurrent_sleep_sta
=
4165 tg_cfg
->max_tdls_concurrent_sleep_sta
;
4166 wmi_cfg
->max_tdls_concurrent_buffer_sta
=
4167 tg_cfg
->max_tdls_concurrent_buffer_sta
;
4168 wmi_cfg
->wmi_send_separate
= tg_cfg
->wmi_send_separate
;
4169 wmi_cfg
->num_ocb_vdevs
= tg_cfg
->num_ocb_vdevs
;
4170 wmi_cfg
->num_ocb_channels
= tg_cfg
->num_ocb_channels
;
4171 wmi_cfg
->num_ocb_schedules
= tg_cfg
->num_ocb_schedules
;
4172 wmi_cfg
->bpf_instruction_size
= tg_cfg
->bpf_instruction_size
;
4173 wmi_cfg
->max_bssid_rx_filters
= tg_cfg
->max_bssid_rx_filters
;
4174 wmi_cfg
->use_pdev_id
= tg_cfg
->use_pdev_id
;
4175 wmi_cfg
->flag1
= tg_cfg
->flag1
;
4176 wmi_cfg
->peer_map_unmap_v2_support
= tg_cfg
->peer_map_unmap_v2_support
;
4177 wmi_cfg
->sched_params
= tg_cfg
->sched_params
;
4178 wmi_cfg
->twt_ap_pdev_count
= tg_cfg
->twt_ap_pdev_count
;
4179 wmi_cfg
->twt_ap_sta_count
= tg_cfg
->twt_ap_sta_count
;
4180 wmi_cfg
->host_service_flags
&=
4181 ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT
);
4182 wmi_cfg
->host_service_flags
|= (tg_cfg
->is_reg_cc_ext_event_supported
<<
4183 WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT
);
4184 wmi_cfg
->flags2
= WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET
;
4185 wmi_cfg
->ema_max_vap_cnt
= tg_cfg
->ema_max_vap_cnt
;
4186 wmi_cfg
->ema_max_profile_period
= tg_cfg
->ema_max_profile_period
;
4189 static int ath11k_init_cmd_send(struct ath11k_pdev_wmi
*wmi
,
4190 struct wmi_init_cmd_param
*param
)
4192 struct ath11k_base
*ab
= wmi
->wmi_ab
->ab
;
4193 struct sk_buff
*skb
;
4194 struct wmi_init_cmd
*cmd
;
4195 struct wmi_resource_config
*cfg
;
4196 struct wmi_pdev_set_hw_mode_cmd_param
*hw_mode
;
4197 struct wmi_pdev_band_to_mac
*band_to_mac
;
4198 struct wlan_host_mem_chunk
*host_mem_chunks
;
4199 struct wmi_tlv
*tlv
;
4202 u32 hw_mode_len
= 0;
4205 if (param
->hw_mode_id
!= WMI_HOST_HW_MODE_MAX
)
4206 hw_mode_len
= sizeof(*hw_mode
) + TLV_HDR_SIZE
+
4207 (param
->num_band_to_mac
* sizeof(*band_to_mac
));
4209 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ sizeof(*cfg
) + hw_mode_len
+
4210 (param
->num_mem_chunks
? (sizeof(*host_mem_chunks
) * WMI_MAX_MEM_REQS
) : 0);
4212 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
4216 cmd
= (struct wmi_init_cmd
*)skb
->data
;
4218 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_INIT_CMD
) |
4219 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4221 ptr
= skb
->data
+ sizeof(*cmd
);
4224 ath11k_wmi_copy_resource_config(cfg
, param
->res_cfg
);
4226 cfg
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_RESOURCE_CONFIG
) |
4227 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cfg
) - TLV_HDR_SIZE
);
4229 ptr
+= sizeof(*cfg
);
4230 host_mem_chunks
= ptr
+ TLV_HDR_SIZE
;
4231 len
= sizeof(struct wlan_host_mem_chunk
);
4233 for (idx
= 0; idx
< param
->num_mem_chunks
; ++idx
) {
4234 host_mem_chunks
[idx
].tlv_header
=
4235 FIELD_PREP(WMI_TLV_TAG
,
4236 WMI_TAG_WLAN_HOST_MEMORY_CHUNK
) |
4237 FIELD_PREP(WMI_TLV_LEN
, len
);
4239 host_mem_chunks
[idx
].ptr
= param
->mem_chunks
[idx
].paddr
;
4240 host_mem_chunks
[idx
].size
= param
->mem_chunks
[idx
].len
;
4241 host_mem_chunks
[idx
].req_id
= param
->mem_chunks
[idx
].req_id
;
4243 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
4244 "host mem chunk req_id %d paddr 0x%llx len %d\n",
4245 param
->mem_chunks
[idx
].req_id
,
4246 (u64
)param
->mem_chunks
[idx
].paddr
,
4247 param
->mem_chunks
[idx
].len
);
4249 cmd
->num_host_mem_chunks
= param
->num_mem_chunks
;
4250 len
= sizeof(struct wlan_host_mem_chunk
) * param
->num_mem_chunks
;
4252 /* num_mem_chunks is zero */
4254 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
4255 FIELD_PREP(WMI_TLV_LEN
, len
);
4256 ptr
+= TLV_HDR_SIZE
+ len
;
4258 if (param
->hw_mode_id
!= WMI_HOST_HW_MODE_MAX
) {
4260 hw_mode
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
4261 WMI_TAG_PDEV_SET_HW_MODE_CMD
) |
4262 FIELD_PREP(WMI_TLV_LEN
,
4263 sizeof(*hw_mode
) - TLV_HDR_SIZE
);
4265 hw_mode
->hw_mode_index
= param
->hw_mode_id
;
4266 hw_mode
->num_band_to_mac
= param
->num_band_to_mac
;
4268 ptr
+= sizeof(*hw_mode
);
4270 len
= param
->num_band_to_mac
* sizeof(*band_to_mac
);
4272 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
4273 FIELD_PREP(WMI_TLV_LEN
, len
);
4275 ptr
+= TLV_HDR_SIZE
;
4276 len
= sizeof(*band_to_mac
);
4278 for (idx
= 0; idx
< param
->num_band_to_mac
; idx
++) {
4281 band_to_mac
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
4282 WMI_TAG_PDEV_BAND_TO_MAC
) |
4283 FIELD_PREP(WMI_TLV_LEN
,
4284 len
- TLV_HDR_SIZE
);
4285 band_to_mac
->pdev_id
= param
->band_to_mac
[idx
].pdev_id
;
4286 band_to_mac
->start_freq
=
4287 param
->band_to_mac
[idx
].start_freq
;
4288 band_to_mac
->end_freq
=
4289 param
->band_to_mac
[idx
].end_freq
;
4290 ptr
+= sizeof(*band_to_mac
);
4294 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_INIT_CMDID
);
4296 ath11k_warn(ab
, "failed to send WMI_INIT_CMDID\n");
4301 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "cmd wmi init");
4306 int ath11k_wmi_pdev_lro_cfg(struct ath11k
*ar
,
4309 struct ath11k_wmi_pdev_lro_config_cmd
*cmd
;
4310 struct sk_buff
*skb
;
4313 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, sizeof(*cmd
));
4317 cmd
= (struct ath11k_wmi_pdev_lro_config_cmd
*)skb
->data
;
4318 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_LRO_INFO_CMD
) |
4319 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4321 get_random_bytes(cmd
->th_4
, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE
);
4322 get_random_bytes(cmd
->th_6
, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE
);
4324 cmd
->pdev_id
= pdev_id
;
4326 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_LRO_CONFIG_CMDID
);
4329 "failed to send lro cfg req wmi cmd\n");
4333 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
4334 "cmd lro config pdev_id 0x%x\n", pdev_id
);
4341 int ath11k_wmi_wait_for_service_ready(struct ath11k_base
*ab
)
4343 unsigned long time_left
;
4345 time_left
= wait_for_completion_timeout(&ab
->wmi_ab
.service_ready
,
4346 WMI_SERVICE_READY_TIMEOUT_HZ
);
4353 int ath11k_wmi_wait_for_unified_ready(struct ath11k_base
*ab
)
4355 unsigned long time_left
;
4357 time_left
= wait_for_completion_timeout(&ab
->wmi_ab
.unified_ready
,
4358 WMI_SERVICE_READY_TIMEOUT_HZ
);
4365 int ath11k_wmi_set_hw_mode(struct ath11k_base
*ab
,
4366 enum wmi_host_hw_mode_config_type mode
)
4368 struct wmi_pdev_set_hw_mode_cmd_param
*cmd
;
4369 struct sk_buff
*skb
;
4370 struct ath11k_wmi_base
*wmi_ab
= &ab
->wmi_ab
;
4376 skb
= ath11k_wmi_alloc_skb(wmi_ab
, len
);
4380 cmd
= (struct wmi_pdev_set_hw_mode_cmd_param
*)skb
->data
;
4382 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_SET_HW_MODE_CMD
) |
4383 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4385 cmd
->pdev_id
= WMI_PDEV_ID_SOC
;
4386 cmd
->hw_mode_index
= mode
;
4388 ret
= ath11k_wmi_cmd_send(&wmi_ab
->wmi
[0], skb
, WMI_PDEV_SET_HW_MODE_CMDID
);
4390 ath11k_warn(ab
, "failed to send WMI_PDEV_SET_HW_MODE_CMDID\n");
4395 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "cmd pdev set hw mode %d", cmd
->hw_mode_index
);
4400 int ath11k_wmi_cmd_init(struct ath11k_base
*ab
)
4402 struct ath11k_wmi_base
*wmi_ab
= &ab
->wmi_ab
;
4403 struct wmi_init_cmd_param init_param
;
4404 struct target_resource_config config
;
4406 memset(&init_param
, 0, sizeof(init_param
));
4407 memset(&config
, 0, sizeof(config
));
4409 ab
->hw_params
.hw_ops
->wmi_init_config(ab
, &config
);
4411 if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT
,
4412 ab
->wmi_ab
.svc_map
))
4413 config
.is_reg_cc_ext_event_supported
= 1;
4415 memcpy(&wmi_ab
->wlan_resource_config
, &config
, sizeof(config
));
4417 init_param
.res_cfg
= &wmi_ab
->wlan_resource_config
;
4418 init_param
.num_mem_chunks
= wmi_ab
->num_mem_chunks
;
4419 init_param
.hw_mode_id
= wmi_ab
->preferred_hw_mode
;
4420 init_param
.mem_chunks
= wmi_ab
->mem_chunks
;
4422 if (ab
->hw_params
.single_pdev_only
)
4423 init_param
.hw_mode_id
= WMI_HOST_HW_MODE_MAX
;
4425 init_param
.num_band_to_mac
= ab
->num_radios
;
4426 ath11k_fill_band_to_mac_param(ab
, init_param
.band_to_mac
);
4428 return ath11k_init_cmd_send(&wmi_ab
->wmi
[0], &init_param
);
4431 int ath11k_wmi_vdev_spectral_conf(struct ath11k
*ar
,
4432 struct ath11k_wmi_vdev_spectral_conf_param
*param
)
4434 struct ath11k_wmi_vdev_spectral_conf_cmd
*cmd
;
4435 struct sk_buff
*skb
;
4438 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, sizeof(*cmd
));
4442 cmd
= (struct ath11k_wmi_vdev_spectral_conf_cmd
*)skb
->data
;
4443 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
4444 WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD
) |
4445 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4447 memcpy(&cmd
->param
, param
, sizeof(*param
));
4449 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
,
4450 WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID
);
4453 "failed to send spectral scan config wmi cmd\n");
4457 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
4458 "cmd vdev spectral scan configure vdev_id 0x%x\n",
4467 int ath11k_wmi_vdev_spectral_enable(struct ath11k
*ar
, u32 vdev_id
,
4468 u32 trigger
, u32 enable
)
4470 struct ath11k_wmi_vdev_spectral_enable_cmd
*cmd
;
4471 struct sk_buff
*skb
;
4474 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, sizeof(*cmd
));
4478 cmd
= (struct ath11k_wmi_vdev_spectral_enable_cmd
*)skb
->data
;
4479 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
4480 WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD
) |
4481 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4483 cmd
->vdev_id
= vdev_id
;
4484 cmd
->trigger_cmd
= trigger
;
4485 cmd
->enable_cmd
= enable
;
4487 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
,
4488 WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID
);
4491 "failed to send spectral enable wmi cmd\n");
4495 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
4496 "cmd vdev spectral scan enable vdev id 0x%x\n",
4505 int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k
*ar
,
4506 struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd
*param
)
4508 struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd
*cmd
;
4509 struct sk_buff
*skb
;
4512 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, sizeof(*cmd
));
4516 cmd
= (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd
*)skb
->data
;
4517 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_DMA_RING_CFG_REQ
) |
4518 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
4520 cmd
->pdev_id
= param
->pdev_id
;
4521 cmd
->module_id
= param
->module_id
;
4522 cmd
->base_paddr_lo
= param
->base_paddr_lo
;
4523 cmd
->base_paddr_hi
= param
->base_paddr_hi
;
4524 cmd
->head_idx_paddr_lo
= param
->head_idx_paddr_lo
;
4525 cmd
->head_idx_paddr_hi
= param
->head_idx_paddr_hi
;
4526 cmd
->tail_idx_paddr_lo
= param
->tail_idx_paddr_lo
;
4527 cmd
->tail_idx_paddr_hi
= param
->tail_idx_paddr_hi
;
4528 cmd
->num_elems
= param
->num_elems
;
4529 cmd
->buf_size
= param
->buf_size
;
4530 cmd
->num_resp_per_event
= param
->num_resp_per_event
;
4531 cmd
->event_timeout_ms
= param
->event_timeout_ms
;
4533 ret
= ath11k_wmi_cmd_send(ar
->wmi
, skb
,
4534 WMI_PDEV_DMA_RING_CFG_REQ_CMDID
);
4537 "failed to send dma ring cfg req wmi cmd\n");
4541 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
4542 "cmd pdev dma ring cfg req pdev_id 0x%x\n",
4551 static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base
*soc
,
4553 const void *ptr
, void *data
)
4555 struct wmi_tlv_dma_buf_release_parse
*parse
= data
;
4557 if (tag
!= WMI_TAG_DMA_BUF_RELEASE_ENTRY
)
4560 if (parse
->num_buf_entry
>= parse
->fixed
.num_buf_release_entry
)
4563 parse
->num_buf_entry
++;
4567 static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base
*soc
,
4569 const void *ptr
, void *data
)
4571 struct wmi_tlv_dma_buf_release_parse
*parse
= data
;
4573 if (tag
!= WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA
)
4576 if (parse
->num_meta
>= parse
->fixed
.num_meta_data_entry
)
4583 static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base
*ab
,
4585 const void *ptr
, void *data
)
4587 struct wmi_tlv_dma_buf_release_parse
*parse
= data
;
4591 case WMI_TAG_DMA_BUF_RELEASE
:
4592 memcpy(&parse
->fixed
, ptr
,
4593 sizeof(struct ath11k_wmi_dma_buf_release_fixed_param
));
4594 parse
->fixed
.pdev_id
= DP_HW2SW_MACID(parse
->fixed
.pdev_id
);
4596 case WMI_TAG_ARRAY_STRUCT
:
4597 if (!parse
->buf_entry_done
) {
4598 parse
->num_buf_entry
= 0;
4599 parse
->buf_entry
= (struct wmi_dma_buf_release_entry
*)ptr
;
4601 ret
= ath11k_wmi_tlv_iter(ab
, ptr
, len
,
4602 ath11k_wmi_tlv_dma_buf_entry_parse
,
4605 ath11k_warn(ab
, "failed to parse dma buf entry tlv %d\n",
4610 parse
->buf_entry_done
= true;
4611 } else if (!parse
->meta_data_done
) {
4612 parse
->num_meta
= 0;
4613 parse
->meta_data
= (struct wmi_dma_buf_release_meta_data
*)ptr
;
4615 ret
= ath11k_wmi_tlv_iter(ab
, ptr
, len
,
4616 ath11k_wmi_tlv_dma_buf_meta_parse
,
4619 ath11k_warn(ab
, "failed to parse dma buf meta tlv %d\n",
4624 parse
->meta_data_done
= true;
4633 static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base
*ab
,
4634 struct sk_buff
*skb
)
4636 struct wmi_tlv_dma_buf_release_parse parse
= { };
4637 struct ath11k_dbring_buf_release_event param
;
4640 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
4641 ath11k_wmi_tlv_dma_buf_parse
,
4644 ath11k_warn(ab
, "failed to parse dma buf release tlv %d\n", ret
);
4648 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event pdev dma ring buf release");
4650 param
.fixed
= parse
.fixed
;
4651 param
.buf_entry
= parse
.buf_entry
;
4652 param
.num_buf_entry
= parse
.num_buf_entry
;
4653 param
.meta_data
= parse
.meta_data
;
4654 param
.num_meta
= parse
.num_meta
;
4656 ret
= ath11k_dbring_buffer_release_event(ab
, ¶m
);
4658 ath11k_warn(ab
, "failed to handle dma buf release event %d\n", ret
);
4663 static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base
*soc
,
4665 const void *ptr
, void *data
)
4667 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4668 struct wmi_hw_mode_capabilities
*hw_mode_cap
;
4671 if (tag
!= WMI_TAG_HW_MODE_CAPABILITIES
)
4674 if (svc_rdy_ext
->n_hw_mode_caps
>= svc_rdy_ext
->param
.num_hw_modes
)
4677 hw_mode_cap
= container_of(ptr
, struct wmi_hw_mode_capabilities
,
4679 svc_rdy_ext
->n_hw_mode_caps
++;
4681 phy_map
= hw_mode_cap
->phy_id_map
;
4683 svc_rdy_ext
->tot_phy_id
++;
4684 phy_map
= phy_map
>> 1;
4690 static int ath11k_wmi_tlv_hw_mode_caps(struct ath11k_base
*soc
,
4691 u16 len
, const void *ptr
, void *data
)
4693 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4694 struct wmi_hw_mode_capabilities
*hw_mode_caps
;
4695 enum wmi_host_hw_mode_config_type mode
, pref
;
4699 svc_rdy_ext
->n_hw_mode_caps
= 0;
4700 svc_rdy_ext
->hw_mode_caps
= (struct wmi_hw_mode_capabilities
*)ptr
;
4702 ret
= ath11k_wmi_tlv_iter(soc
, ptr
, len
,
4703 ath11k_wmi_tlv_hw_mode_caps_parse
,
4706 ath11k_warn(soc
, "failed to parse tlv %d\n", ret
);
4711 while (i
< svc_rdy_ext
->n_hw_mode_caps
) {
4712 hw_mode_caps
= &svc_rdy_ext
->hw_mode_caps
[i
];
4713 mode
= hw_mode_caps
->hw_mode_id
;
4714 pref
= soc
->wmi_ab
.preferred_hw_mode
;
4716 if (ath11k_hw_mode_pri_map
[mode
] < ath11k_hw_mode_pri_map
[pref
]) {
4717 svc_rdy_ext
->pref_hw_mode_caps
= *hw_mode_caps
;
4718 soc
->wmi_ab
.preferred_hw_mode
= mode
;
4723 ath11k_dbg(soc
, ATH11K_DBG_WMI
, "preferred_hw_mode:%d\n",
4724 soc
->wmi_ab
.preferred_hw_mode
);
4725 if (soc
->wmi_ab
.preferred_hw_mode
== WMI_HOST_HW_MODE_MAX
)
4731 static int ath11k_wmi_tlv_mac_phy_caps_parse(struct ath11k_base
*soc
,
4733 const void *ptr
, void *data
)
4735 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4737 if (tag
!= WMI_TAG_MAC_PHY_CAPABILITIES
)
4740 if (svc_rdy_ext
->n_mac_phy_caps
>= svc_rdy_ext
->tot_phy_id
)
4743 len
= min_t(u16
, len
, sizeof(struct wmi_mac_phy_capabilities
));
4744 if (!svc_rdy_ext
->n_mac_phy_caps
) {
4745 svc_rdy_ext
->mac_phy_caps
= kcalloc(svc_rdy_ext
->tot_phy_id
,
4747 if (!svc_rdy_ext
->mac_phy_caps
)
4751 memcpy(svc_rdy_ext
->mac_phy_caps
+ svc_rdy_ext
->n_mac_phy_caps
, ptr
, len
);
4752 svc_rdy_ext
->n_mac_phy_caps
++;
4756 static int ath11k_wmi_tlv_ext_hal_reg_caps_parse(struct ath11k_base
*soc
,
4758 const void *ptr
, void *data
)
4760 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4762 if (tag
!= WMI_TAG_HAL_REG_CAPABILITIES_EXT
)
4765 if (svc_rdy_ext
->n_ext_hal_reg_caps
>= svc_rdy_ext
->param
.num_phy
)
4768 svc_rdy_ext
->n_ext_hal_reg_caps
++;
4772 static int ath11k_wmi_tlv_ext_hal_reg_caps(struct ath11k_base
*soc
,
4773 u16 len
, const void *ptr
, void *data
)
4775 struct ath11k_pdev_wmi
*wmi_handle
= &soc
->wmi_ab
.wmi
[0];
4776 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4777 struct ath11k_hal_reg_capabilities_ext reg_cap
;
4781 svc_rdy_ext
->n_ext_hal_reg_caps
= 0;
4782 svc_rdy_ext
->ext_hal_reg_caps
= (struct wmi_hal_reg_capabilities_ext
*)ptr
;
4783 ret
= ath11k_wmi_tlv_iter(soc
, ptr
, len
,
4784 ath11k_wmi_tlv_ext_hal_reg_caps_parse
,
4787 ath11k_warn(soc
, "failed to parse tlv %d\n", ret
);
4791 for (i
= 0; i
< svc_rdy_ext
->param
.num_phy
; i
++) {
4792 ret
= ath11k_pull_reg_cap_svc_rdy_ext(wmi_handle
,
4793 svc_rdy_ext
->soc_hal_reg_caps
,
4794 svc_rdy_ext
->ext_hal_reg_caps
, i
,
4797 ath11k_warn(soc
, "failed to extract reg cap %d\n", i
);
4801 memcpy(&soc
->hal_reg_cap
[reg_cap
.phy_id
],
4802 ®_cap
, sizeof(reg_cap
));
4807 static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base
*soc
,
4808 u16 len
, const void *ptr
,
4811 struct ath11k_pdev_wmi
*wmi_handle
= &soc
->wmi_ab
.wmi
[0];
4812 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4813 u8 hw_mode_id
= svc_rdy_ext
->pref_hw_mode_caps
.hw_mode_id
;
4818 svc_rdy_ext
->soc_hal_reg_caps
= (struct wmi_soc_hal_reg_capabilities
*)ptr
;
4819 svc_rdy_ext
->param
.num_phy
= svc_rdy_ext
->soc_hal_reg_caps
->num_phy
;
4821 soc
->num_radios
= 0;
4822 soc
->target_pdev_count
= 0;
4823 phy_id_map
= svc_rdy_ext
->pref_hw_mode_caps
.phy_id_map
;
4825 while (phy_id_map
&& soc
->num_radios
< MAX_RADIOS
) {
4826 ret
= ath11k_pull_mac_phy_cap_svc_ready_ext(wmi_handle
,
4827 svc_rdy_ext
->hw_caps
,
4828 svc_rdy_ext
->hw_mode_caps
,
4829 svc_rdy_ext
->soc_hal_reg_caps
,
4830 svc_rdy_ext
->mac_phy_caps
,
4831 hw_mode_id
, soc
->num_radios
,
4832 &soc
->pdevs
[pdev_index
]);
4834 ath11k_warn(soc
, "failed to extract mac caps, idx :%d\n",
4841 /* For QCA6390, save mac_phy capability in the same pdev */
4842 if (soc
->hw_params
.single_pdev_only
)
4845 pdev_index
= soc
->num_radios
;
4847 /* TODO: mac_phy_cap prints */
4851 /* For QCA6390, set num_radios to 1 because host manages
4852 * both 2G and 5G radio in one pdev.
4853 * Set pdev_id = 0 and 0 means soc level.
4855 if (soc
->hw_params
.single_pdev_only
) {
4856 soc
->num_radios
= 1;
4857 soc
->pdevs
[0].pdev_id
= 0;
4860 if (!soc
->reg_info_store
) {
4861 soc
->reg_info_store
= kcalloc(soc
->num_radios
,
4862 sizeof(*soc
->reg_info_store
),
4864 if (!soc
->reg_info_store
)
4871 static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base
*soc
,
4873 const void *ptr
, void *data
)
4875 struct wmi_tlv_dma_ring_caps_parse
*parse
= data
;
4877 if (tag
!= WMI_TAG_DMA_RING_CAPABILITIES
)
4880 parse
->n_dma_ring_caps
++;
4884 static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base
*ab
,
4890 sz
= num_cap
* sizeof(struct ath11k_dbring_cap
);
4891 ptr
= kzalloc(sz
, GFP_ATOMIC
);
4896 ab
->num_db_cap
= num_cap
;
4901 static void ath11k_wmi_free_dbring_caps(struct ath11k_base
*ab
)
4908 static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base
*ab
,
4909 u16 len
, const void *ptr
, void *data
)
4911 struct wmi_tlv_dma_ring_caps_parse
*dma_caps_parse
= data
;
4912 struct wmi_dma_ring_capabilities
*dma_caps
;
4913 struct ath11k_dbring_cap
*dir_buff_caps
;
4917 dma_caps_parse
->n_dma_ring_caps
= 0;
4918 dma_caps
= (struct wmi_dma_ring_capabilities
*)ptr
;
4919 ret
= ath11k_wmi_tlv_iter(ab
, ptr
, len
,
4920 ath11k_wmi_tlv_dma_ring_caps_parse
,
4923 ath11k_warn(ab
, "failed to parse dma ring caps tlv %d\n", ret
);
4927 if (!dma_caps_parse
->n_dma_ring_caps
)
4930 if (ab
->num_db_cap
) {
4931 ath11k_warn(ab
, "Already processed, so ignoring dma ring caps\n");
4935 ret
= ath11k_wmi_alloc_dbring_caps(ab
, dma_caps_parse
->n_dma_ring_caps
);
4939 dir_buff_caps
= ab
->db_caps
;
4940 for (i
= 0; i
< dma_caps_parse
->n_dma_ring_caps
; i
++) {
4941 if (dma_caps
[i
].module_id
>= WMI_DIRECT_BUF_MAX
) {
4942 ath11k_warn(ab
, "Invalid module id %d\n", dma_caps
[i
].module_id
);
4947 dir_buff_caps
[i
].id
= dma_caps
[i
].module_id
;
4948 dir_buff_caps
[i
].pdev_id
= DP_HW2SW_MACID(dma_caps
[i
].pdev_id
);
4949 dir_buff_caps
[i
].min_elem
= dma_caps
[i
].min_elem
;
4950 dir_buff_caps
[i
].min_buf_sz
= dma_caps
[i
].min_buf_sz
;
4951 dir_buff_caps
[i
].min_buf_align
= dma_caps
[i
].min_buf_align
;
4957 ath11k_wmi_free_dbring_caps(ab
);
4961 static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base
*ab
,
4963 const void *ptr
, void *data
)
4965 struct ath11k_pdev_wmi
*wmi_handle
= &ab
->wmi_ab
.wmi
[0];
4966 struct wmi_tlv_svc_rdy_ext_parse
*svc_rdy_ext
= data
;
4970 case WMI_TAG_SERVICE_READY_EXT_EVENT
:
4971 ret
= ath11k_pull_svc_ready_ext(wmi_handle
, ptr
,
4972 &svc_rdy_ext
->param
);
4974 ath11k_warn(ab
, "unable to extract ext params\n");
4979 case WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS
:
4980 svc_rdy_ext
->hw_caps
= (struct wmi_soc_mac_phy_hw_mode_caps
*)ptr
;
4981 svc_rdy_ext
->param
.num_hw_modes
= svc_rdy_ext
->hw_caps
->num_hw_modes
;
4984 case WMI_TAG_SOC_HAL_REG_CAPABILITIES
:
4985 ret
= ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(ab
, len
, ptr
,
4991 case WMI_TAG_ARRAY_STRUCT
:
4992 if (!svc_rdy_ext
->hw_mode_done
) {
4993 ret
= ath11k_wmi_tlv_hw_mode_caps(ab
, len
, ptr
,
4998 svc_rdy_ext
->hw_mode_done
= true;
4999 } else if (!svc_rdy_ext
->mac_phy_done
) {
5000 svc_rdy_ext
->n_mac_phy_caps
= 0;
5001 ret
= ath11k_wmi_tlv_iter(ab
, ptr
, len
,
5002 ath11k_wmi_tlv_mac_phy_caps_parse
,
5005 ath11k_warn(ab
, "failed to parse tlv %d\n", ret
);
5009 svc_rdy_ext
->mac_phy_done
= true;
5010 } else if (!svc_rdy_ext
->ext_hal_reg_done
) {
5011 ret
= ath11k_wmi_tlv_ext_hal_reg_caps(ab
, len
, ptr
,
5016 svc_rdy_ext
->ext_hal_reg_done
= true;
5017 } else if (!svc_rdy_ext
->mac_phy_chainmask_combo_done
) {
5018 svc_rdy_ext
->mac_phy_chainmask_combo_done
= true;
5019 } else if (!svc_rdy_ext
->mac_phy_chainmask_cap_done
) {
5020 svc_rdy_ext
->mac_phy_chainmask_cap_done
= true;
5021 } else if (!svc_rdy_ext
->oem_dma_ring_cap_done
) {
5022 svc_rdy_ext
->oem_dma_ring_cap_done
= true;
5023 } else if (!svc_rdy_ext
->dma_ring_cap_done
) {
5024 ret
= ath11k_wmi_tlv_dma_ring_caps(ab
, len
, ptr
,
5025 &svc_rdy_ext
->dma_caps_parse
);
5029 svc_rdy_ext
->dma_ring_cap_done
= true;
5039 static int ath11k_service_ready_ext_event(struct ath11k_base
*ab
,
5040 struct sk_buff
*skb
)
5042 struct wmi_tlv_svc_rdy_ext_parse svc_rdy_ext
= { };
5045 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
5046 ath11k_wmi_tlv_svc_rdy_ext_parse
,
5049 ath11k_warn(ab
, "failed to parse tlv %d\n", ret
);
5053 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event service ready ext");
5055 if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG
, ab
->wmi_ab
.svc_map
))
5056 complete(&ab
->wmi_ab
.service_ready
);
5058 kfree(svc_rdy_ext
.mac_phy_caps
);
5062 ath11k_wmi_free_dbring_caps(ab
);
5066 static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base
*ab
,
5068 const void *ptr
, void *data
)
5070 struct wmi_tlv_svc_rdy_ext2_parse
*parse
= data
;
5074 case WMI_TAG_ARRAY_STRUCT
:
5075 if (!parse
->dma_ring_cap_done
) {
5076 ret
= ath11k_wmi_tlv_dma_ring_caps(ab
, len
, ptr
,
5077 &parse
->dma_caps_parse
);
5081 parse
->dma_ring_cap_done
= true;
5091 static int ath11k_service_ready_ext2_event(struct ath11k_base
*ab
,
5092 struct sk_buff
*skb
)
5094 struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2
= { };
5097 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
5098 ath11k_wmi_tlv_svc_rdy_ext2_parse
,
5101 ath11k_warn(ab
, "failed to parse ext2 event tlv %d\n", ret
);
5105 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event service ready ext2");
5107 complete(&ab
->wmi_ab
.service_ready
);
5112 ath11k_wmi_free_dbring_caps(ab
);
5116 static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base
*ab
, struct sk_buff
*skb
,
5117 struct wmi_vdev_start_resp_event
*vdev_rsp
)
5120 const struct wmi_vdev_start_resp_event
*ev
;
5123 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5126 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5130 ev
= tb
[WMI_TAG_VDEV_START_RESPONSE_EVENT
];
5132 ath11k_warn(ab
, "failed to fetch vdev start resp ev");
5137 memset(vdev_rsp
, 0, sizeof(*vdev_rsp
));
5139 vdev_rsp
->vdev_id
= ev
->vdev_id
;
5140 vdev_rsp
->requestor_id
= ev
->requestor_id
;
5141 vdev_rsp
->resp_type
= ev
->resp_type
;
5142 vdev_rsp
->status
= ev
->status
;
5143 vdev_rsp
->chain_mask
= ev
->chain_mask
;
5144 vdev_rsp
->smps_mode
= ev
->smps_mode
;
5145 vdev_rsp
->mac_id
= ev
->mac_id
;
5146 vdev_rsp
->cfgd_tx_streams
= ev
->cfgd_tx_streams
;
5147 vdev_rsp
->cfgd_rx_streams
= ev
->cfgd_rx_streams
;
5148 vdev_rsp
->max_allowed_tx_power
= ev
->max_allowed_tx_power
;
5154 static void ath11k_print_reg_rule(struct ath11k_base
*ab
, const char *band
,
5156 struct cur_reg_rule
*reg_rule_ptr
)
5158 struct cur_reg_rule
*reg_rule
= reg_rule_ptr
;
5161 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "number of reg rules in %s band: %d\n",
5162 band
, num_reg_rules
);
5164 for (count
= 0; count
< num_reg_rules
; count
++) {
5165 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5166 "reg rule %d: (%d - %d @ %d) (%d, %d) (FLAGS %d)\n",
5167 count
+ 1, reg_rule
->start_freq
, reg_rule
->end_freq
,
5168 reg_rule
->max_bw
, reg_rule
->ant_gain
,
5169 reg_rule
->reg_power
, reg_rule
->flags
);
5174 static struct cur_reg_rule
5175 *create_reg_rules_from_wmi(u32 num_reg_rules
,
5176 struct wmi_regulatory_rule_struct
*wmi_reg_rule
)
5178 struct cur_reg_rule
*reg_rule_ptr
;
5181 reg_rule_ptr
= kcalloc(num_reg_rules
, sizeof(*reg_rule_ptr
),
5187 for (count
= 0; count
< num_reg_rules
; count
++) {
5188 reg_rule_ptr
[count
].start_freq
=
5189 FIELD_GET(REG_RULE_START_FREQ
,
5190 wmi_reg_rule
[count
].freq_info
);
5191 reg_rule_ptr
[count
].end_freq
=
5192 FIELD_GET(REG_RULE_END_FREQ
,
5193 wmi_reg_rule
[count
].freq_info
);
5194 reg_rule_ptr
[count
].max_bw
=
5195 FIELD_GET(REG_RULE_MAX_BW
,
5196 wmi_reg_rule
[count
].bw_pwr_info
);
5197 reg_rule_ptr
[count
].reg_power
=
5198 FIELD_GET(REG_RULE_REG_PWR
,
5199 wmi_reg_rule
[count
].bw_pwr_info
);
5200 reg_rule_ptr
[count
].ant_gain
=
5201 FIELD_GET(REG_RULE_ANT_GAIN
,
5202 wmi_reg_rule
[count
].bw_pwr_info
);
5203 reg_rule_ptr
[count
].flags
=
5204 FIELD_GET(REG_RULE_FLAGS
,
5205 wmi_reg_rule
[count
].flag_info
);
5208 return reg_rule_ptr
;
5211 static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base
*ab
,
5212 struct sk_buff
*skb
,
5213 struct cur_regulatory_info
*reg_info
)
5216 const struct wmi_reg_chan_list_cc_event
*chan_list_event_hdr
;
5217 struct wmi_regulatory_rule_struct
*wmi_reg_rule
;
5218 u32 num_2ghz_reg_rules
, num_5ghz_reg_rules
;
5221 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "processing regulatory channel list\n");
5223 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5226 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5230 chan_list_event_hdr
= tb
[WMI_TAG_REG_CHAN_LIST_CC_EVENT
];
5231 if (!chan_list_event_hdr
) {
5232 ath11k_warn(ab
, "failed to fetch reg chan list update ev\n");
5237 reg_info
->num_2ghz_reg_rules
= chan_list_event_hdr
->num_2ghz_reg_rules
;
5238 reg_info
->num_5ghz_reg_rules
= chan_list_event_hdr
->num_5ghz_reg_rules
;
5240 if (!(reg_info
->num_2ghz_reg_rules
+ reg_info
->num_5ghz_reg_rules
)) {
5241 ath11k_warn(ab
, "No regulatory rules available in the event info\n");
5246 memcpy(reg_info
->alpha2
, &chan_list_event_hdr
->alpha2
,
5248 reg_info
->dfs_region
= chan_list_event_hdr
->dfs_region
;
5249 reg_info
->phybitmap
= chan_list_event_hdr
->phybitmap
;
5250 reg_info
->num_phy
= chan_list_event_hdr
->num_phy
;
5251 reg_info
->phy_id
= chan_list_event_hdr
->phy_id
;
5252 reg_info
->ctry_code
= chan_list_event_hdr
->country_id
;
5253 reg_info
->reg_dmn_pair
= chan_list_event_hdr
->domain_code
;
5255 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5257 ath11k_cc_status_to_str(reg_info
->status_code
));
5259 reg_info
->status_code
=
5260 ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr
->status_code
);
5262 reg_info
->is_ext_reg_event
= false;
5264 reg_info
->min_bw_2ghz
= chan_list_event_hdr
->min_bw_2ghz
;
5265 reg_info
->max_bw_2ghz
= chan_list_event_hdr
->max_bw_2ghz
;
5266 reg_info
->min_bw_5ghz
= chan_list_event_hdr
->min_bw_5ghz
;
5267 reg_info
->max_bw_5ghz
= chan_list_event_hdr
->max_bw_5ghz
;
5269 num_2ghz_reg_rules
= reg_info
->num_2ghz_reg_rules
;
5270 num_5ghz_reg_rules
= reg_info
->num_5ghz_reg_rules
;
5272 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5273 "cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d",
5274 reg_info
->alpha2
, reg_info
->dfs_region
,
5275 reg_info
->min_bw_2ghz
, reg_info
->max_bw_2ghz
,
5276 reg_info
->min_bw_5ghz
, reg_info
->max_bw_5ghz
);
5278 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5279 "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
5280 num_2ghz_reg_rules
, num_5ghz_reg_rules
);
5283 (struct wmi_regulatory_rule_struct
*)((u8
*)chan_list_event_hdr
5284 + sizeof(*chan_list_event_hdr
)
5285 + sizeof(struct wmi_tlv
));
5287 if (num_2ghz_reg_rules
) {
5288 reg_info
->reg_rules_2ghz_ptr
=
5289 create_reg_rules_from_wmi(num_2ghz_reg_rules
,
5291 if (!reg_info
->reg_rules_2ghz_ptr
) {
5293 ath11k_warn(ab
, "Unable to Allocate memory for 2 GHz rules\n");
5297 ath11k_print_reg_rule(ab
, "2 GHz",
5299 reg_info
->reg_rules_2ghz_ptr
);
5302 if (num_5ghz_reg_rules
) {
5303 wmi_reg_rule
+= num_2ghz_reg_rules
;
5304 reg_info
->reg_rules_5ghz_ptr
=
5305 create_reg_rules_from_wmi(num_5ghz_reg_rules
,
5307 if (!reg_info
->reg_rules_5ghz_ptr
) {
5309 ath11k_warn(ab
, "Unable to Allocate memory for 5 GHz rules\n");
5313 ath11k_print_reg_rule(ab
, "5 GHz",
5315 reg_info
->reg_rules_5ghz_ptr
);
5318 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "processed regulatory channel list\n");
5324 static struct cur_reg_rule
5325 *create_ext_reg_rules_from_wmi(u32 num_reg_rules
,
5326 struct wmi_regulatory_ext_rule
*wmi_reg_rule
)
5328 struct cur_reg_rule
*reg_rule_ptr
;
5331 reg_rule_ptr
= kcalloc(num_reg_rules
, sizeof(*reg_rule_ptr
), GFP_ATOMIC
);
5336 for (count
= 0; count
< num_reg_rules
; count
++) {
5337 reg_rule_ptr
[count
].start_freq
=
5338 u32_get_bits(wmi_reg_rule
[count
].freq_info
,
5339 REG_RULE_START_FREQ
);
5340 reg_rule_ptr
[count
].end_freq
=
5341 u32_get_bits(wmi_reg_rule
[count
].freq_info
,
5343 reg_rule_ptr
[count
].max_bw
=
5344 u32_get_bits(wmi_reg_rule
[count
].bw_pwr_info
,
5346 reg_rule_ptr
[count
].reg_power
=
5347 u32_get_bits(wmi_reg_rule
[count
].bw_pwr_info
,
5349 reg_rule_ptr
[count
].ant_gain
=
5350 u32_get_bits(wmi_reg_rule
[count
].bw_pwr_info
,
5352 reg_rule_ptr
[count
].flags
=
5353 u32_get_bits(wmi_reg_rule
[count
].flag_info
,
5355 reg_rule_ptr
[count
].psd_flag
=
5356 u32_get_bits(wmi_reg_rule
[count
].psd_power_info
,
5358 reg_rule_ptr
[count
].psd_eirp
=
5359 u32_get_bits(wmi_reg_rule
[count
].psd_power_info
,
5363 return reg_rule_ptr
;
5367 ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules
,
5368 const struct wmi_regulatory_ext_rule
*rule
)
5370 u8 num_invalid_5ghz_rules
= 0;
5371 u32 count
, start_freq
;
5373 for (count
= 0; count
< num_reg_rules
; count
++) {
5374 start_freq
= u32_get_bits(rule
[count
].freq_info
,
5375 REG_RULE_START_FREQ
);
5377 if (start_freq
>= ATH11K_MIN_6G_FREQ
)
5378 num_invalid_5ghz_rules
++;
5381 return num_invalid_5ghz_rules
;
5384 static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base
*ab
,
5385 struct sk_buff
*skb
,
5386 struct cur_regulatory_info
*reg_info
)
5389 const struct wmi_reg_chan_list_cc_ext_event
*ev
;
5390 struct wmi_regulatory_ext_rule
*ext_wmi_reg_rule
;
5391 u32 num_2ghz_reg_rules
, num_5ghz_reg_rules
;
5392 u32 num_6ghz_reg_rules_ap
[WMI_REG_CURRENT_MAX_AP_TYPE
];
5393 u32 num_6ghz_client
[WMI_REG_CURRENT_MAX_AP_TYPE
][WMI_REG_MAX_CLIENT_TYPE
];
5394 u32 total_reg_rules
= 0;
5395 int ret
, i
, j
, num_invalid_5ghz_ext_rules
= 0;
5397 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "processing regulatory ext channel list\n");
5399 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5402 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5406 ev
= tb
[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT
];
5408 ath11k_warn(ab
, "failed to fetch reg chan list ext update ev\n");
5413 reg_info
->num_2ghz_reg_rules
= ev
->num_2ghz_reg_rules
;
5414 reg_info
->num_5ghz_reg_rules
= ev
->num_5ghz_reg_rules
;
5415 reg_info
->num_6ghz_rules_ap
[WMI_REG_INDOOR_AP
] =
5416 ev
->num_6ghz_reg_rules_ap_lpi
;
5417 reg_info
->num_6ghz_rules_ap
[WMI_REG_STANDARD_POWER_AP
] =
5418 ev
->num_6ghz_reg_rules_ap_sp
;
5419 reg_info
->num_6ghz_rules_ap
[WMI_REG_VERY_LOW_POWER_AP
] =
5420 ev
->num_6ghz_reg_rules_ap_vlp
;
5422 for (i
= 0; i
< WMI_REG_MAX_CLIENT_TYPE
; i
++) {
5423 reg_info
->num_6ghz_rules_client
[WMI_REG_INDOOR_AP
][i
] =
5424 ev
->num_6ghz_reg_rules_client_lpi
[i
];
5425 reg_info
->num_6ghz_rules_client
[WMI_REG_STANDARD_POWER_AP
][i
] =
5426 ev
->num_6ghz_reg_rules_client_sp
[i
];
5427 reg_info
->num_6ghz_rules_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] =
5428 ev
->num_6ghz_reg_rules_client_vlp
[i
];
5431 num_2ghz_reg_rules
= reg_info
->num_2ghz_reg_rules
;
5432 num_5ghz_reg_rules
= reg_info
->num_5ghz_reg_rules
;
5434 total_reg_rules
+= num_2ghz_reg_rules
;
5435 total_reg_rules
+= num_5ghz_reg_rules
;
5437 if ((num_2ghz_reg_rules
> MAX_REG_RULES
) ||
5438 (num_5ghz_reg_rules
> MAX_REG_RULES
)) {
5439 ath11k_warn(ab
, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n",
5440 num_2ghz_reg_rules
, num_5ghz_reg_rules
, MAX_REG_RULES
);
5445 for (i
= 0; i
< WMI_REG_CURRENT_MAX_AP_TYPE
; i
++) {
5446 num_6ghz_reg_rules_ap
[i
] = reg_info
->num_6ghz_rules_ap
[i
];
5448 if (num_6ghz_reg_rules_ap
[i
] > MAX_6GHZ_REG_RULES
) {
5449 ath11k_warn(ab
, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n",
5450 i
, num_6ghz_reg_rules_ap
[i
], MAX_6GHZ_REG_RULES
);
5455 total_reg_rules
+= num_6ghz_reg_rules_ap
[i
];
5458 for (i
= 0; i
< WMI_REG_MAX_CLIENT_TYPE
; i
++) {
5459 num_6ghz_client
[WMI_REG_INDOOR_AP
][i
] =
5460 reg_info
->num_6ghz_rules_client
[WMI_REG_INDOOR_AP
][i
];
5461 total_reg_rules
+= num_6ghz_client
[WMI_REG_INDOOR_AP
][i
];
5463 num_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
] =
5464 reg_info
->num_6ghz_rules_client
[WMI_REG_STANDARD_POWER_AP
][i
];
5465 total_reg_rules
+= num_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
];
5467 num_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] =
5468 reg_info
->num_6ghz_rules_client
[WMI_REG_VERY_LOW_POWER_AP
][i
];
5469 total_reg_rules
+= num_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
];
5471 if ((num_6ghz_client
[WMI_REG_INDOOR_AP
][i
] > MAX_6GHZ_REG_RULES
) ||
5472 (num_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
] >
5473 MAX_6GHZ_REG_RULES
) ||
5474 (num_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] >
5475 MAX_6GHZ_REG_RULES
)) {
5477 "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n",
5484 if (!total_reg_rules
) {
5485 ath11k_warn(ab
, "No reg rules available\n");
5490 memcpy(reg_info
->alpha2
, &ev
->alpha2
, REG_ALPHA2_LEN
);
5492 reg_info
->dfs_region
= ev
->dfs_region
;
5493 reg_info
->phybitmap
= ev
->phybitmap
;
5494 reg_info
->num_phy
= ev
->num_phy
;
5495 reg_info
->phy_id
= ev
->phy_id
;
5496 reg_info
->ctry_code
= ev
->country_id
;
5497 reg_info
->reg_dmn_pair
= ev
->domain_code
;
5499 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5501 ath11k_cc_status_to_str(reg_info
->status_code
));
5503 reg_info
->status_code
=
5504 ath11k_wmi_cc_setting_code_to_reg(ev
->status_code
);
5506 reg_info
->is_ext_reg_event
= true;
5508 reg_info
->min_bw_2ghz
= ev
->min_bw_2ghz
;
5509 reg_info
->max_bw_2ghz
= ev
->max_bw_2ghz
;
5510 reg_info
->min_bw_5ghz
= ev
->min_bw_5ghz
;
5511 reg_info
->max_bw_5ghz
= ev
->max_bw_5ghz
;
5513 reg_info
->min_bw_6ghz_ap
[WMI_REG_INDOOR_AP
] =
5514 ev
->min_bw_6ghz_ap_lpi
;
5515 reg_info
->max_bw_6ghz_ap
[WMI_REG_INDOOR_AP
] =
5516 ev
->max_bw_6ghz_ap_lpi
;
5517 reg_info
->min_bw_6ghz_ap
[WMI_REG_STANDARD_POWER_AP
] =
5518 ev
->min_bw_6ghz_ap_sp
;
5519 reg_info
->max_bw_6ghz_ap
[WMI_REG_STANDARD_POWER_AP
] =
5520 ev
->max_bw_6ghz_ap_sp
;
5521 reg_info
->min_bw_6ghz_ap
[WMI_REG_VERY_LOW_POWER_AP
] =
5522 ev
->min_bw_6ghz_ap_vlp
;
5523 reg_info
->max_bw_6ghz_ap
[WMI_REG_VERY_LOW_POWER_AP
] =
5524 ev
->max_bw_6ghz_ap_vlp
;
5526 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5527 "6 GHz AP BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n",
5528 reg_info
->min_bw_6ghz_ap
[WMI_REG_INDOOR_AP
],
5529 reg_info
->max_bw_6ghz_ap
[WMI_REG_INDOOR_AP
],
5530 reg_info
->min_bw_6ghz_ap
[WMI_REG_STANDARD_POWER_AP
],
5531 reg_info
->max_bw_6ghz_ap
[WMI_REG_STANDARD_POWER_AP
],
5532 reg_info
->min_bw_6ghz_ap
[WMI_REG_VERY_LOW_POWER_AP
],
5533 reg_info
->max_bw_6ghz_ap
[WMI_REG_VERY_LOW_POWER_AP
]);
5535 for (i
= 0; i
< WMI_REG_MAX_CLIENT_TYPE
; i
++) {
5536 reg_info
->min_bw_6ghz_client
[WMI_REG_INDOOR_AP
][i
] =
5537 ev
->min_bw_6ghz_client_lpi
[i
];
5538 reg_info
->max_bw_6ghz_client
[WMI_REG_INDOOR_AP
][i
] =
5539 ev
->max_bw_6ghz_client_lpi
[i
];
5540 reg_info
->min_bw_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
] =
5541 ev
->min_bw_6ghz_client_sp
[i
];
5542 reg_info
->max_bw_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
] =
5543 ev
->max_bw_6ghz_client_sp
[i
];
5544 reg_info
->min_bw_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] =
5545 ev
->min_bw_6ghz_client_vlp
[i
];
5546 reg_info
->max_bw_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] =
5547 ev
->max_bw_6ghz_client_vlp
[i
];
5549 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5550 "6 GHz %s BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n",
5551 ath11k_6ghz_client_type_to_str(i
),
5552 reg_info
->min_bw_6ghz_client
[WMI_REG_INDOOR_AP
][i
],
5553 reg_info
->max_bw_6ghz_client
[WMI_REG_INDOOR_AP
][i
],
5554 reg_info
->min_bw_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
],
5555 reg_info
->max_bw_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
],
5556 reg_info
->min_bw_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
],
5557 reg_info
->max_bw_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
]);
5560 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5561 "cc_ext %s dfs %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d phy_bitmap 0x%x",
5562 reg_info
->alpha2
, reg_info
->dfs_region
,
5563 reg_info
->min_bw_2ghz
, reg_info
->max_bw_2ghz
,
5564 reg_info
->min_bw_5ghz
, reg_info
->max_bw_5ghz
,
5565 reg_info
->phybitmap
);
5567 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5568 "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
5569 num_2ghz_reg_rules
, num_5ghz_reg_rules
);
5571 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5572 "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d",
5573 num_6ghz_reg_rules_ap
[WMI_REG_INDOOR_AP
],
5574 num_6ghz_reg_rules_ap
[WMI_REG_STANDARD_POWER_AP
],
5575 num_6ghz_reg_rules_ap
[WMI_REG_VERY_LOW_POWER_AP
]);
5577 j
= WMI_REG_DEFAULT_CLIENT
;
5578 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5579 "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
5580 num_6ghz_client
[WMI_REG_INDOOR_AP
][j
],
5581 num_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][j
],
5582 num_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][j
]);
5584 j
= WMI_REG_SUBORDINATE_CLIENT
;
5585 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5586 "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
5587 num_6ghz_client
[WMI_REG_INDOOR_AP
][j
],
5588 num_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][j
],
5589 num_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][j
]);
5592 (struct wmi_regulatory_ext_rule
*)((u8
*)ev
+ sizeof(*ev
) +
5593 sizeof(struct wmi_tlv
));
5594 if (num_2ghz_reg_rules
) {
5595 reg_info
->reg_rules_2ghz_ptr
=
5596 create_ext_reg_rules_from_wmi(num_2ghz_reg_rules
,
5599 if (!reg_info
->reg_rules_2ghz_ptr
) {
5601 ath11k_warn(ab
, "Unable to Allocate memory for 2 GHz rules\n");
5605 ath11k_print_reg_rule(ab
, "2 GHz",
5607 reg_info
->reg_rules_2ghz_ptr
);
5610 ext_wmi_reg_rule
+= num_2ghz_reg_rules
;
5612 /* Firmware might include 6 GHz reg rule in 5 GHz rule list
5613 * for few countries along with separate 6 GHz rule.
5614 * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list
5615 * causes intersect check to be true, and same rules will be
5616 * shown multiple times in iw cmd.
5617 * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list
5619 num_invalid_5ghz_ext_rules
=
5620 ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules
,
5623 if (num_invalid_5ghz_ext_rules
) {
5624 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5625 "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules",
5626 reg_info
->alpha2
, reg_info
->num_5ghz_reg_rules
,
5627 num_invalid_5ghz_ext_rules
);
5629 num_5ghz_reg_rules
= num_5ghz_reg_rules
- num_invalid_5ghz_ext_rules
;
5630 reg_info
->num_5ghz_reg_rules
= num_5ghz_reg_rules
;
5633 if (num_5ghz_reg_rules
) {
5634 reg_info
->reg_rules_5ghz_ptr
=
5635 create_ext_reg_rules_from_wmi(num_5ghz_reg_rules
,
5638 if (!reg_info
->reg_rules_5ghz_ptr
) {
5640 ath11k_warn(ab
, "Unable to Allocate memory for 5 GHz rules\n");
5644 ath11k_print_reg_rule(ab
, "5 GHz",
5646 reg_info
->reg_rules_5ghz_ptr
);
5649 /* We have adjusted the number of 5 GHz reg rules above. But still those
5650 * many rules needs to be adjusted in ext_wmi_reg_rule.
5652 * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases.
5654 ext_wmi_reg_rule
+= (num_5ghz_reg_rules
+ num_invalid_5ghz_ext_rules
);
5656 for (i
= 0; i
< WMI_REG_CURRENT_MAX_AP_TYPE
; i
++) {
5657 reg_info
->reg_rules_6ghz_ap_ptr
[i
] =
5658 create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap
[i
],
5661 if (!reg_info
->reg_rules_6ghz_ap_ptr
[i
]) {
5663 ath11k_warn(ab
, "Unable to Allocate memory for 6 GHz AP rules\n");
5667 ath11k_print_reg_rule(ab
, ath11k_6ghz_ap_type_to_str(i
),
5668 num_6ghz_reg_rules_ap
[i
],
5669 reg_info
->reg_rules_6ghz_ap_ptr
[i
]);
5671 ext_wmi_reg_rule
+= num_6ghz_reg_rules_ap
[i
];
5674 for (j
= 0; j
< WMI_REG_CURRENT_MAX_AP_TYPE
; j
++) {
5675 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5676 "6 GHz AP type %s", ath11k_6ghz_ap_type_to_str(j
));
5678 for (i
= 0; i
< WMI_REG_MAX_CLIENT_TYPE
; i
++) {
5679 reg_info
->reg_rules_6ghz_client_ptr
[j
][i
] =
5680 create_ext_reg_rules_from_wmi(num_6ghz_client
[j
][i
],
5683 if (!reg_info
->reg_rules_6ghz_client_ptr
[j
][i
]) {
5685 ath11k_warn(ab
, "Unable to Allocate memory for 6 GHz client rules\n");
5689 ath11k_print_reg_rule(ab
,
5690 ath11k_6ghz_client_type_to_str(i
),
5691 num_6ghz_client
[j
][i
],
5692 reg_info
->reg_rules_6ghz_client_ptr
[j
][i
]);
5694 ext_wmi_reg_rule
+= num_6ghz_client
[j
][i
];
5698 reg_info
->client_type
= ev
->client_type
;
5699 reg_info
->rnr_tpe_usable
= ev
->rnr_tpe_usable
;
5700 reg_info
->unspecified_ap_usable
=
5701 ev
->unspecified_ap_usable
;
5702 reg_info
->domain_code_6ghz_ap
[WMI_REG_INDOOR_AP
] =
5703 ev
->domain_code_6ghz_ap_lpi
;
5704 reg_info
->domain_code_6ghz_ap
[WMI_REG_STANDARD_POWER_AP
] =
5705 ev
->domain_code_6ghz_ap_sp
;
5706 reg_info
->domain_code_6ghz_ap
[WMI_REG_VERY_LOW_POWER_AP
] =
5707 ev
->domain_code_6ghz_ap_vlp
;
5709 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5710 "6 GHz reg info client type %s rnr_tpe_usable %d unspecified_ap_usable %d AP sub domain: lpi %s, sp %s, vlp %s\n",
5711 ath11k_6ghz_client_type_to_str(reg_info
->client_type
),
5712 reg_info
->rnr_tpe_usable
,
5713 reg_info
->unspecified_ap_usable
,
5714 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_ap_lpi
),
5715 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_ap_sp
),
5716 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_ap_vlp
));
5718 for (i
= 0; i
< WMI_REG_MAX_CLIENT_TYPE
; i
++) {
5719 reg_info
->domain_code_6ghz_client
[WMI_REG_INDOOR_AP
][i
] =
5720 ev
->domain_code_6ghz_client_lpi
[i
];
5721 reg_info
->domain_code_6ghz_client
[WMI_REG_STANDARD_POWER_AP
][i
] =
5722 ev
->domain_code_6ghz_client_sp
[i
];
5723 reg_info
->domain_code_6ghz_client
[WMI_REG_VERY_LOW_POWER_AP
][i
] =
5724 ev
->domain_code_6ghz_client_vlp
[i
];
5726 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5727 "6 GHz client type %s client sub domain: lpi %s, sp %s, vlp %s\n",
5728 ath11k_6ghz_client_type_to_str(i
),
5729 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_client_lpi
[i
]),
5730 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_client_sp
[i
]),
5731 ath11k_sub_reg_6ghz_to_str(ev
->domain_code_6ghz_client_vlp
[i
])
5735 reg_info
->domain_code_6ghz_super_id
= ev
->domain_code_6ghz_super_id
;
5737 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
5738 "6 GHz client_type %s 6 GHz super domain %s",
5739 ath11k_6ghz_client_type_to_str(reg_info
->client_type
),
5740 ath11k_super_reg_6ghz_to_str(reg_info
->domain_code_6ghz_super_id
));
5742 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "processed regulatory ext channel list\n");
5748 static int ath11k_pull_peer_del_resp_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
5749 struct wmi_peer_delete_resp_event
*peer_del_resp
)
5752 const struct wmi_peer_delete_resp_event
*ev
;
5755 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5758 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5762 ev
= tb
[WMI_TAG_PEER_DELETE_RESP_EVENT
];
5764 ath11k_warn(ab
, "failed to fetch peer delete resp ev");
5769 memset(peer_del_resp
, 0, sizeof(*peer_del_resp
));
5771 peer_del_resp
->vdev_id
= ev
->vdev_id
;
5772 ether_addr_copy(peer_del_resp
->peer_macaddr
.addr
,
5773 ev
->peer_macaddr
.addr
);
5779 static int ath11k_pull_vdev_del_resp_ev(struct ath11k_base
*ab
,
5780 struct sk_buff
*skb
,
5784 const struct wmi_vdev_delete_resp_event
*ev
;
5787 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5790 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5794 ev
= tb
[WMI_TAG_VDEV_DELETE_RESP_EVENT
];
5796 ath11k_warn(ab
, "failed to fetch vdev delete resp ev");
5801 *vdev_id
= ev
->vdev_id
;
5807 static int ath11k_pull_bcn_tx_status_ev(struct ath11k_base
*ab
,
5808 struct sk_buff
*skb
,
5809 u32
*vdev_id
, u32
*tx_status
)
5812 const struct wmi_bcn_tx_status_event
*ev
;
5815 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5818 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5822 ev
= tb
[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT
];
5824 ath11k_warn(ab
, "failed to fetch bcn tx status ev");
5829 *vdev_id
= ev
->vdev_id
;
5830 *tx_status
= ev
->tx_status
;
5836 static int ath11k_pull_vdev_stopped_param_tlv(struct ath11k_base
*ab
, struct sk_buff
*skb
,
5840 const struct wmi_vdev_stopped_event
*ev
;
5843 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
5846 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
5850 ev
= tb
[WMI_TAG_VDEV_STOPPED_EVENT
];
5852 ath11k_warn(ab
, "failed to fetch vdev stop ev");
5857 *vdev_id
= ev
->vdev_id
;
5863 static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base
*ab
,
5865 const void *ptr
, void *data
)
5867 struct wmi_tlv_mgmt_rx_parse
*parse
= data
;
5870 case WMI_TAG_MGMT_RX_HDR
:
5873 case WMI_TAG_ARRAY_BYTE
:
5874 if (!parse
->frame_buf_done
) {
5875 parse
->frame_buf
= ptr
;
5876 parse
->frame_buf_done
= true;
5883 static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base
*ab
,
5884 struct sk_buff
*skb
,
5885 struct mgmt_rx_event_params
*hdr
)
5887 struct wmi_tlv_mgmt_rx_parse parse
= { };
5888 const struct wmi_mgmt_rx_hdr
*ev
;
5892 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
5893 ath11k_wmi_tlv_mgmt_rx_parse
,
5896 ath11k_warn(ab
, "failed to parse mgmt rx tlv %d\n",
5902 frame
= parse
.frame_buf
;
5904 if (!ev
|| !frame
) {
5905 ath11k_warn(ab
, "failed to fetch mgmt rx hdr");
5909 hdr
->pdev_id
= ev
->pdev_id
;
5910 hdr
->chan_freq
= ev
->chan_freq
;
5911 hdr
->channel
= ev
->channel
;
5913 hdr
->rate
= ev
->rate
;
5914 hdr
->phy_mode
= ev
->phy_mode
;
5915 hdr
->buf_len
= ev
->buf_len
;
5916 hdr
->status
= ev
->status
;
5917 hdr
->flags
= ev
->flags
;
5918 hdr
->rssi
= ev
->rssi
;
5919 hdr
->tsf_delta
= ev
->tsf_delta
;
5920 memcpy(hdr
->rssi_ctl
, ev
->rssi_ctl
, sizeof(hdr
->rssi_ctl
));
5922 if (skb
->len
< (frame
- skb
->data
) + hdr
->buf_len
) {
5923 ath11k_warn(ab
, "invalid length in mgmt rx hdr ev");
5927 /* shift the sk_buff to point to `frame` */
5929 skb_put(skb
, frame
- skb
->data
);
5930 skb_pull(skb
, frame
- skb
->data
);
5931 skb_put(skb
, hdr
->buf_len
);
5933 ath11k_ce_byte_swap(skb
->data
, hdr
->buf_len
);
5938 static int wmi_process_mgmt_tx_comp(struct ath11k
*ar
,
5939 struct wmi_mgmt_tx_compl_event
*tx_compl_param
)
5941 struct sk_buff
*msdu
;
5942 struct ieee80211_tx_info
*info
;
5943 struct ath11k_skb_cb
*skb_cb
;
5946 spin_lock_bh(&ar
->txmgmt_idr_lock
);
5947 msdu
= idr_find(&ar
->txmgmt_idr
, tx_compl_param
->desc_id
);
5950 ath11k_warn(ar
->ab
, "received mgmt tx compl for invalid msdu_id: %d\n",
5951 tx_compl_param
->desc_id
);
5952 spin_unlock_bh(&ar
->txmgmt_idr_lock
);
5956 idr_remove(&ar
->txmgmt_idr
, tx_compl_param
->desc_id
);
5957 spin_unlock_bh(&ar
->txmgmt_idr_lock
);
5959 skb_cb
= ATH11K_SKB_CB(msdu
);
5960 dma_unmap_single(ar
->ab
->dev
, skb_cb
->paddr
, msdu
->len
, DMA_TO_DEVICE
);
5962 info
= IEEE80211_SKB_CB(msdu
);
5963 if ((!(info
->flags
& IEEE80211_TX_CTL_NO_ACK
)) &&
5964 !tx_compl_param
->status
) {
5965 info
->flags
|= IEEE80211_TX_STAT_ACK
;
5966 if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI
,
5967 ar
->ab
->wmi_ab
.svc_map
))
5968 info
->status
.ack_signal
= tx_compl_param
->ack_rssi
;
5971 ieee80211_tx_status_irqsafe(ar
->hw
, msdu
);
5973 num_mgmt
= atomic_dec_if_positive(&ar
->num_pending_mgmt_tx
);
5975 /* WARN when we received this event without doing any mgmt tx */
5979 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
5980 "mgmt tx comp pending %d desc id %d\n",
5981 num_mgmt
, tx_compl_param
->desc_id
);
5984 wake_up(&ar
->txmgmt_empty_waitq
);
5989 static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base
*ab
,
5990 struct sk_buff
*skb
,
5991 struct wmi_mgmt_tx_compl_event
*param
)
5994 const struct wmi_mgmt_tx_compl_event
*ev
;
5997 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6000 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6004 ev
= tb
[WMI_TAG_MGMT_TX_COMPL_EVENT
];
6006 ath11k_warn(ab
, "failed to fetch mgmt tx compl ev");
6011 param
->pdev_id
= ev
->pdev_id
;
6012 param
->desc_id
= ev
->desc_id
;
6013 param
->status
= ev
->status
;
6014 param
->ack_rssi
= ev
->ack_rssi
;
6020 static void ath11k_wmi_event_scan_started(struct ath11k
*ar
)
6022 lockdep_assert_held(&ar
->data_lock
);
6024 switch (ar
->scan
.state
) {
6025 case ATH11K_SCAN_IDLE
:
6026 case ATH11K_SCAN_RUNNING
:
6027 case ATH11K_SCAN_ABORTING
:
6028 ath11k_warn(ar
->ab
, "received scan started event in an invalid scan state: %s (%d)\n",
6029 ath11k_scan_state_str(ar
->scan
.state
),
6032 case ATH11K_SCAN_STARTING
:
6033 ar
->scan
.state
= ATH11K_SCAN_RUNNING
;
6034 if (ar
->scan
.is_roc
)
6035 ieee80211_ready_on_channel(ar
->hw
);
6036 complete(&ar
->scan
.started
);
6041 static void ath11k_wmi_event_scan_start_failed(struct ath11k
*ar
)
6043 lockdep_assert_held(&ar
->data_lock
);
6045 switch (ar
->scan
.state
) {
6046 case ATH11K_SCAN_IDLE
:
6047 case ATH11K_SCAN_RUNNING
:
6048 case ATH11K_SCAN_ABORTING
:
6049 ath11k_warn(ar
->ab
, "received scan start failed event in an invalid scan state: %s (%d)\n",
6050 ath11k_scan_state_str(ar
->scan
.state
),
6053 case ATH11K_SCAN_STARTING
:
6054 complete(&ar
->scan
.started
);
6055 __ath11k_mac_scan_finish(ar
);
6060 static void ath11k_wmi_event_scan_completed(struct ath11k
*ar
)
6062 lockdep_assert_held(&ar
->data_lock
);
6064 switch (ar
->scan
.state
) {
6065 case ATH11K_SCAN_IDLE
:
6066 case ATH11K_SCAN_STARTING
:
6067 /* One suspected reason scan can be completed while starting is
6068 * if firmware fails to deliver all scan events to the host,
6069 * e.g. when transport pipe is full. This has been observed
6070 * with spectral scan phyerr events starving wmi transport
6071 * pipe. In such case the "scan completed" event should be (and
6072 * is) ignored by the host as it may be just firmware's scan
6073 * state machine recovering.
6075 ath11k_warn(ar
->ab
, "received scan completed event in an invalid scan state: %s (%d)\n",
6076 ath11k_scan_state_str(ar
->scan
.state
),
6079 case ATH11K_SCAN_RUNNING
:
6080 case ATH11K_SCAN_ABORTING
:
6081 __ath11k_mac_scan_finish(ar
);
6086 static void ath11k_wmi_event_scan_bss_chan(struct ath11k
*ar
)
6088 lockdep_assert_held(&ar
->data_lock
);
6090 switch (ar
->scan
.state
) {
6091 case ATH11K_SCAN_IDLE
:
6092 case ATH11K_SCAN_STARTING
:
6093 ath11k_warn(ar
->ab
, "received scan bss chan event in an invalid scan state: %s (%d)\n",
6094 ath11k_scan_state_str(ar
->scan
.state
),
6097 case ATH11K_SCAN_RUNNING
:
6098 case ATH11K_SCAN_ABORTING
:
6099 ar
->scan_channel
= NULL
;
6104 static void ath11k_wmi_event_scan_foreign_chan(struct ath11k
*ar
, u32 freq
)
6106 lockdep_assert_held(&ar
->data_lock
);
6108 switch (ar
->scan
.state
) {
6109 case ATH11K_SCAN_IDLE
:
6110 case ATH11K_SCAN_STARTING
:
6111 ath11k_warn(ar
->ab
, "received scan foreign chan event in an invalid scan state: %s (%d)\n",
6112 ath11k_scan_state_str(ar
->scan
.state
),
6115 case ATH11K_SCAN_RUNNING
:
6116 case ATH11K_SCAN_ABORTING
:
6117 ar
->scan_channel
= ieee80211_get_channel(ar
->hw
->wiphy
, freq
);
6118 if (ar
->scan
.is_roc
&& ar
->scan
.roc_freq
== freq
)
6119 complete(&ar
->scan
.on_channel
);
6125 ath11k_wmi_event_scan_type_str(enum wmi_scan_event_type type
,
6126 enum wmi_scan_completion_reason reason
)
6129 case WMI_SCAN_EVENT_STARTED
:
6131 case WMI_SCAN_EVENT_COMPLETED
:
6133 case WMI_SCAN_REASON_COMPLETED
:
6135 case WMI_SCAN_REASON_CANCELLED
:
6136 return "completed [cancelled]";
6137 case WMI_SCAN_REASON_PREEMPTED
:
6138 return "completed [preempted]";
6139 case WMI_SCAN_REASON_TIMEDOUT
:
6140 return "completed [timedout]";
6141 case WMI_SCAN_REASON_INTERNAL_FAILURE
:
6142 return "completed [internal err]";
6143 case WMI_SCAN_REASON_MAX
:
6146 return "completed [unknown]";
6147 case WMI_SCAN_EVENT_BSS_CHANNEL
:
6148 return "bss channel";
6149 case WMI_SCAN_EVENT_FOREIGN_CHAN
:
6150 return "foreign channel";
6151 case WMI_SCAN_EVENT_DEQUEUED
:
6153 case WMI_SCAN_EVENT_PREEMPTED
:
6155 case WMI_SCAN_EVENT_START_FAILED
:
6156 return "start failed";
6157 case WMI_SCAN_EVENT_RESTARTED
:
6159 case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT
:
6160 return "foreign channel exit";
6166 static int ath11k_pull_scan_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6167 struct wmi_scan_event
*scan_evt_param
)
6170 const struct wmi_scan_event
*ev
;
6173 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6176 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6180 ev
= tb
[WMI_TAG_SCAN_EVENT
];
6182 ath11k_warn(ab
, "failed to fetch scan ev");
6187 scan_evt_param
->event_type
= ev
->event_type
;
6188 scan_evt_param
->reason
= ev
->reason
;
6189 scan_evt_param
->channel_freq
= ev
->channel_freq
;
6190 scan_evt_param
->scan_req_id
= ev
->scan_req_id
;
6191 scan_evt_param
->scan_id
= ev
->scan_id
;
6192 scan_evt_param
->vdev_id
= ev
->vdev_id
;
6193 scan_evt_param
->tsf_timestamp
= ev
->tsf_timestamp
;
6199 static int ath11k_pull_peer_sta_kickout_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6200 struct wmi_peer_sta_kickout_arg
*arg
)
6203 const struct wmi_peer_sta_kickout_event
*ev
;
6206 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6209 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6213 ev
= tb
[WMI_TAG_PEER_STA_KICKOUT_EVENT
];
6215 ath11k_warn(ab
, "failed to fetch peer sta kickout ev");
6220 arg
->mac_addr
= ev
->peer_macaddr
.addr
;
6226 static int ath11k_pull_roam_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6227 struct wmi_roam_event
*roam_ev
)
6230 const struct wmi_roam_event
*ev
;
6233 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6236 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6240 ev
= tb
[WMI_TAG_ROAM_EVENT
];
6242 ath11k_warn(ab
, "failed to fetch roam ev");
6247 roam_ev
->vdev_id
= ev
->vdev_id
;
6248 roam_ev
->reason
= ev
->reason
;
6249 roam_ev
->rssi
= ev
->rssi
;
6255 static int freq_to_idx(struct ath11k
*ar
, int freq
)
6257 struct ieee80211_supported_band
*sband
;
6258 int band
, ch
, idx
= 0;
6260 for (band
= NL80211_BAND_2GHZ
; band
< NUM_NL80211_BANDS
; band
++) {
6261 sband
= ar
->hw
->wiphy
->bands
[band
];
6265 for (ch
= 0; ch
< sband
->n_channels
; ch
++, idx
++)
6266 if (sband
->channels
[ch
].center_freq
== freq
)
6274 static int ath11k_pull_chan_info_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6275 struct wmi_chan_info_event
*ch_info_ev
)
6278 const struct wmi_chan_info_event
*ev
;
6281 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6284 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6288 ev
= tb
[WMI_TAG_CHAN_INFO_EVENT
];
6290 ath11k_warn(ab
, "failed to fetch chan info ev");
6295 ch_info_ev
->err_code
= ev
->err_code
;
6296 ch_info_ev
->freq
= ev
->freq
;
6297 ch_info_ev
->cmd_flags
= ev
->cmd_flags
;
6298 ch_info_ev
->noise_floor
= ev
->noise_floor
;
6299 ch_info_ev
->rx_clear_count
= ev
->rx_clear_count
;
6300 ch_info_ev
->cycle_count
= ev
->cycle_count
;
6301 ch_info_ev
->chan_tx_pwr_range
= ev
->chan_tx_pwr_range
;
6302 ch_info_ev
->chan_tx_pwr_tp
= ev
->chan_tx_pwr_tp
;
6303 ch_info_ev
->rx_frame_count
= ev
->rx_frame_count
;
6304 ch_info_ev
->tx_frame_cnt
= ev
->tx_frame_cnt
;
6305 ch_info_ev
->mac_clk_mhz
= ev
->mac_clk_mhz
;
6306 ch_info_ev
->vdev_id
= ev
->vdev_id
;
6313 ath11k_pull_pdev_bss_chan_info_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6314 struct wmi_pdev_bss_chan_info_event
*bss_ch_info_ev
)
6317 const struct wmi_pdev_bss_chan_info_event
*ev
;
6320 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6323 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6327 ev
= tb
[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT
];
6329 ath11k_warn(ab
, "failed to fetch pdev bss chan info ev");
6334 bss_ch_info_ev
->pdev_id
= ev
->pdev_id
;
6335 bss_ch_info_ev
->freq
= ev
->freq
;
6336 bss_ch_info_ev
->noise_floor
= ev
->noise_floor
;
6337 bss_ch_info_ev
->rx_clear_count_low
= ev
->rx_clear_count_low
;
6338 bss_ch_info_ev
->rx_clear_count_high
= ev
->rx_clear_count_high
;
6339 bss_ch_info_ev
->cycle_count_low
= ev
->cycle_count_low
;
6340 bss_ch_info_ev
->cycle_count_high
= ev
->cycle_count_high
;
6341 bss_ch_info_ev
->tx_cycle_count_low
= ev
->tx_cycle_count_low
;
6342 bss_ch_info_ev
->tx_cycle_count_high
= ev
->tx_cycle_count_high
;
6343 bss_ch_info_ev
->rx_cycle_count_low
= ev
->rx_cycle_count_low
;
6344 bss_ch_info_ev
->rx_cycle_count_high
= ev
->rx_cycle_count_high
;
6345 bss_ch_info_ev
->rx_bss_cycle_count_low
= ev
->rx_bss_cycle_count_low
;
6346 bss_ch_info_ev
->rx_bss_cycle_count_high
= ev
->rx_bss_cycle_count_high
;
6353 ath11k_pull_vdev_install_key_compl_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6354 struct wmi_vdev_install_key_complete_arg
*arg
)
6357 const struct wmi_vdev_install_key_compl_event
*ev
;
6360 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6363 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6367 ev
= tb
[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT
];
6369 ath11k_warn(ab
, "failed to fetch vdev install key compl ev");
6374 arg
->vdev_id
= ev
->vdev_id
;
6375 arg
->macaddr
= ev
->peer_macaddr
.addr
;
6376 arg
->key_idx
= ev
->key_idx
;
6377 arg
->key_flags
= ev
->key_flags
;
6378 arg
->status
= ev
->status
;
6384 static int ath11k_pull_peer_assoc_conf_ev(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6385 struct wmi_peer_assoc_conf_arg
*peer_assoc_conf
)
6388 const struct wmi_peer_assoc_conf_event
*ev
;
6391 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
6394 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
6398 ev
= tb
[WMI_TAG_PEER_ASSOC_CONF_EVENT
];
6400 ath11k_warn(ab
, "failed to fetch peer assoc conf ev");
6405 peer_assoc_conf
->vdev_id
= ev
->vdev_id
;
6406 peer_assoc_conf
->macaddr
= ev
->peer_macaddr
.addr
;
6412 static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base
*src
,
6413 struct ath11k_fw_stats_pdev
*dst
)
6415 dst
->ch_noise_floor
= src
->chan_nf
;
6416 dst
->tx_frame_count
= src
->tx_frame_count
;
6417 dst
->rx_frame_count
= src
->rx_frame_count
;
6418 dst
->rx_clear_count
= src
->rx_clear_count
;
6419 dst
->cycle_count
= src
->cycle_count
;
6420 dst
->phy_err_count
= src
->phy_err_count
;
6421 dst
->chan_tx_power
= src
->chan_tx_pwr
;
6425 ath11k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx
*src
,
6426 struct ath11k_fw_stats_pdev
*dst
)
6428 dst
->comp_queued
= src
->comp_queued
;
6429 dst
->comp_delivered
= src
->comp_delivered
;
6430 dst
->msdu_enqued
= src
->msdu_enqued
;
6431 dst
->mpdu_enqued
= src
->mpdu_enqued
;
6432 dst
->wmm_drop
= src
->wmm_drop
;
6433 dst
->local_enqued
= src
->local_enqued
;
6434 dst
->local_freed
= src
->local_freed
;
6435 dst
->hw_queued
= src
->hw_queued
;
6436 dst
->hw_reaped
= src
->hw_reaped
;
6437 dst
->underrun
= src
->underrun
;
6438 dst
->hw_paused
= src
->hw_paused
;
6439 dst
->tx_abort
= src
->tx_abort
;
6440 dst
->mpdus_requeued
= src
->mpdus_requeued
;
6441 dst
->tx_ko
= src
->tx_ko
;
6442 dst
->tx_xretry
= src
->tx_xretry
;
6443 dst
->data_rc
= src
->data_rc
;
6444 dst
->self_triggers
= src
->self_triggers
;
6445 dst
->sw_retry_failure
= src
->sw_retry_failure
;
6446 dst
->illgl_rate_phy_err
= src
->illgl_rate_phy_err
;
6447 dst
->pdev_cont_xretry
= src
->pdev_cont_xretry
;
6448 dst
->pdev_tx_timeout
= src
->pdev_tx_timeout
;
6449 dst
->pdev_resets
= src
->pdev_resets
;
6450 dst
->stateless_tid_alloc_failure
= src
->stateless_tid_alloc_failure
;
6451 dst
->phy_underrun
= src
->phy_underrun
;
6452 dst
->txop_ovf
= src
->txop_ovf
;
6453 dst
->seq_posted
= src
->seq_posted
;
6454 dst
->seq_failed_queueing
= src
->seq_failed_queueing
;
6455 dst
->seq_completed
= src
->seq_completed
;
6456 dst
->seq_restarted
= src
->seq_restarted
;
6457 dst
->mu_seq_posted
= src
->mu_seq_posted
;
6458 dst
->mpdus_sw_flush
= src
->mpdus_sw_flush
;
6459 dst
->mpdus_hw_filter
= src
->mpdus_hw_filter
;
6460 dst
->mpdus_truncated
= src
->mpdus_truncated
;
6461 dst
->mpdus_ack_failed
= src
->mpdus_ack_failed
;
6462 dst
->mpdus_expired
= src
->mpdus_expired
;
6465 static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx
*src
,
6466 struct ath11k_fw_stats_pdev
*dst
)
6468 dst
->mid_ppdu_route_change
= src
->mid_ppdu_route_change
;
6469 dst
->status_rcvd
= src
->status_rcvd
;
6470 dst
->r0_frags
= src
->r0_frags
;
6471 dst
->r1_frags
= src
->r1_frags
;
6472 dst
->r2_frags
= src
->r2_frags
;
6473 dst
->r3_frags
= src
->r3_frags
;
6474 dst
->htt_msdus
= src
->htt_msdus
;
6475 dst
->htt_mpdus
= src
->htt_mpdus
;
6476 dst
->loc_msdus
= src
->loc_msdus
;
6477 dst
->loc_mpdus
= src
->loc_mpdus
;
6478 dst
->oversize_amsdu
= src
->oversize_amsdu
;
6479 dst
->phy_errs
= src
->phy_errs
;
6480 dst
->phy_err_drop
= src
->phy_err_drop
;
6481 dst
->mpdu_errs
= src
->mpdu_errs
;
6482 dst
->rx_ovfl_errs
= src
->rx_ovfl_errs
;
6486 ath11k_wmi_pull_vdev_stats(const struct wmi_vdev_stats
*src
,
6487 struct ath11k_fw_stats_vdev
*dst
)
6491 dst
->vdev_id
= src
->vdev_id
;
6492 dst
->beacon_snr
= src
->beacon_snr
;
6493 dst
->data_snr
= src
->data_snr
;
6494 dst
->num_rx_frames
= src
->num_rx_frames
;
6495 dst
->num_rts_fail
= src
->num_rts_fail
;
6496 dst
->num_rts_success
= src
->num_rts_success
;
6497 dst
->num_rx_err
= src
->num_rx_err
;
6498 dst
->num_rx_discard
= src
->num_rx_discard
;
6499 dst
->num_tx_not_acked
= src
->num_tx_not_acked
;
6501 for (i
= 0; i
< ARRAY_SIZE(src
->num_tx_frames
); i
++)
6502 dst
->num_tx_frames
[i
] = src
->num_tx_frames
[i
];
6504 for (i
= 0; i
< ARRAY_SIZE(src
->num_tx_frames_retries
); i
++)
6505 dst
->num_tx_frames_retries
[i
] = src
->num_tx_frames_retries
[i
];
6507 for (i
= 0; i
< ARRAY_SIZE(src
->num_tx_frames_failures
); i
++)
6508 dst
->num_tx_frames_failures
[i
] = src
->num_tx_frames_failures
[i
];
6510 for (i
= 0; i
< ARRAY_SIZE(src
->tx_rate_history
); i
++)
6511 dst
->tx_rate_history
[i
] = src
->tx_rate_history
[i
];
6513 for (i
= 0; i
< ARRAY_SIZE(src
->beacon_rssi_history
); i
++)
6514 dst
->beacon_rssi_history
[i
] = src
->beacon_rssi_history
[i
];
6518 ath11k_wmi_pull_bcn_stats(const struct wmi_bcn_stats
*src
,
6519 struct ath11k_fw_stats_bcn
*dst
)
6521 dst
->vdev_id
= src
->vdev_id
;
6522 dst
->tx_bcn_succ_cnt
= src
->tx_bcn_succ_cnt
;
6523 dst
->tx_bcn_outage_cnt
= src
->tx_bcn_outage_cnt
;
6526 static int ath11k_wmi_tlv_rssi_chain_parse(struct ath11k_base
*ab
,
6528 const void *ptr
, void *data
)
6530 struct wmi_tlv_fw_stats_parse
*parse
= data
;
6531 const struct wmi_stats_event
*ev
= parse
->ev
;
6532 struct ath11k_fw_stats
*stats
= parse
->stats
;
6534 struct ath11k_vif
*arvif
;
6535 struct ieee80211_sta
*sta
;
6536 struct ath11k_sta
*arsta
;
6537 const struct wmi_rssi_stats
*stats_rssi
= (const struct wmi_rssi_stats
*)ptr
;
6540 if (tag
!= WMI_TAG_RSSI_STATS
)
6545 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, ev
->pdev_id
);
6546 stats
->stats_id
= WMI_REQUEST_RSSI_PER_CHAIN_STAT
;
6548 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6549 "stats vdev id %d mac %pM\n",
6550 stats_rssi
->vdev_id
, stats_rssi
->peer_macaddr
.addr
);
6552 arvif
= ath11k_mac_get_arvif(ar
, stats_rssi
->vdev_id
);
6554 ath11k_warn(ab
, "not found vif for vdev id %d\n",
6555 stats_rssi
->vdev_id
);
6560 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6561 "stats bssid %pM vif %p\n",
6562 arvif
->bssid
, arvif
->vif
);
6564 sta
= ieee80211_find_sta_by_ifaddr(ar
->hw
,
6568 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6569 "not found station of bssid %pM for rssi chain\n",
6574 arsta
= ath11k_sta_to_arsta(sta
);
6576 BUILD_BUG_ON(ARRAY_SIZE(arsta
->chain_signal
) >
6577 ARRAY_SIZE(stats_rssi
->rssi_avg_beacon
));
6579 for (j
= 0; j
< ARRAY_SIZE(arsta
->chain_signal
); j
++) {
6580 arsta
->chain_signal
[j
] = stats_rssi
->rssi_avg_beacon
[j
];
6581 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6582 "stats beacon rssi[%d] %d data rssi[%d] %d\n",
6584 stats_rssi
->rssi_avg_beacon
[j
],
6586 stats_rssi
->rssi_avg_data
[j
]);
6594 static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base
*ab
,
6595 struct wmi_tlv_fw_stats_parse
*parse
,
6599 struct ath11k_fw_stats
*stats
= parse
->stats
;
6600 const struct wmi_stats_event
*ev
= parse
->ev
;
6602 struct ath11k_vif
*arvif
;
6603 struct ieee80211_sta
*sta
;
6604 struct ath11k_sta
*arsta
;
6606 const void *data
= ptr
;
6609 ath11k_warn(ab
, "failed to fetch update stats ev");
6613 stats
->stats_id
= 0;
6617 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, ev
->pdev_id
);
6619 for (i
= 0; i
< ev
->num_pdev_stats
; i
++) {
6620 const struct wmi_pdev_stats
*src
;
6621 struct ath11k_fw_stats_pdev
*dst
;
6624 if (len
< sizeof(*src
)) {
6629 stats
->stats_id
= WMI_REQUEST_PDEV_STAT
;
6631 data
+= sizeof(*src
);
6632 len
-= sizeof(*src
);
6634 dst
= kzalloc(sizeof(*dst
), GFP_ATOMIC
);
6638 ath11k_wmi_pull_pdev_stats_base(&src
->base
, dst
);
6639 ath11k_wmi_pull_pdev_stats_tx(&src
->tx
, dst
);
6640 ath11k_wmi_pull_pdev_stats_rx(&src
->rx
, dst
);
6641 list_add_tail(&dst
->list
, &stats
->pdevs
);
6644 for (i
= 0; i
< ev
->num_vdev_stats
; i
++) {
6645 const struct wmi_vdev_stats
*src
;
6646 struct ath11k_fw_stats_vdev
*dst
;
6649 if (len
< sizeof(*src
)) {
6654 stats
->stats_id
= WMI_REQUEST_VDEV_STAT
;
6656 arvif
= ath11k_mac_get_arvif(ar
, src
->vdev_id
);
6658 sta
= ieee80211_find_sta_by_ifaddr(ar
->hw
,
6662 arsta
= ath11k_sta_to_arsta(sta
);
6663 arsta
->rssi_beacon
= src
->beacon_snr
;
6664 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6665 "stats vdev id %d snr %d\n",
6666 src
->vdev_id
, src
->beacon_snr
);
6668 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6669 "not found station of bssid %pM for vdev stat\n",
6674 data
+= sizeof(*src
);
6675 len
-= sizeof(*src
);
6677 dst
= kzalloc(sizeof(*dst
), GFP_ATOMIC
);
6681 ath11k_wmi_pull_vdev_stats(src
, dst
);
6682 list_add_tail(&dst
->list
, &stats
->vdevs
);
6685 for (i
= 0; i
< ev
->num_bcn_stats
; i
++) {
6686 const struct wmi_bcn_stats
*src
;
6687 struct ath11k_fw_stats_bcn
*dst
;
6690 if (len
< sizeof(*src
)) {
6695 stats
->stats_id
= WMI_REQUEST_BCN_STAT
;
6697 data
+= sizeof(*src
);
6698 len
-= sizeof(*src
);
6700 dst
= kzalloc(sizeof(*dst
), GFP_ATOMIC
);
6704 ath11k_wmi_pull_bcn_stats(src
, dst
);
6705 list_add_tail(&dst
->list
, &stats
->bcn
);
6713 static int ath11k_wmi_tlv_fw_stats_parse(struct ath11k_base
*ab
,
6715 const void *ptr
, void *data
)
6717 struct wmi_tlv_fw_stats_parse
*parse
= data
;
6721 case WMI_TAG_STATS_EVENT
:
6722 parse
->ev
= (struct wmi_stats_event
*)ptr
;
6723 parse
->stats
->pdev_id
= parse
->ev
->pdev_id
;
6725 case WMI_TAG_ARRAY_BYTE
:
6726 ret
= ath11k_wmi_tlv_fw_stats_data_parse(ab
, parse
, ptr
, len
);
6728 case WMI_TAG_PER_CHAIN_RSSI_STATS
:
6729 parse
->rssi
= (struct wmi_per_chain_rssi_stats
*)ptr
;
6731 if (parse
->ev
->stats_id
& WMI_REQUEST_RSSI_PER_CHAIN_STAT
)
6732 parse
->rssi_num
= parse
->rssi
->num_per_chain_rssi_stats
;
6734 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
6735 "stats id 0x%x num chain %d\n",
6736 parse
->ev
->stats_id
,
6739 case WMI_TAG_ARRAY_STRUCT
:
6740 if (parse
->rssi_num
&& !parse
->chain_rssi_done
) {
6741 ret
= ath11k_wmi_tlv_iter(ab
, ptr
, len
,
6742 ath11k_wmi_tlv_rssi_chain_parse
,
6745 ath11k_warn(ab
, "failed to parse rssi chain %d\n",
6749 parse
->chain_rssi_done
= true;
6758 int ath11k_wmi_pull_fw_stats(struct ath11k_base
*ab
, struct sk_buff
*skb
,
6759 struct ath11k_fw_stats
*stats
)
6761 struct wmi_tlv_fw_stats_parse parse
= { };
6763 stats
->stats_id
= 0;
6764 parse
.stats
= stats
;
6766 return ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
6767 ath11k_wmi_tlv_fw_stats_parse
,
6772 ath11k_wmi_fw_pdev_base_stats_fill(const struct ath11k_fw_stats_pdev
*pdev
,
6773 char *buf
, u32
*length
)
6776 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
6778 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
6779 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n",
6780 "ath11k PDEV stats");
6781 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
6782 "=================");
6784 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6785 "Channel noise floor", pdev
->ch_noise_floor
);
6786 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6787 "Channel TX power", pdev
->chan_tx_power
);
6788 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6789 "TX frame count", pdev
->tx_frame_count
);
6790 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6791 "RX frame count", pdev
->rx_frame_count
);
6792 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6793 "RX clear count", pdev
->rx_clear_count
);
6794 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6795 "Cycle count", pdev
->cycle_count
);
6796 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6797 "PHY error count", pdev
->phy_err_count
);
6803 ath11k_wmi_fw_pdev_tx_stats_fill(const struct ath11k_fw_stats_pdev
*pdev
,
6804 char *buf
, u32
*length
)
6807 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
6809 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n%30s\n",
6810 "ath11k PDEV TX stats");
6811 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
6812 "====================");
6814 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6815 "HTT cookies queued", pdev
->comp_queued
);
6816 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6817 "HTT cookies disp.", pdev
->comp_delivered
);
6818 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6819 "MSDU queued", pdev
->msdu_enqued
);
6820 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6821 "MPDU queued", pdev
->mpdu_enqued
);
6822 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6823 "MSDUs dropped", pdev
->wmm_drop
);
6824 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6825 "Local enqued", pdev
->local_enqued
);
6826 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6827 "Local freed", pdev
->local_freed
);
6828 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6829 "HW queued", pdev
->hw_queued
);
6830 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6831 "PPDUs reaped", pdev
->hw_reaped
);
6832 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6833 "Num underruns", pdev
->underrun
);
6834 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6835 "Num HW Paused", pdev
->hw_paused
);
6836 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6837 "PPDUs cleaned", pdev
->tx_abort
);
6838 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6839 "MPDUs requeued", pdev
->mpdus_requeued
);
6840 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6841 "PPDU OK", pdev
->tx_ko
);
6842 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6843 "Excessive retries", pdev
->tx_xretry
);
6844 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6845 "HW rate", pdev
->data_rc
);
6846 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6847 "Sched self triggers", pdev
->self_triggers
);
6848 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6849 "Dropped due to SW retries",
6850 pdev
->sw_retry_failure
);
6851 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6852 "Illegal rate phy errors",
6853 pdev
->illgl_rate_phy_err
);
6854 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6855 "PDEV continuous xretry", pdev
->pdev_cont_xretry
);
6856 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6857 "TX timeout", pdev
->pdev_tx_timeout
);
6858 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6859 "PDEV resets", pdev
->pdev_resets
);
6860 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6861 "Stateless TIDs alloc failures",
6862 pdev
->stateless_tid_alloc_failure
);
6863 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6864 "PHY underrun", pdev
->phy_underrun
);
6865 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6866 "MPDU is more than txop limit", pdev
->txop_ovf
);
6867 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6868 "Num sequences posted", pdev
->seq_posted
);
6869 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6870 "Num seq failed queueing ", pdev
->seq_failed_queueing
);
6871 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6872 "Num sequences completed ", pdev
->seq_completed
);
6873 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6874 "Num sequences restarted ", pdev
->seq_restarted
);
6875 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6876 "Num of MU sequences posted ", pdev
->mu_seq_posted
);
6877 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6878 "Num of MPDUS SW flushed ", pdev
->mpdus_sw_flush
);
6879 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6880 "Num of MPDUS HW filtered ", pdev
->mpdus_hw_filter
);
6881 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6882 "Num of MPDUS truncated ", pdev
->mpdus_truncated
);
6883 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6884 "Num of MPDUS ACK failed ", pdev
->mpdus_ack_failed
);
6885 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
6886 "Num of MPDUS expired ", pdev
->mpdus_expired
);
6891 ath11k_wmi_fw_pdev_rx_stats_fill(const struct ath11k_fw_stats_pdev
*pdev
,
6892 char *buf
, u32
*length
)
6895 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
6897 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n%30s\n",
6898 "ath11k PDEV RX stats");
6899 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
6900 "====================");
6902 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6903 "Mid PPDU route change",
6904 pdev
->mid_ppdu_route_change
);
6905 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6906 "Tot. number of statuses", pdev
->status_rcvd
);
6907 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6908 "Extra frags on rings 0", pdev
->r0_frags
);
6909 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6910 "Extra frags on rings 1", pdev
->r1_frags
);
6911 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6912 "Extra frags on rings 2", pdev
->r2_frags
);
6913 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6914 "Extra frags on rings 3", pdev
->r3_frags
);
6915 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6916 "MSDUs delivered to HTT", pdev
->htt_msdus
);
6917 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6918 "MPDUs delivered to HTT", pdev
->htt_mpdus
);
6919 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6920 "MSDUs delivered to stack", pdev
->loc_msdus
);
6921 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6922 "MPDUs delivered to stack", pdev
->loc_mpdus
);
6923 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6924 "Oversized AMSUs", pdev
->oversize_amsdu
);
6925 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6926 "PHY errors", pdev
->phy_errs
);
6927 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6928 "PHY errors drops", pdev
->phy_err_drop
);
6929 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6930 "MPDU errors (FCS, MIC, ENC)", pdev
->mpdu_errs
);
6931 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
6932 "Overflow errors", pdev
->rx_ovfl_errs
);
6937 ath11k_wmi_fw_vdev_stats_fill(struct ath11k
*ar
,
6938 const struct ath11k_fw_stats_vdev
*vdev
,
6939 char *buf
, u32
*length
)
6942 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
6943 struct ath11k_vif
*arvif
= ath11k_mac_get_arvif(ar
, vdev
->vdev_id
);
6947 /* VDEV stats has all the active VDEVs of other PDEVs as well,
6948 * ignoring those not part of requested PDEV
6953 vif_macaddr
= arvif
->vif
->addr
;
6955 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6956 "VDEV ID", vdev
->vdev_id
);
6957 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %pM\n",
6958 "VDEV MAC address", vif_macaddr
);
6959 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6960 "beacon snr", vdev
->beacon_snr
);
6961 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6962 "data snr", vdev
->data_snr
);
6963 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6964 "num rx frames", vdev
->num_rx_frames
);
6965 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6966 "num rts fail", vdev
->num_rts_fail
);
6967 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6968 "num rts success", vdev
->num_rts_success
);
6969 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6970 "num rx err", vdev
->num_rx_err
);
6971 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6972 "num rx discard", vdev
->num_rx_discard
);
6973 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
6974 "num tx not acked", vdev
->num_tx_not_acked
);
6976 for (i
= 0 ; i
< ARRAY_SIZE(vdev
->num_tx_frames
); i
++)
6977 len
+= scnprintf(buf
+ len
, buf_len
- len
,
6980 vdev
->num_tx_frames
[i
]);
6982 for (i
= 0 ; i
< ARRAY_SIZE(vdev
->num_tx_frames_retries
); i
++)
6983 len
+= scnprintf(buf
+ len
, buf_len
- len
,
6985 "num tx frames retries", i
,
6986 vdev
->num_tx_frames_retries
[i
]);
6988 for (i
= 0 ; i
< ARRAY_SIZE(vdev
->num_tx_frames_failures
); i
++)
6989 len
+= scnprintf(buf
+ len
, buf_len
- len
,
6991 "num tx frames failures", i
,
6992 vdev
->num_tx_frames_failures
[i
]);
6994 for (i
= 0 ; i
< ARRAY_SIZE(vdev
->tx_rate_history
); i
++)
6995 len
+= scnprintf(buf
+ len
, buf_len
- len
,
6996 "%25s [%02d] 0x%08x\n",
6997 "tx rate history", i
,
6998 vdev
->tx_rate_history
[i
]);
7000 for (i
= 0 ; i
< ARRAY_SIZE(vdev
->beacon_rssi_history
); i
++)
7001 len
+= scnprintf(buf
+ len
, buf_len
- len
,
7003 "beacon rssi history", i
,
7004 vdev
->beacon_rssi_history
[i
]);
7006 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
7011 ath11k_wmi_fw_bcn_stats_fill(struct ath11k
*ar
,
7012 const struct ath11k_fw_stats_bcn
*bcn
,
7013 char *buf
, u32
*length
)
7016 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
7017 struct ath11k_vif
*arvif
= ath11k_mac_get_arvif(ar
, bcn
->vdev_id
);
7021 ath11k_warn(ar
->ab
, "invalid vdev id %d in bcn stats",
7026 vdev_macaddr
= arvif
->vif
->addr
;
7028 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
7029 "VDEV ID", bcn
->vdev_id
);
7030 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %pM\n",
7031 "VDEV MAC address", vdev_macaddr
);
7032 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
7033 "================");
7034 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
7035 "Num of beacon tx success", bcn
->tx_bcn_succ_cnt
);
7036 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
7037 "Num of beacon tx failures", bcn
->tx_bcn_outage_cnt
);
7039 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
7043 void ath11k_wmi_fw_stats_fill(struct ath11k
*ar
,
7044 struct ath11k_fw_stats
*fw_stats
,
7045 u32 stats_id
, char *buf
)
7048 u32 buf_len
= ATH11K_FW_STATS_BUF_SIZE
;
7049 const struct ath11k_fw_stats_pdev
*pdev
;
7050 const struct ath11k_fw_stats_vdev
*vdev
;
7051 const struct ath11k_fw_stats_bcn
*bcn
;
7054 spin_lock_bh(&ar
->data_lock
);
7056 if (stats_id
== WMI_REQUEST_PDEV_STAT
) {
7057 pdev
= list_first_entry_or_null(&fw_stats
->pdevs
,
7058 struct ath11k_fw_stats_pdev
, list
);
7060 ath11k_warn(ar
->ab
, "failed to get pdev stats\n");
7064 ath11k_wmi_fw_pdev_base_stats_fill(pdev
, buf
, &len
);
7065 ath11k_wmi_fw_pdev_tx_stats_fill(pdev
, buf
, &len
);
7066 ath11k_wmi_fw_pdev_rx_stats_fill(pdev
, buf
, &len
);
7069 if (stats_id
== WMI_REQUEST_VDEV_STAT
) {
7070 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
7071 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n",
7072 "ath11k VDEV stats");
7073 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
7074 "=================");
7076 list_for_each_entry(vdev
, &fw_stats
->vdevs
, list
)
7077 ath11k_wmi_fw_vdev_stats_fill(ar
, vdev
, buf
, &len
);
7080 if (stats_id
== WMI_REQUEST_BCN_STAT
) {
7081 num_bcn
= list_count_nodes(&fw_stats
->bcn
);
7083 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
7084 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s (%zu)\n",
7085 "ath11k Beacon stats", num_bcn
);
7086 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
7087 "===================");
7089 list_for_each_entry(bcn
, &fw_stats
->bcn
, list
)
7090 ath11k_wmi_fw_bcn_stats_fill(ar
, bcn
, buf
, &len
);
7094 spin_unlock_bh(&ar
->data_lock
);
7102 static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base
*ab
)
7104 /* try to send pending beacons first. they take priority */
7105 wake_up(&ab
->wmi_ab
.tx_credits_wq
);
7108 static int ath11k_reg_11d_new_cc_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7110 const struct wmi_11d_new_cc_ev
*ev
;
7112 struct ath11k_pdev
*pdev
;
7116 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
7119 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
7123 ev
= tb
[WMI_TAG_11D_NEW_COUNTRY_EVENT
];
7126 ath11k_warn(ab
, "failed to fetch 11d new cc ev");
7130 spin_lock_bh(&ab
->base_lock
);
7131 memcpy(&ab
->new_alpha2
, &ev
->new_alpha2
, 2);
7132 spin_unlock_bh(&ab
->base_lock
);
7134 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event 11d new cc %c%c\n",
7140 for (i
= 0; i
< ab
->num_radios
; i
++) {
7141 pdev
= &ab
->pdevs
[i
];
7143 ar
->state_11d
= ATH11K_11D_IDLE
;
7144 complete(&ar
->completed_11d_scan
);
7147 queue_work(ab
->workqueue
, &ab
->update_11d_work
);
7152 static void ath11k_wmi_htc_tx_complete(struct ath11k_base
*ab
,
7153 struct sk_buff
*skb
)
7155 struct ath11k_pdev_wmi
*wmi
= NULL
;
7160 eid
= ATH11K_SKB_CB(skb
)->eid
;
7163 if (eid
>= ATH11K_HTC_EP_COUNT
)
7166 wmi_ep_count
= ab
->htc
.wmi_ep_count
;
7167 if (wmi_ep_count
> ab
->hw_params
.max_radios
)
7170 for (i
= 0; i
< ab
->htc
.wmi_ep_count
; i
++) {
7171 if (ab
->wmi_ab
.wmi
[i
].eid
== eid
) {
7172 wmi
= &ab
->wmi_ab
.wmi
[i
];
7178 wake_up(&wmi
->tx_ce_desc_wq
);
7181 static int ath11k_reg_chan_list_event(struct ath11k_base
*ab
, struct sk_buff
*skb
,
7182 enum wmi_reg_chan_list_cmd_type id
)
7184 struct cur_regulatory_info
*reg_info
;
7187 reg_info
= kzalloc(sizeof(*reg_info
), GFP_ATOMIC
);
7191 if (id
== WMI_REG_CHAN_LIST_CC_ID
)
7192 ret
= ath11k_pull_reg_chan_list_update_ev(ab
, skb
, reg_info
);
7194 ret
= ath11k_pull_reg_chan_list_ext_update_ev(ab
, skb
, reg_info
);
7197 ath11k_warn(ab
, "failed to extract regulatory info\n");
7201 ret
= ath11k_reg_handle_chan_list(ab
, reg_info
, IEEE80211_REG_UNSET_AP
);
7203 ath11k_warn(ab
, "failed to process regulatory info %d\n", ret
);
7211 ath11k_reg_reset_info(reg_info
);
7216 static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base
*ab
, u16 tag
, u16 len
,
7217 const void *ptr
, void *data
)
7219 struct wmi_tlv_rdy_parse
*rdy_parse
= data
;
7220 struct wmi_ready_event fixed_param
;
7221 struct wmi_mac_addr
*addr_list
;
7222 struct ath11k_pdev
*pdev
;
7227 case WMI_TAG_READY_EVENT
:
7228 memset(&fixed_param
, 0, sizeof(fixed_param
));
7229 memcpy(&fixed_param
, (struct wmi_ready_event
*)ptr
,
7230 min_t(u16
, sizeof(fixed_param
), len
));
7231 rdy_parse
->num_extra_mac_addr
=
7232 fixed_param
.ready_event_min
.num_extra_mac_addr
;
7234 ether_addr_copy(ab
->mac_addr
,
7235 fixed_param
.ready_event_min
.mac_addr
.addr
);
7236 ab
->pktlog_defs_checksum
= fixed_param
.pktlog_defs_checksum
;
7238 case WMI_TAG_ARRAY_FIXED_STRUCT
:
7239 addr_list
= (struct wmi_mac_addr
*)ptr
;
7240 num_mac_addr
= rdy_parse
->num_extra_mac_addr
;
7242 if (!(ab
->num_radios
> 1 && num_mac_addr
>= ab
->num_radios
))
7245 for (i
= 0; i
< ab
->num_radios
; i
++) {
7246 pdev
= &ab
->pdevs
[i
];
7247 ether_addr_copy(pdev
->mac_addr
, addr_list
[i
].addr
);
7249 ab
->pdevs_macaddr_valid
= true;
7258 static int ath11k_ready_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7260 struct wmi_tlv_rdy_parse rdy_parse
= { };
7263 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
7264 ath11k_wmi_tlv_rdy_parse
, &rdy_parse
);
7266 ath11k_warn(ab
, "failed to parse tlv %d\n", ret
);
7270 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event ready");
7272 complete(&ab
->wmi_ab
.unified_ready
);
7276 static void ath11k_peer_delete_resp_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7278 struct wmi_peer_delete_resp_event peer_del_resp
;
7281 if (ath11k_pull_peer_del_resp_ev(ab
, skb
, &peer_del_resp
) != 0) {
7282 ath11k_warn(ab
, "failed to extract peer delete resp");
7286 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event peer delete resp");
7289 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, peer_del_resp
.vdev_id
);
7291 ath11k_warn(ab
, "invalid vdev id in peer delete resp ev %d",
7292 peer_del_resp
.vdev_id
);
7297 complete(&ar
->peer_delete_done
);
7299 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "peer delete resp for vdev id %d addr %pM\n",
7300 peer_del_resp
.vdev_id
, peer_del_resp
.peer_macaddr
.addr
);
7303 static void ath11k_vdev_delete_resp_event(struct ath11k_base
*ab
,
7304 struct sk_buff
*skb
)
7309 if (ath11k_pull_vdev_del_resp_ev(ab
, skb
, &vdev_id
) != 0) {
7310 ath11k_warn(ab
, "failed to extract vdev delete resp");
7315 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, vdev_id
);
7317 ath11k_warn(ab
, "invalid vdev id in vdev delete resp ev %d",
7323 complete(&ar
->vdev_delete_done
);
7327 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event vdev delete resp for vdev id %d\n",
7331 static inline const char *ath11k_wmi_vdev_resp_print(u32 vdev_resp_status
)
7333 switch (vdev_resp_status
) {
7334 case WMI_VDEV_START_RESPONSE_INVALID_VDEVID
:
7335 return "invalid vdev id";
7336 case WMI_VDEV_START_RESPONSE_NOT_SUPPORTED
:
7337 return "not supported";
7338 case WMI_VDEV_START_RESPONSE_DFS_VIOLATION
:
7339 return "dfs violation";
7340 case WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN
:
7341 return "invalid regdomain";
7347 static void ath11k_vdev_start_resp_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7349 struct wmi_vdev_start_resp_event vdev_start_resp
;
7353 if (ath11k_pull_vdev_start_resp_tlv(ab
, skb
, &vdev_start_resp
) != 0) {
7354 ath11k_warn(ab
, "failed to extract vdev start resp");
7358 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event start resp event");
7361 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, vdev_start_resp
.vdev_id
);
7363 ath11k_warn(ab
, "invalid vdev id in vdev start resp ev %d",
7364 vdev_start_resp
.vdev_id
);
7369 ar
->last_wmi_vdev_start_status
= 0;
7370 ar
->max_allowed_tx_power
= vdev_start_resp
.max_allowed_tx_power
;
7371 status
= vdev_start_resp
.status
;
7373 if (WARN_ON_ONCE(status
)) {
7374 ath11k_warn(ab
, "vdev start resp error status %d (%s)\n",
7375 status
, ath11k_wmi_vdev_resp_print(status
));
7376 ar
->last_wmi_vdev_start_status
= status
;
7379 complete(&ar
->vdev_setup_done
);
7383 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "vdev start resp for vdev id %d",
7384 vdev_start_resp
.vdev_id
);
7387 static void ath11k_bcn_tx_status_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7389 struct ath11k_vif
*arvif
;
7390 u32 vdev_id
, tx_status
;
7392 if (ath11k_pull_bcn_tx_status_ev(ab
, skb
, &vdev_id
, &tx_status
) != 0) {
7393 ath11k_warn(ab
, "failed to extract bcn tx status");
7397 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event offload bcn tx status");
7400 arvif
= ath11k_mac_get_arvif_by_vdev_id(ab
, vdev_id
);
7402 ath11k_warn(ab
, "invalid vdev id %d in bcn_tx_status",
7408 queue_work(ab
->workqueue
, &arvif
->bcn_tx_work
);
7413 static void ath11k_wmi_event_peer_sta_ps_state_chg(struct ath11k_base
*ab
,
7414 struct sk_buff
*skb
)
7416 const struct wmi_peer_sta_ps_state_chg_event
*ev
;
7417 struct ieee80211_sta
*sta
;
7418 struct ath11k_peer
*peer
;
7420 struct ath11k_sta
*arsta
;
7422 enum ath11k_wmi_peer_ps_state peer_previous_ps_state
;
7425 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
7428 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
7432 ev
= tb
[WMI_TAG_PEER_STA_PS_STATECHANGE_EVENT
];
7434 ath11k_warn(ab
, "failed to fetch sta ps change ev");
7439 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7440 "event peer sta ps change ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n",
7441 ev
->peer_macaddr
.addr
, ev
->peer_ps_state
,
7442 ev
->ps_supported_bitmap
, ev
->peer_ps_valid
,
7443 ev
->peer_ps_timestamp
);
7447 spin_lock_bh(&ab
->base_lock
);
7449 peer
= ath11k_peer_find_by_addr(ab
, ev
->peer_macaddr
.addr
);
7452 spin_unlock_bh(&ab
->base_lock
);
7453 ath11k_warn(ab
, "peer not found %pM\n", ev
->peer_macaddr
.addr
);
7457 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, peer
->vdev_id
);
7460 spin_unlock_bh(&ab
->base_lock
);
7461 ath11k_warn(ab
, "invalid vdev id in peer sta ps state change ev %d",
7469 spin_unlock_bh(&ab
->base_lock
);
7472 ath11k_warn(ab
, "failed to find station entry %pM\n",
7473 ev
->peer_macaddr
.addr
);
7477 arsta
= ath11k_sta_to_arsta(sta
);
7479 spin_lock_bh(&ar
->data_lock
);
7481 peer_previous_ps_state
= arsta
->peer_ps_state
;
7482 arsta
->peer_ps_state
= ev
->peer_ps_state
;
7483 arsta
->peer_current_ps_valid
= !!ev
->peer_ps_valid
;
7485 if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT
,
7486 ar
->ab
->wmi_ab
.svc_map
)) {
7487 if (!(ev
->ps_supported_bitmap
& WMI_PEER_PS_VALID
) ||
7488 !(ev
->ps_supported_bitmap
& WMI_PEER_PS_STATE_TIMESTAMP
) ||
7492 if (arsta
->peer_ps_state
== WMI_PEER_PS_STATE_ON
) {
7493 arsta
->ps_start_time
= ev
->peer_ps_timestamp
;
7494 arsta
->ps_start_jiffies
= jiffies
;
7495 } else if (arsta
->peer_ps_state
== WMI_PEER_PS_STATE_OFF
&&
7496 peer_previous_ps_state
== WMI_PEER_PS_STATE_ON
) {
7497 arsta
->ps_total_duration
= arsta
->ps_total_duration
+
7498 (ev
->peer_ps_timestamp
- arsta
->ps_start_time
);
7501 if (ar
->ps_timekeeper_enable
)
7502 trace_ath11k_ps_timekeeper(ar
, ev
->peer_macaddr
.addr
,
7503 ev
->peer_ps_timestamp
,
7504 arsta
->peer_ps_state
);
7508 spin_unlock_bh(&ar
->data_lock
);
7514 static void ath11k_vdev_stopped_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7519 if (ath11k_pull_vdev_stopped_param_tlv(ab
, skb
, &vdev_id
) != 0) {
7520 ath11k_warn(ab
, "failed to extract vdev stopped event");
7524 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event vdev stopped");
7527 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, vdev_id
);
7529 ath11k_warn(ab
, "invalid vdev id in vdev stopped ev %d",
7535 complete(&ar
->vdev_setup_done
);
7539 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "vdev stopped for vdev id %d", vdev_id
);
7542 static void ath11k_mgmt_rx_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7544 struct mgmt_rx_event_params rx_ev
= {0};
7546 struct ieee80211_rx_status
*status
= IEEE80211_SKB_RXCB(skb
);
7547 struct ieee80211_hdr
*hdr
;
7549 struct ieee80211_supported_band
*sband
;
7551 if (ath11k_pull_mgmt_rx_params_tlv(ab
, skb
, &rx_ev
) != 0) {
7552 ath11k_warn(ab
, "failed to extract mgmt rx event");
7557 memset(status
, 0, sizeof(*status
));
7559 ath11k_dbg(ab
, ATH11K_DBG_MGMT
, "event mgmt rx status %08x\n",
7563 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, rx_ev
.pdev_id
);
7566 ath11k_warn(ab
, "invalid pdev_id %d in mgmt_rx_event\n",
7572 if ((test_bit(ATH11K_CAC_RUNNING
, &ar
->dev_flags
)) ||
7573 (rx_ev
.status
& (WMI_RX_STATUS_ERR_DECRYPT
|
7574 WMI_RX_STATUS_ERR_KEY_CACHE_MISS
| WMI_RX_STATUS_ERR_CRC
))) {
7579 if (rx_ev
.status
& WMI_RX_STATUS_ERR_MIC
)
7580 status
->flag
|= RX_FLAG_MMIC_ERROR
;
7582 if (rx_ev
.chan_freq
>= ATH11K_MIN_6G_FREQ
&&
7583 rx_ev
.chan_freq
<= ATH11K_MAX_6G_FREQ
) {
7584 status
->band
= NL80211_BAND_6GHZ
;
7585 status
->freq
= rx_ev
.chan_freq
;
7586 } else if (rx_ev
.channel
>= 1 && rx_ev
.channel
<= 14) {
7587 status
->band
= NL80211_BAND_2GHZ
;
7588 } else if (rx_ev
.channel
>= 36 && rx_ev
.channel
<= ATH11K_MAX_5G_CHAN
) {
7589 status
->band
= NL80211_BAND_5GHZ
;
7591 /* Shouldn't happen unless list of advertised channels to
7592 * mac80211 has been changed.
7599 if (rx_ev
.phy_mode
== MODE_11B
&&
7600 (status
->band
== NL80211_BAND_5GHZ
|| status
->band
== NL80211_BAND_6GHZ
))
7601 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7602 "mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status
->band
);
7604 sband
= &ar
->mac
.sbands
[status
->band
];
7606 if (status
->band
!= NL80211_BAND_6GHZ
)
7607 status
->freq
= ieee80211_channel_to_frequency(rx_ev
.channel
,
7610 status
->signal
= rx_ev
.snr
+ ATH11K_DEFAULT_NOISE_FLOOR
;
7611 status
->rate_idx
= ath11k_mac_bitrate_to_idx(sband
, rx_ev
.rate
/ 100);
7613 hdr
= (struct ieee80211_hdr
*)skb
->data
;
7614 fc
= le16_to_cpu(hdr
->frame_control
);
7616 /* Firmware is guaranteed to report all essential management frames via
7617 * WMI while it can deliver some extra via HTT. Since there can be
7618 * duplicates split the reporting wrt monitor/sniffing.
7620 status
->flag
|= RX_FLAG_SKIP_MONITOR
;
7622 /* In case of PMF, FW delivers decrypted frames with Protected Bit set.
7623 * Don't clear that. Also, FW delivers broadcast management frames
7624 * (ex: group privacy action frames in mesh) as encrypted payload.
7626 if (ieee80211_has_protected(hdr
->frame_control
) &&
7627 !is_multicast_ether_addr(ieee80211_get_DA(hdr
))) {
7628 status
->flag
|= RX_FLAG_DECRYPTED
;
7630 if (!ieee80211_is_robust_mgmt_frame(skb
)) {
7631 status
->flag
|= RX_FLAG_IV_STRIPPED
|
7632 RX_FLAG_MMIC_STRIPPED
;
7633 hdr
->frame_control
= __cpu_to_le16(fc
&
7634 ~IEEE80211_FCTL_PROTECTED
);
7638 if (ieee80211_is_beacon(hdr
->frame_control
))
7639 ath11k_mac_handle_beacon(ar
, skb
);
7641 ath11k_dbg(ab
, ATH11K_DBG_MGMT
,
7642 "event mgmt rx skb %p len %d ftype %02x stype %02x\n",
7644 fc
& IEEE80211_FCTL_FTYPE
, fc
& IEEE80211_FCTL_STYPE
);
7646 ath11k_dbg(ab
, ATH11K_DBG_MGMT
,
7647 "event mgmt rx freq %d band %d snr %d, rate_idx %d\n",
7648 status
->freq
, status
->band
, status
->signal
,
7651 ieee80211_rx_ni(ar
->hw
, skb
);
7657 static void ath11k_mgmt_tx_compl_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7659 struct wmi_mgmt_tx_compl_event tx_compl_param
= {0};
7662 if (ath11k_pull_mgmt_tx_compl_param_tlv(ab
, skb
, &tx_compl_param
) != 0) {
7663 ath11k_warn(ab
, "failed to extract mgmt tx compl event");
7668 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, tx_compl_param
.pdev_id
);
7670 ath11k_warn(ab
, "invalid pdev id %d in mgmt_tx_compl_event\n",
7671 tx_compl_param
.pdev_id
);
7675 wmi_process_mgmt_tx_comp(ar
, &tx_compl_param
);
7677 ath11k_dbg(ab
, ATH11K_DBG_MGMT
,
7678 "event mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d",
7679 tx_compl_param
.pdev_id
, tx_compl_param
.desc_id
,
7680 tx_compl_param
.status
, tx_compl_param
.ack_rssi
);
7686 static struct ath11k
*ath11k_get_ar_on_scan_state(struct ath11k_base
*ab
,
7688 enum ath11k_scan_state state
)
7691 struct ath11k_pdev
*pdev
;
7694 for (i
= 0; i
< ab
->num_radios
; i
++) {
7695 pdev
= rcu_dereference(ab
->pdevs_active
[i
]);
7696 if (pdev
&& pdev
->ar
) {
7699 spin_lock_bh(&ar
->data_lock
);
7700 if (ar
->scan
.state
== state
&&
7701 ar
->scan
.vdev_id
== vdev_id
) {
7702 spin_unlock_bh(&ar
->data_lock
);
7705 spin_unlock_bh(&ar
->data_lock
);
7711 static void ath11k_scan_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7714 struct wmi_scan_event scan_ev
= {0};
7716 if (ath11k_pull_scan_ev(ab
, skb
, &scan_ev
) != 0) {
7717 ath11k_warn(ab
, "failed to extract scan event");
7723 /* In case the scan was cancelled, ex. during interface teardown,
7724 * the interface will not be found in active interfaces.
7725 * Rather, in such scenarios, iterate over the active pdev's to
7726 * search 'ar' if the corresponding 'ar' scan is ABORTING and the
7727 * aborting scan's vdev id matches this event info.
7729 if (scan_ev
.event_type
== WMI_SCAN_EVENT_COMPLETED
&&
7730 scan_ev
.reason
== WMI_SCAN_REASON_CANCELLED
) {
7731 ar
= ath11k_get_ar_on_scan_state(ab
, scan_ev
.vdev_id
,
7732 ATH11K_SCAN_ABORTING
);
7734 ar
= ath11k_get_ar_on_scan_state(ab
, scan_ev
.vdev_id
,
7735 ATH11K_SCAN_RUNNING
);
7737 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, scan_ev
.vdev_id
);
7741 ath11k_warn(ab
, "Received scan event for unknown vdev");
7746 spin_lock_bh(&ar
->data_lock
);
7748 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7749 "event scan %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n",
7750 ath11k_wmi_event_scan_type_str(scan_ev
.event_type
, scan_ev
.reason
),
7751 scan_ev
.event_type
, scan_ev
.reason
, scan_ev
.channel_freq
,
7752 scan_ev
.scan_req_id
, scan_ev
.scan_id
, scan_ev
.vdev_id
,
7753 ath11k_scan_state_str(ar
->scan
.state
), ar
->scan
.state
);
7755 switch (scan_ev
.event_type
) {
7756 case WMI_SCAN_EVENT_STARTED
:
7757 ath11k_wmi_event_scan_started(ar
);
7759 case WMI_SCAN_EVENT_COMPLETED
:
7760 ath11k_wmi_event_scan_completed(ar
);
7762 case WMI_SCAN_EVENT_BSS_CHANNEL
:
7763 ath11k_wmi_event_scan_bss_chan(ar
);
7765 case WMI_SCAN_EVENT_FOREIGN_CHAN
:
7766 ath11k_wmi_event_scan_foreign_chan(ar
, scan_ev
.channel_freq
);
7768 case WMI_SCAN_EVENT_START_FAILED
:
7769 ath11k_warn(ab
, "received scan start failure event\n");
7770 ath11k_wmi_event_scan_start_failed(ar
);
7772 case WMI_SCAN_EVENT_DEQUEUED
:
7773 __ath11k_mac_scan_finish(ar
);
7775 case WMI_SCAN_EVENT_PREEMPTED
:
7776 case WMI_SCAN_EVENT_RESTARTED
:
7777 case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT
:
7782 spin_unlock_bh(&ar
->data_lock
);
7787 static void ath11k_peer_sta_kickout_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7789 struct wmi_peer_sta_kickout_arg arg
= {};
7790 struct ieee80211_sta
*sta
;
7791 struct ath11k_peer
*peer
;
7795 if (ath11k_pull_peer_sta_kickout_ev(ab
, skb
, &arg
) != 0) {
7796 ath11k_warn(ab
, "failed to extract peer sta kickout event");
7802 spin_lock_bh(&ab
->base_lock
);
7804 peer
= ath11k_peer_find_by_addr(ab
, arg
.mac_addr
);
7807 ath11k_warn(ab
, "peer not found %pM\n",
7809 spin_unlock_bh(&ab
->base_lock
);
7813 vdev_id
= peer
->vdev_id
;
7815 spin_unlock_bh(&ab
->base_lock
);
7817 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, vdev_id
);
7819 ath11k_warn(ab
, "invalid vdev id in peer sta kickout ev %d",
7824 sta
= ieee80211_find_sta_by_ifaddr(ar
->hw
,
7825 arg
.mac_addr
, NULL
);
7827 ath11k_warn(ab
, "Spurious quick kickout for STA %pM\n",
7832 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event peer sta kickout %pM",
7835 ieee80211_report_low_ack(sta
, 10);
7841 static void ath11k_roam_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7843 struct wmi_roam_event roam_ev
= {};
7846 if (ath11k_pull_roam_ev(ab
, skb
, &roam_ev
) != 0) {
7847 ath11k_warn(ab
, "failed to extract roam event");
7851 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7852 "event roam vdev %u reason 0x%08x rssi %d\n",
7853 roam_ev
.vdev_id
, roam_ev
.reason
, roam_ev
.rssi
);
7856 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, roam_ev
.vdev_id
);
7858 ath11k_warn(ab
, "invalid vdev id in roam ev %d",
7864 if (roam_ev
.reason
>= WMI_ROAM_REASON_MAX
)
7865 ath11k_warn(ab
, "ignoring unknown roam event reason %d on vdev %i\n",
7866 roam_ev
.reason
, roam_ev
.vdev_id
);
7868 switch (roam_ev
.reason
) {
7869 case WMI_ROAM_REASON_BEACON_MISS
:
7870 ath11k_mac_handle_beacon_miss(ar
, roam_ev
.vdev_id
);
7872 case WMI_ROAM_REASON_BETTER_AP
:
7873 case WMI_ROAM_REASON_LOW_RSSI
:
7874 case WMI_ROAM_REASON_SUITABLE_AP_FOUND
:
7875 case WMI_ROAM_REASON_HO_FAILED
:
7876 ath11k_warn(ab
, "ignoring not implemented roam event reason %d on vdev %i\n",
7877 roam_ev
.reason
, roam_ev
.vdev_id
);
7884 static void ath11k_chan_info_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7886 struct wmi_chan_info_event ch_info_ev
= {0};
7888 struct survey_info
*survey
;
7890 /* HW channel counters frequency value in hertz */
7891 u32 cc_freq_hz
= ab
->cc_freq_hz
;
7893 if (ath11k_pull_chan_info_ev(ab
, skb
, &ch_info_ev
) != 0) {
7894 ath11k_warn(ab
, "failed to extract chan info event");
7898 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7899 "event chan info vdev_id %d err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d mac_clk_mhz %d\n",
7900 ch_info_ev
.vdev_id
, ch_info_ev
.err_code
, ch_info_ev
.freq
,
7901 ch_info_ev
.cmd_flags
, ch_info_ev
.noise_floor
,
7902 ch_info_ev
.rx_clear_count
, ch_info_ev
.cycle_count
,
7903 ch_info_ev
.mac_clk_mhz
);
7905 if (ch_info_ev
.cmd_flags
== WMI_CHAN_INFO_END_RESP
) {
7906 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "chan info report completed\n");
7911 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, ch_info_ev
.vdev_id
);
7913 ath11k_warn(ab
, "invalid vdev id in chan info ev %d",
7914 ch_info_ev
.vdev_id
);
7918 spin_lock_bh(&ar
->data_lock
);
7920 switch (ar
->scan
.state
) {
7921 case ATH11K_SCAN_IDLE
:
7922 case ATH11K_SCAN_STARTING
:
7923 ath11k_warn(ab
, "received chan info event without a scan request, ignoring\n");
7925 case ATH11K_SCAN_RUNNING
:
7926 case ATH11K_SCAN_ABORTING
:
7930 idx
= freq_to_idx(ar
, ch_info_ev
.freq
);
7931 if (idx
>= ARRAY_SIZE(ar
->survey
)) {
7932 ath11k_warn(ab
, "chan info: invalid frequency %d (idx %d out of bounds)\n",
7933 ch_info_ev
.freq
, idx
);
7937 /* If FW provides MAC clock frequency in Mhz, overriding the initialized
7938 * HW channel counters frequency value
7940 if (ch_info_ev
.mac_clk_mhz
)
7941 cc_freq_hz
= (ch_info_ev
.mac_clk_mhz
* 1000);
7943 if (ch_info_ev
.cmd_flags
== WMI_CHAN_INFO_START_RESP
) {
7944 survey
= &ar
->survey
[idx
];
7945 memset(survey
, 0, sizeof(*survey
));
7946 survey
->noise
= ch_info_ev
.noise_floor
;
7947 survey
->filled
= SURVEY_INFO_NOISE_DBM
| SURVEY_INFO_TIME
|
7948 SURVEY_INFO_TIME_BUSY
;
7949 survey
->time
= div_u64(ch_info_ev
.cycle_count
, cc_freq_hz
);
7950 survey
->time_busy
= div_u64(ch_info_ev
.rx_clear_count
, cc_freq_hz
);
7953 spin_unlock_bh(&ar
->data_lock
);
7958 ath11k_pdev_bss_chan_info_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
7960 struct wmi_pdev_bss_chan_info_event bss_ch_info_ev
= {};
7961 struct survey_info
*survey
;
7963 u32 cc_freq_hz
= ab
->cc_freq_hz
;
7964 u64 busy
, total
, tx
, rx
, rx_bss
;
7967 if (ath11k_pull_pdev_bss_chan_info_ev(ab
, skb
, &bss_ch_info_ev
) != 0) {
7968 ath11k_warn(ab
, "failed to extract pdev bss chan info event");
7972 busy
= (u64
)(bss_ch_info_ev
.rx_clear_count_high
) << 32 |
7973 bss_ch_info_ev
.rx_clear_count_low
;
7975 total
= (u64
)(bss_ch_info_ev
.cycle_count_high
) << 32 |
7976 bss_ch_info_ev
.cycle_count_low
;
7978 tx
= (u64
)(bss_ch_info_ev
.tx_cycle_count_high
) << 32 |
7979 bss_ch_info_ev
.tx_cycle_count_low
;
7981 rx
= (u64
)(bss_ch_info_ev
.rx_cycle_count_high
) << 32 |
7982 bss_ch_info_ev
.rx_cycle_count_low
;
7984 rx_bss
= (u64
)(bss_ch_info_ev
.rx_bss_cycle_count_high
) << 32 |
7985 bss_ch_info_ev
.rx_bss_cycle_count_low
;
7987 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
7988 "event pdev bss chan info:\n pdev_id: %d freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
7989 bss_ch_info_ev
.pdev_id
, bss_ch_info_ev
.freq
,
7990 bss_ch_info_ev
.noise_floor
, busy
, total
,
7994 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, bss_ch_info_ev
.pdev_id
);
7997 ath11k_warn(ab
, "invalid pdev id %d in bss_chan_info event\n",
7998 bss_ch_info_ev
.pdev_id
);
8003 spin_lock_bh(&ar
->data_lock
);
8004 idx
= freq_to_idx(ar
, bss_ch_info_ev
.freq
);
8005 if (idx
>= ARRAY_SIZE(ar
->survey
)) {
8006 ath11k_warn(ab
, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
8007 bss_ch_info_ev
.freq
, idx
);
8011 survey
= &ar
->survey
[idx
];
8013 survey
->noise
= bss_ch_info_ev
.noise_floor
;
8014 survey
->time
= div_u64(total
, cc_freq_hz
);
8015 survey
->time_busy
= div_u64(busy
, cc_freq_hz
);
8016 survey
->time_rx
= div_u64(rx_bss
, cc_freq_hz
);
8017 survey
->time_tx
= div_u64(tx
, cc_freq_hz
);
8018 survey
->filled
|= (SURVEY_INFO_NOISE_DBM
|
8020 SURVEY_INFO_TIME_BUSY
|
8021 SURVEY_INFO_TIME_RX
|
8022 SURVEY_INFO_TIME_TX
);
8024 spin_unlock_bh(&ar
->data_lock
);
8025 complete(&ar
->bss_survey_done
);
8030 static void ath11k_vdev_install_key_compl_event(struct ath11k_base
*ab
,
8031 struct sk_buff
*skb
)
8033 struct wmi_vdev_install_key_complete_arg install_key_compl
= {0};
8036 if (ath11k_pull_vdev_install_key_compl_ev(ab
, skb
, &install_key_compl
) != 0) {
8037 ath11k_warn(ab
, "failed to extract install key compl event");
8041 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8042 "event vdev install key ev idx %d flags %08x macaddr %pM status %d\n",
8043 install_key_compl
.key_idx
, install_key_compl
.key_flags
,
8044 install_key_compl
.macaddr
, install_key_compl
.status
);
8047 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, install_key_compl
.vdev_id
);
8049 ath11k_warn(ab
, "invalid vdev id in install key compl ev %d",
8050 install_key_compl
.vdev_id
);
8055 ar
->install_key_status
= 0;
8057 if (install_key_compl
.status
!= WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS
) {
8058 ath11k_warn(ab
, "install key failed for %pM status %d\n",
8059 install_key_compl
.macaddr
, install_key_compl
.status
);
8060 ar
->install_key_status
= install_key_compl
.status
;
8063 complete(&ar
->install_key_done
);
8067 static int ath11k_wmi_tlv_services_parser(struct ath11k_base
*ab
,
8069 const void *ptr
, void *data
)
8071 const struct wmi_service_available_event
*ev
;
8072 u32
*wmi_ext2_service_bitmap
;
8076 case WMI_TAG_SERVICE_AVAILABLE_EVENT
:
8077 ev
= (struct wmi_service_available_event
*)ptr
;
8078 for (i
= 0, j
= WMI_MAX_SERVICE
;
8079 i
< WMI_SERVICE_SEGMENT_BM_SIZE32
&& j
< WMI_MAX_EXT_SERVICE
;
8082 if (ev
->wmi_service_segment_bitmap
[i
] &
8083 BIT(j
% WMI_AVAIL_SERVICE_BITS_IN_SIZE32
))
8084 set_bit(j
, ab
->wmi_ab
.svc_map
);
8085 } while (++j
% WMI_AVAIL_SERVICE_BITS_IN_SIZE32
);
8088 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8089 "wmi_ext_service_bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x",
8090 ev
->wmi_service_segment_bitmap
[0],
8091 ev
->wmi_service_segment_bitmap
[1],
8092 ev
->wmi_service_segment_bitmap
[2],
8093 ev
->wmi_service_segment_bitmap
[3]);
8095 case WMI_TAG_ARRAY_UINT32
:
8096 wmi_ext2_service_bitmap
= (u32
*)ptr
;
8097 for (i
= 0, j
= WMI_MAX_EXT_SERVICE
;
8098 i
< WMI_SERVICE_SEGMENT_BM_SIZE32
&& j
< WMI_MAX_EXT2_SERVICE
;
8101 if (wmi_ext2_service_bitmap
[i
] &
8102 BIT(j
% WMI_AVAIL_SERVICE_BITS_IN_SIZE32
))
8103 set_bit(j
, ab
->wmi_ab
.svc_map
);
8104 } while (++j
% WMI_AVAIL_SERVICE_BITS_IN_SIZE32
);
8107 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8108 "wmi_ext2_service__bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x",
8109 wmi_ext2_service_bitmap
[0], wmi_ext2_service_bitmap
[1],
8110 wmi_ext2_service_bitmap
[2], wmi_ext2_service_bitmap
[3]);
8116 static void ath11k_service_available_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8120 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
8121 ath11k_wmi_tlv_services_parser
,
8124 ath11k_warn(ab
, "failed to parse services available tlv %d\n", ret
);
8126 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event service available");
8129 static void ath11k_peer_assoc_conf_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8131 struct wmi_peer_assoc_conf_arg peer_assoc_conf
= {0};
8134 if (ath11k_pull_peer_assoc_conf_ev(ab
, skb
, &peer_assoc_conf
) != 0) {
8135 ath11k_warn(ab
, "failed to extract peer assoc conf event");
8139 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8140 "event peer assoc conf ev vdev id %d macaddr %pM\n",
8141 peer_assoc_conf
.vdev_id
, peer_assoc_conf
.macaddr
);
8144 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, peer_assoc_conf
.vdev_id
);
8147 ath11k_warn(ab
, "invalid vdev id in peer assoc conf ev %d",
8148 peer_assoc_conf
.vdev_id
);
8153 complete(&ar
->peer_assoc_done
);
8157 static void ath11k_update_stats_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8159 struct ath11k_fw_stats stats
= {};
8163 INIT_LIST_HEAD(&stats
.pdevs
);
8164 INIT_LIST_HEAD(&stats
.vdevs
);
8165 INIT_LIST_HEAD(&stats
.bcn
);
8167 ret
= ath11k_wmi_pull_fw_stats(ab
, skb
, &stats
);
8169 ath11k_warn(ab
, "failed to pull fw stats: %d\n", ret
);
8173 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event update stats");
8176 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, stats
.pdev_id
);
8179 ath11k_warn(ab
, "failed to get ar for pdev_id %d: %d\n",
8180 stats
.pdev_id
, ret
);
8184 spin_lock_bh(&ar
->data_lock
);
8186 /* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
8187 * debugfs fw stats. Therefore, processing it separately.
8189 if (stats
.stats_id
== WMI_REQUEST_PDEV_STAT
) {
8190 list_splice_tail_init(&stats
.pdevs
, &ar
->fw_stats
.pdevs
);
8191 ar
->fw_stats_done
= true;
8195 /* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
8196 * are currently requested only via debugfs fw stats. Hence, processing these
8197 * in debugfs context
8199 ath11k_debugfs_fw_stats_process(ar
, &stats
);
8202 complete(&ar
->fw_stats_complete
);
8204 spin_unlock_bh(&ar
->data_lock
);
8206 /* Since the stats's pdev, vdev and beacon list are spliced and reinitialised
8207 * at this point, no need to free the individual list.
8212 ath11k_fw_stats_free(&stats
);
8215 /* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned
8216 * is not part of BDF CTL(Conformance test limits) table entries.
8218 static void ath11k_pdev_ctl_failsafe_check_event(struct ath11k_base
*ab
,
8219 struct sk_buff
*skb
)
8222 const struct wmi_pdev_ctl_failsafe_chk_event
*ev
;
8225 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8228 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
8232 ev
= tb
[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT
];
8234 ath11k_warn(ab
, "failed to fetch pdev ctl failsafe check ev");
8239 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8240 "event pdev ctl failsafe check status %d\n",
8241 ev
->ctl_failsafe_status
);
8243 /* If ctl_failsafe_status is set to 1 FW will max out the Transmit power
8244 * to 10 dBm else the CTL power entry in the BDF would be picked up.
8246 if (ev
->ctl_failsafe_status
!= 0)
8247 ath11k_warn(ab
, "pdev ctl failsafe failure status %d",
8248 ev
->ctl_failsafe_status
);
8254 ath11k_wmi_process_csa_switch_count_event(struct ath11k_base
*ab
,
8255 const struct wmi_pdev_csa_switch_ev
*ev
,
8256 const u32
*vdev_ids
)
8259 struct ath11k_vif
*arvif
;
8261 /* Finish CSA once the switch count becomes NULL */
8262 if (ev
->current_switch_count
)
8266 for (i
= 0; i
< ev
->num_vdevs
; i
++) {
8267 arvif
= ath11k_mac_get_arvif_by_vdev_id(ab
, vdev_ids
[i
]);
8270 ath11k_warn(ab
, "Recvd csa status for unknown vdev %d",
8275 if (arvif
->is_up
&& arvif
->vif
->bss_conf
.csa_active
)
8276 ieee80211_csa_finish(arvif
->vif
, 0);
8282 ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base
*ab
,
8283 struct sk_buff
*skb
)
8286 const struct wmi_pdev_csa_switch_ev
*ev
;
8287 const u32
*vdev_ids
;
8290 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8293 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
8297 ev
= tb
[WMI_TAG_PDEV_CSA_SWITCH_COUNT_STATUS_EVENT
];
8298 vdev_ids
= tb
[WMI_TAG_ARRAY_UINT32
];
8300 if (!ev
|| !vdev_ids
) {
8301 ath11k_warn(ab
, "failed to fetch pdev csa switch count ev");
8306 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8307 "event pdev csa switch count %d for pdev %d, num_vdevs %d",
8308 ev
->current_switch_count
, ev
->pdev_id
,
8311 ath11k_wmi_process_csa_switch_count_event(ab
, ev
, vdev_ids
);
8317 ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8320 const struct wmi_pdev_radar_ev
*ev
;
8324 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8327 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
8331 ev
= tb
[WMI_TAG_PDEV_DFS_RADAR_DETECTION_EVENT
];
8334 ath11k_warn(ab
, "failed to fetch pdev dfs radar detected ev");
8339 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8340 "event pdev dfs radar detected on pdev %d, detection mode %d, chan freq %d, chan_width %d, detector id %d, seg id %d, timestamp %d, chirp %d, freq offset %d, sidx %d",
8341 ev
->pdev_id
, ev
->detection_mode
, ev
->chan_freq
, ev
->chan_width
,
8342 ev
->detector_id
, ev
->segment_id
, ev
->timestamp
, ev
->is_chirp
,
8343 ev
->freq_offset
, ev
->sidx
);
8347 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, ev
->pdev_id
);
8350 ath11k_warn(ab
, "radar detected in invalid pdev %d\n",
8355 ath11k_dbg(ar
->ab
, ATH11K_DBG_REG
, "DFS Radar Detected in pdev %d\n",
8358 if (ar
->dfs_block_radar_events
)
8359 ath11k_info(ab
, "DFS Radar detected, but ignored as requested\n");
8361 ieee80211_radar_detected(ar
->hw
, NULL
);
8370 ath11k_wmi_pdev_temperature_event(struct ath11k_base
*ab
,
8371 struct sk_buff
*skb
)
8375 const struct wmi_pdev_temperature_event
*ev
;
8378 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8381 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
8385 ev
= tb
[WMI_TAG_PDEV_TEMPERATURE_EVENT
];
8387 ath11k_warn(ab
, "failed to fetch pdev temp ev");
8392 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event pdev temperature ev temp %d pdev_id %d\n",
8393 ev
->temp
, ev
->pdev_id
);
8397 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, ev
->pdev_id
);
8399 ath11k_warn(ab
, "invalid pdev id in pdev temperature ev %d", ev
->pdev_id
);
8403 ath11k_thermal_event_temperature(ar
, ev
->temp
);
8411 static void ath11k_fils_discovery_event(struct ath11k_base
*ab
,
8412 struct sk_buff
*skb
)
8415 const struct wmi_fils_discovery_event
*ev
;
8418 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8422 "failed to parse FILS discovery event tlv %d\n",
8427 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event fils discovery");
8429 ev
= tb
[WMI_TAG_HOST_SWFDA_EVENT
];
8431 ath11k_warn(ab
, "failed to fetch FILS discovery event\n");
8437 "FILS discovery frame expected from host for vdev_id: %u, transmission scheduled at %u, next TBTT: %u\n",
8438 ev
->vdev_id
, ev
->fils_tt
, ev
->tbtt
);
8443 static void ath11k_probe_resp_tx_status_event(struct ath11k_base
*ab
,
8444 struct sk_buff
*skb
)
8447 const struct wmi_probe_resp_tx_status_event
*ev
;
8450 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8454 "failed to parse probe response transmission status event tlv: %d\n",
8459 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event probe resp tx status");
8461 ev
= tb
[WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT
];
8464 "failed to fetch probe response transmission status event");
8471 "Probe response transmission failed for vdev_id %u, status %u\n",
8472 ev
->vdev_id
, ev
->tx_status
);
8477 static int ath11k_wmi_tlv_wow_wakeup_host_parse(struct ath11k_base
*ab
,
8479 const void *ptr
, void *data
)
8481 struct wmi_wow_ev_arg
*ev
= data
;
8482 const char *wow_pg_fault
;
8486 case WMI_TAG_WOW_EVENT_INFO
:
8487 memcpy(ev
, ptr
, sizeof(*ev
));
8488 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "wow wakeup host reason %d %s\n",
8489 ev
->wake_reason
, wow_reason(ev
->wake_reason
));
8492 case WMI_TAG_ARRAY_BYTE
:
8493 if (ev
&& ev
->wake_reason
== WOW_REASON_PAGE_FAULT
) {
8495 /* the first 4 bytes are length */
8496 wow_pg_len
= *(int *)wow_pg_fault
;
8497 wow_pg_fault
+= sizeof(int);
8498 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "wow data_len = %d\n",
8500 ath11k_dbg_dump(ab
, ATH11K_DBG_WMI
,
8501 "wow_event_info_type packet present",
8514 static void ath11k_wmi_event_wow_wakeup_host(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8516 struct wmi_wow_ev_arg ev
= { };
8519 ret
= ath11k_wmi_tlv_iter(ab
, skb
->data
, skb
->len
,
8520 ath11k_wmi_tlv_wow_wakeup_host_parse
,
8523 ath11k_warn(ab
, "failed to parse wmi wow tlv: %d\n", ret
);
8527 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event wow wakeup host");
8529 complete(&ab
->wow
.wakeup_completed
);
8533 ath11k_wmi_diag_event(struct ath11k_base
*ab
,
8534 struct sk_buff
*skb
)
8536 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event diag");
8538 trace_ath11k_wmi_diag(ab
, skb
->data
, skb
->len
);
8541 static const char *ath11k_wmi_twt_add_dialog_event_status(u32 status
)
8544 case WMI_ADD_TWT_STATUS_OK
:
8546 case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED
:
8547 return "twt disabled";
8548 case WMI_ADD_TWT_STATUS_USED_DIALOG_ID
:
8549 return "dialog id in use";
8550 case WMI_ADD_TWT_STATUS_INVALID_PARAM
:
8551 return "invalid parameters";
8552 case WMI_ADD_TWT_STATUS_NOT_READY
:
8554 case WMI_ADD_TWT_STATUS_NO_RESOURCE
:
8555 return "resource unavailable";
8556 case WMI_ADD_TWT_STATUS_NO_ACK
:
8558 case WMI_ADD_TWT_STATUS_NO_RESPONSE
:
8559 return "no response";
8560 case WMI_ADD_TWT_STATUS_DENIED
:
8562 case WMI_ADD_TWT_STATUS_UNKNOWN_ERROR
:
8565 return "unknown error";
8569 static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base
*ab
,
8570 struct sk_buff
*skb
)
8573 const struct wmi_twt_add_dialog_event
*ev
;
8576 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8580 "failed to parse wmi twt add dialog status event tlv: %d\n",
8585 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event twt add dialog");
8587 ev
= tb
[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT
];
8589 ath11k_warn(ab
, "failed to fetch twt add dialog wmi event\n");
8595 "wmi add twt dialog event vdev %d dialog id %d status %s\n",
8596 ev
->vdev_id
, ev
->dialog_id
,
8597 ath11k_wmi_twt_add_dialog_event_status(ev
->status
));
8603 static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base
*ab
,
8604 struct sk_buff
*skb
)
8607 const struct wmi_gtk_offload_status_event
*ev
;
8608 struct ath11k_vif
*arvif
;
8609 __be64 replay_ctr_be
;
8613 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8616 ath11k_warn(ab
, "failed to parse tlv: %d\n", ret
);
8620 ev
= tb
[WMI_TAG_GTK_OFFLOAD_STATUS_EVENT
];
8622 ath11k_warn(ab
, "failed to fetch gtk offload status ev");
8629 arvif
= ath11k_mac_get_arvif_by_vdev_id(ab
, ev
->vdev_id
);
8631 ath11k_warn(ab
, "failed to get arvif for vdev_id:%d\n",
8636 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "event gtk offload refresh_cnt %d\n",
8638 ath11k_dbg_dump(ab
, ATH11K_DBG_WMI
, "replay_cnt",
8639 NULL
, ev
->replay_ctr
.counter
, GTK_REPLAY_COUNTER_BYTES
);
8641 replay_ctr
= ev
->replay_ctr
.word1
;
8642 replay_ctr
= (replay_ctr
<< 32) | ev
->replay_ctr
.word0
;
8643 arvif
->rekey_data
.replay_ctr
= replay_ctr
;
8645 /* supplicant expects big-endian replay counter */
8646 replay_ctr_be
= cpu_to_be64(replay_ctr
);
8648 ieee80211_gtk_rekey_notify(arvif
->vif
, arvif
->bssid
,
8649 (void *)&replay_ctr_be
, GFP_ATOMIC
);
8656 static void ath11k_wmi_p2p_noa_event(struct ath11k_base
*ab
,
8657 struct sk_buff
*skb
)
8660 const struct wmi_p2p_noa_event
*ev
;
8661 const struct ath11k_wmi_p2p_noa_info
*noa
;
8666 tb
= ath11k_wmi_tlv_parse_alloc(ab
, skb
, GFP_ATOMIC
);
8668 ath11k_warn(ab
, "failed to parse tlv: %ld\n", PTR_ERR(tb
));
8672 ev
= tb
[WMI_TAG_P2P_NOA_EVENT
];
8673 noa
= tb
[WMI_TAG_P2P_NOA_INFO
];
8678 vdev_id
= ev
->vdev_id
;
8679 noa_descriptors
= u32_get_bits(noa
->noa_attr
,
8680 WMI_P2P_NOA_INFO_DESC_NUM
);
8682 if (noa_descriptors
> WMI_P2P_MAX_NOA_DESCRIPTORS
) {
8683 ath11k_warn(ab
, "invalid descriptor num %d in P2P NoA event\n",
8688 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
8689 "wmi tlv p2p noa vdev_id %i descriptors %u\n",
8690 vdev_id
, noa_descriptors
);
8693 ar
= ath11k_mac_get_ar_by_vdev_id(ab
, vdev_id
);
8695 ath11k_warn(ab
, "invalid vdev id %d in P2P NoA event\n",
8700 ath11k_p2p_noa_update_by_vdev_id(ar
, vdev_id
, noa
);
8708 static void ath11k_wmi_tlv_op_rx(struct ath11k_base
*ab
, struct sk_buff
*skb
)
8710 struct wmi_cmd_hdr
*cmd_hdr
;
8711 enum wmi_tlv_event_id id
;
8713 cmd_hdr
= (struct wmi_cmd_hdr
*)skb
->data
;
8714 id
= FIELD_GET(WMI_CMD_HDR_CMD_ID
, (cmd_hdr
->cmd_id
));
8716 trace_ath11k_wmi_event(ab
, id
, skb
->data
, skb
->len
);
8718 if (skb_pull(skb
, sizeof(struct wmi_cmd_hdr
)) == NULL
)
8722 /* Process all the WMI events here */
8723 case WMI_SERVICE_READY_EVENTID
:
8724 ath11k_service_ready_event(ab
, skb
);
8726 case WMI_SERVICE_READY_EXT_EVENTID
:
8727 ath11k_service_ready_ext_event(ab
, skb
);
8729 case WMI_SERVICE_READY_EXT2_EVENTID
:
8730 ath11k_service_ready_ext2_event(ab
, skb
);
8732 case WMI_REG_CHAN_LIST_CC_EVENTID
:
8733 ath11k_reg_chan_list_event(ab
, skb
, WMI_REG_CHAN_LIST_CC_ID
);
8735 case WMI_REG_CHAN_LIST_CC_EXT_EVENTID
:
8736 ath11k_reg_chan_list_event(ab
, skb
, WMI_REG_CHAN_LIST_CC_EXT_ID
);
8738 case WMI_READY_EVENTID
:
8739 ath11k_ready_event(ab
, skb
);
8741 case WMI_PEER_DELETE_RESP_EVENTID
:
8742 ath11k_peer_delete_resp_event(ab
, skb
);
8744 case WMI_VDEV_START_RESP_EVENTID
:
8745 ath11k_vdev_start_resp_event(ab
, skb
);
8747 case WMI_OFFLOAD_BCN_TX_STATUS_EVENTID
:
8748 ath11k_bcn_tx_status_event(ab
, skb
);
8750 case WMI_VDEV_STOPPED_EVENTID
:
8751 ath11k_vdev_stopped_event(ab
, skb
);
8753 case WMI_MGMT_RX_EVENTID
:
8754 ath11k_mgmt_rx_event(ab
, skb
);
8755 /* mgmt_rx_event() owns the skb now! */
8757 case WMI_MGMT_TX_COMPLETION_EVENTID
:
8758 ath11k_mgmt_tx_compl_event(ab
, skb
);
8760 case WMI_SCAN_EVENTID
:
8761 ath11k_scan_event(ab
, skb
);
8763 case WMI_PEER_STA_KICKOUT_EVENTID
:
8764 ath11k_peer_sta_kickout_event(ab
, skb
);
8766 case WMI_ROAM_EVENTID
:
8767 ath11k_roam_event(ab
, skb
);
8769 case WMI_CHAN_INFO_EVENTID
:
8770 ath11k_chan_info_event(ab
, skb
);
8772 case WMI_PDEV_BSS_CHAN_INFO_EVENTID
:
8773 ath11k_pdev_bss_chan_info_event(ab
, skb
);
8775 case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID
:
8776 ath11k_vdev_install_key_compl_event(ab
, skb
);
8778 case WMI_SERVICE_AVAILABLE_EVENTID
:
8779 ath11k_service_available_event(ab
, skb
);
8781 case WMI_PEER_ASSOC_CONF_EVENTID
:
8782 ath11k_peer_assoc_conf_event(ab
, skb
);
8784 case WMI_UPDATE_STATS_EVENTID
:
8785 ath11k_update_stats_event(ab
, skb
);
8787 case WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID
:
8788 ath11k_pdev_ctl_failsafe_check_event(ab
, skb
);
8790 case WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID
:
8791 ath11k_wmi_pdev_csa_switch_count_status_event(ab
, skb
);
8793 case WMI_PDEV_UTF_EVENTID
:
8794 ath11k_tm_wmi_event(ab
, id
, skb
);
8796 case WMI_PDEV_TEMPERATURE_EVENTID
:
8797 ath11k_wmi_pdev_temperature_event(ab
, skb
);
8799 case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID
:
8800 ath11k_wmi_pdev_dma_ring_buf_release_event(ab
, skb
);
8802 case WMI_HOST_FILS_DISCOVERY_EVENTID
:
8803 ath11k_fils_discovery_event(ab
, skb
);
8805 case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID
:
8806 ath11k_probe_resp_tx_status_event(ab
, skb
);
8808 case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID
:
8809 ath11k_wmi_obss_color_collision_event(ab
, skb
);
8811 case WMI_TWT_ADD_DIALOG_EVENTID
:
8812 ath11k_wmi_twt_add_dialog_event(ab
, skb
);
8814 case WMI_PDEV_DFS_RADAR_DETECTION_EVENTID
:
8815 ath11k_wmi_pdev_dfs_radar_detected_event(ab
, skb
);
8817 case WMI_VDEV_DELETE_RESP_EVENTID
:
8818 ath11k_vdev_delete_resp_event(ab
, skb
);
8820 case WMI_WOW_WAKEUP_HOST_EVENTID
:
8821 ath11k_wmi_event_wow_wakeup_host(ab
, skb
);
8823 case WMI_11D_NEW_COUNTRY_EVENTID
:
8824 ath11k_reg_11d_new_cc_event(ab
, skb
);
8826 case WMI_DIAG_EVENTID
:
8827 ath11k_wmi_diag_event(ab
, skb
);
8829 case WMI_PEER_STA_PS_STATECHG_EVENTID
:
8830 ath11k_wmi_event_peer_sta_ps_state_chg(ab
, skb
);
8832 case WMI_GTK_OFFLOAD_STATUS_EVENTID
:
8833 ath11k_wmi_gtk_offload_status_event(ab
, skb
);
8835 case WMI_P2P_NOA_EVENTID
:
8836 ath11k_wmi_p2p_noa_event(ab
, skb
);
8839 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "unsupported event id 0x%x\n", id
);
8847 static int ath11k_connect_pdev_htc_service(struct ath11k_base
*ab
,
8851 u32 svc_id
[] = { ATH11K_HTC_SVC_ID_WMI_CONTROL
,
8852 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1
,
8853 ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2
};
8855 struct ath11k_htc_svc_conn_req conn_req
;
8856 struct ath11k_htc_svc_conn_resp conn_resp
;
8858 memset(&conn_req
, 0, sizeof(conn_req
));
8859 memset(&conn_resp
, 0, sizeof(conn_resp
));
8861 /* these fields are the same for all service endpoints */
8862 conn_req
.ep_ops
.ep_tx_complete
= ath11k_wmi_htc_tx_complete
;
8863 conn_req
.ep_ops
.ep_rx_complete
= ath11k_wmi_tlv_op_rx
;
8864 conn_req
.ep_ops
.ep_tx_credits
= ath11k_wmi_op_ep_tx_credits
;
8866 /* connect to control service */
8867 conn_req
.service_id
= svc_id
[pdev_idx
];
8869 status
= ath11k_htc_connect_service(&ab
->htc
, &conn_req
, &conn_resp
);
8871 ath11k_warn(ab
, "failed to connect to WMI CONTROL service status: %d\n",
8876 ab
->wmi_ab
.wmi_endpoint_id
[pdev_idx
] = conn_resp
.eid
;
8877 ab
->wmi_ab
.wmi
[pdev_idx
].eid
= conn_resp
.eid
;
8878 ab
->wmi_ab
.max_msg_len
[pdev_idx
] = conn_resp
.max_msg_len
;
8879 init_waitqueue_head(&ab
->wmi_ab
.wmi
[pdev_idx
].tx_ce_desc_wq
);
8885 ath11k_wmi_send_unit_test_cmd(struct ath11k
*ar
,
8886 struct wmi_unit_test_cmd ut_cmd
,
8889 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
8890 struct wmi_unit_test_cmd
*cmd
;
8891 struct sk_buff
*skb
;
8892 struct wmi_tlv
*tlv
;
8895 int buf_len
, arg_len
;
8899 arg_len
= sizeof(u32
) * ut_cmd
.num_args
;
8900 buf_len
= sizeof(ut_cmd
) + arg_len
+ TLV_HDR_SIZE
;
8902 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, buf_len
);
8906 cmd
= (struct wmi_unit_test_cmd
*)skb
->data
;
8907 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_UNIT_TEST_CMD
) |
8908 FIELD_PREP(WMI_TLV_LEN
, sizeof(ut_cmd
) - TLV_HDR_SIZE
);
8910 cmd
->vdev_id
= ut_cmd
.vdev_id
;
8911 cmd
->module_id
= ut_cmd
.module_id
;
8912 cmd
->num_args
= ut_cmd
.num_args
;
8913 cmd
->diag_token
= ut_cmd
.diag_token
;
8915 ptr
= skb
->data
+ sizeof(ut_cmd
);
8918 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_UINT32
) |
8919 FIELD_PREP(WMI_TLV_LEN
, arg_len
);
8921 ptr
+= TLV_HDR_SIZE
;
8924 for (i
= 0; i
< ut_cmd
.num_args
; i
++)
8925 ut_cmd_args
[i
] = test_args
[i
];
8927 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_UNIT_TEST_CMDID
);
8930 ath11k_warn(ar
->ab
, "failed to send WMI_UNIT_TEST CMD :%d\n",
8935 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
8936 "cmd unit test module %d vdev %d n_args %d token %d\n",
8937 cmd
->module_id
, cmd
->vdev_id
, cmd
->num_args
,
8943 int ath11k_wmi_simulate_radar(struct ath11k
*ar
)
8945 struct ath11k_vif
*arvif
;
8946 u32 dfs_args
[DFS_MAX_TEST_ARGS
];
8947 struct wmi_unit_test_cmd wmi_ut
;
8948 bool arvif_found
= false;
8950 list_for_each_entry(arvif
, &ar
->arvifs
, list
) {
8951 if (arvif
->is_started
&& arvif
->vdev_type
== WMI_VDEV_TYPE_AP
) {
8960 dfs_args
[DFS_TEST_CMDID
] = 0;
8961 dfs_args
[DFS_TEST_PDEV_ID
] = ar
->pdev
->pdev_id
;
8962 /* Currently we could pass segment_id(b0 - b1), chirp(b2)
8963 * freq offset (b3 - b10) to unit test. For simulation
8964 * purpose this can be set to 0 which is valid.
8966 dfs_args
[DFS_TEST_RADAR_PARAM
] = 0;
8968 wmi_ut
.vdev_id
= arvif
->vdev_id
;
8969 wmi_ut
.module_id
= DFS_UNIT_TEST_MODULE
;
8970 wmi_ut
.num_args
= DFS_MAX_TEST_ARGS
;
8971 wmi_ut
.diag_token
= DFS_UNIT_TEST_TOKEN
;
8973 ath11k_dbg(ar
->ab
, ATH11K_DBG_REG
, "Triggering Radar Simulation\n");
8975 return ath11k_wmi_send_unit_test_cmd(ar
, wmi_ut
, dfs_args
);
8978 int ath11k_wmi_fw_dbglog_cfg(struct ath11k
*ar
, u32
*module_id_bitmap
,
8979 struct ath11k_fw_dbglog
*dbglog
)
8981 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
8982 struct wmi_debug_log_config_cmd_fixed_param
*cmd
;
8983 struct sk_buff
*skb
;
8984 struct wmi_tlv
*tlv
;
8987 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ (MAX_MODULE_ID_BITMAP_WORDS
* sizeof(u32
));
8988 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
8992 cmd
= (struct wmi_debug_log_config_cmd_fixed_param
*)skb
->data
;
8993 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_DEBUG_LOG_CONFIG_CMD
) |
8994 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
8995 cmd
->dbg_log_param
= dbglog
->param
;
8997 tlv
= (struct wmi_tlv
*)((u8
*)cmd
+ sizeof(*cmd
));
8998 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_UINT32
) |
8999 FIELD_PREP(WMI_TLV_LEN
, MAX_MODULE_ID_BITMAP_WORDS
* sizeof(u32
));
9001 switch (dbglog
->param
) {
9002 case WMI_DEBUG_LOG_PARAM_LOG_LEVEL
:
9003 case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE
:
9004 case WMI_DEBUG_LOG_PARAM_VDEV_DISABLE
:
9005 case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP
:
9006 cmd
->value
= dbglog
->value
;
9008 case WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP
:
9009 case WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP
:
9010 cmd
->value
= dbglog
->value
;
9011 memcpy(tlv
->value
, module_id_bitmap
,
9012 MAX_MODULE_ID_BITMAP_WORDS
* sizeof(u32
));
9013 /* clear current config to be used for next user config */
9014 memset(module_id_bitmap
, 0,
9015 MAX_MODULE_ID_BITMAP_WORDS
* sizeof(u32
));
9022 ret
= ath11k_wmi_cmd_send(wmi
, skb
, WMI_DBGLOG_CFG_CMDID
);
9025 "failed to send WMI_DBGLOG_CFG_CMDID\n");
9029 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "cmd dbglog cfg");
9034 int ath11k_wmi_connect(struct ath11k_base
*ab
)
9039 wmi_ep_count
= ab
->htc
.wmi_ep_count
;
9040 if (wmi_ep_count
> ab
->hw_params
.max_radios
)
9043 for (i
= 0; i
< wmi_ep_count
; i
++)
9044 ath11k_connect_pdev_htc_service(ab
, i
);
9049 static void ath11k_wmi_pdev_detach(struct ath11k_base
*ab
, u8 pdev_id
)
9051 if (WARN_ON(pdev_id
>= MAX_RADIOS
))
9054 /* TODO: Deinit any pdev specific wmi resource */
9057 int ath11k_wmi_pdev_attach(struct ath11k_base
*ab
,
9060 struct ath11k_pdev_wmi
*wmi_handle
;
9062 if (pdev_id
>= ab
->hw_params
.max_radios
)
9065 wmi_handle
= &ab
->wmi_ab
.wmi
[pdev_id
];
9067 wmi_handle
->wmi_ab
= &ab
->wmi_ab
;
9070 /* TODO: Init remaining resource specific to pdev */
9075 int ath11k_wmi_attach(struct ath11k_base
*ab
)
9079 ret
= ath11k_wmi_pdev_attach(ab
, 0);
9084 ab
->wmi_ab
.preferred_hw_mode
= WMI_HOST_HW_MODE_MAX
;
9086 /* It's overwritten when service_ext_ready is handled */
9087 if (ab
->hw_params
.single_pdev_only
&& ab
->hw_params
.num_rxdma_per_pdev
> 1)
9088 ab
->wmi_ab
.preferred_hw_mode
= WMI_HOST_HW_MODE_SINGLE
;
9090 /* TODO: Init remaining wmi soc resources required */
9091 init_completion(&ab
->wmi_ab
.service_ready
);
9092 init_completion(&ab
->wmi_ab
.unified_ready
);
9097 void ath11k_wmi_detach(struct ath11k_base
*ab
)
9101 /* TODO: Deinit wmi resource specific to SOC as required */
9103 for (i
= 0; i
< ab
->htc
.wmi_ep_count
; i
++)
9104 ath11k_wmi_pdev_detach(ab
, i
);
9106 ath11k_wmi_free_dbring_caps(ab
);
9109 int ath11k_wmi_hw_data_filter_cmd(struct ath11k
*ar
, u32 vdev_id
,
9110 u32 filter_bitmap
, bool enable
)
9112 struct wmi_hw_data_filter_cmd
*cmd
;
9113 struct sk_buff
*skb
;
9117 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9122 cmd
= (struct wmi_hw_data_filter_cmd
*)skb
->data
;
9123 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_HW_DATA_FILTER_CMD
) |
9124 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9126 cmd
->vdev_id
= vdev_id
;
9127 cmd
->enable
= enable
;
9129 /* Set all modes in case of disable */
9131 cmd
->hw_filter_bitmap
= filter_bitmap
;
9133 cmd
->hw_filter_bitmap
= ((u32
)~0U);
9135 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
9136 "hw data filter enable %d filter_bitmap 0x%x\n",
9137 enable
, filter_bitmap
);
9139 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_HW_DATA_FILTER_CMDID
);
9142 int ath11k_wmi_wow_host_wakeup_ind(struct ath11k
*ar
)
9144 struct wmi_wow_host_wakeup_ind
*cmd
;
9145 struct sk_buff
*skb
;
9149 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9153 cmd
= (struct wmi_wow_host_wakeup_ind
*)skb
->data
;
9154 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9155 WMI_TAG_WOW_HOSTWAKEUP_FROM_SLEEP_CMD
) |
9156 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9158 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv wow host wakeup ind\n");
9160 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID
);
9163 int ath11k_wmi_wow_enable(struct ath11k
*ar
)
9165 struct wmi_wow_enable_cmd
*cmd
;
9166 struct sk_buff
*skb
;
9170 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9174 cmd
= (struct wmi_wow_enable_cmd
*)skb
->data
;
9175 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_WOW_ENABLE_CMD
) |
9176 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9179 cmd
->pause_iface_config
= WOW_IFACE_PAUSE_ENABLED
;
9180 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv wow enable\n");
9182 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_WOW_ENABLE_CMDID
);
9185 int ath11k_wmi_scan_prob_req_oui(struct ath11k
*ar
,
9186 const u8 mac_addr
[ETH_ALEN
])
9188 struct sk_buff
*skb
;
9189 struct wmi_scan_prob_req_oui_cmd
*cmd
;
9193 prob_req_oui
= (((u32
)mac_addr
[0]) << 16) |
9194 (((u32
)mac_addr
[1]) << 8) | mac_addr
[2];
9197 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9201 cmd
= (struct wmi_scan_prob_req_oui_cmd
*)skb
->data
;
9202 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9203 WMI_TAG_SCAN_PROB_REQ_OUI_CMD
) |
9204 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9205 cmd
->prob_req_oui
= prob_req_oui
;
9207 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "scan prob req oui %d\n",
9210 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_SCAN_PROB_REQ_OUI_CMDID
);
9213 int ath11k_wmi_wow_add_wakeup_event(struct ath11k
*ar
, u32 vdev_id
,
9214 enum wmi_wow_wakeup_event event
,
9217 struct wmi_wow_add_del_event_cmd
*cmd
;
9218 struct sk_buff
*skb
;
9222 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9226 cmd
= (struct wmi_wow_add_del_event_cmd
*)skb
->data
;
9227 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_WOW_ADD_DEL_EVT_CMD
) |
9228 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9230 cmd
->vdev_id
= vdev_id
;
9231 cmd
->is_add
= enable
;
9232 cmd
->event_bitmap
= (1 << event
);
9234 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv wow add wakeup event %s enable %d vdev_id %d\n",
9235 wow_wakeup_event(event
), enable
, vdev_id
);
9237 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID
);
9240 int ath11k_wmi_wow_add_pattern(struct ath11k
*ar
, u32 vdev_id
, u32 pattern_id
,
9241 const u8
*pattern
, const u8
*mask
,
9242 int pattern_len
, int pattern_offset
)
9244 struct wmi_wow_add_pattern_cmd
*cmd
;
9245 struct wmi_wow_bitmap_pattern
*bitmap
;
9246 struct wmi_tlv
*tlv
;
9247 struct sk_buff
*skb
;
9251 len
= sizeof(*cmd
) +
9252 sizeof(*tlv
) + /* array struct */
9253 sizeof(*bitmap
) + /* bitmap */
9254 sizeof(*tlv
) + /* empty ipv4 sync */
9255 sizeof(*tlv
) + /* empty ipv6 sync */
9256 sizeof(*tlv
) + /* empty magic */
9257 sizeof(*tlv
) + /* empty info timeout */
9258 sizeof(*tlv
) + sizeof(u32
); /* ratelimit interval */
9260 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9265 ptr
= (u8
*)skb
->data
;
9266 cmd
= (struct wmi_wow_add_pattern_cmd
*)ptr
;
9267 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9268 WMI_TAG_WOW_ADD_PATTERN_CMD
) |
9269 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9271 cmd
->vdev_id
= vdev_id
;
9272 cmd
->pattern_id
= pattern_id
;
9273 cmd
->pattern_type
= WOW_BITMAP_PATTERN
;
9275 ptr
+= sizeof(*cmd
);
9278 tlv
= (struct wmi_tlv
*)ptr
;
9279 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9280 WMI_TAG_ARRAY_STRUCT
) |
9281 FIELD_PREP(WMI_TLV_LEN
, sizeof(*bitmap
));
9283 ptr
+= sizeof(*tlv
);
9285 bitmap
= (struct wmi_wow_bitmap_pattern
*)ptr
;
9286 bitmap
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9287 WMI_TAG_WOW_BITMAP_PATTERN_T
) |
9288 FIELD_PREP(WMI_TLV_LEN
, sizeof(*bitmap
) - TLV_HDR_SIZE
);
9290 memcpy(bitmap
->patternbuf
, pattern
, pattern_len
);
9291 ath11k_ce_byte_swap(bitmap
->patternbuf
, roundup(pattern_len
, 4));
9292 memcpy(bitmap
->bitmaskbuf
, mask
, pattern_len
);
9293 ath11k_ce_byte_swap(bitmap
->bitmaskbuf
, roundup(pattern_len
, 4));
9294 bitmap
->pattern_offset
= pattern_offset
;
9295 bitmap
->pattern_len
= pattern_len
;
9296 bitmap
->bitmask_len
= pattern_len
;
9297 bitmap
->pattern_id
= pattern_id
;
9299 ptr
+= sizeof(*bitmap
);
9302 tlv
= (struct wmi_tlv
*)ptr
;
9303 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9304 WMI_TAG_ARRAY_STRUCT
) |
9305 FIELD_PREP(WMI_TLV_LEN
, 0);
9307 ptr
+= sizeof(*tlv
);
9310 tlv
= (struct wmi_tlv
*)ptr
;
9311 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9312 WMI_TAG_ARRAY_STRUCT
) |
9313 FIELD_PREP(WMI_TLV_LEN
, 0);
9315 ptr
+= sizeof(*tlv
);
9318 tlv
= (struct wmi_tlv
*)ptr
;
9319 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9320 WMI_TAG_ARRAY_STRUCT
) |
9321 FIELD_PREP(WMI_TLV_LEN
, 0);
9323 ptr
+= sizeof(*tlv
);
9325 /* pattern info timeout */
9326 tlv
= (struct wmi_tlv
*)ptr
;
9327 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9328 WMI_TAG_ARRAY_UINT32
) |
9329 FIELD_PREP(WMI_TLV_LEN
, 0);
9331 ptr
+= sizeof(*tlv
);
9333 /* ratelimit interval */
9334 tlv
= (struct wmi_tlv
*)ptr
;
9335 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9336 WMI_TAG_ARRAY_UINT32
) |
9337 FIELD_PREP(WMI_TLV_LEN
, sizeof(u32
));
9339 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv wow add pattern vdev_id %d pattern_id %d pattern_offset %d\n",
9340 vdev_id
, pattern_id
, pattern_offset
);
9342 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_WOW_ADD_WAKE_PATTERN_CMDID
);
9345 int ath11k_wmi_wow_del_pattern(struct ath11k
*ar
, u32 vdev_id
, u32 pattern_id
)
9347 struct wmi_wow_del_pattern_cmd
*cmd
;
9348 struct sk_buff
*skb
;
9352 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9356 cmd
= (struct wmi_wow_del_pattern_cmd
*)skb
->data
;
9357 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9358 WMI_TAG_WOW_DEL_PATTERN_CMD
) |
9359 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9361 cmd
->vdev_id
= vdev_id
;
9362 cmd
->pattern_id
= pattern_id
;
9363 cmd
->pattern_type
= WOW_BITMAP_PATTERN
;
9365 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv wow del pattern vdev_id %d pattern_id %d\n",
9366 vdev_id
, pattern_id
);
9368 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_WOW_DEL_WAKE_PATTERN_CMDID
);
9371 static struct sk_buff
*
9372 ath11k_wmi_op_gen_config_pno_start(struct ath11k
*ar
,
9374 struct wmi_pno_scan_req
*pno
)
9376 struct nlo_configured_parameters
*nlo_list
;
9377 struct wmi_wow_nlo_config_cmd
*cmd
;
9378 struct wmi_tlv
*tlv
;
9379 struct sk_buff
*skb
;
9381 size_t len
, nlo_list_len
, channel_list_len
;
9385 len
= sizeof(*cmd
) +
9387 /* TLV place holder for array of structures
9388 * nlo_configured_parameters(nlo_list)
9391 /* TLV place holder for array of uint32 channel_list */
9393 channel_list_len
= sizeof(u32
) * pno
->a_networks
[0].channel_count
;
9394 len
+= channel_list_len
;
9396 nlo_list_len
= sizeof(*nlo_list
) * pno
->uc_networks_count
;
9397 len
+= nlo_list_len
;
9399 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9401 return ERR_PTR(-ENOMEM
);
9403 ptr
= (u8
*)skb
->data
;
9404 cmd
= (struct wmi_wow_nlo_config_cmd
*)ptr
;
9405 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_NLO_CONFIG_CMD
) |
9406 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9408 cmd
->vdev_id
= pno
->vdev_id
;
9409 cmd
->flags
= WMI_NLO_CONFIG_START
| WMI_NLO_CONFIG_SSID_HIDE_EN
;
9411 /* current FW does not support min-max range for dwell time */
9412 cmd
->active_dwell_time
= pno
->active_max_time
;
9413 cmd
->passive_dwell_time
= pno
->passive_max_time
;
9415 if (pno
->do_passive_scan
)
9416 cmd
->flags
|= WMI_NLO_CONFIG_SCAN_PASSIVE
;
9418 cmd
->fast_scan_period
= pno
->fast_scan_period
;
9419 cmd
->slow_scan_period
= pno
->slow_scan_period
;
9420 cmd
->fast_scan_max_cycles
= pno
->fast_scan_max_cycles
;
9421 cmd
->delay_start_time
= pno
->delay_start_time
;
9423 if (pno
->enable_pno_scan_randomization
) {
9424 cmd
->flags
|= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ
|
9425 WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ
;
9426 ether_addr_copy(cmd
->mac_addr
.addr
, pno
->mac_addr
);
9427 ether_addr_copy(cmd
->mac_mask
.addr
, pno
->mac_addr_mask
);
9428 ath11k_ce_byte_swap(cmd
->mac_addr
.addr
, 8);
9429 ath11k_ce_byte_swap(cmd
->mac_mask
.addr
, 8);
9432 ptr
+= sizeof(*cmd
);
9434 /* nlo_configured_parameters(nlo_list) */
9435 cmd
->no_of_ssids
= pno
->uc_networks_count
;
9436 tlv
= (struct wmi_tlv
*)ptr
;
9437 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
,
9438 WMI_TAG_ARRAY_STRUCT
) |
9439 FIELD_PREP(WMI_TLV_LEN
, nlo_list_len
);
9441 ptr
+= sizeof(*tlv
);
9442 nlo_list
= (struct nlo_configured_parameters
*)ptr
;
9443 for (i
= 0; i
< cmd
->no_of_ssids
; i
++) {
9444 tlv
= (struct wmi_tlv
*)(&nlo_list
[i
].tlv_header
);
9445 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
9446 FIELD_PREP(WMI_TLV_LEN
, sizeof(*nlo_list
) - sizeof(*tlv
));
9448 nlo_list
[i
].ssid
.valid
= true;
9449 nlo_list
[i
].ssid
.ssid
.ssid_len
= pno
->a_networks
[i
].ssid
.ssid_len
;
9450 memcpy(nlo_list
[i
].ssid
.ssid
.ssid
,
9451 pno
->a_networks
[i
].ssid
.ssid
,
9452 nlo_list
[i
].ssid
.ssid
.ssid_len
);
9453 ath11k_ce_byte_swap(nlo_list
[i
].ssid
.ssid
.ssid
,
9454 roundup(nlo_list
[i
].ssid
.ssid
.ssid_len
, 4));
9456 if (pno
->a_networks
[i
].rssi_threshold
&&
9457 pno
->a_networks
[i
].rssi_threshold
> -300) {
9458 nlo_list
[i
].rssi_cond
.valid
= true;
9459 nlo_list
[i
].rssi_cond
.rssi
=
9460 pno
->a_networks
[i
].rssi_threshold
;
9463 nlo_list
[i
].bcast_nw_type
.valid
= true;
9464 nlo_list
[i
].bcast_nw_type
.bcast_nw_type
=
9465 pno
->a_networks
[i
].bcast_nw_type
;
9468 ptr
+= nlo_list_len
;
9469 cmd
->num_of_channels
= pno
->a_networks
[0].channel_count
;
9470 tlv
= (struct wmi_tlv
*)ptr
;
9471 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_UINT32
) |
9472 FIELD_PREP(WMI_TLV_LEN
, channel_list_len
);
9473 ptr
+= sizeof(*tlv
);
9474 channel_list
= (u32
*)ptr
;
9475 for (i
= 0; i
< cmd
->num_of_channels
; i
++)
9476 channel_list
[i
] = pno
->a_networks
[0].channels
[i
];
9478 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "tlv start pno config vdev_id %d\n",
9484 static struct sk_buff
*ath11k_wmi_op_gen_config_pno_stop(struct ath11k
*ar
,
9487 struct wmi_wow_nlo_config_cmd
*cmd
;
9488 struct sk_buff
*skb
;
9492 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9494 return ERR_PTR(-ENOMEM
);
9496 cmd
= (struct wmi_wow_nlo_config_cmd
*)skb
->data
;
9497 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_NLO_CONFIG_CMD
) |
9498 FIELD_PREP(WMI_TLV_LEN
, len
- TLV_HDR_SIZE
);
9500 cmd
->vdev_id
= vdev_id
;
9501 cmd
->flags
= WMI_NLO_CONFIG_STOP
;
9503 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
9504 "tlv stop pno config vdev_id %d\n", vdev_id
);
9508 int ath11k_wmi_wow_config_pno(struct ath11k
*ar
, u32 vdev_id
,
9509 struct wmi_pno_scan_req
*pno_scan
)
9511 struct sk_buff
*skb
;
9513 if (pno_scan
->enable
)
9514 skb
= ath11k_wmi_op_gen_config_pno_start(ar
, vdev_id
, pno_scan
);
9516 skb
= ath11k_wmi_op_gen_config_pno_stop(ar
, vdev_id
);
9518 if (IS_ERR_OR_NULL(skb
))
9521 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID
);
9524 static void ath11k_wmi_fill_ns_offload(struct ath11k
*ar
,
9525 struct ath11k_arp_ns_offload
*offload
,
9530 struct wmi_ns_offload_tuple
*ns
;
9531 struct wmi_tlv
*tlv
;
9533 u32 ns_cnt
, ns_ext_tuples
;
9534 int i
, max_offloads
;
9536 ns_cnt
= offload
->ipv6_count
;
9538 tlv
= (struct wmi_tlv
*)buf_ptr
;
9541 ns_ext_tuples
= offload
->ipv6_count
- WMI_MAX_NS_OFFLOADS
;
9542 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
9543 FIELD_PREP(WMI_TLV_LEN
, ns_ext_tuples
* sizeof(*ns
));
9544 i
= WMI_MAX_NS_OFFLOADS
;
9545 max_offloads
= offload
->ipv6_count
;
9547 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
9548 FIELD_PREP(WMI_TLV_LEN
, WMI_MAX_NS_OFFLOADS
* sizeof(*ns
));
9550 max_offloads
= WMI_MAX_NS_OFFLOADS
;
9553 buf_ptr
+= sizeof(*tlv
);
9555 for (; i
< max_offloads
; i
++) {
9556 ns
= (struct wmi_ns_offload_tuple
*)buf_ptr
;
9557 ns
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_NS_OFFLOAD_TUPLE
) |
9558 FIELD_PREP(WMI_TLV_LEN
, sizeof(*ns
) - TLV_HDR_SIZE
);
9562 ns
->flags
|= WMI_NSOL_FLAGS_VALID
;
9564 memcpy(ns
->target_ipaddr
[0], offload
->ipv6_addr
[i
], 16);
9565 memcpy(ns
->solicitation_ipaddr
, offload
->self_ipv6_addr
[i
], 16);
9566 ath11k_ce_byte_swap(ns
->target_ipaddr
[0], 16);
9567 ath11k_ce_byte_swap(ns
->solicitation_ipaddr
, 16);
9569 if (offload
->ipv6_type
[i
])
9570 ns
->flags
|= WMI_NSOL_FLAGS_IS_IPV6_ANYCAST
;
9572 memcpy(ns
->target_mac
.addr
, offload
->mac_addr
, ETH_ALEN
);
9573 ath11k_ce_byte_swap(ns
->target_mac
.addr
, 8);
9575 if (ns
->target_mac
.word0
!= 0 ||
9576 ns
->target_mac
.word1
!= 0) {
9577 ns
->flags
|= WMI_NSOL_FLAGS_MAC_VALID
;
9580 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
9581 "index %d ns_solicited %pI6 target %pI6",
9582 i
, ns
->solicitation_ipaddr
,
9583 ns
->target_ipaddr
[0]);
9586 buf_ptr
+= sizeof(*ns
);
9592 static void ath11k_wmi_fill_arp_offload(struct ath11k
*ar
,
9593 struct ath11k_arp_ns_offload
*offload
,
9597 struct wmi_arp_offload_tuple
*arp
;
9598 struct wmi_tlv
*tlv
;
9602 /* fill arp tuple */
9603 tlv
= (struct wmi_tlv
*)buf_ptr
;
9604 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_STRUCT
) |
9605 FIELD_PREP(WMI_TLV_LEN
, WMI_MAX_ARP_OFFLOADS
* sizeof(*arp
));
9606 buf_ptr
+= sizeof(*tlv
);
9608 for (i
= 0; i
< WMI_MAX_ARP_OFFLOADS
; i
++) {
9609 arp
= (struct wmi_arp_offload_tuple
*)buf_ptr
;
9610 arp
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARP_OFFLOAD_TUPLE
) |
9611 FIELD_PREP(WMI_TLV_LEN
, sizeof(*arp
) - TLV_HDR_SIZE
);
9613 if (enable
&& i
< offload
->ipv4_count
) {
9614 /* Copy the target ip addr and flags */
9615 arp
->flags
= WMI_ARPOL_FLAGS_VALID
;
9616 memcpy(arp
->target_ipaddr
, offload
->ipv4_addr
[i
], 4);
9617 ath11k_ce_byte_swap(arp
->target_ipaddr
, 4);
9619 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "arp offload address %pI4",
9620 arp
->target_ipaddr
);
9623 buf_ptr
+= sizeof(*arp
);
9629 int ath11k_wmi_arp_ns_offload(struct ath11k
*ar
,
9630 struct ath11k_vif
*arvif
, bool enable
)
9632 struct ath11k_arp_ns_offload
*offload
;
9633 struct wmi_set_arp_ns_offload_cmd
*cmd
;
9634 struct wmi_tlv
*tlv
;
9635 struct sk_buff
*skb
;
9638 u8 ns_cnt
, ns_ext_tuples
= 0;
9640 offload
= &arvif
->arp_ns_offload
;
9641 ns_cnt
= offload
->ipv6_count
;
9643 len
= sizeof(*cmd
) +
9645 WMI_MAX_NS_OFFLOADS
* sizeof(struct wmi_ns_offload_tuple
) +
9647 WMI_MAX_ARP_OFFLOADS
* sizeof(struct wmi_arp_offload_tuple
);
9649 if (ns_cnt
> WMI_MAX_NS_OFFLOADS
) {
9650 ns_ext_tuples
= ns_cnt
- WMI_MAX_NS_OFFLOADS
;
9651 len
+= sizeof(*tlv
) +
9652 ns_ext_tuples
* sizeof(struct wmi_ns_offload_tuple
);
9655 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9659 buf_ptr
= skb
->data
;
9660 cmd
= (struct wmi_set_arp_ns_offload_cmd
*)buf_ptr
;
9661 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9662 WMI_TAG_SET_ARP_NS_OFFLOAD_CMD
) |
9663 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9666 cmd
->vdev_id
= arvif
->vdev_id
;
9667 cmd
->num_ns_ext_tuples
= ns_ext_tuples
;
9669 buf_ptr
+= sizeof(*cmd
);
9671 ath11k_wmi_fill_ns_offload(ar
, offload
, &buf_ptr
, enable
, 0);
9672 ath11k_wmi_fill_arp_offload(ar
, offload
, &buf_ptr
, enable
);
9675 ath11k_wmi_fill_ns_offload(ar
, offload
, &buf_ptr
, enable
, 1);
9677 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_SET_ARP_NS_OFFLOAD_CMDID
);
9680 int ath11k_wmi_gtk_rekey_offload(struct ath11k
*ar
,
9681 struct ath11k_vif
*arvif
, bool enable
)
9683 struct wmi_gtk_rekey_offload_cmd
*cmd
;
9684 struct ath11k_rekey_data
*rekey_data
= &arvif
->rekey_data
;
9686 struct sk_buff
*skb
;
9690 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9694 cmd
= (struct wmi_gtk_rekey_offload_cmd
*)skb
->data
;
9695 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_GTK_OFFLOAD_CMD
) |
9696 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9698 cmd
->vdev_id
= arvif
->vdev_id
;
9701 cmd
->flags
= GTK_OFFLOAD_ENABLE_OPCODE
;
9703 /* the length in rekey_data and cmd is equal */
9704 memcpy(cmd
->kck
, rekey_data
->kck
, sizeof(cmd
->kck
));
9705 ath11k_ce_byte_swap(cmd
->kck
, GTK_OFFLOAD_KEK_BYTES
);
9706 memcpy(cmd
->kek
, rekey_data
->kek
, sizeof(cmd
->kek
));
9707 ath11k_ce_byte_swap(cmd
->kek
, GTK_OFFLOAD_KEK_BYTES
);
9709 replay_ctr
= cpu_to_le64(rekey_data
->replay_ctr
);
9710 memcpy(cmd
->replay_ctr
, &replay_ctr
,
9711 sizeof(replay_ctr
));
9712 ath11k_ce_byte_swap(cmd
->replay_ctr
, GTK_REPLAY_COUNTER_BYTES
);
9714 cmd
->flags
= GTK_OFFLOAD_DISABLE_OPCODE
;
9717 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "offload gtk rekey vdev: %d %d\n",
9718 arvif
->vdev_id
, enable
);
9719 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_GTK_OFFLOAD_CMDID
);
9722 int ath11k_wmi_gtk_rekey_getinfo(struct ath11k
*ar
,
9723 struct ath11k_vif
*arvif
)
9725 struct wmi_gtk_rekey_offload_cmd
*cmd
;
9727 struct sk_buff
*skb
;
9730 skb
= ath11k_wmi_alloc_skb(ar
->wmi
->wmi_ab
, len
);
9734 cmd
= (struct wmi_gtk_rekey_offload_cmd
*)skb
->data
;
9735 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_GTK_OFFLOAD_CMD
) |
9736 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9738 cmd
->vdev_id
= arvif
->vdev_id
;
9739 cmd
->flags
= GTK_OFFLOAD_REQUEST_STATUS_OPCODE
;
9741 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
, "get gtk rekey vdev_id: %d\n",
9743 return ath11k_wmi_cmd_send(ar
->wmi
, skb
, WMI_GTK_OFFLOAD_CMDID
);
9746 int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k
*ar
, const u8
*sar_val
)
9747 { struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
9748 struct wmi_pdev_set_sar_table_cmd
*cmd
;
9749 struct wmi_tlv
*tlv
;
9750 struct sk_buff
*skb
;
9752 u32 len
, sar_len_aligned
, rsvd_len_aligned
;
9754 sar_len_aligned
= roundup(BIOS_SAR_TABLE_LEN
, sizeof(u32
));
9755 rsvd_len_aligned
= roundup(BIOS_SAR_RSVD1_LEN
, sizeof(u32
));
9756 len
= sizeof(*cmd
) +
9757 TLV_HDR_SIZE
+ sar_len_aligned
+
9758 TLV_HDR_SIZE
+ rsvd_len_aligned
;
9760 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
9764 cmd
= (struct wmi_pdev_set_sar_table_cmd
*)skb
->data
;
9765 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD
) |
9766 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9767 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
9768 cmd
->sar_len
= BIOS_SAR_TABLE_LEN
;
9769 cmd
->rsvd_len
= BIOS_SAR_RSVD1_LEN
;
9771 buf_ptr
= skb
->data
+ sizeof(*cmd
);
9772 tlv
= (struct wmi_tlv
*)buf_ptr
;
9773 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
9774 FIELD_PREP(WMI_TLV_LEN
, sar_len_aligned
);
9775 buf_ptr
+= TLV_HDR_SIZE
;
9776 memcpy(buf_ptr
, sar_val
, BIOS_SAR_TABLE_LEN
);
9778 buf_ptr
+= sar_len_aligned
;
9779 tlv
= (struct wmi_tlv
*)buf_ptr
;
9780 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
9781 FIELD_PREP(WMI_TLV_LEN
, rsvd_len_aligned
);
9783 return ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID
);
9786 int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k
*ar
)
9788 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
9789 struct wmi_pdev_set_geo_table_cmd
*cmd
;
9790 struct wmi_tlv
*tlv
;
9791 struct sk_buff
*skb
;
9793 u32 len
, rsvd_len_aligned
;
9795 rsvd_len_aligned
= roundup(BIOS_SAR_RSVD2_LEN
, sizeof(u32
));
9796 len
= sizeof(*cmd
) + TLV_HDR_SIZE
+ rsvd_len_aligned
;
9798 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
9802 cmd
= (struct wmi_pdev_set_geo_table_cmd
*)skb
->data
;
9803 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD
) |
9804 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9805 cmd
->pdev_id
= ar
->pdev
->pdev_id
;
9806 cmd
->rsvd_len
= BIOS_SAR_RSVD2_LEN
;
9808 buf_ptr
= skb
->data
+ sizeof(*cmd
);
9809 tlv
= (struct wmi_tlv
*)buf_ptr
;
9810 tlv
->header
= FIELD_PREP(WMI_TLV_TAG
, WMI_TAG_ARRAY_BYTE
) |
9811 FIELD_PREP(WMI_TLV_LEN
, rsvd_len_aligned
);
9813 return ath11k_wmi_cmd_send(wmi
, skb
, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID
);
9816 int ath11k_wmi_sta_keepalive(struct ath11k
*ar
,
9817 const struct wmi_sta_keepalive_arg
*arg
)
9819 struct ath11k_pdev_wmi
*wmi
= ar
->wmi
;
9820 struct wmi_sta_keepalive_cmd
*cmd
;
9821 struct wmi_sta_keepalive_arp_resp
*arp
;
9822 struct sk_buff
*skb
;
9825 len
= sizeof(*cmd
) + sizeof(*arp
);
9826 skb
= ath11k_wmi_alloc_skb(wmi
->wmi_ab
, len
);
9830 cmd
= (struct wmi_sta_keepalive_cmd
*)skb
->data
;
9831 cmd
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9832 WMI_TAG_STA_KEEPALIVE_CMD
) |
9833 FIELD_PREP(WMI_TLV_LEN
, sizeof(*cmd
) - TLV_HDR_SIZE
);
9834 cmd
->vdev_id
= arg
->vdev_id
;
9835 cmd
->enabled
= arg
->enabled
;
9836 cmd
->interval
= arg
->interval
;
9837 cmd
->method
= arg
->method
;
9839 arp
= (struct wmi_sta_keepalive_arp_resp
*)(cmd
+ 1);
9840 arp
->tlv_header
= FIELD_PREP(WMI_TLV_TAG
,
9841 WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE
) |
9842 FIELD_PREP(WMI_TLV_LEN
, sizeof(*arp
) - TLV_HDR_SIZE
);
9844 if (arg
->method
== WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE
||
9845 arg
->method
== WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST
) {
9846 arp
->src_ip4_addr
= arg
->src_ip4_addr
;
9847 arp
->dest_ip4_addr
= arg
->dest_ip4_addr
;
9848 ether_addr_copy(arp
->dest_mac_addr
.addr
, arg
->dest_mac_addr
);
9851 ath11k_dbg(ar
->ab
, ATH11K_DBG_WMI
,
9852 "sta keepalive vdev %d enabled %d method %d interval %d\n",
9853 arg
->vdev_id
, arg
->enabled
, arg
->method
, arg
->interval
);
9855 return ath11k_wmi_cmd_send(wmi
, skb
, WMI_STA_KEEPALIVE_CMDID
);
9858 bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k
*ar
)
9860 return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT
,
9861 ar
->ab
->wmi_ab
.svc_map
) && ar
->supports_6ghz
;