1// SPDX-License-Identifier: ISC
2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */
7
8#include <linux/skbuff.h>
9#include <linux/ctype.h>
10#if defined(__FreeBSD__)
11#include <linux/ktime.h>
12#include <linux/math64.h>
13#endif
14
15#include "core.h"
16#include "htc.h"
17#include "debug.h"
18#include "wmi.h"
19#include "wmi-tlv.h"
20#include "mac.h"
21#include "testmode.h"
22#include "wmi-ops.h"
23#include "p2p.h"
24#include "hw.h"
25#include "hif.h"
26#include "txrx.h"
27#if defined(CONFIG_FWLOG)
28#include "fwlog.h"
29#endif
30
31#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
32#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
33#define ATH10K_WMI_DFS_CONF_TIMEOUT_HZ (HZ / 6)
34
35/* MAIN WMI cmd track */
36static struct wmi_cmd_map wmi_cmd_map = {
37	.init_cmdid = WMI_INIT_CMDID,
38	.start_scan_cmdid = WMI_START_SCAN_CMDID,
39	.stop_scan_cmdid = WMI_STOP_SCAN_CMDID,
40	.scan_chan_list_cmdid = WMI_SCAN_CHAN_LIST_CMDID,
41	.scan_sch_prio_tbl_cmdid = WMI_SCAN_SCH_PRIO_TBL_CMDID,
42	.scan_prob_req_oui_cmdid = WMI_CMD_UNSUPPORTED,
43	.pdev_set_regdomain_cmdid = WMI_PDEV_SET_REGDOMAIN_CMDID,
44	.pdev_set_channel_cmdid = WMI_PDEV_SET_CHANNEL_CMDID,
45	.pdev_set_param_cmdid = WMI_PDEV_SET_PARAM_CMDID,
46	.pdev_pktlog_enable_cmdid = WMI_PDEV_PKTLOG_ENABLE_CMDID,
47	.pdev_pktlog_disable_cmdid = WMI_PDEV_PKTLOG_DISABLE_CMDID,
48	.pdev_set_wmm_params_cmdid = WMI_PDEV_SET_WMM_PARAMS_CMDID,
49	.pdev_set_ht_cap_ie_cmdid = WMI_PDEV_SET_HT_CAP_IE_CMDID,
50	.pdev_set_vht_cap_ie_cmdid = WMI_PDEV_SET_VHT_CAP_IE_CMDID,
51	.pdev_set_dscp_tid_map_cmdid = WMI_PDEV_SET_DSCP_TID_MAP_CMDID,
52	.pdev_set_quiet_mode_cmdid = WMI_PDEV_SET_QUIET_MODE_CMDID,
53	.pdev_green_ap_ps_enable_cmdid = WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID,
54	.pdev_get_tpc_config_cmdid = WMI_PDEV_GET_TPC_CONFIG_CMDID,
55	.pdev_set_base_macaddr_cmdid = WMI_PDEV_SET_BASE_MACADDR_CMDID,
56	.vdev_create_cmdid = WMI_VDEV_CREATE_CMDID,
57	.vdev_delete_cmdid = WMI_VDEV_DELETE_CMDID,
58	.vdev_start_request_cmdid = WMI_VDEV_START_REQUEST_CMDID,
59	.vdev_restart_request_cmdid = WMI_VDEV_RESTART_REQUEST_CMDID,
60	.vdev_up_cmdid = WMI_VDEV_UP_CMDID,
61	.vdev_stop_cmdid = WMI_VDEV_STOP_CMDID,
62	.vdev_down_cmdid = WMI_VDEV_DOWN_CMDID,
63	.vdev_set_param_cmdid = WMI_VDEV_SET_PARAM_CMDID,
64	.vdev_install_key_cmdid = WMI_VDEV_INSTALL_KEY_CMDID,
65	.peer_create_cmdid = WMI_PEER_CREATE_CMDID,
66	.peer_delete_cmdid = WMI_PEER_DELETE_CMDID,
67	.peer_flush_tids_cmdid = WMI_PEER_FLUSH_TIDS_CMDID,
68	.peer_set_param_cmdid = WMI_PEER_SET_PARAM_CMDID,
69	.peer_assoc_cmdid = WMI_PEER_ASSOC_CMDID,
70	.peer_add_wds_entry_cmdid = WMI_PEER_ADD_WDS_ENTRY_CMDID,
71	.peer_remove_wds_entry_cmdid = WMI_PEER_REMOVE_WDS_ENTRY_CMDID,
72	.peer_mcast_group_cmdid = WMI_PEER_MCAST_GROUP_CMDID,
73	.bcn_tx_cmdid = WMI_BCN_TX_CMDID,
74	.pdev_send_bcn_cmdid = WMI_PDEV_SEND_BCN_CMDID,
75	.bcn_tmpl_cmdid = WMI_BCN_TMPL_CMDID,
76	.bcn_filter_rx_cmdid = WMI_BCN_FILTER_RX_CMDID,
77	.prb_req_filter_rx_cmdid = WMI_PRB_REQ_FILTER_RX_CMDID,
78	.mgmt_tx_cmdid = WMI_MGMT_TX_CMDID,
79	.prb_tmpl_cmdid = WMI_PRB_TMPL_CMDID,
80	.addba_clear_resp_cmdid = WMI_ADDBA_CLEAR_RESP_CMDID,
81	.addba_send_cmdid = WMI_ADDBA_SEND_CMDID,
82	.addba_status_cmdid = WMI_ADDBA_STATUS_CMDID,
83	.delba_send_cmdid = WMI_DELBA_SEND_CMDID,
84	.addba_set_resp_cmdid = WMI_ADDBA_SET_RESP_CMDID,
85	.send_singleamsdu_cmdid = WMI_SEND_SINGLEAMSDU_CMDID,
86	.sta_powersave_mode_cmdid = WMI_STA_POWERSAVE_MODE_CMDID,
87	.sta_powersave_param_cmdid = WMI_STA_POWERSAVE_PARAM_CMDID,
88	.sta_mimo_ps_mode_cmdid = WMI_STA_MIMO_PS_MODE_CMDID,
89	.pdev_dfs_enable_cmdid = WMI_PDEV_DFS_ENABLE_CMDID,
90	.pdev_dfs_disable_cmdid = WMI_PDEV_DFS_DISABLE_CMDID,
91	.roam_scan_mode = WMI_ROAM_SCAN_MODE,
92	.roam_scan_rssi_threshold = WMI_ROAM_SCAN_RSSI_THRESHOLD,
93	.roam_scan_period = WMI_ROAM_SCAN_PERIOD,
94	.roam_scan_rssi_change_threshold = WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
95	.roam_ap_profile = WMI_ROAM_AP_PROFILE,
96	.ofl_scan_add_ap_profile = WMI_ROAM_AP_PROFILE,
97	.ofl_scan_remove_ap_profile = WMI_OFL_SCAN_REMOVE_AP_PROFILE,
98	.ofl_scan_period = WMI_OFL_SCAN_PERIOD,
99	.p2p_dev_set_device_info = WMI_P2P_DEV_SET_DEVICE_INFO,
100	.p2p_dev_set_discoverability = WMI_P2P_DEV_SET_DISCOVERABILITY,
101	.p2p_go_set_beacon_ie = WMI_P2P_GO_SET_BEACON_IE,
102	.p2p_go_set_probe_resp_ie = WMI_P2P_GO_SET_PROBE_RESP_IE,
103	.p2p_set_vendor_ie_data_cmdid = WMI_P2P_SET_VENDOR_IE_DATA_CMDID,
104	.ap_ps_peer_param_cmdid = WMI_AP_PS_PEER_PARAM_CMDID,
105	.ap_ps_peer_uapsd_coex_cmdid = WMI_AP_PS_PEER_UAPSD_COEX_CMDID,
106	.peer_rate_retry_sched_cmdid = WMI_PEER_RATE_RETRY_SCHED_CMDID,
107	.wlan_profile_trigger_cmdid = WMI_WLAN_PROFILE_TRIGGER_CMDID,
108	.wlan_profile_set_hist_intvl_cmdid =
109				WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
110	.wlan_profile_get_profile_data_cmdid =
111				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
112	.wlan_profile_enable_profile_id_cmdid =
113				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
114	.wlan_profile_list_profile_id_cmdid =
115				WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
116	.pdev_suspend_cmdid = WMI_PDEV_SUSPEND_CMDID,
117	.pdev_resume_cmdid = WMI_PDEV_RESUME_CMDID,
118	.add_bcn_filter_cmdid = WMI_ADD_BCN_FILTER_CMDID,
119	.rmv_bcn_filter_cmdid = WMI_RMV_BCN_FILTER_CMDID,
120	.wow_add_wake_pattern_cmdid = WMI_WOW_ADD_WAKE_PATTERN_CMDID,
121	.wow_del_wake_pattern_cmdid = WMI_WOW_DEL_WAKE_PATTERN_CMDID,
122	.wow_enable_disable_wake_event_cmdid =
123				WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
124	.wow_enable_cmdid = WMI_WOW_ENABLE_CMDID,
125	.wow_hostwakeup_from_sleep_cmdid = WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
126	.rtt_measreq_cmdid = WMI_RTT_MEASREQ_CMDID,
127	.rtt_tsf_cmdid = WMI_RTT_TSF_CMDID,
128	.vdev_spectral_scan_configure_cmdid =
129				WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
130	.vdev_spectral_scan_enable_cmdid = WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
131	.request_stats_cmdid = WMI_REQUEST_STATS_CMDID,
132	.set_arp_ns_offload_cmdid = WMI_SET_ARP_NS_OFFLOAD_CMDID,
133	.network_list_offload_config_cmdid =
134				WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
135	.gtk_offload_cmdid = WMI_GTK_OFFLOAD_CMDID,
136	.csa_offload_enable_cmdid = WMI_CSA_OFFLOAD_ENABLE_CMDID,
137	.csa_offload_chanswitch_cmdid = WMI_CSA_OFFLOAD_CHANSWITCH_CMDID,
138	.chatter_set_mode_cmdid = WMI_CHATTER_SET_MODE_CMDID,
139	.peer_tid_addba_cmdid = WMI_PEER_TID_ADDBA_CMDID,
140	.peer_tid_delba_cmdid = WMI_PEER_TID_DELBA_CMDID,
141	.sta_dtim_ps_method_cmdid = WMI_STA_DTIM_PS_METHOD_CMDID,
142	.sta_uapsd_auto_trig_cmdid = WMI_STA_UAPSD_AUTO_TRIG_CMDID,
143	.sta_keepalive_cmd = WMI_STA_KEEPALIVE_CMD,
144	.echo_cmdid = WMI_ECHO_CMDID,
145	.pdev_utf_cmdid = WMI_PDEV_UTF_CMDID,
146	.dbglog_cfg_cmdid = WMI_DBGLOG_CFG_CMDID,
147	.pdev_qvit_cmdid = WMI_PDEV_QVIT_CMDID,
148	.pdev_ftm_intg_cmdid = WMI_PDEV_FTM_INTG_CMDID,
149	.vdev_set_keepalive_cmdid = WMI_VDEV_SET_KEEPALIVE_CMDID,
150	.vdev_get_keepalive_cmdid = WMI_VDEV_GET_KEEPALIVE_CMDID,
151	.force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID,
152	.gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID,
153	.gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID,
154	.pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
155	.pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
156	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
157	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
158	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
159	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
160	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
161	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
162	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
163	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
164	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
165	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
166	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
167	.nan_cmdid = WMI_CMD_UNSUPPORTED,
168	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
169	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
170	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
171	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
172	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
173	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
174	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
175	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
176	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
177	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
178	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
179	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
180	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
181	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
182	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
183	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
184	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
185	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
186	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
187	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
188	.pdev_get_nfcal_power_cmdid = WMI_CMD_UNSUPPORTED,
189	.pdev_get_tpc_cmdid = WMI_CMD_UNSUPPORTED,
190	.pdev_get_ast_info_cmdid = WMI_CMD_UNSUPPORTED,
191	.vdev_set_dscp_tid_map_cmdid = WMI_CMD_UNSUPPORTED,
192	.pdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
193	.vdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
194	.vdev_filter_neighbor_rx_packets_cmdid = WMI_CMD_UNSUPPORTED,
195	.mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
196	.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
197	.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
198	.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
199	.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
200};
201
202/* 10.X WMI cmd track */
203static struct wmi_cmd_map wmi_10x_cmd_map = {
204	.init_cmdid = WMI_10X_INIT_CMDID,
205	.start_scan_cmdid = WMI_10X_START_SCAN_CMDID,
206	.stop_scan_cmdid = WMI_10X_STOP_SCAN_CMDID,
207	.scan_chan_list_cmdid = WMI_10X_SCAN_CHAN_LIST_CMDID,
208	.scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED,
209	.scan_prob_req_oui_cmdid = WMI_CMD_UNSUPPORTED,
210	.pdev_set_regdomain_cmdid = WMI_10X_PDEV_SET_REGDOMAIN_CMDID,
211	.pdev_set_channel_cmdid = WMI_10X_PDEV_SET_CHANNEL_CMDID,
212	.pdev_set_param_cmdid = WMI_10X_PDEV_SET_PARAM_CMDID,
213	.pdev_pktlog_enable_cmdid = WMI_10X_PDEV_PKTLOG_ENABLE_CMDID,
214	.pdev_pktlog_disable_cmdid = WMI_10X_PDEV_PKTLOG_DISABLE_CMDID,
215	.pdev_set_wmm_params_cmdid = WMI_10X_PDEV_SET_WMM_PARAMS_CMDID,
216	.pdev_set_ht_cap_ie_cmdid = WMI_10X_PDEV_SET_HT_CAP_IE_CMDID,
217	.pdev_set_vht_cap_ie_cmdid = WMI_10X_PDEV_SET_VHT_CAP_IE_CMDID,
218	.pdev_set_dscp_tid_map_cmdid = WMI_10X_PDEV_SET_DSCP_TID_MAP_CMDID,
219	.pdev_set_quiet_mode_cmdid = WMI_10X_PDEV_SET_QUIET_MODE_CMDID,
220	.pdev_green_ap_ps_enable_cmdid = WMI_10X_PDEV_GREEN_AP_PS_ENABLE_CMDID,
221	.pdev_get_tpc_config_cmdid = WMI_10X_PDEV_GET_TPC_CONFIG_CMDID,
222	.pdev_set_base_macaddr_cmdid = WMI_10X_PDEV_SET_BASE_MACADDR_CMDID,
223	.vdev_create_cmdid = WMI_10X_VDEV_CREATE_CMDID,
224	.vdev_delete_cmdid = WMI_10X_VDEV_DELETE_CMDID,
225	.vdev_start_request_cmdid = WMI_10X_VDEV_START_REQUEST_CMDID,
226	.vdev_restart_request_cmdid = WMI_10X_VDEV_RESTART_REQUEST_CMDID,
227	.vdev_up_cmdid = WMI_10X_VDEV_UP_CMDID,
228	.vdev_stop_cmdid = WMI_10X_VDEV_STOP_CMDID,
229	.vdev_down_cmdid = WMI_10X_VDEV_DOWN_CMDID,
230	.vdev_set_param_cmdid = WMI_10X_VDEV_SET_PARAM_CMDID,
231	.vdev_install_key_cmdid = WMI_10X_VDEV_INSTALL_KEY_CMDID,
232	.peer_create_cmdid = WMI_10X_PEER_CREATE_CMDID,
233	.peer_delete_cmdid = WMI_10X_PEER_DELETE_CMDID,
234	.peer_flush_tids_cmdid = WMI_10X_PEER_FLUSH_TIDS_CMDID,
235	.peer_set_param_cmdid = WMI_10X_PEER_SET_PARAM_CMDID,
236	.peer_assoc_cmdid = WMI_10X_PEER_ASSOC_CMDID,
237	.peer_add_wds_entry_cmdid = WMI_10X_PEER_ADD_WDS_ENTRY_CMDID,
238	.peer_remove_wds_entry_cmdid = WMI_10X_PEER_REMOVE_WDS_ENTRY_CMDID,
239	.peer_mcast_group_cmdid = WMI_10X_PEER_MCAST_GROUP_CMDID,
240	.bcn_tx_cmdid = WMI_10X_BCN_TX_CMDID,
241	.pdev_send_bcn_cmdid = WMI_10X_PDEV_SEND_BCN_CMDID,
242	.bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
243	.bcn_filter_rx_cmdid = WMI_10X_BCN_FILTER_RX_CMDID,
244	.prb_req_filter_rx_cmdid = WMI_10X_PRB_REQ_FILTER_RX_CMDID,
245	.mgmt_tx_cmdid = WMI_10X_MGMT_TX_CMDID,
246	.prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
247	.addba_clear_resp_cmdid = WMI_10X_ADDBA_CLEAR_RESP_CMDID,
248	.addba_send_cmdid = WMI_10X_ADDBA_SEND_CMDID,
249	.addba_status_cmdid = WMI_10X_ADDBA_STATUS_CMDID,
250	.delba_send_cmdid = WMI_10X_DELBA_SEND_CMDID,
251	.addba_set_resp_cmdid = WMI_10X_ADDBA_SET_RESP_CMDID,
252	.send_singleamsdu_cmdid = WMI_10X_SEND_SINGLEAMSDU_CMDID,
253	.sta_powersave_mode_cmdid = WMI_10X_STA_POWERSAVE_MODE_CMDID,
254	.sta_powersave_param_cmdid = WMI_10X_STA_POWERSAVE_PARAM_CMDID,
255	.sta_mimo_ps_mode_cmdid = WMI_10X_STA_MIMO_PS_MODE_CMDID,
256	.pdev_dfs_enable_cmdid = WMI_10X_PDEV_DFS_ENABLE_CMDID,
257	.pdev_dfs_disable_cmdid = WMI_10X_PDEV_DFS_DISABLE_CMDID,
258	.roam_scan_mode = WMI_10X_ROAM_SCAN_MODE,
259	.roam_scan_rssi_threshold = WMI_10X_ROAM_SCAN_RSSI_THRESHOLD,
260	.roam_scan_period = WMI_10X_ROAM_SCAN_PERIOD,
261	.roam_scan_rssi_change_threshold =
262				WMI_10X_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
263	.roam_ap_profile = WMI_10X_ROAM_AP_PROFILE,
264	.ofl_scan_add_ap_profile = WMI_10X_OFL_SCAN_ADD_AP_PROFILE,
265	.ofl_scan_remove_ap_profile = WMI_10X_OFL_SCAN_REMOVE_AP_PROFILE,
266	.ofl_scan_period = WMI_10X_OFL_SCAN_PERIOD,
267	.p2p_dev_set_device_info = WMI_10X_P2P_DEV_SET_DEVICE_INFO,
268	.p2p_dev_set_discoverability = WMI_10X_P2P_DEV_SET_DISCOVERABILITY,
269	.p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE,
270	.p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE,
271	.p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
272	.ap_ps_peer_param_cmdid = WMI_10X_AP_PS_PEER_PARAM_CMDID,
273	.ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
274	.peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID,
275	.wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID,
276	.wlan_profile_set_hist_intvl_cmdid =
277				WMI_10X_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
278	.wlan_profile_get_profile_data_cmdid =
279				WMI_10X_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
280	.wlan_profile_enable_profile_id_cmdid =
281				WMI_10X_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
282	.wlan_profile_list_profile_id_cmdid =
283				WMI_10X_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
284	.pdev_suspend_cmdid = WMI_10X_PDEV_SUSPEND_CMDID,
285	.pdev_resume_cmdid = WMI_10X_PDEV_RESUME_CMDID,
286	.add_bcn_filter_cmdid = WMI_10X_ADD_BCN_FILTER_CMDID,
287	.rmv_bcn_filter_cmdid = WMI_10X_RMV_BCN_FILTER_CMDID,
288	.wow_add_wake_pattern_cmdid = WMI_10X_WOW_ADD_WAKE_PATTERN_CMDID,
289	.wow_del_wake_pattern_cmdid = WMI_10X_WOW_DEL_WAKE_PATTERN_CMDID,
290	.wow_enable_disable_wake_event_cmdid =
291				WMI_10X_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
292	.wow_enable_cmdid = WMI_10X_WOW_ENABLE_CMDID,
293	.wow_hostwakeup_from_sleep_cmdid =
294				WMI_10X_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
295	.rtt_measreq_cmdid = WMI_10X_RTT_MEASREQ_CMDID,
296	.rtt_tsf_cmdid = WMI_10X_RTT_TSF_CMDID,
297	.vdev_spectral_scan_configure_cmdid =
298				WMI_10X_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
299	.vdev_spectral_scan_enable_cmdid =
300				WMI_10X_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
301	.request_stats_cmdid = WMI_10X_REQUEST_STATS_CMDID,
302	.set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED,
303	.network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED,
304	.gtk_offload_cmdid = WMI_CMD_UNSUPPORTED,
305	.csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED,
306	.csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED,
307	.chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED,
308	.peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED,
309	.peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED,
310	.sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED,
311	.sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED,
312	.sta_keepalive_cmd = WMI_CMD_UNSUPPORTED,
313	.echo_cmdid = WMI_10X_ECHO_CMDID,
314	.pdev_utf_cmdid = WMI_10X_PDEV_UTF_CMDID,
315	.dbglog_cfg_cmdid = WMI_10X_DBGLOG_CFG_CMDID,
316	.pdev_qvit_cmdid = WMI_10X_PDEV_QVIT_CMDID,
317	.pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED,
318	.vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
319	.vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
320	.force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
321	.gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID,
322	.gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
323	.pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
324	.pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
325	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
326	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
327	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
328	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
329	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
330	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
331	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
332	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
333	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
334	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
335	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
336	.nan_cmdid = WMI_CMD_UNSUPPORTED,
337	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
338	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
339	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
340	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
341	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
342	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
343	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
344	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
345	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
346	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
347	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
348	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
349	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
350	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
351	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
352	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
353	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
354	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
355	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
356	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
357	.pdev_get_nfcal_power_cmdid = WMI_CMD_UNSUPPORTED,
358	.pdev_get_tpc_cmdid = WMI_CMD_UNSUPPORTED,
359	.pdev_get_ast_info_cmdid = WMI_CMD_UNSUPPORTED,
360	.vdev_set_dscp_tid_map_cmdid = WMI_CMD_UNSUPPORTED,
361	.pdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
362	.vdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
363	.vdev_filter_neighbor_rx_packets_cmdid = WMI_CMD_UNSUPPORTED,
364	.mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
365	.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
366	.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
367	.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
368	.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
369};
370
371/* 10.2.4 WMI cmd track */
372static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
373	.init_cmdid = WMI_10_2_INIT_CMDID,
374	.start_scan_cmdid = WMI_10_2_START_SCAN_CMDID,
375	.stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID,
376	.scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID,
377	.scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED,
378	.scan_prob_req_oui_cmdid = WMI_CMD_UNSUPPORTED,
379	.pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID,
380	.pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID,
381	.pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID,
382	.pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID,
383	.pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID,
384	.pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID,
385	.pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID,
386	.pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID,
387	.pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID,
388	.pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID,
389	.pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID,
390	.pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID,
391	.vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID,
392	.vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID,
393	.vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID,
394	.vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID,
395	.vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID,
396	.vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID,
397	.vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID,
398	.vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID,
399	.vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID,
400	.peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID,
401	.peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID,
402	.peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID,
403	.peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID,
404	.peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID,
405	.peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID,
406	.peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID,
407	.peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID,
408	.bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID,
409	.pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID,
410	.bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
411	.bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID,
412	.prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID,
413	.mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID,
414	.prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
415	.addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID,
416	.addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID,
417	.addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID,
418	.delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID,
419	.addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID,
420	.send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID,
421	.sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID,
422	.sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID,
423	.sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID,
424	.pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID,
425	.pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID,
426	.roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE,
427	.roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD,
428	.roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD,
429	.roam_scan_rssi_change_threshold =
430				WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
431	.roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE,
432	.ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE,
433	.ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE,
434	.ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD,
435	.p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO,
436	.p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY,
437	.p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE,
438	.p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE,
439	.p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
440	.ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID,
441	.ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
442	.peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID,
443	.wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID,
444	.wlan_profile_set_hist_intvl_cmdid =
445				WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
446	.wlan_profile_get_profile_data_cmdid =
447				WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
448	.wlan_profile_enable_profile_id_cmdid =
449				WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
450	.wlan_profile_list_profile_id_cmdid =
451				WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
452	.pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID,
453	.pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID,
454	.add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID,
455	.rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID,
456	.wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID,
457	.wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID,
458	.wow_enable_disable_wake_event_cmdid =
459				WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
460	.wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID,
461	.wow_hostwakeup_from_sleep_cmdid =
462				WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
463	.rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID,
464	.rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID,
465	.vdev_spectral_scan_configure_cmdid =
466				WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
467	.vdev_spectral_scan_enable_cmdid =
468				WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
469	.request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID,
470	.set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED,
471	.network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED,
472	.gtk_offload_cmdid = WMI_CMD_UNSUPPORTED,
473	.csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED,
474	.csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED,
475	.chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED,
476	.peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED,
477	.peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED,
478	.sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED,
479	.sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED,
480	.sta_keepalive_cmd = WMI_CMD_UNSUPPORTED,
481	.echo_cmdid = WMI_10_2_ECHO_CMDID,
482	.pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID,
483	.dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID,
484	.pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID,
485	.pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED,
486	.vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
487	.vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
488	.force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
489	.gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
490	.gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
491	.pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
492	.pdev_enable_adaptive_cca_cmdid = WMI_10_2_SET_CCA_PARAMS,
493	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
494	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
495	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
496	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
497	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
498	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
499	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
500	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
501	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
502	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
503	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
504	.nan_cmdid = WMI_CMD_UNSUPPORTED,
505	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
506	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
507	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
508	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
509	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
510	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
511	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
512	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
513	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
514	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
515	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
516	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
517	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
518	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
519	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
520	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
521	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
522	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
523	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
524	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
525	.pdev_get_nfcal_power_cmdid = WMI_CMD_UNSUPPORTED,
526	.pdev_get_tpc_cmdid = WMI_CMD_UNSUPPORTED,
527	.pdev_get_ast_info_cmdid = WMI_CMD_UNSUPPORTED,
528	.vdev_set_dscp_tid_map_cmdid = WMI_CMD_UNSUPPORTED,
529	.pdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
530	.vdev_get_info_cmdid = WMI_CMD_UNSUPPORTED,
531	.vdev_filter_neighbor_rx_packets_cmdid = WMI_CMD_UNSUPPORTED,
532	.mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
533	.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
534	.pdev_bss_chan_info_request_cmdid =
535		WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
536	.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
537	.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
538	.set_bb_timing_cmdid = WMI_10_2_PDEV_SET_BB_TIMING_CONFIG_CMDID,
539};
540
541/* 10.4 WMI cmd track */
542static struct wmi_cmd_map wmi_10_4_cmd_map = {
543	.init_cmdid = WMI_10_4_INIT_CMDID,
544	.start_scan_cmdid = WMI_10_4_START_SCAN_CMDID,
545	.stop_scan_cmdid = WMI_10_4_STOP_SCAN_CMDID,
546	.scan_chan_list_cmdid = WMI_10_4_SCAN_CHAN_LIST_CMDID,
547	.scan_sch_prio_tbl_cmdid = WMI_10_4_SCAN_SCH_PRIO_TBL_CMDID,
548	.scan_prob_req_oui_cmdid = WMI_CMD_UNSUPPORTED,
549	.pdev_set_regdomain_cmdid = WMI_10_4_PDEV_SET_REGDOMAIN_CMDID,
550	.pdev_set_channel_cmdid = WMI_10_4_PDEV_SET_CHANNEL_CMDID,
551	.pdev_set_param_cmdid = WMI_10_4_PDEV_SET_PARAM_CMDID,
552	.pdev_pktlog_enable_cmdid = WMI_10_4_PDEV_PKTLOG_ENABLE_CMDID,
553	.pdev_pktlog_disable_cmdid = WMI_10_4_PDEV_PKTLOG_DISABLE_CMDID,
554	.pdev_set_wmm_params_cmdid = WMI_10_4_PDEV_SET_WMM_PARAMS_CMDID,
555	.pdev_set_ht_cap_ie_cmdid = WMI_10_4_PDEV_SET_HT_CAP_IE_CMDID,
556	.pdev_set_vht_cap_ie_cmdid = WMI_10_4_PDEV_SET_VHT_CAP_IE_CMDID,
557	.pdev_set_dscp_tid_map_cmdid = WMI_10_4_PDEV_SET_DSCP_TID_MAP_CMDID,
558	.pdev_set_quiet_mode_cmdid = WMI_10_4_PDEV_SET_QUIET_MODE_CMDID,
559	.pdev_green_ap_ps_enable_cmdid = WMI_10_4_PDEV_GREEN_AP_PS_ENABLE_CMDID,
560	.pdev_get_tpc_config_cmdid = WMI_10_4_PDEV_GET_TPC_CONFIG_CMDID,
561	.pdev_set_base_macaddr_cmdid = WMI_10_4_PDEV_SET_BASE_MACADDR_CMDID,
562	.vdev_create_cmdid = WMI_10_4_VDEV_CREATE_CMDID,
563	.vdev_delete_cmdid = WMI_10_4_VDEV_DELETE_CMDID,
564	.vdev_start_request_cmdid = WMI_10_4_VDEV_START_REQUEST_CMDID,
565	.vdev_restart_request_cmdid = WMI_10_4_VDEV_RESTART_REQUEST_CMDID,
566	.vdev_up_cmdid = WMI_10_4_VDEV_UP_CMDID,
567	.vdev_stop_cmdid = WMI_10_4_VDEV_STOP_CMDID,
568	.vdev_down_cmdid = WMI_10_4_VDEV_DOWN_CMDID,
569	.vdev_set_param_cmdid = WMI_10_4_VDEV_SET_PARAM_CMDID,
570	.vdev_install_key_cmdid = WMI_10_4_VDEV_INSTALL_KEY_CMDID,
571	.peer_create_cmdid = WMI_10_4_PEER_CREATE_CMDID,
572	.peer_delete_cmdid = WMI_10_4_PEER_DELETE_CMDID,
573	.peer_flush_tids_cmdid = WMI_10_4_PEER_FLUSH_TIDS_CMDID,
574	.peer_set_param_cmdid = WMI_10_4_PEER_SET_PARAM_CMDID,
575	.peer_assoc_cmdid = WMI_10_4_PEER_ASSOC_CMDID,
576	.peer_add_wds_entry_cmdid = WMI_10_4_PEER_ADD_WDS_ENTRY_CMDID,
577	.peer_remove_wds_entry_cmdid = WMI_10_4_PEER_REMOVE_WDS_ENTRY_CMDID,
578	.peer_mcast_group_cmdid = WMI_10_4_PEER_MCAST_GROUP_CMDID,
579	.bcn_tx_cmdid = WMI_10_4_BCN_TX_CMDID,
580	.pdev_send_bcn_cmdid = WMI_10_4_PDEV_SEND_BCN_CMDID,
581	.bcn_tmpl_cmdid = WMI_10_4_BCN_PRB_TMPL_CMDID,
582	.bcn_filter_rx_cmdid = WMI_10_4_BCN_FILTER_RX_CMDID,
583	.prb_req_filter_rx_cmdid = WMI_10_4_PRB_REQ_FILTER_RX_CMDID,
584	.mgmt_tx_cmdid = WMI_10_4_MGMT_TX_CMDID,
585	.prb_tmpl_cmdid = WMI_10_4_PRB_TMPL_CMDID,
586	.addba_clear_resp_cmdid = WMI_10_4_ADDBA_CLEAR_RESP_CMDID,
587	.addba_send_cmdid = WMI_10_4_ADDBA_SEND_CMDID,
588	.addba_status_cmdid = WMI_10_4_ADDBA_STATUS_CMDID,
589	.delba_send_cmdid = WMI_10_4_DELBA_SEND_CMDID,
590	.addba_set_resp_cmdid = WMI_10_4_ADDBA_SET_RESP_CMDID,
591	.send_singleamsdu_cmdid = WMI_10_4_SEND_SINGLEAMSDU_CMDID,
592	.sta_powersave_mode_cmdid = WMI_10_4_STA_POWERSAVE_MODE_CMDID,
593	.sta_powersave_param_cmdid = WMI_10_4_STA_POWERSAVE_PARAM_CMDID,
594	.sta_mimo_ps_mode_cmdid = WMI_10_4_STA_MIMO_PS_MODE_CMDID,
595	.pdev_dfs_enable_cmdid = WMI_10_4_PDEV_DFS_ENABLE_CMDID,
596	.pdev_dfs_disable_cmdid = WMI_10_4_PDEV_DFS_DISABLE_CMDID,
597	.roam_scan_mode = WMI_10_4_ROAM_SCAN_MODE,
598	.roam_scan_rssi_threshold = WMI_10_4_ROAM_SCAN_RSSI_THRESHOLD,
599	.roam_scan_period = WMI_10_4_ROAM_SCAN_PERIOD,
600	.roam_scan_rssi_change_threshold =
601				WMI_10_4_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
602	.roam_ap_profile = WMI_10_4_ROAM_AP_PROFILE,
603	.ofl_scan_add_ap_profile = WMI_10_4_OFL_SCAN_ADD_AP_PROFILE,
604	.ofl_scan_remove_ap_profile = WMI_10_4_OFL_SCAN_REMOVE_AP_PROFILE,
605	.ofl_scan_period = WMI_10_4_OFL_SCAN_PERIOD,
606	.p2p_dev_set_device_info = WMI_10_4_P2P_DEV_SET_DEVICE_INFO,
607	.p2p_dev_set_discoverability = WMI_10_4_P2P_DEV_SET_DISCOVERABILITY,
608	.p2p_go_set_beacon_ie = WMI_10_4_P2P_GO_SET_BEACON_IE,
609	.p2p_go_set_probe_resp_ie = WMI_10_4_P2P_GO_SET_PROBE_RESP_IE,
610	.p2p_set_vendor_ie_data_cmdid = WMI_10_4_P2P_SET_VENDOR_IE_DATA_CMDID,
611	.ap_ps_peer_param_cmdid = WMI_10_4_AP_PS_PEER_PARAM_CMDID,
612	.ap_ps_peer_uapsd_coex_cmdid = WMI_10_4_AP_PS_PEER_UAPSD_COEX_CMDID,
613	.peer_rate_retry_sched_cmdid = WMI_10_4_PEER_RATE_RETRY_SCHED_CMDID,
614	.wlan_profile_trigger_cmdid = WMI_10_4_WLAN_PROFILE_TRIGGER_CMDID,
615	.wlan_profile_set_hist_intvl_cmdid =
616				WMI_10_4_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
617	.wlan_profile_get_profile_data_cmdid =
618				WMI_10_4_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
619	.wlan_profile_enable_profile_id_cmdid =
620				WMI_10_4_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
621	.wlan_profile_list_profile_id_cmdid =
622				WMI_10_4_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
623	.pdev_suspend_cmdid = WMI_10_4_PDEV_SUSPEND_CMDID,
624	.pdev_resume_cmdid = WMI_10_4_PDEV_RESUME_CMDID,
625	.add_bcn_filter_cmdid = WMI_10_4_ADD_BCN_FILTER_CMDID,
626	.rmv_bcn_filter_cmdid = WMI_10_4_RMV_BCN_FILTER_CMDID,
627	.wow_add_wake_pattern_cmdid = WMI_10_4_WOW_ADD_WAKE_PATTERN_CMDID,
628	.wow_del_wake_pattern_cmdid = WMI_10_4_WOW_DEL_WAKE_PATTERN_CMDID,
629	.wow_enable_disable_wake_event_cmdid =
630				WMI_10_4_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
631	.wow_enable_cmdid = WMI_10_4_WOW_ENABLE_CMDID,
632	.wow_hostwakeup_from_sleep_cmdid =
633				WMI_10_4_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
634	.rtt_measreq_cmdid = WMI_10_4_RTT_MEASREQ_CMDID,
635	.rtt_tsf_cmdid = WMI_10_4_RTT_TSF_CMDID,
636	.vdev_spectral_scan_configure_cmdid =
637				WMI_10_4_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
638	.vdev_spectral_scan_enable_cmdid =
639				WMI_10_4_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
640	.request_stats_cmdid = WMI_10_4_REQUEST_STATS_CMDID,
641	.set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED,
642	.network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED,
643	.gtk_offload_cmdid = WMI_10_4_GTK_OFFLOAD_CMDID,
644	.csa_offload_enable_cmdid = WMI_10_4_CSA_OFFLOAD_ENABLE_CMDID,
645	.csa_offload_chanswitch_cmdid = WMI_10_4_CSA_OFFLOAD_CHANSWITCH_CMDID,
646	.chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED,
647	.peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED,
648	.peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED,
649	.sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED,
650	.sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED,
651	.sta_keepalive_cmd = WMI_CMD_UNSUPPORTED,
652	.echo_cmdid = WMI_10_4_ECHO_CMDID,
653	.pdev_utf_cmdid = WMI_10_4_PDEV_UTF_CMDID,
654	.dbglog_cfg_cmdid = WMI_10_4_DBGLOG_CFG_CMDID,
655	.pdev_qvit_cmdid = WMI_10_4_PDEV_QVIT_CMDID,
656	.pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED,
657	.vdev_set_keepalive_cmdid = WMI_10_4_VDEV_SET_KEEPALIVE_CMDID,
658	.vdev_get_keepalive_cmdid = WMI_10_4_VDEV_GET_KEEPALIVE_CMDID,
659	.force_fw_hang_cmdid = WMI_10_4_FORCE_FW_HANG_CMDID,
660	.gpio_config_cmdid = WMI_10_4_GPIO_CONFIG_CMDID,
661	.gpio_output_cmdid = WMI_10_4_GPIO_OUTPUT_CMDID,
662	.pdev_get_temperature_cmdid = WMI_10_4_PDEV_GET_TEMPERATURE_CMDID,
663	.vdev_set_wmm_params_cmdid = WMI_CMD_UNSUPPORTED,
664	.adaptive_qcs_cmdid = WMI_CMD_UNSUPPORTED,
665	.scan_update_request_cmdid = WMI_10_4_SCAN_UPDATE_REQUEST_CMDID,
666	.vdev_standby_response_cmdid = WMI_10_4_VDEV_STANDBY_RESPONSE_CMDID,
667	.vdev_resume_response_cmdid = WMI_10_4_VDEV_RESUME_RESPONSE_CMDID,
668	.wlan_peer_caching_add_peer_cmdid =
669			WMI_10_4_WLAN_PEER_CACHING_ADD_PEER_CMDID,
670	.wlan_peer_caching_evict_peer_cmdid =
671			WMI_10_4_WLAN_PEER_CACHING_EVICT_PEER_CMDID,
672	.wlan_peer_caching_restore_peer_cmdid =
673			WMI_10_4_WLAN_PEER_CACHING_RESTORE_PEER_CMDID,
674	.wlan_peer_caching_print_all_peers_info_cmdid =
675			WMI_10_4_WLAN_PEER_CACHING_PRINT_ALL_PEERS_INFO_CMDID,
676	.peer_update_wds_entry_cmdid = WMI_10_4_PEER_UPDATE_WDS_ENTRY_CMDID,
677	.peer_add_proxy_sta_entry_cmdid =
678			WMI_10_4_PEER_ADD_PROXY_STA_ENTRY_CMDID,
679	.rtt_keepalive_cmdid = WMI_10_4_RTT_KEEPALIVE_CMDID,
680	.oem_req_cmdid = WMI_10_4_OEM_REQ_CMDID,
681	.nan_cmdid = WMI_10_4_NAN_CMDID,
682	.vdev_ratemask_cmdid = WMI_10_4_VDEV_RATEMASK_CMDID,
683	.qboost_cfg_cmdid = WMI_10_4_QBOOST_CFG_CMDID,
684	.pdev_smart_ant_enable_cmdid = WMI_10_4_PDEV_SMART_ANT_ENABLE_CMDID,
685	.pdev_smart_ant_set_rx_antenna_cmdid =
686			WMI_10_4_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID,
687	.peer_smart_ant_set_tx_antenna_cmdid =
688			WMI_10_4_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID,
689	.peer_smart_ant_set_train_info_cmdid =
690			WMI_10_4_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID,
691	.peer_smart_ant_set_node_config_ops_cmdid =
692			WMI_10_4_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID,
693	.pdev_set_antenna_switch_table_cmdid =
694			WMI_10_4_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID,
695	.pdev_set_ctl_table_cmdid = WMI_10_4_PDEV_SET_CTL_TABLE_CMDID,
696	.pdev_set_mimogain_table_cmdid = WMI_10_4_PDEV_SET_MIMOGAIN_TABLE_CMDID,
697	.pdev_ratepwr_table_cmdid = WMI_10_4_PDEV_RATEPWR_TABLE_CMDID,
698	.pdev_ratepwr_chainmsk_table_cmdid =
699			WMI_10_4_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID,
700	.pdev_fips_cmdid = WMI_10_4_PDEV_FIPS_CMDID,
701	.tt_set_conf_cmdid = WMI_10_4_TT_SET_CONF_CMDID,
702	.fwtest_cmdid = WMI_10_4_FWTEST_CMDID,
703	.vdev_atf_request_cmdid = WMI_10_4_VDEV_ATF_REQUEST_CMDID,
704	.peer_atf_request_cmdid = WMI_10_4_PEER_ATF_REQUEST_CMDID,
705	.pdev_get_ani_cck_config_cmdid = WMI_10_4_PDEV_GET_ANI_CCK_CONFIG_CMDID,
706	.pdev_get_ani_ofdm_config_cmdid =
707			WMI_10_4_PDEV_GET_ANI_OFDM_CONFIG_CMDID,
708	.pdev_reserve_ast_entry_cmdid = WMI_10_4_PDEV_RESERVE_AST_ENTRY_CMDID,
709	.pdev_get_nfcal_power_cmdid = WMI_10_4_PDEV_GET_NFCAL_POWER_CMDID,
710	.pdev_get_tpc_cmdid = WMI_10_4_PDEV_GET_TPC_CMDID,
711	.pdev_get_ast_info_cmdid = WMI_10_4_PDEV_GET_AST_INFO_CMDID,
712	.vdev_set_dscp_tid_map_cmdid = WMI_10_4_VDEV_SET_DSCP_TID_MAP_CMDID,
713	.pdev_get_info_cmdid = WMI_10_4_PDEV_GET_INFO_CMDID,
714	.vdev_get_info_cmdid = WMI_10_4_VDEV_GET_INFO_CMDID,
715	.vdev_filter_neighbor_rx_packets_cmdid =
716			WMI_10_4_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID,
717	.mu_cal_start_cmdid = WMI_10_4_MU_CAL_START_CMDID,
718	.set_cca_params_cmdid = WMI_10_4_SET_CCA_PARAMS_CMDID,
719	.pdev_bss_chan_info_request_cmdid =
720			WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
721	.ext_resource_cfg_cmdid = WMI_10_4_EXT_RESOURCE_CFG_CMDID,
722	.vdev_set_ie_cmdid = WMI_10_4_VDEV_SET_IE_CMDID,
723	.set_lteu_config_cmdid = WMI_10_4_SET_LTEU_CONFIG_CMDID,
724	.atf_ssid_grouping_request_cmdid =
725			WMI_10_4_ATF_SSID_GROUPING_REQUEST_CMDID,
726	.peer_atf_ext_request_cmdid = WMI_10_4_PEER_ATF_EXT_REQUEST_CMDID,
727	.set_periodic_channel_stats_cfg_cmdid =
728			WMI_10_4_SET_PERIODIC_CHANNEL_STATS_CONFIG,
729	.peer_bwf_request_cmdid = WMI_10_4_PEER_BWF_REQUEST_CMDID,
730	.btcoex_cfg_cmdid = WMI_10_4_BTCOEX_CFG_CMDID,
731	.peer_tx_mu_txmit_count_cmdid = WMI_10_4_PEER_TX_MU_TXMIT_COUNT_CMDID,
732	.peer_tx_mu_txmit_rstcnt_cmdid = WMI_10_4_PEER_TX_MU_TXMIT_RSTCNT_CMDID,
733	.peer_gid_userpos_list_cmdid = WMI_10_4_PEER_GID_USERPOS_LIST_CMDID,
734	.pdev_check_cal_version_cmdid = WMI_10_4_PDEV_CHECK_CAL_VERSION_CMDID,
735	.coex_version_cfg_cmid = WMI_10_4_COEX_VERSION_CFG_CMID,
736	.pdev_get_rx_filter_cmdid = WMI_10_4_PDEV_GET_RX_FILTER_CMDID,
737	.pdev_extended_nss_cfg_cmdid = WMI_10_4_PDEV_EXTENDED_NSS_CFG_CMDID,
738	.vdev_set_scan_nac_rssi_cmdid = WMI_10_4_VDEV_SET_SCAN_NAC_RSSI_CMDID,
739	.prog_gpio_band_select_cmdid = WMI_10_4_PROG_GPIO_BAND_SELECT_CMDID,
740	.config_smart_logging_cmdid = WMI_10_4_CONFIG_SMART_LOGGING_CMDID,
741	.debug_fatal_condition_cmdid = WMI_10_4_DEBUG_FATAL_CONDITION_CMDID,
742	.get_tsf_timer_cmdid = WMI_10_4_GET_TSF_TIMER_CMDID,
743	.pdev_get_tpc_table_cmdid = WMI_10_4_PDEV_GET_TPC_TABLE_CMDID,
744	.vdev_sifs_trigger_time_cmdid = WMI_10_4_VDEV_SIFS_TRIGGER_TIME_CMDID,
745	.pdev_wds_entry_list_cmdid = WMI_10_4_PDEV_WDS_ENTRY_LIST_CMDID,
746	.tdls_set_state_cmdid = WMI_10_4_TDLS_SET_STATE_CMDID,
747	.tdls_peer_update_cmdid = WMI_10_4_TDLS_PEER_UPDATE_CMDID,
748	.tdls_set_offchan_mode_cmdid = WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
749	.radar_found_cmdid = WMI_10_4_RADAR_FOUND_CMDID,
750	.per_peer_per_tid_config_cmdid = WMI_10_4_PER_PEER_PER_TID_CONFIG_CMDID,
751};
752
753static struct wmi_peer_param_map wmi_peer_param_map = {
754	.smps_state = WMI_PEER_SMPS_STATE,
755	.ampdu = WMI_PEER_AMPDU,
756	.authorize = WMI_PEER_AUTHORIZE,
757	.chan_width = WMI_PEER_CHAN_WIDTH,
758	.nss = WMI_PEER_NSS,
759	.use_4addr = WMI_PEER_USE_4ADDR,
760	.use_fixed_power = WMI_PEER_USE_FIXED_PWR,
761	.debug = WMI_PEER_DEBUG,
762	.phymode = WMI_PEER_PHYMODE,
763	.dummy_var = WMI_PEER_DUMMY_VAR,
764};
765
766/* MAIN WMI VDEV param map */
767static struct wmi_vdev_param_map wmi_vdev_param_map = {
768	.rts_threshold = WMI_VDEV_PARAM_RTS_THRESHOLD,
769	.fragmentation_threshold = WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
770	.beacon_interval = WMI_VDEV_PARAM_BEACON_INTERVAL,
771	.listen_interval = WMI_VDEV_PARAM_LISTEN_INTERVAL,
772	.multicast_rate = WMI_VDEV_PARAM_MULTICAST_RATE,
773	.mgmt_tx_rate = WMI_VDEV_PARAM_MGMT_TX_RATE,
774	.slot_time = WMI_VDEV_PARAM_SLOT_TIME,
775	.preamble = WMI_VDEV_PARAM_PREAMBLE,
776	.swba_time = WMI_VDEV_PARAM_SWBA_TIME,
777	.wmi_vdev_stats_update_period = WMI_VDEV_STATS_UPDATE_PERIOD,
778	.wmi_vdev_pwrsave_ageout_time = WMI_VDEV_PWRSAVE_AGEOUT_TIME,
779	.wmi_vdev_host_swba_interval = WMI_VDEV_HOST_SWBA_INTERVAL,
780	.dtim_period = WMI_VDEV_PARAM_DTIM_PERIOD,
781	.wmi_vdev_oc_scheduler_air_time_limit =
782					WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
783	.wds = WMI_VDEV_PARAM_WDS,
784	.atim_window = WMI_VDEV_PARAM_ATIM_WINDOW,
785	.bmiss_count_max = WMI_VDEV_PARAM_BMISS_COUNT_MAX,
786	.bmiss_first_bcnt = WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
787	.bmiss_final_bcnt = WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
788	.feature_wmm = WMI_VDEV_PARAM_FEATURE_WMM,
789	.chwidth = WMI_VDEV_PARAM_CHWIDTH,
790	.chextoffset = WMI_VDEV_PARAM_CHEXTOFFSET,
791	.disable_htprotection =	WMI_VDEV_PARAM_DISABLE_HTPROTECTION,
792	.sta_quickkickout = WMI_VDEV_PARAM_STA_QUICKKICKOUT,
793	.mgmt_rate = WMI_VDEV_PARAM_MGMT_RATE,
794	.protection_mode = WMI_VDEV_PARAM_PROTECTION_MODE,
795	.fixed_rate = WMI_VDEV_PARAM_FIXED_RATE,
796	.sgi = WMI_VDEV_PARAM_SGI,
797	.ldpc = WMI_VDEV_PARAM_LDPC,
798	.tx_stbc = WMI_VDEV_PARAM_TX_STBC,
799	.rx_stbc = WMI_VDEV_PARAM_RX_STBC,
800	.intra_bss_fwd = WMI_VDEV_PARAM_INTRA_BSS_FWD,
801	.def_keyid = WMI_VDEV_PARAM_DEF_KEYID,
802	.nss = WMI_VDEV_PARAM_NSS,
803	.bcast_data_rate = WMI_VDEV_PARAM_BCAST_DATA_RATE,
804	.mcast_data_rate = WMI_VDEV_PARAM_MCAST_DATA_RATE,
805	.mcast_indicate = WMI_VDEV_PARAM_MCAST_INDICATE,
806	.dhcp_indicate = WMI_VDEV_PARAM_DHCP_INDICATE,
807	.unknown_dest_indicate = WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
808	.ap_keepalive_min_idle_inactive_time_secs =
809			WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
810	.ap_keepalive_max_idle_inactive_time_secs =
811			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
812	.ap_keepalive_max_unresponsive_time_secs =
813			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
814	.ap_enable_nawds = WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
815	.mcast2ucast_set = WMI_VDEV_PARAM_UNSUPPORTED,
816	.enable_rtscts = WMI_VDEV_PARAM_ENABLE_RTSCTS,
817	.txbf = WMI_VDEV_PARAM_TXBF,
818	.packet_powersave = WMI_VDEV_PARAM_PACKET_POWERSAVE,
819	.drop_unencry = WMI_VDEV_PARAM_DROP_UNENCRY,
820	.tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE,
821	.ap_detect_out_of_sync_sleeping_sta_time_secs =
822					WMI_VDEV_PARAM_UNSUPPORTED,
823	.rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
824	.cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
825	.mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
826	.rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
827	.vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
828	.vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
829	.early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
830	.early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
831	.early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
832	.early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
833	.early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
834	.early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
835	.proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
836	.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
837	.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
838	.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
839	.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
840	.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
841};
842
843/* 10.X WMI VDEV param map */
844static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
845	.rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD,
846	.fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
847	.beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL,
848	.listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL,
849	.multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE,
850	.mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE,
851	.slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME,
852	.preamble = WMI_10X_VDEV_PARAM_PREAMBLE,
853	.swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME,
854	.wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD,
855	.wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME,
856	.wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL,
857	.dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD,
858	.wmi_vdev_oc_scheduler_air_time_limit =
859				WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
860	.wds = WMI_10X_VDEV_PARAM_WDS,
861	.atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW,
862	.bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX,
863	.bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
864	.bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
865	.feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM,
866	.chwidth = WMI_10X_VDEV_PARAM_CHWIDTH,
867	.chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET,
868	.disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
869	.sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT,
870	.mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE,
871	.protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE,
872	.fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE,
873	.sgi = WMI_10X_VDEV_PARAM_SGI,
874	.ldpc = WMI_10X_VDEV_PARAM_LDPC,
875	.tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC,
876	.rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC,
877	.intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD,
878	.def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID,
879	.nss = WMI_10X_VDEV_PARAM_NSS,
880	.bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE,
881	.mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE,
882	.mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE,
883	.dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE,
884	.unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
885	.ap_keepalive_min_idle_inactive_time_secs =
886		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
887	.ap_keepalive_max_idle_inactive_time_secs =
888		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
889	.ap_keepalive_max_unresponsive_time_secs =
890		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
891	.ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS,
892	.mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET,
893	.enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS,
894	.txbf = WMI_VDEV_PARAM_UNSUPPORTED,
895	.packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED,
896	.drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED,
897	.tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED,
898	.ap_detect_out_of_sync_sleeping_sta_time_secs =
899		WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
900	.rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
901	.cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
902	.mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
903	.rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
904	.vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
905	.vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
906	.early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
907	.early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
908	.early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
909	.early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
910	.early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
911	.early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
912	.proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
913	.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
914	.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
915	.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
916	.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
917	.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
918};
919
920static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
921	.rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD,
922	.fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
923	.beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL,
924	.listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL,
925	.multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE,
926	.mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE,
927	.slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME,
928	.preamble = WMI_10X_VDEV_PARAM_PREAMBLE,
929	.swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME,
930	.wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD,
931	.wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME,
932	.wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL,
933	.dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD,
934	.wmi_vdev_oc_scheduler_air_time_limit =
935				WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
936	.wds = WMI_10X_VDEV_PARAM_WDS,
937	.atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW,
938	.bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX,
939	.bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
940	.bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
941	.feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM,
942	.chwidth = WMI_10X_VDEV_PARAM_CHWIDTH,
943	.chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET,
944	.disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
945	.sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT,
946	.mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE,
947	.protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE,
948	.fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE,
949	.sgi = WMI_10X_VDEV_PARAM_SGI,
950	.ldpc = WMI_10X_VDEV_PARAM_LDPC,
951	.tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC,
952	.rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC,
953	.intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD,
954	.def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID,
955	.nss = WMI_10X_VDEV_PARAM_NSS,
956	.bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE,
957	.mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE,
958	.mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE,
959	.dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE,
960	.unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
961	.ap_keepalive_min_idle_inactive_time_secs =
962		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
963	.ap_keepalive_max_idle_inactive_time_secs =
964		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
965	.ap_keepalive_max_unresponsive_time_secs =
966		WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
967	.ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS,
968	.mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET,
969	.enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS,
970	.txbf = WMI_VDEV_PARAM_UNSUPPORTED,
971	.packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED,
972	.drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED,
973	.tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED,
974	.ap_detect_out_of_sync_sleeping_sta_time_secs =
975		WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
976	.rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
977	.cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
978	.mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
979	.rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
980	.vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
981	.vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
982	.early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
983	.early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
984	.early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
985	.early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
986	.early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
987	.early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
988	.proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
989	.meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
990	.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
991	.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
992	.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
993	.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
994};
995
996static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
997	.rts_threshold = WMI_10_4_VDEV_PARAM_RTS_THRESHOLD,
998	.fragmentation_threshold = WMI_10_4_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
999	.beacon_interval = WMI_10_4_VDEV_PARAM_BEACON_INTERVAL,
1000	.listen_interval = WMI_10_4_VDEV_PARAM_LISTEN_INTERVAL,
1001	.multicast_rate = WMI_10_4_VDEV_PARAM_MULTICAST_RATE,
1002	.mgmt_tx_rate = WMI_10_4_VDEV_PARAM_MGMT_TX_RATE,
1003	.slot_time = WMI_10_4_VDEV_PARAM_SLOT_TIME,
1004	.preamble = WMI_10_4_VDEV_PARAM_PREAMBLE,
1005	.swba_time = WMI_10_4_VDEV_PARAM_SWBA_TIME,
1006	.wmi_vdev_stats_update_period = WMI_10_4_VDEV_STATS_UPDATE_PERIOD,
1007	.wmi_vdev_pwrsave_ageout_time = WMI_10_4_VDEV_PWRSAVE_AGEOUT_TIME,
1008	.wmi_vdev_host_swba_interval = WMI_10_4_VDEV_HOST_SWBA_INTERVAL,
1009	.dtim_period = WMI_10_4_VDEV_PARAM_DTIM_PERIOD,
1010	.wmi_vdev_oc_scheduler_air_time_limit =
1011	       WMI_10_4_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
1012	.wds = WMI_10_4_VDEV_PARAM_WDS,
1013	.atim_window = WMI_10_4_VDEV_PARAM_ATIM_WINDOW,
1014	.bmiss_count_max = WMI_10_4_VDEV_PARAM_BMISS_COUNT_MAX,
1015	.bmiss_first_bcnt = WMI_10_4_VDEV_PARAM_BMISS_FIRST_BCNT,
1016	.bmiss_final_bcnt = WMI_10_4_VDEV_PARAM_BMISS_FINAL_BCNT,
1017	.feature_wmm = WMI_10_4_VDEV_PARAM_FEATURE_WMM,
1018	.chwidth = WMI_10_4_VDEV_PARAM_CHWIDTH,
1019	.chextoffset = WMI_10_4_VDEV_PARAM_CHEXTOFFSET,
1020	.disable_htprotection = WMI_10_4_VDEV_PARAM_DISABLE_HTPROTECTION,
1021	.sta_quickkickout = WMI_10_4_VDEV_PARAM_STA_QUICKKICKOUT,
1022	.mgmt_rate = WMI_10_4_VDEV_PARAM_MGMT_RATE,
1023	.protection_mode = WMI_10_4_VDEV_PARAM_PROTECTION_MODE,
1024	.fixed_rate = WMI_10_4_VDEV_PARAM_FIXED_RATE,
1025	.sgi = WMI_10_4_VDEV_PARAM_SGI,
1026	.ldpc = WMI_10_4_VDEV_PARAM_LDPC,
1027	.tx_stbc = WMI_10_4_VDEV_PARAM_TX_STBC,
1028	.rx_stbc = WMI_10_4_VDEV_PARAM_RX_STBC,
1029	.intra_bss_fwd = WMI_10_4_VDEV_PARAM_INTRA_BSS_FWD,
1030	.def_keyid = WMI_10_4_VDEV_PARAM_DEF_KEYID,
1031	.nss = WMI_10_4_VDEV_PARAM_NSS,
1032	.bcast_data_rate = WMI_10_4_VDEV_PARAM_BCAST_DATA_RATE,
1033	.mcast_data_rate = WMI_10_4_VDEV_PARAM_MCAST_DATA_RATE,
1034	.mcast_indicate = WMI_10_4_VDEV_PARAM_MCAST_INDICATE,
1035	.dhcp_indicate = WMI_10_4_VDEV_PARAM_DHCP_INDICATE,
1036	.unknown_dest_indicate = WMI_10_4_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
1037	.ap_keepalive_min_idle_inactive_time_secs =
1038	       WMI_10_4_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
1039	.ap_keepalive_max_idle_inactive_time_secs =
1040	       WMI_10_4_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
1041	.ap_keepalive_max_unresponsive_time_secs =
1042	       WMI_10_4_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
1043	.ap_enable_nawds = WMI_10_4_VDEV_PARAM_AP_ENABLE_NAWDS,
1044	.mcast2ucast_set = WMI_10_4_VDEV_PARAM_MCAST2UCAST_SET,
1045	.enable_rtscts = WMI_10_4_VDEV_PARAM_ENABLE_RTSCTS,
1046	.txbf = WMI_10_4_VDEV_PARAM_TXBF,
1047	.packet_powersave = WMI_10_4_VDEV_PARAM_PACKET_POWERSAVE,
1048	.drop_unencry = WMI_10_4_VDEV_PARAM_DROP_UNENCRY,
1049	.tx_encap_type = WMI_10_4_VDEV_PARAM_TX_ENCAP_TYPE,
1050	.ap_detect_out_of_sync_sleeping_sta_time_secs =
1051	       WMI_10_4_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
1052	.rc_num_retries = WMI_10_4_VDEV_PARAM_RC_NUM_RETRIES,
1053	.cabq_maxdur = WMI_10_4_VDEV_PARAM_CABQ_MAXDUR,
1054	.mfptest_set = WMI_10_4_VDEV_PARAM_MFPTEST_SET,
1055	.rts_fixed_rate = WMI_10_4_VDEV_PARAM_RTS_FIXED_RATE,
1056	.vht_sgimask = WMI_10_4_VDEV_PARAM_VHT_SGIMASK,
1057	.vht80_ratemask = WMI_10_4_VDEV_PARAM_VHT80_RATEMASK,
1058	.early_rx_adjust_enable = WMI_10_4_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
1059	.early_rx_tgt_bmiss_num = WMI_10_4_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
1060	.early_rx_bmiss_sample_cycle =
1061	       WMI_10_4_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
1062	.early_rx_slop_step = WMI_10_4_VDEV_PARAM_EARLY_RX_SLOP_STEP,
1063	.early_rx_init_slop = WMI_10_4_VDEV_PARAM_EARLY_RX_INIT_SLOP,
1064	.early_rx_adjust_pause = WMI_10_4_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
1065	.proxy_sta = WMI_10_4_VDEV_PARAM_PROXY_STA,
1066	.meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC,
1067	.rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE,
1068	.bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK,
1069	.inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
1070	.dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
1071	.disable_4addr_src_lrn = WMI_10_4_VDEV_PARAM_DISABLE_4_ADDR_SRC_LRN,
1072	.rtt_responder_role = WMI_10_4_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
1073};
1074
1075static struct wmi_pdev_param_map wmi_pdev_param_map = {
1076	.tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK,
1077	.rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK,
1078	.txpower_limit2g = WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
1079	.txpower_limit5g = WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
1080	.txpower_scale = WMI_PDEV_PARAM_TXPOWER_SCALE,
1081	.beacon_gen_mode = WMI_PDEV_PARAM_BEACON_GEN_MODE,
1082	.beacon_tx_mode = WMI_PDEV_PARAM_BEACON_TX_MODE,
1083	.resmgr_offchan_mode = WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
1084	.protection_mode = WMI_PDEV_PARAM_PROTECTION_MODE,
1085	.dynamic_bw = WMI_PDEV_PARAM_DYNAMIC_BW,
1086	.non_agg_sw_retry_th = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
1087	.agg_sw_retry_th = WMI_PDEV_PARAM_AGG_SW_RETRY_TH,
1088	.sta_kickout_th = WMI_PDEV_PARAM_STA_KICKOUT_TH,
1089	.ac_aggrsize_scaling = WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING,
1090	.ltr_enable = WMI_PDEV_PARAM_LTR_ENABLE,
1091	.ltr_ac_latency_be = WMI_PDEV_PARAM_LTR_AC_LATENCY_BE,
1092	.ltr_ac_latency_bk = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK,
1093	.ltr_ac_latency_vi = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI,
1094	.ltr_ac_latency_vo = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO,
1095	.ltr_ac_latency_timeout = WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
1096	.ltr_sleep_override = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
1097	.ltr_rx_override = WMI_PDEV_PARAM_LTR_RX_OVERRIDE,
1098	.ltr_tx_activity_timeout = WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
1099	.l1ss_enable = WMI_PDEV_PARAM_L1SS_ENABLE,
1100	.dsleep_enable = WMI_PDEV_PARAM_DSLEEP_ENABLE,
1101	.pcielp_txbuf_flush = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
1102	.pcielp_txbuf_watermark = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
1103	.pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
1104	.pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
1105	.pdev_stats_update_period = WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
1106	.vdev_stats_update_period = WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
1107	.peer_stats_update_period = WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
1108	.bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
1109	.pmf_qos = WMI_PDEV_PARAM_PMF_QOS,
1110	.arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
1111	.dcs = WMI_PDEV_PARAM_DCS,
1112	.ani_enable = WMI_PDEV_PARAM_ANI_ENABLE,
1113	.ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD,
1114	.ani_listen_period = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
1115	.ani_ofdm_level = WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
1116	.ani_cck_level = WMI_PDEV_PARAM_ANI_CCK_LEVEL,
1117	.dyntxchain = WMI_PDEV_PARAM_DYNTXCHAIN,
1118	.proxy_sta = WMI_PDEV_PARAM_PROXY_STA,
1119	.idle_ps_config = WMI_PDEV_PARAM_IDLE_PS_CONFIG,
1120	.power_gating_sleep = WMI_PDEV_PARAM_POWER_GATING_SLEEP,
1121	.fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED,
1122	.burst_dur = WMI_PDEV_PARAM_UNSUPPORTED,
1123	.burst_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1124	.cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
1125	.aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
1126	.rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1127	.smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
1128	.igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
1129	.igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1130	.antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
1131	.rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
1132	.set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1133	.proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1134	.set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1135	.set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1136	.remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1137	.peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1138	.igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
1139	.block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
1140	.set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1141	.set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1142	.set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1143	.txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1144	.set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1145	.set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1146	.en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
1147	.mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
1148	.noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
1149	.noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1150	.dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1151	.set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
1152	.atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
1153	.atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
1154	.ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
1155	.mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
1156	.sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
1157	.signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
1158	.signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
1159	.enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
1160	.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
1161	.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1162	.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
1163	.pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
1164	.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
1165	.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1166	.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1167	.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
1168};
1169
1170static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
1171	.tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK,
1172	.rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK,
1173	.txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G,
1174	.txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G,
1175	.txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE,
1176	.beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE,
1177	.beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE,
1178	.resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
1179	.protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE,
1180	.dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW,
1181	.non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
1182	.agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH,
1183	.sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH,
1184	.ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING,
1185	.ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE,
1186	.ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE,
1187	.ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK,
1188	.ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI,
1189	.ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO,
1190	.ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
1191	.ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
1192	.ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE,
1193	.ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
1194	.l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE,
1195	.dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE,
1196	.pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED,
1197	.pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED,
1198	.pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED,
1199	.pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED,
1200	.pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
1201	.vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
1202	.peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
1203	.bcnflt_stats_update_period =
1204				WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
1205	.pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
1206	.arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
1207	.dcs = WMI_10X_PDEV_PARAM_DCS,
1208	.ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
1209	.ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
1210	.ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD,
1211	.ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL,
1212	.ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL,
1213	.dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN,
1214	.proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED,
1215	.idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED,
1216	.power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED,
1217	.fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
1218	.burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR,
1219	.burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE,
1220	.cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD,
1221	.aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
1222	.rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1223	.smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
1224	.igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
1225	.igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1226	.antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
1227	.rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
1228	.set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1229	.proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1230	.set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1231	.set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1232	.remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1233	.peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1234	.igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
1235	.block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
1236	.set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1237	.set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1238	.set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1239	.txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1240	.set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1241	.set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1242	.en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
1243	.mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
1244	.noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
1245	.noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1246	.dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1247	.set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
1248	.atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
1249	.atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
1250	.ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
1251	.mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
1252	.sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
1253	.signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
1254	.signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
1255	.enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
1256	.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
1257	.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1258	.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
1259	.pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
1260	.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
1261	.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1262	.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1263	.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
1264};
1265
1266static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = {
1267	.tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK,
1268	.rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK,
1269	.txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G,
1270	.txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G,
1271	.txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE,
1272	.beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE,
1273	.beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE,
1274	.resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
1275	.protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE,
1276	.dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW,
1277	.non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
1278	.agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH,
1279	.sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH,
1280	.ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING,
1281	.ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE,
1282	.ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE,
1283	.ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK,
1284	.ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI,
1285	.ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO,
1286	.ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
1287	.ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
1288	.ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE,
1289	.ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
1290	.l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE,
1291	.dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE,
1292	.pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED,
1293	.pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED,
1294	.pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED,
1295	.pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED,
1296	.pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
1297	.vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
1298	.peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
1299	.bcnflt_stats_update_period =
1300				WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
1301	.pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
1302	.arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
1303	.dcs = WMI_10X_PDEV_PARAM_DCS,
1304	.ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
1305	.ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
1306	.ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD,
1307	.ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL,
1308	.ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL,
1309	.dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN,
1310	.proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED,
1311	.idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED,
1312	.power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED,
1313	.fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
1314	.burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR,
1315	.burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE,
1316	.cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD,
1317	.aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
1318	.rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1319	.smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
1320	.igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
1321	.igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1322	.antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
1323	.rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
1324	.set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
1325	.proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1326	.set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
1327	.set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1328	.remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
1329	.peer_sta_ps_statechg_enable =
1330				WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE,
1331	.igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
1332	.block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
1333	.set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1334	.set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1335	.set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1336	.txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1337	.set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1338	.set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
1339	.en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
1340	.mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
1341	.noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
1342	.noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1343	.dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
1344	.set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
1345	.atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
1346	.atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
1347	.ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
1348	.mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
1349	.sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
1350	.signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
1351	.signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
1352	.enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
1353	.enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
1354	.cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
1355	.rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
1356	.pdev_reset = WMI_10X_PDEV_PARAM_PDEV_RESET,
1357	.wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
1358	.arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1359	.arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
1360	.enable_btcoex = WMI_PDEV_PARAM_UNSUPPORTED,
1361};
1362
1363/* firmware 10.2 specific mappings */
1364static struct wmi_cmd_map wmi_10_2_cmd_map = {
1365	.init_cmdid = WMI_10_2_INIT_CMDID,
1366	.start_scan_cmdid = WMI_10_2_START_SCAN_CMDID,
1367	.stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID,
1368	.scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID,
1369	.scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED,
1370	.scan_prob_req_oui_cmdid = WMI_CMD_UNSUPPORTED,
1371	.pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID,
1372	.pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID,
1373	.pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID,
1374	.pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID,
1375	.pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID,
1376	.pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID,
1377	.pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID,
1378	.pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID,
1379	.pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID,
1380	.pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID,
1381	.pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID,
1382	.pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID,
1383	.vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID,
1384	.vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID,
1385	.vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID,
1386	.vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID,
1387	.vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID,
1388	.vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID,
1389	.vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID,
1390	.vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID,
1391	.vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID,
1392	.peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID,
1393	.peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID,
1394	.peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID,
1395	.peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID,
1396	.peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID,
1397	.peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID,
1398	.peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID,
1399	.peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID,
1400	.bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID,
1401	.pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID,
1402	.bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
1403	.bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID,
1404	.prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID,
1405	.mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID,
1406	.prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
1407	.addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID,
1408	.addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID,
1409	.addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID,
1410	.delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID,
1411	.addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID,
1412	.send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID,
1413	.sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID,
1414	.sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID,
1415	.sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID,
1416	.pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID,
1417	.pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID,
1418	.roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE,
1419	.roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD,
1420	.roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD,
1421	.roam_scan_rssi_change_threshold =
1422				WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
1423	.roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE,
1424	.ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE,
1425	.ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE,
1426	.ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD,
1427	.p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO,
1428	.p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY,
1429	.p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE,
1430	.p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE,
1431	.p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
1432	.ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID,
1433	.ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
1434	.peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID,
1435	.wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID,
1436	.wlan_profile_set_hist_intvl_cmdid =
1437				WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
1438	.wlan_profile_get_profile_data_cmdid =
1439				WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
1440	.wlan_profile_enable_profile_id_cmdid =
1441				WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
1442	.wlan_profile_list_profile_id_cmdid =
1443				WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
1444	.pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID,
1445	.pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID,
1446	.add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID,
1447	.rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID,
1448	.wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID,
1449	.wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID,
1450	.wow_enable_disable_wake_event_cmdid =
1451				WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
1452	.wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID,
1453	.wow_hostwakeup_from_sleep_cmdid =
1454				WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
1455	.rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID,
1456	.rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID,
1457	.vdev_spectral_scan_configure_cmdid =
1458				WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
1459	.vdev_spectral_scan_enable_cmdid =
1460				WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
1461	.request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID,
1462	.set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED,
1463	.network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED,
1464	.gtk_offload_cmdid = WMI_CMD_UNSUPPORTED,
1465	.csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED,
1466	.csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED,
1467	.chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED,
1468	.peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED,
1469	.peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED,
1470	.sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED,
1471	.sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED,
1472	.sta_keepalive_cmd = WMI_CMD_UNSUPPORTED,
1473	.echo_cmdid = WMI_10_2_ECHO_CMDID,
1474	.pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID,
1475	.dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID,
1476	.pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID,
1477	.pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED,
1478	.vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
1479	.vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
1480	.force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
1481	.gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
1482	.gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
1483	.pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
1484	.pdev_enable_adaptive_cca_cmdid = WMI_CMD_UNSUPPORTED,
1485	.scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
1486	.vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
1487	.vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
1488	.wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
1489	.wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
1490	.wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
1491	.wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
1492	.peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
1493	.peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
1494	.rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
1495	.oem_req_cmdid = WMI_CMD_UNSUPPORTED,
1496	.nan_cmdid = WMI_CMD_UNSUPPORTED,
1497	.vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
1498	.qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
1499	.pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
1500	.pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
1501	.peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
1502	.peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
1503	.peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
1504	.pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
1505	.pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
1506	.pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
1507	.pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
1508	.pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
1509	.pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
1510	.tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
1511	.fwtest_cmdid = WMI_CMD_UNSUPPORTED,
1512	.vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
1513	.peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
1514	.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
1515	.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
1516	.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
1517	.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
1518	.radar_found_cmdid = WMI_CMD_UNSUPPORTED,
1519};
1520
1521static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
1522	.tx_chain_mask = WMI_10_4_PDEV_PARAM_TX_CHAIN_MASK,
1523	.rx_chain_mask = WMI_10_4_PDEV_PARAM_RX_CHAIN_MASK,
1524	.txpower_limit2g = WMI_10_4_PDEV_PARAM_TXPOWER_LIMIT2G,
1525	.txpower_limit5g = WMI_10_4_PDEV_PARAM_TXPOWER_LIMIT5G,
1526	.txpower_scale = WMI_10_4_PDEV_PARAM_TXPOWER_SCALE,
1527	.beacon_gen_mode = WMI_10_4_PDEV_PARAM_BEACON_GEN_MODE,
1528	.beacon_tx_mode = WMI_10_4_PDEV_PARAM_BEACON_TX_MODE,
1529	.resmgr_offchan_mode = WMI_10_4_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
1530	.protection_mode = WMI_10_4_PDEV_PARAM_PROTECTION_MODE,
1531	.dynamic_bw = WMI_10_4_PDEV_PARAM_DYNAMIC_BW,
1532	.non_agg_sw_retry_th = WMI_10_4_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
1533	.agg_sw_retry_th = WMI_10_4_PDEV_PARAM_AGG_SW_RETRY_TH,
1534	.sta_kickout_th = WMI_10_4_PDEV_PARAM_STA_KICKOUT_TH,
1535	.ac_aggrsize_scaling = WMI_10_4_PDEV_PARAM_AC_AGGRSIZE_SCALING,
1536	.ltr_enable = WMI_10_4_PDEV_PARAM_LTR_ENABLE,
1537	.ltr_ac_latency_be = WMI_10_4_PDEV_PARAM_LTR_AC_LATENCY_BE,
1538	.ltr_ac_latency_bk = WMI_10_4_PDEV_PARAM_LTR_AC_LATENCY_BK,
1539	.ltr_ac_latency_vi = WMI_10_4_PDEV_PARAM_LTR_AC_LATENCY_VI,
1540	.ltr_ac_latency_vo = WMI_10_4_PDEV_PARAM_LTR_AC_LATENCY_VO,
1541	.ltr_ac_latency_timeout = WMI_10_4_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
1542	.ltr_sleep_override = WMI_10_4_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
1543	.ltr_rx_override = WMI_10_4_PDEV_PARAM_LTR_RX_OVERRIDE,
1544	.ltr_tx_activity_timeout = WMI_10_4_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
1545	.l1ss_enable = WMI_10_4_PDEV_PARAM_L1SS_ENABLE,
1546	.dsleep_enable = WMI_10_4_PDEV_PARAM_DSLEEP_ENABLE,
1547	.pcielp_txbuf_flush = WMI_10_4_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
1548	.pcielp_txbuf_watermark = WMI_10_4_PDEV_PARAM_PCIELP_TXBUF_WATERMARK,
1549	.pcielp_txbuf_tmo_en = WMI_10_4_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
1550	.pcielp_txbuf_tmo_value = WMI_10_4_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
1551	.pdev_stats_update_period =
1552			WMI_10_4_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
1553	.vdev_stats_update_period =
1554			WMI_10_4_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
1555	.peer_stats_update_period =
1556			WMI_10_4_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
1557	.bcnflt_stats_update_period =
1558			WMI_10_4_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
1559	.pmf_qos = WMI_10_4_PDEV_PARAM_PMF_QOS,
1560	.arp_ac_override = WMI_10_4_PDEV_PARAM_ARP_AC_OVERRIDE,
1561	.dcs = WMI_10_4_PDEV_PARAM_DCS,
1562	.ani_enable = WMI_10_4_PDEV_PARAM_ANI_ENABLE,
1563	.ani_poll_period = WMI_10_4_PDEV_PARAM_ANI_POLL_PERIOD,
1564	.ani_listen_period = WMI_10_4_PDEV_PARAM_ANI_LISTEN_PERIOD,
1565	.ani_ofdm_level = WMI_10_4_PDEV_PARAM_ANI_OFDM_LEVEL,
1566	.ani_cck_level = WMI_10_4_PDEV_PARAM_ANI_CCK_LEVEL,
1567	.dyntxchain = WMI_10_4_PDEV_PARAM_DYNTXCHAIN,
1568	.proxy_sta = WMI_10_4_PDEV_PARAM_PROXY_STA,
1569	.idle_ps_config = WMI_10_4_PDEV_PARAM_IDLE_PS_CONFIG,
1570	.power_gating_sleep = WMI_10_4_PDEV_PARAM_POWER_GATING_SLEEP,
1571	.fast_channel_reset = WMI_10_4_PDEV_PARAM_FAST_CHANNEL_RESET,
1572	.burst_dur = WMI_10_4_PDEV_PARAM_BURST_DUR,
1573	.burst_enable = WMI_10_4_PDEV_PARAM_BURST_ENABLE,
1574	.cal_period = WMI_10_4_PDEV_PARAM_CAL_PERIOD,
1575	.aggr_burst = WMI_10_4_PDEV_PARAM_AGGR_BURST,
1576	.rx_decap_mode = WMI_10_4_PDEV_PARAM_RX_DECAP_MODE,
1577	.smart_antenna_default_antenna =
1578			WMI_10_4_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA,
1579	.igmpmld_override = WMI_10_4_PDEV_PARAM_IGMPMLD_OVERRIDE,
1580	.igmpmld_tid = WMI_10_4_PDEV_PARAM_IGMPMLD_TID,
1581	.antenna_gain = WMI_10_4_PDEV_PARAM_ANTENNA_GAIN,
1582	.rx_filter = WMI_10_4_PDEV_PARAM_RX_FILTER,
1583	.set_mcast_to_ucast_tid = WMI_10_4_PDEV_SET_MCAST_TO_UCAST_TID,
1584	.proxy_sta_mode = WMI_10_4_PDEV_PARAM_PROXY_STA_MODE,
1585	.set_mcast2ucast_mode = WMI_10_4_PDEV_PARAM_SET_MCAST2UCAST_MODE,
1586	.set_mcast2ucast_buffer = WMI_10_4_PDEV_PARAM_SET_MCAST2UCAST_BUFFER,
1587	.remove_mcast2ucast_buffer =
1588			WMI_10_4_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
1589	.peer_sta_ps_statechg_enable =
1590			WMI_10_4_PDEV_PEER_STA_PS_STATECHG_ENABLE,
1591	.igmpmld_ac_override = WMI_10_4_PDEV_PARAM_IGMPMLD_AC_OVERRIDE,
1592	.block_interbss = WMI_10_4_PDEV_PARAM_BLOCK_INTERBSS,
1593	.set_disable_reset_cmdid = WMI_10_4_PDEV_PARAM_SET_DISABLE_RESET_CMDID,
1594	.set_msdu_ttl_cmdid = WMI_10_4_PDEV_PARAM_SET_MSDU_TTL_CMDID,
1595	.set_ppdu_duration_cmdid = WMI_10_4_PDEV_PARAM_SET_PPDU_DURATION_CMDID,
1596	.txbf_sound_period_cmdid = WMI_10_4_PDEV_PARAM_TXBF_SOUND_PERIOD_CMDID,
1597	.set_promisc_mode_cmdid = WMI_10_4_PDEV_PARAM_SET_PROMISC_MODE_CMDID,
1598	.set_burst_mode_cmdid = WMI_10_4_PDEV_PARAM_SET_BURST_MODE_CMDID,
1599	.en_stats = WMI_10_4_PDEV_PARAM_EN_STATS,
1600	.mu_group_policy = WMI_10_4_PDEV_PARAM_MU_GROUP_POLICY,
1601	.noise_detection = WMI_10_4_PDEV_PARAM_NOISE_DETECTION,
1602	.noise_threshold = WMI_10_4_PDEV_PARAM_NOISE_THRESHOLD,
1603	.dpd_enable = WMI_10_4_PDEV_PARAM_DPD_ENABLE,
1604	.set_mcast_bcast_echo = WMI_10_4_PDEV_PARAM_SET_MCAST_BCAST_ECHO,
1605	.atf_strict_sch = WMI_10_4_PDEV_PARAM_ATF_STRICT_SCH,
1606	.atf_sched_duration = WMI_10_4_PDEV_PARAM_ATF_SCHED_DURATION,
1607	.ant_plzn = WMI_10_4_PDEV_PARAM_ANT_PLZN,
1608	.mgmt_retry_limit = WMI_10_4_PDEV_PARAM_MGMT_RETRY_LIMIT,
1609	.sensitivity_level = WMI_10_4_PDEV_PARAM_SENSITIVITY_LEVEL,
1610	.signed_txpower_2g = WMI_10_4_PDEV_PARAM_SIGNED_TXPOWER_2G,
1611	.signed_txpower_5g = WMI_10_4_PDEV_PARAM_SIGNED_TXPOWER_5G,
1612	.enable_per_tid_amsdu = WMI_10_4_PDEV_PARAM_ENABLE_PER_TID_AMSDU,
1613	.enable_per_tid_ampdu = WMI_10_4_PDEV_PARAM_ENABLE_PER_TID_AMPDU,
1614	.cca_threshold = WMI_10_4_PDEV_PARAM_CCA_THRESHOLD,
1615	.rts_fixed_rate = WMI_10_4_PDEV_PARAM_RTS_FIXED_RATE,
1616	.pdev_reset = WMI_10_4_PDEV_PARAM_PDEV_RESET,
1617	.wapi_mbssid_offset = WMI_10_4_PDEV_PARAM_WAPI_MBSSID_OFFSET,
1618	.arp_srcaddr = WMI_10_4_PDEV_PARAM_ARP_SRCADDR,
1619	.arp_dstaddr = WMI_10_4_PDEV_PARAM_ARP_DSTADDR,
1620	.enable_btcoex = WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX,
1621};
1622
1623static const u8 wmi_key_cipher_suites[] = {
1624	[WMI_CIPHER_NONE] = WMI_CIPHER_NONE,
1625	[WMI_CIPHER_WEP] = WMI_CIPHER_WEP,
1626	[WMI_CIPHER_TKIP] = WMI_CIPHER_TKIP,
1627	[WMI_CIPHER_AES_OCB] = WMI_CIPHER_AES_OCB,
1628	[WMI_CIPHER_AES_CCM] = WMI_CIPHER_AES_CCM,
1629	[WMI_CIPHER_WAPI] = WMI_CIPHER_WAPI,
1630	[WMI_CIPHER_CKIP] = WMI_CIPHER_CKIP,
1631	[WMI_CIPHER_AES_CMAC] = WMI_CIPHER_AES_CMAC,
1632	[WMI_CIPHER_AES_GCM] = WMI_CIPHER_AES_GCM,
1633};
1634
1635static const u8 wmi_tlv_key_cipher_suites[] = {
1636	[WMI_CIPHER_NONE] = WMI_TLV_CIPHER_NONE,
1637	[WMI_CIPHER_WEP] = WMI_TLV_CIPHER_WEP,
1638	[WMI_CIPHER_TKIP] = WMI_TLV_CIPHER_TKIP,
1639	[WMI_CIPHER_AES_OCB] = WMI_TLV_CIPHER_AES_OCB,
1640	[WMI_CIPHER_AES_CCM] = WMI_TLV_CIPHER_AES_CCM,
1641	[WMI_CIPHER_WAPI] = WMI_TLV_CIPHER_WAPI,
1642	[WMI_CIPHER_CKIP] = WMI_TLV_CIPHER_CKIP,
1643	[WMI_CIPHER_AES_CMAC] = WMI_TLV_CIPHER_AES_CMAC,
1644	[WMI_CIPHER_AES_GCM] = WMI_TLV_CIPHER_AES_GCM,
1645};
1646
1647static const struct wmi_peer_flags_map wmi_peer_flags_map = {
1648	.auth = WMI_PEER_AUTH,
1649	.qos = WMI_PEER_QOS,
1650	.need_ptk_4_way = WMI_PEER_NEED_PTK_4_WAY,
1651	.need_gtk_2_way = WMI_PEER_NEED_GTK_2_WAY,
1652	.apsd = WMI_PEER_APSD,
1653	.ht = WMI_PEER_HT,
1654	.bw40 = WMI_PEER_40MHZ,
1655	.stbc = WMI_PEER_STBC,
1656	.ldbc = WMI_PEER_LDPC,
1657	.dyn_mimops = WMI_PEER_DYN_MIMOPS,
1658	.static_mimops = WMI_PEER_STATIC_MIMOPS,
1659	.spatial_mux = WMI_PEER_SPATIAL_MUX,
1660	.vht = WMI_PEER_VHT,
1661	.bw80 = WMI_PEER_80MHZ,
1662	.vht_2g = WMI_PEER_VHT_2G,
1663	.pmf = WMI_PEER_PMF,
1664	.bw160 = WMI_PEER_160MHZ,
1665};
1666
1667static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
1668	.auth = WMI_10X_PEER_AUTH,
1669	.qos = WMI_10X_PEER_QOS,
1670	.need_ptk_4_way = WMI_10X_PEER_NEED_PTK_4_WAY,
1671	.need_gtk_2_way = WMI_10X_PEER_NEED_GTK_2_WAY,
1672	.apsd = WMI_10X_PEER_APSD,
1673	.ht = WMI_10X_PEER_HT,
1674	.bw40 = WMI_10X_PEER_40MHZ,
1675	.stbc = WMI_10X_PEER_STBC,
1676	.ldbc = WMI_10X_PEER_LDPC,
1677	.dyn_mimops = WMI_10X_PEER_DYN_MIMOPS,
1678	.static_mimops = WMI_10X_PEER_STATIC_MIMOPS,
1679	.spatial_mux = WMI_10X_PEER_SPATIAL_MUX,
1680	.vht = WMI_10X_PEER_VHT,
1681	.bw80 = WMI_10X_PEER_80MHZ,
1682	.bw160 = WMI_10X_PEER_160MHZ,
1683};
1684
1685static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
1686	.auth = WMI_10_2_PEER_AUTH,
1687	.qos = WMI_10_2_PEER_QOS,
1688	.need_ptk_4_way = WMI_10_2_PEER_NEED_PTK_4_WAY,
1689	.need_gtk_2_way = WMI_10_2_PEER_NEED_GTK_2_WAY,
1690	.apsd = WMI_10_2_PEER_APSD,
1691	.ht = WMI_10_2_PEER_HT,
1692	.bw40 = WMI_10_2_PEER_40MHZ,
1693	.stbc = WMI_10_2_PEER_STBC,
1694	.ldbc = WMI_10_2_PEER_LDPC,
1695	.dyn_mimops = WMI_10_2_PEER_DYN_MIMOPS,
1696	.static_mimops = WMI_10_2_PEER_STATIC_MIMOPS,
1697	.spatial_mux = WMI_10_2_PEER_SPATIAL_MUX,
1698	.vht = WMI_10_2_PEER_VHT,
1699	.bw80 = WMI_10_2_PEER_80MHZ,
1700	.vht_2g = WMI_10_2_PEER_VHT_2G,
1701	.pmf = WMI_10_2_PEER_PMF,
1702	.bw160 = WMI_10_2_PEER_160MHZ,
1703};
1704
1705void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
1706				const struct wmi_channel_arg *arg)
1707{
1708	u32 flags = 0;
1709	struct ieee80211_channel *chan = NULL;
1710
1711	memset(ch, 0, sizeof(*ch));
1712
1713	if (arg->passive)
1714		flags |= WMI_CHAN_FLAG_PASSIVE;
1715	if (arg->allow_ibss)
1716		flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED;
1717	if (arg->allow_ht)
1718		flags |= WMI_CHAN_FLAG_ALLOW_HT;
1719	if (arg->allow_vht)
1720		flags |= WMI_CHAN_FLAG_ALLOW_VHT;
1721	if (arg->ht40plus)
1722		flags |= WMI_CHAN_FLAG_HT40_PLUS;
1723	if (arg->chan_radar)
1724		flags |= WMI_CHAN_FLAG_DFS;
1725
1726	ch->band_center_freq2 = 0;
1727	ch->mhz = __cpu_to_le32(arg->freq);
1728	ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
1729	if (arg->mode == MODE_11AC_VHT80_80) {
1730		ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
1731		chan = ieee80211_get_channel(ar->hw->wiphy,
1732					     arg->band_center_freq2 - 10);
1733	}
1734
1735	if (arg->mode == MODE_11AC_VHT160) {
1736		u32 band_center_freq1;
1737		u32 band_center_freq2;
1738
1739		if (arg->freq > arg->band_center_freq1) {
1740			band_center_freq1 = arg->band_center_freq1 + 40;
1741			band_center_freq2 = arg->band_center_freq1 - 40;
1742		} else {
1743			band_center_freq1 = arg->band_center_freq1 - 40;
1744			band_center_freq2 = arg->band_center_freq1 + 40;
1745		}
1746
1747		ch->band_center_freq1 =
1748					__cpu_to_le32(band_center_freq1);
1749		/* Minus 10 to get a defined 5G channel frequency*/
1750		chan = ieee80211_get_channel(ar->hw->wiphy,
1751					     band_center_freq2 - 10);
1752		/* The center frequency of the entire VHT160 */
1753		ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1);
1754	}
1755
1756	if (chan && chan->flags & IEEE80211_CHAN_RADAR)
1757		flags |= WMI_CHAN_FLAG_DFS_CFREQ2;
1758
1759	ch->min_power = arg->min_power;
1760	ch->max_power = arg->max_power;
1761	ch->reg_power = arg->max_reg_power;
1762	ch->antenna_max = arg->max_antenna_gain;
1763	ch->max_tx_power = arg->max_power;
1764
1765	/* mode & flags share storage */
1766	ch->mode = arg->mode;
1767	ch->flags |= __cpu_to_le32(flags);
1768}
1769
1770int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
1771{
1772	unsigned long time_left;
1773
1774	time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
1775						WMI_SERVICE_READY_TIMEOUT_HZ);
1776	if (!time_left)
1777		return -ETIMEDOUT;
1778	return 0;
1779}
1780
1781int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)
1782{
1783	unsigned long time_left;
1784
1785	time_left = wait_for_completion_timeout(&ar->wmi.unified_ready,
1786						WMI_UNIFIED_READY_TIMEOUT_HZ);
1787	if (!time_left)
1788		return -ETIMEDOUT;
1789	return 0;
1790}
1791
1792struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len)
1793{
1794	struct sk_buff *skb;
1795	u32 round_len = roundup(len, 4);
1796
1797	skb = ath10k_htc_alloc_skb(ar, WMI_SKB_HEADROOM + round_len);
1798	if (!skb)
1799		return NULL;
1800
1801	skb_reserve(skb, WMI_SKB_HEADROOM);
1802	if (!IS_ALIGNED((unsigned long)skb->data, 4))
1803		ath10k_warn(ar, "Unaligned WMI skb\n");
1804
1805	skb_put(skb, round_len);
1806	memset(skb->data, 0, round_len);
1807
1808	return skb;
1809}
1810
1811static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
1812{
1813	dev_kfree_skb(skb);
1814}
1815
1816int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
1817			       u32 cmd_id)
1818{
1819	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
1820	struct wmi_cmd_hdr *cmd_hdr;
1821	int ret;
1822	u32 cmd = 0;
1823
1824	if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
1825		return -ENOMEM;
1826
1827	cmd |= SM(cmd_id, WMI_CMD_HDR_CMD_ID);
1828
1829	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
1830	cmd_hdr->cmd_id = __cpu_to_le32(cmd);
1831
1832	memset(skb_cb, 0, sizeof(*skb_cb));
1833	trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len);
1834	ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb);
1835
1836	if (ret)
1837		goto err_pull;
1838
1839	return 0;
1840
1841err_pull:
1842	skb_pull(skb, sizeof(struct wmi_cmd_hdr));
1843	return ret;
1844}
1845
1846static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
1847{
1848	struct ath10k *ar = arvif->ar;
1849	struct ath10k_skb_cb *cb;
1850	struct sk_buff *bcn;
1851	bool dtim_zero;
1852	bool deliver_cab;
1853	int ret;
1854
1855	spin_lock_bh(&ar->data_lock);
1856
1857	bcn = arvif->beacon;
1858
1859	if (!bcn)
1860		goto unlock;
1861
1862	cb = ATH10K_SKB_CB(bcn);
1863
1864	switch (arvif->beacon_state) {
1865	case ATH10K_BEACON_SENDING:
1866	case ATH10K_BEACON_SENT:
1867		break;
1868	case ATH10K_BEACON_SCHEDULED:
1869		arvif->beacon_state = ATH10K_BEACON_SENDING;
1870		spin_unlock_bh(&ar->data_lock);
1871
1872		dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
1873		deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
1874		ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
1875							arvif->vdev_id,
1876							bcn->data, bcn->len,
1877							cb->paddr,
1878							dtim_zero,
1879							deliver_cab);
1880
1881		spin_lock_bh(&ar->data_lock);
1882
1883		if (ret == 0)
1884			arvif->beacon_state = ATH10K_BEACON_SENT;
1885		else
1886			arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
1887	}
1888
1889unlock:
1890	spin_unlock_bh(&ar->data_lock);
1891}
1892
1893static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
1894				       struct ieee80211_vif *vif)
1895{
1896	struct ath10k_vif *arvif = (void *)vif->drv_priv;
1897
1898	ath10k_wmi_tx_beacon_nowait(arvif);
1899}
1900
1901static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar)
1902{
1903	ieee80211_iterate_active_interfaces_atomic(ar->hw,
1904						   ATH10K_ITER_NORMAL_FLAGS,
1905						   ath10k_wmi_tx_beacons_iter,
1906						   NULL);
1907}
1908
1909static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar)
1910{
1911	/* try to send pending beacons first. they take priority */
1912	ath10k_wmi_tx_beacons_nowait(ar);
1913
1914	wake_up(&ar->wmi.tx_credits_wq);
1915}
1916
1917int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
1918{
1919	int ret = -EOPNOTSUPP;
1920
1921	might_sleep();
1922
1923	if (cmd_id == WMI_CMD_UNSUPPORTED) {
1924		ath10k_warn(ar, "wmi command %d is not supported by firmware\n",
1925			    cmd_id);
1926		return ret;
1927	}
1928
1929	wait_event_timeout(ar->wmi.tx_credits_wq, ({
1930		/* try to send pending beacons first. they take priority */
1931		ath10k_wmi_tx_beacons_nowait(ar);
1932
1933		ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id);
1934
1935		if (ret && test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
1936			ret = -ESHUTDOWN;
1937
1938		(ret != -EAGAIN);
1939	}), 3 * HZ);
1940
1941	if (ret)
1942		dev_kfree_skb_any(skb);
1943
1944	if (ret == -EAGAIN) {
1945		ath10k_warn(ar, "wmi command %d timeout, restarting hardware\n",
1946			    cmd_id);
1947		ath10k_core_start_recovery(ar);
1948	}
1949
1950	return ret;
1951}
1952
1953static struct sk_buff *
1954ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
1955{
1956	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
1957	struct ath10k_vif *arvif;
1958	struct wmi_mgmt_tx_cmd *cmd;
1959	struct ieee80211_hdr *hdr;
1960	struct sk_buff *skb;
1961	int len;
1962	u32 vdev_id;
1963	u32 buf_len = msdu->len;
1964	u16 fc;
1965	const u8 *peer_addr;
1966
1967	hdr = (struct ieee80211_hdr *)msdu->data;
1968	fc = le16_to_cpu(hdr->frame_control);
1969
1970	if (cb->vif) {
1971		arvif = (void *)cb->vif->drv_priv;
1972		vdev_id = arvif->vdev_id;
1973	} else {
1974		vdev_id = 0;
1975	}
1976
1977	if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
1978		return ERR_PTR(-EINVAL);
1979
1980	len = sizeof(cmd->hdr) + msdu->len;
1981
1982	if ((ieee80211_is_action(hdr->frame_control) ||
1983	     ieee80211_is_deauth(hdr->frame_control) ||
1984	     ieee80211_is_disassoc(hdr->frame_control)) &&
1985	     ieee80211_has_protected(hdr->frame_control)) {
1986		peer_addr = hdr->addr1;
1987		if (is_multicast_ether_addr(peer_addr)) {
1988			len += sizeof(struct ieee80211_mmie_16);
1989			buf_len += sizeof(struct ieee80211_mmie_16);
1990		} else {
1991			if (cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP ||
1992			    cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256) {
1993				len += IEEE80211_GCMP_MIC_LEN;
1994				buf_len += IEEE80211_GCMP_MIC_LEN;
1995			} else {
1996				len += IEEE80211_CCMP_MIC_LEN;
1997				buf_len += IEEE80211_CCMP_MIC_LEN;
1998			}
1999		}
2000	}
2001
2002	len = round_up(len, 4);
2003
2004	skb = ath10k_wmi_alloc_skb(ar, len);
2005	if (!skb)
2006		return ERR_PTR(-ENOMEM);
2007
2008	cmd = (struct wmi_mgmt_tx_cmd *)skb->data;
2009
2010	cmd->hdr.vdev_id = __cpu_to_le32(vdev_id);
2011	cmd->hdr.tx_rate = 0;
2012	cmd->hdr.tx_power = 0;
2013	cmd->hdr.buf_len = __cpu_to_le32(buf_len);
2014
2015	ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
2016	memcpy(cmd->buf, msdu->data, msdu->len);
2017
2018	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %pK len %d ftype %02x stype %02x\n",
2019		   msdu, skb->len, fc & IEEE80211_FCTL_FTYPE,
2020		   fc & IEEE80211_FCTL_STYPE);
2021	trace_ath10k_tx_hdr(ar, skb->data, skb->len);
2022	trace_ath10k_tx_payload(ar, skb->data, skb->len);
2023
2024	return skb;
2025}
2026
2027static void ath10k_wmi_event_scan_started(struct ath10k *ar)
2028{
2029	lockdep_assert_held(&ar->data_lock);
2030
2031	switch (ar->scan.state) {
2032	case ATH10K_SCAN_IDLE:
2033	case ATH10K_SCAN_RUNNING:
2034	case ATH10K_SCAN_ABORTING:
2035		ath10k_warn(ar, "received scan started event in an invalid scan state: %s (%d)\n",
2036			    ath10k_scan_state_str(ar->scan.state),
2037			    ar->scan.state);
2038		break;
2039	case ATH10K_SCAN_STARTING:
2040		ar->scan.state = ATH10K_SCAN_RUNNING;
2041
2042		if (ar->scan.is_roc)
2043			ieee80211_ready_on_channel(ar->hw);
2044
2045		complete(&ar->scan.started);
2046		break;
2047	}
2048}
2049
2050static void ath10k_wmi_event_scan_start_failed(struct ath10k *ar)
2051{
2052	lockdep_assert_held(&ar->data_lock);
2053
2054	switch (ar->scan.state) {
2055	case ATH10K_SCAN_IDLE:
2056	case ATH10K_SCAN_RUNNING:
2057	case ATH10K_SCAN_ABORTING:
2058		ath10k_warn(ar, "received scan start failed event in an invalid scan state: %s (%d)\n",
2059			    ath10k_scan_state_str(ar->scan.state),
2060			    ar->scan.state);
2061		break;
2062	case ATH10K_SCAN_STARTING:
2063		complete(&ar->scan.started);
2064		__ath10k_scan_finish(ar);
2065		break;
2066	}
2067}
2068
2069static void ath10k_wmi_event_scan_completed(struct ath10k *ar)
2070{
2071	lockdep_assert_held(&ar->data_lock);
2072
2073	switch (ar->scan.state) {
2074	case ATH10K_SCAN_IDLE:
2075	case ATH10K_SCAN_STARTING:
2076		/* One suspected reason scan can be completed while starting is
2077		 * if firmware fails to deliver all scan events to the host,
2078		 * e.g. when transport pipe is full. This has been observed
2079		 * with spectral scan phyerr events starving wmi transport
2080		 * pipe. In such case the "scan completed" event should be (and
2081		 * is) ignored by the host as it may be just firmware's scan
2082		 * state machine recovering.
2083		 */
2084		ath10k_warn(ar, "received scan completed event in an invalid scan state: %s (%d)\n",
2085			    ath10k_scan_state_str(ar->scan.state),
2086			    ar->scan.state);
2087		break;
2088	case ATH10K_SCAN_RUNNING:
2089	case ATH10K_SCAN_ABORTING:
2090		__ath10k_scan_finish(ar);
2091		break;
2092	}
2093}
2094
2095static void ath10k_wmi_event_scan_bss_chan(struct ath10k *ar)
2096{
2097	lockdep_assert_held(&ar->data_lock);
2098
2099	switch (ar->scan.state) {
2100	case ATH10K_SCAN_IDLE:
2101	case ATH10K_SCAN_STARTING:
2102		ath10k_warn(ar, "received scan bss chan event in an invalid scan state: %s (%d)\n",
2103			    ath10k_scan_state_str(ar->scan.state),
2104			    ar->scan.state);
2105		break;
2106	case ATH10K_SCAN_RUNNING:
2107	case ATH10K_SCAN_ABORTING:
2108		ar->scan_channel = NULL;
2109		break;
2110	}
2111}
2112
2113static void ath10k_wmi_event_scan_foreign_chan(struct ath10k *ar, u32 freq)
2114{
2115	lockdep_assert_held(&ar->data_lock);
2116
2117	switch (ar->scan.state) {
2118	case ATH10K_SCAN_IDLE:
2119	case ATH10K_SCAN_STARTING:
2120		ath10k_warn(ar, "received scan foreign chan event in an invalid scan state: %s (%d)\n",
2121			    ath10k_scan_state_str(ar->scan.state),
2122			    ar->scan.state);
2123		break;
2124	case ATH10K_SCAN_RUNNING:
2125	case ATH10K_SCAN_ABORTING:
2126		ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq);
2127
2128		if (ar->scan.is_roc && ar->scan.roc_freq == freq)
2129			complete(&ar->scan.on_channel);
2130		break;
2131	}
2132}
2133
2134static const char *
2135ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type,
2136			       enum wmi_scan_completion_reason reason)
2137{
2138	switch (type) {
2139	case WMI_SCAN_EVENT_STARTED:
2140		return "started";
2141	case WMI_SCAN_EVENT_COMPLETED:
2142		switch (reason) {
2143		case WMI_SCAN_REASON_COMPLETED:
2144			return "completed";
2145		case WMI_SCAN_REASON_CANCELLED:
2146			return "completed [cancelled]";
2147		case WMI_SCAN_REASON_PREEMPTED:
2148			return "completed [preempted]";
2149		case WMI_SCAN_REASON_TIMEDOUT:
2150			return "completed [timedout]";
2151		case WMI_SCAN_REASON_INTERNAL_FAILURE:
2152			return "completed [internal err]";
2153		case WMI_SCAN_REASON_MAX:
2154			break;
2155		}
2156		return "completed [unknown]";
2157	case WMI_SCAN_EVENT_BSS_CHANNEL:
2158		return "bss channel";
2159	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
2160		return "foreign channel";
2161	case WMI_SCAN_EVENT_DEQUEUED:
2162		return "dequeued";
2163	case WMI_SCAN_EVENT_PREEMPTED:
2164		return "preempted";
2165	case WMI_SCAN_EVENT_START_FAILED:
2166		return "start failed";
2167	case WMI_SCAN_EVENT_RESTARTED:
2168		return "restarted";
2169	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
2170		return "foreign channel exit";
2171	default:
2172		return "unknown";
2173	}
2174}
2175
2176static int ath10k_wmi_op_pull_scan_ev(struct ath10k *ar, struct sk_buff *skb,
2177				      struct wmi_scan_ev_arg *arg)
2178{
2179	struct wmi_scan_event *ev = (void *)skb->data;
2180
2181	if (skb->len < sizeof(*ev))
2182		return -EPROTO;
2183
2184	skb_pull(skb, sizeof(*ev));
2185	arg->event_type = ev->event_type;
2186	arg->reason = ev->reason;
2187	arg->channel_freq = ev->channel_freq;
2188	arg->scan_req_id = ev->scan_req_id;
2189	arg->scan_id = ev->scan_id;
2190	arg->vdev_id = ev->vdev_id;
2191
2192	return 0;
2193}
2194
2195int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
2196{
2197	struct wmi_scan_ev_arg arg = {};
2198	enum wmi_scan_event_type event_type;
2199	enum wmi_scan_completion_reason reason;
2200	u32 freq;
2201	u32 req_id;
2202	u32 scan_id;
2203	u32 vdev_id;
2204	int ret;
2205
2206	ret = ath10k_wmi_pull_scan(ar, skb, &arg);
2207	if (ret) {
2208		ath10k_warn(ar, "failed to parse scan event: %d\n", ret);
2209		return ret;
2210	}
2211
2212	event_type = __le32_to_cpu(arg.event_type);
2213	reason = __le32_to_cpu(arg.reason);
2214	freq = __le32_to_cpu(arg.channel_freq);
2215	req_id = __le32_to_cpu(arg.scan_req_id);
2216	scan_id = __le32_to_cpu(arg.scan_id);
2217	vdev_id = __le32_to_cpu(arg.vdev_id);
2218
2219	spin_lock_bh(&ar->data_lock);
2220
2221	ath10k_dbg(ar, ATH10K_DBG_WMI,
2222		   "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n",
2223		   ath10k_wmi_event_scan_type_str(event_type, reason),
2224		   event_type, reason, freq, req_id, scan_id, vdev_id,
2225		   ath10k_scan_state_str(ar->scan.state), ar->scan.state);
2226
2227	switch (event_type) {
2228	case WMI_SCAN_EVENT_STARTED:
2229		ath10k_wmi_event_scan_started(ar);
2230		break;
2231	case WMI_SCAN_EVENT_COMPLETED:
2232		ath10k_wmi_event_scan_completed(ar);
2233		break;
2234	case WMI_SCAN_EVENT_BSS_CHANNEL:
2235		ath10k_wmi_event_scan_bss_chan(ar);
2236		break;
2237	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
2238		ath10k_wmi_event_scan_foreign_chan(ar, freq);
2239		break;
2240	case WMI_SCAN_EVENT_START_FAILED:
2241		ath10k_warn(ar, "received scan start failure event\n");
2242		ath10k_wmi_event_scan_start_failed(ar);
2243		break;
2244	case WMI_SCAN_EVENT_DEQUEUED:
2245	case WMI_SCAN_EVENT_PREEMPTED:
2246	case WMI_SCAN_EVENT_RESTARTED:
2247	case WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT:
2248	default:
2249		break;
2250	}
2251
2252	spin_unlock_bh(&ar->data_lock);
2253	return 0;
2254}
2255
2256/* If keys are configured, HW decrypts all frames
2257 * with protected bit set. Mark such frames as decrypted.
2258 */
2259static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar,
2260					 struct sk_buff *skb,
2261					 struct ieee80211_rx_status *status)
2262{
2263	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2264	unsigned int hdrlen;
2265	bool peer_key;
2266	u8 *addr, keyidx;
2267
2268	if (!ieee80211_is_auth(hdr->frame_control) ||
2269	    !ieee80211_has_protected(hdr->frame_control))
2270		return;
2271
2272	hdrlen = ieee80211_hdrlen(hdr->frame_control);
2273	if (skb->len < (hdrlen + IEEE80211_WEP_IV_LEN))
2274		return;
2275
2276	keyidx = skb->data[hdrlen + (IEEE80211_WEP_IV_LEN - 1)] >> WEP_KEYID_SHIFT;
2277	addr = ieee80211_get_SA(hdr);
2278
2279	spin_lock_bh(&ar->data_lock);
2280	peer_key = ath10k_mac_is_peer_wep_key_set(ar, addr, keyidx);
2281	spin_unlock_bh(&ar->data_lock);
2282
2283	if (peer_key) {
2284		ath10k_dbg(ar, ATH10K_DBG_MAC,
2285			   "mac wep key present for peer %pM\n", addr);
2286		status->flag |= RX_FLAG_DECRYPTED;
2287	}
2288}
2289
2290static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb,
2291					 struct wmi_mgmt_rx_ev_arg *arg)
2292{
2293	struct wmi_mgmt_rx_event_v1 *ev_v1;
2294	struct wmi_mgmt_rx_event_v2 *ev_v2;
2295	struct wmi_mgmt_rx_hdr_v1 *ev_hdr;
2296	struct wmi_mgmt_rx_ext_info *ext_info;
2297	size_t pull_len;
2298	u32 msdu_len;
2299	u32 len;
2300
2301	if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX,
2302		     ar->running_fw->fw_file.fw_features)) {
2303		ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data;
2304		ev_hdr = &ev_v2->hdr.v1;
2305		pull_len = sizeof(*ev_v2);
2306	} else {
2307		ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data;
2308		ev_hdr = &ev_v1->hdr;
2309		pull_len = sizeof(*ev_v1);
2310	}
2311
2312	if (skb->len < pull_len)
2313		return -EPROTO;
2314
2315	skb_pull(skb, pull_len);
2316	arg->channel = ev_hdr->channel;
2317	arg->buf_len = ev_hdr->buf_len;
2318	arg->status = ev_hdr->status;
2319	arg->snr = ev_hdr->snr;
2320	arg->phy_mode = ev_hdr->phy_mode;
2321	arg->rate = ev_hdr->rate;
2322
2323	msdu_len = __le32_to_cpu(arg->buf_len);
2324	if (skb->len < msdu_len)
2325		return -EPROTO;
2326
2327	if (le32_to_cpu(arg->status) & WMI_RX_STATUS_EXT_INFO) {
2328		len = ALIGN(le32_to_cpu(arg->buf_len), 4);
2329		ext_info = (struct wmi_mgmt_rx_ext_info *)(skb->data + len);
2330		memcpy(&arg->ext_info, ext_info,
2331		       sizeof(struct wmi_mgmt_rx_ext_info));
2332	}
2333	/* the WMI buffer might've ended up being padded to 4 bytes due to HTC
2334	 * trailer with credit update. Trim the excess garbage.
2335	 */
2336	skb_trim(skb, msdu_len);
2337
2338	return 0;
2339}
2340
2341static int ath10k_wmi_10_4_op_pull_mgmt_rx_ev(struct ath10k *ar,
2342					      struct sk_buff *skb,
2343					      struct wmi_mgmt_rx_ev_arg *arg)
2344{
2345	struct wmi_10_4_mgmt_rx_event *ev;
2346	struct wmi_10_4_mgmt_rx_hdr *ev_hdr;
2347	size_t pull_len;
2348	u32 msdu_len;
2349	struct wmi_mgmt_rx_ext_info *ext_info;
2350	u32 len;
2351
2352	ev = (struct wmi_10_4_mgmt_rx_event *)skb->data;
2353	ev_hdr = &ev->hdr;
2354	pull_len = sizeof(*ev);
2355
2356	if (skb->len < pull_len)
2357		return -EPROTO;
2358
2359	skb_pull(skb, pull_len);
2360	arg->channel = ev_hdr->channel;
2361	arg->buf_len = ev_hdr->buf_len;
2362	arg->status = ev_hdr->status;
2363	arg->snr = ev_hdr->snr;
2364	arg->phy_mode = ev_hdr->phy_mode;
2365	arg->rate = ev_hdr->rate;
2366
2367	msdu_len = __le32_to_cpu(arg->buf_len);
2368	if (skb->len < msdu_len)
2369		return -EPROTO;
2370
2371	if (le32_to_cpu(arg->status) & WMI_RX_STATUS_EXT_INFO) {
2372		len = ALIGN(le32_to_cpu(arg->buf_len), 4);
2373		ext_info = (struct wmi_mgmt_rx_ext_info *)(skb->data + len);
2374		memcpy(&arg->ext_info, ext_info,
2375		       sizeof(struct wmi_mgmt_rx_ext_info));
2376	}
2377
2378	/* Make sure bytes added for padding are removed. */
2379	skb_trim(skb, msdu_len);
2380
2381	return 0;
2382}
2383
2384static bool ath10k_wmi_rx_is_decrypted(struct ath10k *ar,
2385				       struct ieee80211_hdr *hdr)
2386{
2387	if (!ieee80211_has_protected(hdr->frame_control))
2388		return false;
2389
2390	/* FW delivers WEP Shared Auth frame with Protected Bit set and
2391	 * encrypted payload. However in case of PMF it delivers decrypted
2392	 * frames with Protected Bit set.
2393	 */
2394	if (ieee80211_is_auth(hdr->frame_control))
2395		return false;
2396
2397	/* qca99x0 based FW delivers broadcast or multicast management frames
2398	 * (ex: group privacy action frames in mesh) as encrypted payload.
2399	 */
2400	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) &&
2401	    ar->hw_params.sw_decrypt_mcast_mgmt)
2402		return false;
2403
2404	return true;
2405}
2406
2407static int
2408wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param)
2409{
2410	struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
2411	struct ath10k_wmi *wmi = &ar->wmi;
2412	struct ieee80211_tx_info *info;
2413	struct sk_buff *msdu;
2414	int ret;
2415
2416	spin_lock_bh(&ar->data_lock);
2417
2418	pkt_addr = idr_find(&wmi->mgmt_pending_tx, param->desc_id);
2419	if (!pkt_addr) {
2420		ath10k_warn(ar, "received mgmt tx completion for invalid msdu_id: %d\n",
2421			    param->desc_id);
2422		ret = -ENOENT;
2423		goto out;
2424	}
2425
2426	msdu = pkt_addr->vaddr;
2427	dma_unmap_single(ar->dev, pkt_addr->paddr,
2428			 msdu->len, DMA_TO_DEVICE);
2429	info = IEEE80211_SKB_CB(msdu);
2430
2431	if (param->status) {
2432		info->flags &= ~IEEE80211_TX_STAT_ACK;
2433	} else {
2434		info->flags |= IEEE80211_TX_STAT_ACK;
2435		info->status.ack_signal = ATH10K_DEFAULT_NOISE_FLOOR +
2436					  param->ack_rssi;
2437		info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
2438	}
2439
2440	ieee80211_tx_status_irqsafe(ar->hw, msdu);
2441
2442	ret = 0;
2443
2444out:
2445	idr_remove(&wmi->mgmt_pending_tx, param->desc_id);
2446	spin_unlock_bh(&ar->data_lock);
2447	return ret;
2448}
2449
2450int ath10k_wmi_event_mgmt_tx_compl(struct ath10k *ar, struct sk_buff *skb)
2451{
2452	struct wmi_tlv_mgmt_tx_compl_ev_arg arg;
2453	struct mgmt_tx_compl_params param;
2454	int ret;
2455
2456	ret = ath10k_wmi_pull_mgmt_tx_compl(ar, skb, &arg);
2457	if (ret) {
2458		ath10k_warn(ar, "failed to parse mgmt comp event: %d\n", ret);
2459		return ret;
2460	}
2461
2462	memset(&param, 0, sizeof(struct mgmt_tx_compl_params));
2463	param.desc_id = __le32_to_cpu(arg.desc_id);
2464	param.status = __le32_to_cpu(arg.status);
2465
2466	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
2467		param.ack_rssi = __le32_to_cpu(arg.ack_rssi);
2468
2469	wmi_process_mgmt_tx_comp(ar, &param);
2470
2471	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv evnt mgmt tx completion\n");
2472
2473	return 0;
2474}
2475
2476int ath10k_wmi_event_mgmt_tx_bundle_compl(struct ath10k *ar, struct sk_buff *skb)
2477{
2478	struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg arg;
2479	struct mgmt_tx_compl_params param;
2480	u32 num_reports;
2481	int i, ret;
2482
2483	ret = ath10k_wmi_pull_mgmt_tx_bundle_compl(ar, skb, &arg);
2484	if (ret) {
2485		ath10k_warn(ar, "failed to parse bundle mgmt compl event: %d\n", ret);
2486		return ret;
2487	}
2488
2489	num_reports = __le32_to_cpu(arg.num_reports);
2490
2491	for (i = 0; i < num_reports; i++) {
2492		memset(&param, 0, sizeof(struct mgmt_tx_compl_params));
2493		param.desc_id = __le32_to_cpu(arg.desc_ids[i]);
2494		param.status = __le32_to_cpu(arg.desc_ids[i]);
2495
2496		if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
2497			param.ack_rssi = __le32_to_cpu(arg.ack_rssi[i]);
2498		wmi_process_mgmt_tx_comp(ar, &param);
2499	}
2500
2501	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv event bundle mgmt tx completion\n");
2502
2503	return 0;
2504}
2505
2506int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
2507{
2508	struct wmi_mgmt_rx_ev_arg arg = {};
2509	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2510	struct ieee80211_hdr *hdr;
2511	struct ieee80211_supported_band *sband;
2512	u32 rx_status;
2513	u32 channel;
2514	u32 phy_mode;
2515	u32 snr, rssi;
2516	u32 rate;
2517	u16 fc;
2518	int ret, i;
2519
2520	ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
2521	if (ret) {
2522		ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
2523		dev_kfree_skb(skb);
2524		return ret;
2525	}
2526
2527	channel = __le32_to_cpu(arg.channel);
2528	rx_status = __le32_to_cpu(arg.status);
2529	snr = __le32_to_cpu(arg.snr);
2530	phy_mode = __le32_to_cpu(arg.phy_mode);
2531	rate = __le32_to_cpu(arg.rate);
2532
2533	memset(status, 0, sizeof(*status));
2534
2535	ath10k_dbg(ar, ATH10K_DBG_MGMT,
2536		   "event mgmt rx status %08x\n", rx_status);
2537
2538	if ((test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) ||
2539	    (rx_status & (WMI_RX_STATUS_ERR_DECRYPT |
2540	    WMI_RX_STATUS_ERR_KEY_CACHE_MISS | WMI_RX_STATUS_ERR_CRC))) {
2541		dev_kfree_skb(skb);
2542		return 0;
2543	}
2544
2545	if (rx_status & WMI_RX_STATUS_ERR_MIC)
2546		status->flag |= RX_FLAG_MMIC_ERROR;
2547
2548	if (rx_status & WMI_RX_STATUS_EXT_INFO) {
2549		status->mactime =
2550			__le64_to_cpu(arg.ext_info.rx_mac_timestamp);
2551		status->flag |= RX_FLAG_MACTIME_END;
2552	}
2553	/* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is set to
2554	 * MODE_11B. This means phy_mode is not a reliable source for the band
2555	 * of mgmt rx.
2556	 */
2557	if (channel >= 1 && channel <= 14) {
2558		status->band = NL80211_BAND_2GHZ;
2559	} else if (channel >= 36 && channel <= ATH10K_MAX_5G_CHAN) {
2560		status->band = NL80211_BAND_5GHZ;
2561	} else {
2562		/* Shouldn't happen unless list of advertised channels to
2563		 * mac80211 has been changed.
2564		 */
2565		WARN_ON_ONCE(1);
2566		dev_kfree_skb(skb);
2567		return 0;
2568	}
2569
2570	if (phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
2571		ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");
2572
2573	sband = &ar->mac.sbands[status->band];
2574
2575	status->freq = ieee80211_channel_to_frequency(channel, status->band);
2576	status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
2577
2578	BUILD_BUG_ON(ARRAY_SIZE(status->chain_signal) != ARRAY_SIZE(arg.rssi));
2579
2580	for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
2581		status->chains &= ~BIT(i);
2582		rssi = __le32_to_cpu(arg.rssi[i]);
2583		ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt rssi[%d]:%d\n", i, arg.rssi[i]);
2584
2585		if (rssi != ATH10K_INVALID_RSSI && rssi != 0) {
2586			status->chain_signal[i] = ATH10K_DEFAULT_NOISE_FLOOR + rssi;
2587			status->chains |= BIT(i);
2588		}
2589	}
2590
2591	status->rate_idx = ath10k_mac_bitrate_to_idx(sband, rate / 100);
2592
2593	hdr = (struct ieee80211_hdr *)skb->data;
2594	fc = le16_to_cpu(hdr->frame_control);
2595
2596	/* Firmware is guaranteed to report all essential management frames via
2597	 * WMI while it can deliver some extra via HTT. Since there can be
2598	 * duplicates split the reporting wrt monitor/sniffing.
2599	 */
2600	status->flag |= RX_FLAG_SKIP_MONITOR;
2601
2602	ath10k_wmi_handle_wep_reauth(ar, skb, status);
2603
2604	if (ath10k_wmi_rx_is_decrypted(ar, hdr)) {
2605		status->flag |= RX_FLAG_DECRYPTED;
2606
2607		if (!ieee80211_is_action(hdr->frame_control) &&
2608		    !ieee80211_is_deauth(hdr->frame_control) &&
2609		    !ieee80211_is_disassoc(hdr->frame_control)) {
2610			status->flag |= RX_FLAG_IV_STRIPPED |
2611					RX_FLAG_MMIC_STRIPPED;
2612			hdr->frame_control = __cpu_to_le16(fc &
2613					~IEEE80211_FCTL_PROTECTED);
2614		}
2615	}
2616
2617	if (ieee80211_is_beacon(hdr->frame_control))
2618		ath10k_mac_handle_beacon(ar, skb);
2619
2620	if (ieee80211_is_beacon(hdr->frame_control) ||
2621	    ieee80211_is_probe_resp(hdr->frame_control))
2622		status->boottime_ns = ktime_get_boottime_ns();
2623
2624	ath10k_dbg(ar, ATH10K_DBG_MGMT,
2625		   "event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
2626		   skb, skb->len,
2627		   fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE);
2628
2629	ath10k_dbg(ar, ATH10K_DBG_MGMT,
2630		   "event mgmt rx freq %d band %d snr %d, rate_idx %d\n",
2631		   status->freq, status->band, status->signal,
2632		   status->rate_idx);
2633
2634	ieee80211_rx_ni(ar->hw, skb);
2635
2636	return 0;
2637}
2638
2639static int freq_to_idx(struct ath10k *ar, int freq)
2640{
2641	struct ieee80211_supported_band *sband;
2642	int band, ch, idx = 0;
2643
2644	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
2645		sband = ar->hw->wiphy->bands[band];
2646		if (!sband)
2647			continue;
2648
2649		for (ch = 0; ch < sband->n_channels; ch++, idx++)
2650			if (sband->channels[ch].center_freq == freq)
2651				goto exit;
2652	}
2653
2654exit:
2655	return idx;
2656}
2657
2658static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb,
2659					 struct wmi_ch_info_ev_arg *arg)
2660{
2661	struct wmi_chan_info_event *ev = (void *)skb->data;
2662
2663	if (skb->len < sizeof(*ev))
2664		return -EPROTO;
2665
2666	skb_pull(skb, sizeof(*ev));
2667	arg->err_code = ev->err_code;
2668	arg->freq = ev->freq;
2669	arg->cmd_flags = ev->cmd_flags;
2670	arg->noise_floor = ev->noise_floor;
2671	arg->rx_clear_count = ev->rx_clear_count;
2672	arg->cycle_count = ev->cycle_count;
2673
2674	return 0;
2675}
2676
2677static int ath10k_wmi_10_4_op_pull_ch_info_ev(struct ath10k *ar,
2678					      struct sk_buff *skb,
2679					      struct wmi_ch_info_ev_arg *arg)
2680{
2681	struct wmi_10_4_chan_info_event *ev = (void *)skb->data;
2682
2683	if (skb->len < sizeof(*ev))
2684		return -EPROTO;
2685
2686	skb_pull(skb, sizeof(*ev));
2687	arg->err_code = ev->err_code;
2688	arg->freq = ev->freq;
2689	arg->cmd_flags = ev->cmd_flags;
2690	arg->noise_floor = ev->noise_floor;
2691	arg->rx_clear_count = ev->rx_clear_count;
2692	arg->cycle_count = ev->cycle_count;
2693	arg->chan_tx_pwr_range = ev->chan_tx_pwr_range;
2694	arg->chan_tx_pwr_tp = ev->chan_tx_pwr_tp;
2695	arg->rx_frame_count = ev->rx_frame_count;
2696
2697	return 0;
2698}
2699
2700/*
2701 * Handle the channel info event for firmware which only sends one
2702 * chan_info event per scanned channel.
2703 */
2704static void ath10k_wmi_event_chan_info_unpaired(struct ath10k *ar,
2705						struct chan_info_params *params)
2706{
2707	struct survey_info *survey;
2708	int idx;
2709
2710	if (params->cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
2711		ath10k_dbg(ar, ATH10K_DBG_WMI, "chan info report completed\n");
2712		return;
2713	}
2714
2715	idx = freq_to_idx(ar, params->freq);
2716	if (idx >= ARRAY_SIZE(ar->survey)) {
2717		ath10k_warn(ar, "chan info: invalid frequency %d (idx %d out of bounds)\n",
2718			    params->freq, idx);
2719		return;
2720	}
2721
2722	survey = &ar->survey[idx];
2723
2724	if (!params->mac_clk_mhz)
2725		return;
2726
2727	memset(survey, 0, sizeof(*survey));
2728
2729	survey->noise = params->noise_floor;
2730	survey->time = (params->cycle_count / params->mac_clk_mhz) / 1000;
2731	survey->time_busy = (params->rx_clear_count / params->mac_clk_mhz) / 1000;
2732	survey->filled |= SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME |
2733			  SURVEY_INFO_TIME_BUSY;
2734}
2735
2736/*
2737 * Handle the channel info event for firmware which sends chan_info
2738 * event in pairs(start and stop events) for every scanned channel.
2739 */
2740static void ath10k_wmi_event_chan_info_paired(struct ath10k *ar,
2741					      struct chan_info_params *params)
2742{
2743	struct survey_info *survey;
2744	int idx;
2745
2746	idx = freq_to_idx(ar, params->freq);
2747	if (idx >= ARRAY_SIZE(ar->survey)) {
2748		ath10k_warn(ar, "chan info: invalid frequency %d (idx %d out of bounds)\n",
2749			    params->freq, idx);
2750		return;
2751	}
2752
2753	if (params->cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
2754		if (ar->ch_info_can_report_survey) {
2755			survey = &ar->survey[idx];
2756			survey->noise = params->noise_floor;
2757			survey->filled = SURVEY_INFO_NOISE_DBM;
2758
2759			ath10k_hw_fill_survey_time(ar,
2760						   survey,
2761						   params->cycle_count,
2762						   params->rx_clear_count,
2763						   ar->survey_last_cycle_count,
2764						   ar->survey_last_rx_clear_count);
2765		}
2766
2767		ar->ch_info_can_report_survey = false;
2768	} else {
2769		ar->ch_info_can_report_survey = true;
2770	}
2771
2772	if (!(params->cmd_flags & WMI_CHAN_INFO_FLAG_PRE_COMPLETE)) {
2773		ar->survey_last_rx_clear_count = params->rx_clear_count;
2774		ar->survey_last_cycle_count = params->cycle_count;
2775	}
2776}
2777
2778void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
2779{
2780	struct chan_info_params ch_info_param;
2781	struct wmi_ch_info_ev_arg arg = {};
2782	int ret;
2783
2784	ret = ath10k_wmi_pull_ch_info(ar, skb, &arg);
2785	if (ret) {
2786		ath10k_warn(ar, "failed to parse chan info event: %d\n", ret);
2787		return;
2788	}
2789
2790	ch_info_param.err_code = __le32_to_cpu(arg.err_code);
2791	ch_info_param.freq = __le32_to_cpu(arg.freq);
2792	ch_info_param.cmd_flags = __le32_to_cpu(arg.cmd_flags);
2793	ch_info_param.noise_floor = __le32_to_cpu(arg.noise_floor);
2794	ch_info_param.rx_clear_count = __le32_to_cpu(arg.rx_clear_count);
2795	ch_info_param.cycle_count = __le32_to_cpu(arg.cycle_count);
2796	ch_info_param.mac_clk_mhz = __le32_to_cpu(arg.mac_clk_mhz);
2797
2798	ath10k_dbg(ar, ATH10K_DBG_WMI,
2799		   "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n",
2800		   ch_info_param.err_code, ch_info_param.freq, ch_info_param.cmd_flags,
2801		   ch_info_param.noise_floor, ch_info_param.rx_clear_count,
2802		   ch_info_param.cycle_count);
2803
2804	spin_lock_bh(&ar->data_lock);
2805
2806	switch (ar->scan.state) {
2807	case ATH10K_SCAN_IDLE:
2808	case ATH10K_SCAN_STARTING:
2809		ath10k_dbg(ar, ATH10K_DBG_WMI, "received chan info event without a scan request, ignoring\n");
2810		goto exit;
2811	case ATH10K_SCAN_RUNNING:
2812	case ATH10K_SCAN_ABORTING:
2813		break;
2814	}
2815
2816	if (test_bit(ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL,
2817		     ar->running_fw->fw_file.fw_features))
2818		ath10k_wmi_event_chan_info_unpaired(ar, &ch_info_param);
2819	else
2820		ath10k_wmi_event_chan_info_paired(ar, &ch_info_param);
2821
2822exit:
2823	spin_unlock_bh(&ar->data_lock);
2824}
2825
2826void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
2827{
2828	struct wmi_echo_ev_arg arg = {};
2829	int ret;
2830
2831	ret = ath10k_wmi_pull_echo_ev(ar, skb, &arg);
2832	if (ret) {
2833		ath10k_warn(ar, "failed to parse echo: %d\n", ret);
2834		return;
2835	}
2836
2837	ath10k_dbg(ar, ATH10K_DBG_WMI,
2838		   "wmi event echo value 0x%08x\n",
2839		   le32_to_cpu(arg.value));
2840
2841	if (le32_to_cpu(arg.value) == ATH10K_WMI_BARRIER_ECHO_ID)
2842		complete(&ar->wmi.barrier);
2843}
2844
2845int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
2846{
2847	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
2848		   skb->len);
2849
2850	trace_ath10k_wmi_dbglog(ar, skb->data, skb->len);
2851#if defined(CONFIG_FWLOG)
2852	ath10k_handle_fwlog_msg(ar, skb);
2853#endif
2854
2855	return 0;
2856}
2857
2858void ath10k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src,
2859				     struct ath10k_fw_stats_pdev *dst)
2860{
2861	dst->ch_noise_floor = __le32_to_cpu(src->chan_nf);
2862	dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count);
2863	dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count);
2864	dst->rx_clear_count = __le32_to_cpu(src->rx_clear_count);
2865	dst->cycle_count = __le32_to_cpu(src->cycle_count);
2866	dst->phy_err_count = __le32_to_cpu(src->phy_err_count);
2867	dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr);
2868}
2869
2870void ath10k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
2871				   struct ath10k_fw_stats_pdev *dst)
2872{
2873	dst->comp_queued = __le32_to_cpu(src->comp_queued);
2874	dst->comp_delivered = __le32_to_cpu(src->comp_delivered);
2875	dst->msdu_enqued = __le32_to_cpu(src->msdu_enqued);
2876	dst->mpdu_enqued = __le32_to_cpu(src->mpdu_enqued);
2877	dst->wmm_drop = __le32_to_cpu(src->wmm_drop);
2878	dst->local_enqued = __le32_to_cpu(src->local_enqued);
2879	dst->local_freed = __le32_to_cpu(src->local_freed);
2880	dst->hw_queued = __le32_to_cpu(src->hw_queued);
2881	dst->hw_reaped = __le32_to_cpu(src->hw_reaped);
2882	dst->underrun = __le32_to_cpu(src->underrun);
2883	dst->tx_abort = __le32_to_cpu(src->tx_abort);
2884	dst->mpdus_requeued = __le32_to_cpu(src->mpdus_requeued);
2885	dst->tx_ko = __le32_to_cpu(src->tx_ko);
2886	dst->data_rc = __le32_to_cpu(src->data_rc);
2887	dst->self_triggers = __le32_to_cpu(src->self_triggers);
2888	dst->sw_retry_failure = __le32_to_cpu(src->sw_retry_failure);
2889	dst->illgl_rate_phy_err = __le32_to_cpu(src->illgl_rate_phy_err);
2890	dst->pdev_cont_xretry = __le32_to_cpu(src->pdev_cont_xretry);
2891	dst->pdev_tx_timeout = __le32_to_cpu(src->pdev_tx_timeout);
2892	dst->pdev_resets = __le32_to_cpu(src->pdev_resets);
2893	dst->phy_underrun = __le32_to_cpu(src->phy_underrun);
2894	dst->txop_ovf = __le32_to_cpu(src->txop_ovf);
2895}
2896
2897static void
2898ath10k_wmi_10_4_pull_pdev_stats_tx(const struct wmi_10_4_pdev_stats_tx *src,
2899				   struct ath10k_fw_stats_pdev *dst)
2900{
2901	dst->comp_queued = __le32_to_cpu(src->comp_queued);
2902	dst->comp_delivered = __le32_to_cpu(src->comp_delivered);
2903	dst->msdu_enqued = __le32_to_cpu(src->msdu_enqued);
2904	dst->mpdu_enqued = __le32_to_cpu(src->mpdu_enqued);
2905	dst->wmm_drop = __le32_to_cpu(src->wmm_drop);
2906	dst->local_enqued = __le32_to_cpu(src->local_enqued);
2907	dst->local_freed = __le32_to_cpu(src->local_freed);
2908	dst->hw_queued = __le32_to_cpu(src->hw_queued);
2909	dst->hw_reaped = __le32_to_cpu(src->hw_reaped);
2910	dst->underrun = __le32_to_cpu(src->underrun);
2911	dst->tx_abort = __le32_to_cpu(src->tx_abort);
2912	dst->mpdus_requeued = __le32_to_cpu(src->mpdus_requeued);
2913	dst->tx_ko = __le32_to_cpu(src->tx_ko);
2914	dst->data_rc = __le32_to_cpu(src->data_rc);
2915	dst->self_triggers = __le32_to_cpu(src->self_triggers);
2916	dst->sw_retry_failure = __le32_to_cpu(src->sw_retry_failure);
2917	dst->illgl_rate_phy_err = __le32_to_cpu(src->illgl_rate_phy_err);
2918	dst->pdev_cont_xretry = __le32_to_cpu(src->pdev_cont_xretry);
2919	dst->pdev_tx_timeout = __le32_to_cpu(src->pdev_tx_timeout);
2920	dst->pdev_resets = __le32_to_cpu(src->pdev_resets);
2921	dst->phy_underrun = __le32_to_cpu(src->phy_underrun);
2922	dst->txop_ovf = __le32_to_cpu(src->txop_ovf);
2923	dst->hw_paused = __le32_to_cpu(src->hw_paused);
2924	dst->seq_posted = __le32_to_cpu(src->seq_posted);
2925	dst->seq_failed_queueing =
2926		__le32_to_cpu(src->seq_failed_queueing);
2927	dst->seq_completed = __le32_to_cpu(src->seq_completed);
2928	dst->seq_restarted = __le32_to_cpu(src->seq_restarted);
2929	dst->mu_seq_posted = __le32_to_cpu(src->mu_seq_posted);
2930	dst->mpdus_sw_flush = __le32_to_cpu(src->mpdus_sw_flush);
2931	dst->mpdus_hw_filter = __le32_to_cpu(src->mpdus_hw_filter);
2932	dst->mpdus_truncated = __le32_to_cpu(src->mpdus_truncated);
2933	dst->mpdus_ack_failed = __le32_to_cpu(src->mpdus_ack_failed);
2934	dst->mpdus_hw_filter = __le32_to_cpu(src->mpdus_hw_filter);
2935	dst->mpdus_expired = __le32_to_cpu(src->mpdus_expired);
2936}
2937
2938void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
2939				   struct ath10k_fw_stats_pdev *dst)
2940{
2941	dst->mid_ppdu_route_change = __le32_to_cpu(src->mid_ppdu_route_change);
2942	dst->status_rcvd = __le32_to_cpu(src->status_rcvd);
2943	dst->r0_frags = __le32_to_cpu(src->r0_frags);
2944	dst->r1_frags = __le32_to_cpu(src->r1_frags);
2945	dst->r2_frags = __le32_to_cpu(src->r2_frags);
2946	dst->r3_frags = __le32_to_cpu(src->r3_frags);
2947	dst->htt_msdus = __le32_to_cpu(src->htt_msdus);
2948	dst->htt_mpdus = __le32_to_cpu(src->htt_mpdus);
2949	dst->loc_msdus = __le32_to_cpu(src->loc_msdus);
2950	dst->loc_mpdus = __le32_to_cpu(src->loc_mpdus);
2951	dst->oversize_amsdu = __le32_to_cpu(src->oversize_amsdu);
2952	dst->phy_errs = __le32_to_cpu(src->phy_errs);
2953	dst->phy_err_drop = __le32_to_cpu(src->phy_err_drop);
2954	dst->mpdu_errs = __le32_to_cpu(src->mpdu_errs);
2955}
2956
2957void ath10k_wmi_pull_pdev_stats_extra(const struct wmi_pdev_stats_extra *src,
2958				      struct ath10k_fw_stats_pdev *dst)
2959{
2960	dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad);
2961	dst->rts_bad = __le32_to_cpu(src->rts_bad);
2962	dst->rts_good = __le32_to_cpu(src->rts_good);
2963	dst->fcs_bad = __le32_to_cpu(src->fcs_bad);
2964	dst->no_beacons = __le32_to_cpu(src->no_beacons);
2965	dst->mib_int_count = __le32_to_cpu(src->mib_int_count);
2966}
2967
2968void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
2969				struct ath10k_fw_stats_peer *dst)
2970{
2971	ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
2972	dst->peer_rssi = __le32_to_cpu(src->peer_rssi);
2973	dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate);
2974}
2975
2976static void
2977ath10k_wmi_10_4_pull_peer_stats(const struct wmi_10_4_peer_stats *src,
2978				struct ath10k_fw_stats_peer *dst)
2979{
2980	ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
2981	dst->peer_rssi = __le32_to_cpu(src->peer_rssi);
2982	dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate);
2983	dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
2984}
2985
2986static void
2987ath10k_wmi_10_4_pull_vdev_stats(const struct wmi_vdev_stats_extd *src,
2988				struct ath10k_fw_stats_vdev_extd *dst)
2989{
2990	dst->vdev_id = __le32_to_cpu(src->vdev_id);
2991	dst->ppdu_aggr_cnt = __le32_to_cpu(src->ppdu_aggr_cnt);
2992	dst->ppdu_noack = __le32_to_cpu(src->ppdu_noack);
2993	dst->mpdu_queued = __le32_to_cpu(src->mpdu_queued);
2994	dst->ppdu_nonaggr_cnt = __le32_to_cpu(src->ppdu_nonaggr_cnt);
2995	dst->mpdu_sw_requeued = __le32_to_cpu(src->mpdu_sw_requeued);
2996	dst->mpdu_suc_retry = __le32_to_cpu(src->mpdu_suc_retry);
2997	dst->mpdu_suc_multitry = __le32_to_cpu(src->mpdu_suc_multitry);
2998	dst->mpdu_fail_retry = __le32_to_cpu(src->mpdu_fail_retry);
2999	dst->tx_ftm_suc = __le32_to_cpu(src->tx_ftm_suc);
3000	dst->tx_ftm_suc_retry = __le32_to_cpu(src->tx_ftm_suc_retry);
3001	dst->tx_ftm_fail = __le32_to_cpu(src->tx_ftm_fail);
3002	dst->rx_ftmr_cnt = __le32_to_cpu(src->rx_ftmr_cnt);
3003	dst->rx_ftmr_dup_cnt = __le32_to_cpu(src->rx_ftmr_dup_cnt);
3004	dst->rx_iftmr_cnt = __le32_to_cpu(src->rx_iftmr_cnt);
3005	dst->rx_iftmr_dup_cnt = __le32_to_cpu(src->rx_iftmr_dup_cnt);
3006}
3007
3008static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar,
3009					    struct sk_buff *skb,
3010					    struct ath10k_fw_stats *stats)
3011{
3012	const struct wmi_stats_event *ev = (void *)skb->data;
3013	u32 num_pdev_stats, num_peer_stats;
3014	int i;
3015
3016	if (!skb_pull(skb, sizeof(*ev)))
3017		return -EPROTO;
3018
3019	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
3020	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
3021
3022	for (i = 0; i < num_pdev_stats; i++) {
3023		const struct wmi_pdev_stats *src;
3024		struct ath10k_fw_stats_pdev *dst;
3025
3026		src = (void *)skb->data;
3027		if (!skb_pull(skb, sizeof(*src)))
3028			return -EPROTO;
3029
3030		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3031		if (!dst)
3032			continue;
3033
3034		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
3035		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
3036		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
3037
3038		list_add_tail(&dst->list, &stats->pdevs);
3039	}
3040
3041	/* fw doesn't implement vdev stats */
3042
3043	for (i = 0; i < num_peer_stats; i++) {
3044		const struct wmi_peer_stats *src;
3045		struct ath10k_fw_stats_peer *dst;
3046
3047		src = (void *)skb->data;
3048		if (!skb_pull(skb, sizeof(*src)))
3049			return -EPROTO;
3050
3051		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3052		if (!dst)
3053			continue;
3054
3055		ath10k_wmi_pull_peer_stats(src, dst);
3056		list_add_tail(&dst->list, &stats->peers);
3057	}
3058
3059	return 0;
3060}
3061
3062static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
3063					   struct sk_buff *skb,
3064					   struct ath10k_fw_stats *stats)
3065{
3066	const struct wmi_stats_event *ev = (void *)skb->data;
3067	u32 num_pdev_stats, num_peer_stats;
3068	int i;
3069
3070	if (!skb_pull(skb, sizeof(*ev)))
3071		return -EPROTO;
3072
3073	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
3074	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
3075
3076	for (i = 0; i < num_pdev_stats; i++) {
3077		const struct wmi_10x_pdev_stats *src;
3078		struct ath10k_fw_stats_pdev *dst;
3079
3080		src = (void *)skb->data;
3081		if (!skb_pull(skb, sizeof(*src)))
3082			return -EPROTO;
3083
3084		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3085		if (!dst)
3086			continue;
3087
3088		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
3089		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
3090		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
3091		ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
3092
3093		list_add_tail(&dst->list, &stats->pdevs);
3094	}
3095
3096	/* fw doesn't implement vdev stats */
3097
3098	for (i = 0; i < num_peer_stats; i++) {
3099		const struct wmi_10x_peer_stats *src;
3100		struct ath10k_fw_stats_peer *dst;
3101
3102		src = (void *)skb->data;
3103		if (!skb_pull(skb, sizeof(*src)))
3104			return -EPROTO;
3105
3106		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3107		if (!dst)
3108			continue;
3109
3110		ath10k_wmi_pull_peer_stats(&src->old, dst);
3111
3112		dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
3113
3114		list_add_tail(&dst->list, &stats->peers);
3115	}
3116
3117	return 0;
3118}
3119
3120static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar,
3121					    struct sk_buff *skb,
3122					    struct ath10k_fw_stats *stats)
3123{
3124	const struct wmi_10_2_stats_event *ev = (void *)skb->data;
3125	u32 num_pdev_stats;
3126	u32 num_pdev_ext_stats;
3127	u32 num_peer_stats;
3128	int i;
3129
3130	if (!skb_pull(skb, sizeof(*ev)))
3131		return -EPROTO;
3132
3133	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
3134	num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
3135	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
3136
3137	for (i = 0; i < num_pdev_stats; i++) {
3138		const struct wmi_10_2_pdev_stats *src;
3139		struct ath10k_fw_stats_pdev *dst;
3140
3141		src = (void *)skb->data;
3142		if (!skb_pull(skb, sizeof(*src)))
3143			return -EPROTO;
3144
3145		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3146		if (!dst)
3147			continue;
3148
3149		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
3150		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
3151		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
3152		ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
3153		/* FIXME: expose 10.2 specific values */
3154
3155		list_add_tail(&dst->list, &stats->pdevs);
3156	}
3157
3158	for (i = 0; i < num_pdev_ext_stats; i++) {
3159		const struct wmi_10_2_pdev_ext_stats *src;
3160
3161		src = (void *)skb->data;
3162		if (!skb_pull(skb, sizeof(*src)))
3163			return -EPROTO;
3164
3165		/* FIXME: expose values to userspace
3166		 *
3167		 * Note: Even though this loop seems to do nothing it is
3168		 * required to parse following sub-structures properly.
3169		 */
3170	}
3171
3172	/* fw doesn't implement vdev stats */
3173
3174	for (i = 0; i < num_peer_stats; i++) {
3175		const struct wmi_10_2_peer_stats *src;
3176		struct ath10k_fw_stats_peer *dst;
3177
3178		src = (void *)skb->data;
3179		if (!skb_pull(skb, sizeof(*src)))
3180			return -EPROTO;
3181
3182		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3183		if (!dst)
3184			continue;
3185
3186		ath10k_wmi_pull_peer_stats(&src->old, dst);
3187
3188		dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
3189		/* FIXME: expose 10.2 specific values */
3190
3191		list_add_tail(&dst->list, &stats->peers);
3192	}
3193
3194	return 0;
3195}
3196
3197static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
3198					      struct sk_buff *skb,
3199					      struct ath10k_fw_stats *stats)
3200{
3201	const struct wmi_10_2_stats_event *ev = (void *)skb->data;
3202	u32 num_pdev_stats;
3203	u32 num_pdev_ext_stats;
3204	u32 num_peer_stats;
3205	int i;
3206
3207	if (!skb_pull(skb, sizeof(*ev)))
3208		return -EPROTO;
3209
3210	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
3211	num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
3212	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
3213
3214	for (i = 0; i < num_pdev_stats; i++) {
3215		const struct wmi_10_2_pdev_stats *src;
3216		struct ath10k_fw_stats_pdev *dst;
3217
3218		src = (void *)skb->data;
3219		if (!skb_pull(skb, sizeof(*src)))
3220			return -EPROTO;
3221
3222		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3223		if (!dst)
3224			continue;
3225
3226		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
3227		ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
3228		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
3229		ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
3230		/* FIXME: expose 10.2 specific values */
3231
3232		list_add_tail(&dst->list, &stats->pdevs);
3233	}
3234
3235	for (i = 0; i < num_pdev_ext_stats; i++) {
3236		const struct wmi_10_2_pdev_ext_stats *src;
3237
3238		src = (void *)skb->data;
3239		if (!skb_pull(skb, sizeof(*src)))
3240			return -EPROTO;
3241
3242		/* FIXME: expose values to userspace
3243		 *
3244		 * Note: Even though this loop seems to do nothing it is
3245		 * required to parse following sub-structures properly.
3246		 */
3247	}
3248
3249	/* fw doesn't implement vdev stats */
3250
3251	for (i = 0; i < num_peer_stats; i++) {
3252		const struct wmi_10_2_4_ext_peer_stats *src;
3253		struct ath10k_fw_stats_peer *dst;
3254		int stats_len;
3255
3256		if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
3257			stats_len = sizeof(struct wmi_10_2_4_ext_peer_stats);
3258		else
3259			stats_len = sizeof(struct wmi_10_2_4_peer_stats);
3260
3261		src = (void *)skb->data;
3262		if (!skb_pull(skb, stats_len))
3263			return -EPROTO;
3264
3265		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3266		if (!dst)
3267			continue;
3268
3269		ath10k_wmi_pull_peer_stats(&src->common.old, dst);
3270
3271		dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate);
3272
3273		if (ath10k_peer_stats_enabled(ar))
3274			dst->rx_duration = __le32_to_cpu(src->rx_duration);
3275		/* FIXME: expose 10.2 specific values */
3276
3277		list_add_tail(&dst->list, &stats->peers);
3278	}
3279
3280	return 0;
3281}
3282
3283static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
3284					    struct sk_buff *skb,
3285					    struct ath10k_fw_stats *stats)
3286{
3287	const struct wmi_10_2_stats_event *ev = (void *)skb->data;
3288	u32 num_pdev_stats;
3289	u32 num_pdev_ext_stats;
3290	u32 num_vdev_stats;
3291	u32 num_peer_stats;
3292	u32 num_bcnflt_stats;
3293	u32 stats_id;
3294	int i;
3295
3296	if (!skb_pull(skb, sizeof(*ev)))
3297		return -EPROTO;
3298
3299	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
3300	num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
3301	num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
3302	num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
3303	num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
3304	stats_id = __le32_to_cpu(ev->stats_id);
3305
3306	for (i = 0; i < num_pdev_stats; i++) {
3307		const struct wmi_10_4_pdev_stats *src;
3308		struct ath10k_fw_stats_pdev *dst;
3309
3310		src = (void *)skb->data;
3311		if (!skb_pull(skb, sizeof(*src)))
3312			return -EPROTO;
3313
3314		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3315		if (!dst)
3316			continue;
3317
3318		ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
3319		ath10k_wmi_10_4_pull_pdev_stats_tx(&src->tx, dst);
3320		ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
3321		dst->rx_ovfl_errs = __le32_to_cpu(src->rx_ovfl_errs);
3322		ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
3323
3324		list_add_tail(&dst->list, &stats->pdevs);
3325	}
3326
3327	for (i = 0; i < num_pdev_ext_stats; i++) {
3328		const struct wmi_10_2_pdev_ext_stats *src;
3329
3330		src = (void *)skb->data;
3331		if (!skb_pull(skb, sizeof(*src)))
3332			return -EPROTO;
3333
3334		/* FIXME: expose values to userspace
3335		 *
3336		 * Note: Even though this loop seems to do nothing it is
3337		 * required to parse following sub-structures properly.
3338		 */
3339	}
3340
3341	for (i = 0; i < num_vdev_stats; i++) {
3342		const struct wmi_vdev_stats *src;
3343
3344		/* Ignore vdev stats here as it has only vdev id. Actual vdev
3345		 * stats will be retrieved from vdev extended stats.
3346		 */
3347		src = (void *)skb->data;
3348		if (!skb_pull(skb, sizeof(*src)))
3349			return -EPROTO;
3350	}
3351
3352	for (i = 0; i < num_peer_stats; i++) {
3353		const struct wmi_10_4_peer_stats *src;
3354		struct ath10k_fw_stats_peer *dst;
3355
3356		src = (void *)skb->data;
3357		if (!skb_pull(skb, sizeof(*src)))
3358			return -EPROTO;
3359
3360		dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3361		if (!dst)
3362			continue;
3363
3364		ath10k_wmi_10_4_pull_peer_stats(src, dst);
3365		list_add_tail(&dst->list, &stats->peers);
3366	}
3367
3368	for (i = 0; i < num_bcnflt_stats; i++) {
3369		const struct wmi_10_4_bss_bcn_filter_stats *src;
3370
3371		src = (void *)skb->data;
3372		if (!skb_pull(skb, sizeof(*src)))
3373			return -EPROTO;
3374
3375		/* FIXME: expose values to userspace
3376		 *
3377		 * Note: Even though this loop seems to do nothing it is
3378		 * required to parse following sub-structures properly.
3379		 */
3380	}
3381
3382	if (stats_id & WMI_10_4_STAT_PEER_EXTD) {
3383		stats->extended = true;
3384
3385		for (i = 0; i < num_peer_stats; i++) {
3386			const struct wmi_10_4_peer_extd_stats *src;
3387			struct ath10k_fw_extd_stats_peer *dst;
3388
3389			src = (void *)skb->data;
3390			if (!skb_pull(skb, sizeof(*src)))
3391				return -EPROTO;
3392
3393			dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3394			if (!dst)
3395				continue;
3396
3397			ether_addr_copy(dst->peer_macaddr,
3398					src->peer_macaddr.addr);
3399			dst->rx_duration = __le32_to_cpu(src->rx_duration);
3400			list_add_tail(&dst->list, &stats->peers_extd);
3401		}
3402	}
3403
3404	if (stats_id & WMI_10_4_STAT_VDEV_EXTD) {
3405		for (i = 0; i < num_vdev_stats; i++) {
3406			const struct wmi_vdev_stats_extd *src;
3407			struct ath10k_fw_stats_vdev_extd *dst;
3408
3409			src = (void *)skb->data;
3410			if (!skb_pull(skb, sizeof(*src)))
3411				return -EPROTO;
3412
3413			dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
3414			if (!dst)
3415				continue;
3416			ath10k_wmi_10_4_pull_vdev_stats(src, dst);
3417			list_add_tail(&dst->list, &stats->vdevs);
3418		}
3419	}
3420
3421	return 0;
3422}
3423
3424void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb)
3425{
3426	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
3427	ath10k_debug_fw_stats_process(ar, skb);
3428}
3429
3430static int
3431ath10k_wmi_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
3432				 struct wmi_vdev_start_ev_arg *arg)
3433{
3434	struct wmi_vdev_start_response_event *ev = (void *)skb->data;
3435
3436	if (skb->len < sizeof(*ev))
3437		return -EPROTO;
3438
3439	skb_pull(skb, sizeof(*ev));
3440	arg->vdev_id = ev->vdev_id;
3441	arg->req_id = ev->req_id;
3442	arg->resp_type = ev->resp_type;
3443	arg->status = ev->status;
3444
3445	return 0;
3446}
3447
3448void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb)
3449{
3450	struct wmi_vdev_start_ev_arg arg = {};
3451	int ret;
3452	u32 status;
3453
3454	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n");
3455
3456	ar->last_wmi_vdev_start_status = 0;
3457
3458	ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg);
3459	if (ret) {
3460		ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret);
3461		ar->last_wmi_vdev_start_status = ret;
3462		goto out;
3463	}
3464
3465	status = __le32_to_cpu(arg.status);
3466	if (WARN_ON_ONCE(status)) {
3467		ath10k_warn(ar, "vdev-start-response reports status error: %d (%s)\n",
3468			    status, (status == WMI_VDEV_START_CHAN_INVALID) ?
3469			    "chan-invalid" : "unknown");
3470		/* Setup is done one way or another though, so we should still
3471		 * do the completion, so don't return here.
3472		 */
3473		ar->last_wmi_vdev_start_status = -EINVAL;
3474	}
3475
3476out:
3477	complete(&ar->vdev_setup_done);
3478}
3479
3480void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb)
3481{
3482	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n");
3483	complete(&ar->vdev_setup_done);
3484}
3485
3486static int
3487ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb,
3488				struct wmi_peer_kick_ev_arg *arg)
3489{
3490	struct wmi_peer_sta_kickout_event *ev = (void *)skb->data;
3491
3492	if (skb->len < sizeof(*ev))
3493		return -EPROTO;
3494
3495	skb_pull(skb, sizeof(*ev));
3496	arg->mac_addr = ev->peer_macaddr.addr;
3497
3498	return 0;
3499}
3500
3501void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb)
3502{
3503	struct wmi_peer_kick_ev_arg arg = {};
3504	struct ieee80211_sta *sta;
3505	int ret;
3506
3507	ret = ath10k_wmi_pull_peer_kick(ar, skb, &arg);
3508	if (ret) {
3509		ath10k_warn(ar, "failed to parse peer kickout event: %d\n",
3510			    ret);
3511		return;
3512	}
3513
3514	ath10k_dbg(ar, ATH10K_DBG_STA, "wmi event peer sta kickout %pM\n",
3515		   arg.mac_addr);
3516
3517	rcu_read_lock();
3518
3519	sta = ieee80211_find_sta_by_ifaddr(ar->hw, arg.mac_addr, NULL);
3520	if (!sta) {
3521		ath10k_warn(ar, "Spurious quick kickout for STA %pM\n",
3522			    arg.mac_addr);
3523		goto exit;
3524	}
3525
3526	ieee80211_report_low_ack(sta, 10);
3527
3528exit:
3529	rcu_read_unlock();
3530}
3531
3532/*
3533 * FIXME
3534 *
3535 * We don't report to mac80211 sleep state of connected
3536 * stations. Due to this mac80211 can't fill in TIM IE
3537 * correctly.
3538 *
3539 * I know of no way of getting nullfunc frames that contain
3540 * sleep transition from connected stations - these do not
3541 * seem to be sent from the target to the host. There also
3542 * doesn't seem to be a dedicated event for that. So the
3543 * only way left to do this would be to read tim_bitmap
3544 * during SWBA.
3545 *
3546 * We could probably try using tim_bitmap from SWBA to tell
3547 * mac80211 which stations are asleep and which are not. The
3548 * problem here is calling mac80211 functions so many times
3549 * could take too long and make us miss the time to submit
3550 * the beacon to the target.
3551 *
3552 * So as a workaround we try to extend the TIM IE if there
3553 * is unicast buffered for stations with aid > 7 and fill it
3554 * in ourselves.
3555 */
3556static void ath10k_wmi_update_tim(struct ath10k *ar,
3557				  struct ath10k_vif *arvif,
3558				  struct sk_buff *bcn,
3559				  const struct wmi_tim_info_arg *tim_info)
3560{
3561	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data;
3562	struct ieee80211_tim_ie *tim;
3563	u8 *ies, *ie;
3564	u8 ie_len, pvm_len;
3565	__le32 t;
3566	u32 v, tim_len;
3567
3568	/* When FW reports 0 in tim_len, ensure at least first byte
3569	 * in tim_bitmap is considered for pvm calculation.
3570	 */
3571	tim_len = tim_info->tim_len ? __le32_to_cpu(tim_info->tim_len) : 1;
3572
3573	/* if next SWBA has no tim_changed the tim_bitmap is garbage.
3574	 * we must copy the bitmap upon change and reuse it later
3575	 */
3576	if (__le32_to_cpu(tim_info->tim_changed)) {
3577		int i;
3578
3579		if (sizeof(arvif->u.ap.tim_bitmap) < tim_len) {
3580			ath10k_warn(ar, "SWBA TIM field is too big (%u), truncated it to %zu",
3581				    tim_len, sizeof(arvif->u.ap.tim_bitmap));
3582			tim_len = sizeof(arvif->u.ap.tim_bitmap);
3583		}
3584
3585		for (i = 0; i < tim_len; i++) {
3586			t = tim_info->tim_bitmap[i / 4];
3587			v = __le32_to_cpu(t);
3588			arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
3589		}
3590
3591		/* FW reports either length 0 or length based on max supported
3592		 * station. so we calculate this on our own
3593		 */
3594		arvif->u.ap.tim_len = 0;
3595		for (i = 0; i < tim_len; i++)
3596			if (arvif->u.ap.tim_bitmap[i])
3597				arvif->u.ap.tim_len = i;
3598
3599		arvif->u.ap.tim_len++;
3600	}
3601
3602	ies = bcn->data;
3603	ies += ieee80211_hdrlen(hdr->frame_control);
3604	ies += 12; /* fixed parameters */
3605
3606#if defined(__linux__)
3607	ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies,
3608				    (u8 *)skb_tail_pointer(bcn) - ies);
3609#elif defined(__FreeBSD__)
3610	ie = __DECONST(u8 *, cfg80211_find_ie(WLAN_EID_TIM, ies,
3611				    (u8 *)skb_tail_pointer(bcn) - ies));
3612#endif
3613	if (!ie) {
3614		if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
3615			ath10k_warn(ar, "no tim ie found;\n");
3616		return;
3617	}
3618
3619#if defined(__linux__)
3620	tim = (void *)ie + 2;
3621#elif defined(__FreeBSD__)
3622	tim = (void *)(ie + 2);
3623#endif
3624	ie_len = ie[1];
3625	pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */
3626
3627	if (pvm_len < arvif->u.ap.tim_len) {
3628		int expand_size = tim_len - pvm_len;
3629		int move_size = skb_tail_pointer(bcn) - (ie + 2 + ie_len);
3630#if defined(__linux__)
3631		void *next_ie = ie + 2 + ie_len;
3632#elif defined(__FreeBSD__)
3633		u8 *next_ie = ie + 2 + ie_len;
3634#endif
3635
3636		if (skb_put(bcn, expand_size)) {
3637			memmove(next_ie + expand_size, next_ie, move_size);
3638
3639#if defined(__FreeBSD__)
3640			/* XXX-BZ this seems to modify the skb data. */
3641#endif
3642			ie[1] += expand_size;
3643			ie_len += expand_size;
3644			pvm_len += expand_size;
3645		} else {
3646			ath10k_warn(ar, "tim expansion failed\n");
3647		}
3648	}
3649
3650	if (pvm_len > tim_len) {
3651		ath10k_warn(ar, "tim pvm length is too great (%d)\n", pvm_len);
3652		return;
3653	}
3654
3655#if defined(__FreeBSD__)
3656	/* XXX-BZ this seems to modify the skb data. */
3657#endif
3658	tim->bitmap_ctrl = !!__le32_to_cpu(tim_info->tim_mcast);
3659	memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
3660
3661	if (tim->dtim_count == 0) {
3662		ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DTIM_ZERO;
3663
3664		if (__le32_to_cpu(tim_info->tim_mcast) == 1)
3665			ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DELIVER_CAB;
3666	}
3667
3668	ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
3669		   tim->dtim_count, tim->dtim_period,
3670		   tim->bitmap_ctrl, pvm_len);
3671}
3672
3673static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
3674				  struct sk_buff *bcn,
3675				  const struct wmi_p2p_noa_info *noa)
3676{
3677	if (!arvif->vif->p2p)
3678		return;
3679
3680	ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed);
3681
3682	if (noa->changed & WMI_P2P_NOA_CHANGED_BIT)
3683		ath10k_p2p_noa_update(arvif, noa);
3684
3685	if (arvif->u.ap.noa_data)
3686		if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC))
3687			skb_put_data(bcn, arvif->u.ap.noa_data,
3688				     arvif->u.ap.noa_len);
3689}
3690
3691static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
3692				      struct wmi_swba_ev_arg *arg)
3693{
3694	struct wmi_host_swba_event *ev = (void *)skb->data;
3695	u32 map;
3696	size_t i;
3697
3698	if (skb->len < sizeof(*ev))
3699		return -EPROTO;
3700
3701	skb_pull(skb, sizeof(*ev));
3702	arg->vdev_map = ev->vdev_map;
3703
3704	for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
3705		if (!(map & BIT(0)))
3706			continue;
3707
3708		/* If this happens there were some changes in firmware and
3709		 * ath10k should update the max size of tim_info array.
3710		 */
3711		if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
3712			break;
3713
3714		if (__le32_to_cpu(ev->bcn_info[i].tim_info.tim_len) >
3715		     sizeof(ev->bcn_info[i].tim_info.tim_bitmap)) {
3716			ath10k_warn(ar, "refusing to parse invalid swba structure\n");
3717			return -EPROTO;
3718		}
3719
3720		arg->tim_info[i].tim_len = ev->bcn_info[i].tim_info.tim_len;
3721		arg->tim_info[i].tim_mcast = ev->bcn_info[i].tim_info.tim_mcast;
3722		arg->tim_info[i].tim_bitmap =
3723				ev->bcn_info[i].tim_info.tim_bitmap;
3724		arg->tim_info[i].tim_changed =
3725				ev->bcn_info[i].tim_info.tim_changed;
3726		arg->tim_info[i].tim_num_ps_pending =
3727				ev->bcn_info[i].tim_info.tim_num_ps_pending;
3728
3729		arg->noa_info[i] = &ev->bcn_info[i].p2p_noa_info;
3730		i++;
3731	}
3732
3733	return 0;
3734}
3735
3736static int ath10k_wmi_10_2_4_op_pull_swba_ev(struct ath10k *ar,
3737					     struct sk_buff *skb,
3738					     struct wmi_swba_ev_arg *arg)
3739{
3740	struct wmi_10_2_4_host_swba_event *ev = (void *)skb->data;
3741	u32 map;
3742	size_t i;
3743
3744	if (skb->len < sizeof(*ev))
3745		return -EPROTO;
3746
3747	skb_pull(skb, sizeof(*ev));
3748	arg->vdev_map = ev->vdev_map;
3749
3750	for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
3751		if (!(map & BIT(0)))
3752			continue;
3753
3754		/* If this happens there were some changes in firmware and
3755		 * ath10k should update the max size of tim_info array.
3756		 */
3757		if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
3758			break;
3759
3760		if (__le32_to_cpu(ev->bcn_info[i].tim_info.tim_len) >
3761		     sizeof(ev->bcn_info[i].tim_info.tim_bitmap)) {
3762			ath10k_warn(ar, "refusing to parse invalid swba structure\n");
3763			return -EPROTO;
3764		}
3765
3766		arg->tim_info[i].tim_len = ev->bcn_info[i].tim_info.tim_len;
3767		arg->tim_info[i].tim_mcast = ev->bcn_info[i].tim_info.tim_mcast;
3768		arg->tim_info[i].tim_bitmap =
3769				ev->bcn_info[i].tim_info.tim_bitmap;
3770		arg->tim_info[i].tim_changed =
3771				ev->bcn_info[i].tim_info.tim_changed;
3772		arg->tim_info[i].tim_num_ps_pending =
3773				ev->bcn_info[i].tim_info.tim_num_ps_pending;
3774		i++;
3775	}
3776
3777	return 0;
3778}
3779
3780static int ath10k_wmi_10_4_op_pull_swba_ev(struct ath10k *ar,
3781					   struct sk_buff *skb,
3782					   struct wmi_swba_ev_arg *arg)
3783{
3784	struct wmi_10_4_host_swba_event *ev = (void *)skb->data;
3785	u32 map, tim_len;
3786	size_t i;
3787
3788	if (skb->len < sizeof(*ev))
3789		return -EPROTO;
3790
3791	skb_pull(skb, sizeof(*ev));
3792	arg->vdev_map = ev->vdev_map;
3793
3794	for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
3795		if (!(map & BIT(0)))
3796			continue;
3797
3798		/* If this happens there were some changes in firmware and
3799		 * ath10k should update the max size of tim_info array.
3800		 */
3801		if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
3802			break;
3803
3804		if (__le32_to_cpu(ev->bcn_info[i].tim_info.tim_len) >
3805		      sizeof(ev->bcn_info[i].tim_info.tim_bitmap)) {
3806			ath10k_warn(ar, "refusing to parse invalid swba structure\n");
3807			return -EPROTO;
3808		}
3809
3810		tim_len = __le32_to_cpu(ev->bcn_info[i].tim_info.tim_len);
3811		if (tim_len) {
3812			/* Exclude 4 byte guard length */
3813			tim_len -= 4;
3814			arg->tim_info[i].tim_len = __cpu_to_le32(tim_len);
3815		} else {
3816			arg->tim_info[i].tim_len = 0;
3817		}
3818
3819		arg->tim_info[i].tim_mcast = ev->bcn_info[i].tim_info.tim_mcast;
3820		arg->tim_info[i].tim_bitmap =
3821				ev->bcn_info[i].tim_info.tim_bitmap;
3822		arg->tim_info[i].tim_changed =
3823				ev->bcn_info[i].tim_info.tim_changed;
3824		arg->tim_info[i].tim_num_ps_pending =
3825				ev->bcn_info[i].tim_info.tim_num_ps_pending;
3826
3827		/* 10.4 firmware doesn't have p2p support. notice of absence
3828		 * info can be ignored for now.
3829		 */
3830
3831		i++;
3832	}
3833
3834	return 0;
3835}
3836
3837static enum wmi_txbf_conf ath10k_wmi_10_4_txbf_conf_scheme(struct ath10k *ar)
3838{
3839	return WMI_TXBF_CONF_BEFORE_ASSOC;
3840}
3841
3842void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
3843{
3844	struct wmi_swba_ev_arg arg = {};
3845	u32 map;
3846	int i = -1;
3847	const struct wmi_tim_info_arg *tim_info;
3848	const struct wmi_p2p_noa_info *noa_info;
3849	struct ath10k_vif *arvif;
3850	struct sk_buff *bcn;
3851	dma_addr_t paddr;
3852	int ret, vdev_id = 0;
3853
3854	ret = ath10k_wmi_pull_swba(ar, skb, &arg);
3855	if (ret) {
3856		ath10k_warn(ar, "failed to parse swba event: %d\n", ret);
3857		return;
3858	}
3859
3860	map = __le32_to_cpu(arg.vdev_map);
3861
3862	ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
3863		   map);
3864
3865	for (; map; map >>= 1, vdev_id++) {
3866		if (!(map & 0x1))
3867			continue;
3868
3869		i++;
3870
3871		if (i >= WMI_MAX_AP_VDEV) {
3872			ath10k_warn(ar, "swba has corrupted vdev map\n");
3873			break;
3874		}
3875
3876		tim_info = &arg.tim_info[i];
3877		noa_info = arg.noa_info[i];
3878
3879		ath10k_dbg(ar, ATH10K_DBG_MGMT,
3880			   "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n",
3881			   i,
3882			   __le32_to_cpu(tim_info->tim_len),
3883			   __le32_to_cpu(tim_info->tim_mcast),
3884			   __le32_to_cpu(tim_info->tim_changed),
3885			   __le32_to_cpu(tim_info->tim_num_ps_pending),
3886			   __le32_to_cpu(tim_info->tim_bitmap[3]),
3887			   __le32_to_cpu(tim_info->tim_bitmap[2]),
3888			   __le32_to_cpu(tim_info->tim_bitmap[1]),
3889			   __le32_to_cpu(tim_info->tim_bitmap[0]));
3890
3891		/* TODO: Only first 4 word from tim_bitmap is dumped.
3892		 * Extend debug code to dump full tim_bitmap.
3893		 */
3894
3895		arvif = ath10k_get_arvif(ar, vdev_id);
3896		if (arvif == NULL) {
3897			ath10k_warn(ar, "no vif for vdev_id %d found\n",
3898				    vdev_id);
3899			continue;
3900		}
3901
3902		/* mac80211 would have already asked us to stop beaconing and
3903		 * bring the vdev down, so continue in that case
3904		 */
3905		if (!arvif->is_up)
3906			continue;
3907
3908		/* There are no completions for beacons so wait for next SWBA
3909		 * before telling mac80211 to decrement CSA counter
3910		 *
3911		 * Once CSA counter is completed stop sending beacons until
3912		 * actual channel switch is done
3913		 */
3914		if (arvif->vif->bss_conf.csa_active &&
3915		    ieee80211_beacon_cntdwn_is_complete(arvif->vif)) {
3916			ieee80211_csa_finish(arvif->vif);
3917			continue;
3918		}
3919
3920		bcn = ieee80211_beacon_get(ar->hw, arvif->vif, 0);
3921		if (!bcn) {
3922			ath10k_warn(ar, "could not get mac80211 beacon\n");
3923			continue;
3924		}
3925
3926		ath10k_tx_h_seq_no(arvif->vif, bcn);
3927		ath10k_wmi_update_tim(ar, arvif, bcn, tim_info);
3928		ath10k_wmi_update_noa(ar, arvif, bcn, noa_info);
3929
3930		spin_lock_bh(&ar->data_lock);
3931
3932		if (arvif->beacon) {
3933			switch (arvif->beacon_state) {
3934			case ATH10K_BEACON_SENT:
3935				break;
3936			case ATH10K_BEACON_SCHEDULED:
3937				ath10k_warn(ar, "SWBA overrun on vdev %d, skipped old beacon\n",
3938					    arvif->vdev_id);
3939				break;
3940			case ATH10K_BEACON_SENDING:
3941				ath10k_warn(ar, "SWBA overrun on vdev %d, skipped new beacon\n",
3942					    arvif->vdev_id);
3943				dev_kfree_skb(bcn);
3944				goto skip;
3945			}
3946
3947			ath10k_mac_vif_beacon_free(arvif);
3948		}
3949
3950		if (!arvif->beacon_buf) {
3951			paddr = dma_map_single(arvif->ar->dev, bcn->data,
3952					       bcn->len, DMA_TO_DEVICE);
3953			ret = dma_mapping_error(arvif->ar->dev, paddr);
3954			if (ret) {
3955				ath10k_warn(ar, "failed to map beacon: %d\n",
3956					    ret);
3957				dev_kfree_skb_any(bcn);
3958				goto skip;
3959			}
3960
3961			ATH10K_SKB_CB(bcn)->paddr = paddr;
3962		} else {
3963			if (bcn->len > IEEE80211_MAX_FRAME_LEN) {
3964				ath10k_warn(ar, "trimming beacon %d -> %d bytes!\n",
3965					    bcn->len, IEEE80211_MAX_FRAME_LEN);
3966				skb_trim(bcn, IEEE80211_MAX_FRAME_LEN);
3967			}
3968			memcpy(arvif->beacon_buf, bcn->data, bcn->len);
3969			ATH10K_SKB_CB(bcn)->paddr = arvif->beacon_paddr;
3970		}
3971
3972		arvif->beacon = bcn;
3973		arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
3974
3975		trace_ath10k_tx_hdr(ar, bcn->data, bcn->len);
3976		trace_ath10k_tx_payload(ar, bcn->data, bcn->len);
3977
3978skip:
3979		spin_unlock_bh(&ar->data_lock);
3980	}
3981
3982	ath10k_wmi_tx_beacons_nowait(ar);
3983}
3984
3985void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb)
3986{
3987	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
3988}
3989
3990static void ath10k_radar_detected(struct ath10k *ar)
3991{
3992	ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
3993	ATH10K_DFS_STAT_INC(ar, radar_detected);
3994
3995	/* Control radar events reporting in debugfs file
3996	 * dfs_block_radar_events
3997	 */
3998	if (ar->dfs_block_radar_events)
3999		ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
4000	else
4001		ieee80211_radar_detected(ar->hw);
4002}
4003
4004static void ath10k_radar_confirmation_work(struct work_struct *work)
4005{
4006	struct ath10k *ar = container_of(work, struct ath10k,
4007					 radar_confirmation_work);
4008	struct ath10k_radar_found_info radar_info;
4009	int ret, time_left;
4010
4011	reinit_completion(&ar->wmi.radar_confirm);
4012
4013	spin_lock_bh(&ar->data_lock);
4014	memcpy(&radar_info, &ar->last_radar_info, sizeof(radar_info));
4015	spin_unlock_bh(&ar->data_lock);
4016
4017	ret = ath10k_wmi_report_radar_found(ar, &radar_info);
4018	if (ret) {
4019		ath10k_warn(ar, "failed to send radar found %d\n", ret);
4020		goto wait_complete;
4021	}
4022
4023	time_left = wait_for_completion_timeout(&ar->wmi.radar_confirm,
4024						ATH10K_WMI_DFS_CONF_TIMEOUT_HZ);
4025	if (time_left) {
4026		/* DFS Confirmation status event received and
4027		 * necessary action completed.
4028		 */
4029		goto wait_complete;
4030	} else {
4031		/* DFS Confirmation event not received from FW.Considering this
4032		 * as real radar.
4033		 */
4034		ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4035			   "dfs confirmation not received from fw, considering as radar\n");
4036		goto radar_detected;
4037	}
4038
4039radar_detected:
4040	ath10k_radar_detected(ar);
4041
4042	/* Reset state to allow sending confirmation on consecutive radar
4043	 * detections, unless radar confirmation is disabled/stopped.
4044	 */
4045wait_complete:
4046	spin_lock_bh(&ar->data_lock);
4047	if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_STOPPED)
4048		ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
4049	spin_unlock_bh(&ar->data_lock);
4050}
4051
4052static void ath10k_dfs_radar_report(struct ath10k *ar,
4053				    struct wmi_phyerr_ev_arg *phyerr,
4054				    const struct phyerr_radar_report *rr,
4055				    u64 tsf)
4056{
4057	u32 reg0, reg1, tsf32l;
4058	struct ieee80211_channel *ch;
4059	struct pulse_event pe;
4060	struct radar_detector_specs rs;
4061	u64 tsf64;
4062	u8 rssi, width;
4063	struct ath10k_radar_found_info *radar_info;
4064
4065	reg0 = __le32_to_cpu(rr->reg0);
4066	reg1 = __le32_to_cpu(rr->reg1);
4067
4068	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4069		   "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n",
4070		   MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP),
4071		   MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH),
4072		   MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN),
4073		   MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF));
4074	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4075		   "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n",
4076		   MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK),
4077		   MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX),
4078		   MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID),
4079		   MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN),
4080		   MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK));
4081	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4082		   "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n",
4083		   MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET),
4084		   MS(reg1, RADAR_REPORT_REG1_PULSE_DUR));
4085
4086	if (!ar->dfs_detector)
4087		return;
4088
4089	spin_lock_bh(&ar->data_lock);
4090	ch = ar->rx_channel;
4091
4092	/* fetch target operating channel during channel change */
4093	if (!ch)
4094		ch = ar->tgt_oper_chan;
4095
4096	spin_unlock_bh(&ar->data_lock);
4097
4098	if (!ch) {
4099		ath10k_warn(ar, "failed to derive channel for radar pulse, treating as radar\n");
4100		goto radar_detected;
4101	}
4102
4103	/* report event to DFS pattern detector */
4104	tsf32l = phyerr->tsf_timestamp;
4105	tsf64 = tsf & (~0xFFFFFFFFULL);
4106	tsf64 |= tsf32l;
4107
4108	width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR);
4109	rssi = phyerr->rssi_combined;
4110
4111	/* hardware store this as 8 bit signed value,
4112	 * set to zero if negative number
4113	 */
4114	if (rssi & 0x80)
4115		rssi = 0;
4116
4117	pe.ts = tsf64;
4118	pe.freq = ch->center_freq;
4119	pe.width = width;
4120	pe.rssi = rssi;
4121	pe.chirp = (MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP) != 0);
4122	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4123#if defined(__linux__)
4124		   "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n",
4125		   pe.freq, pe.width, pe.rssi, pe.ts);
4126#elif defined(__FreeBSD__)
4127		   "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %jX\n",
4128		   pe.freq, pe.width, pe.rssi, (uintmax_t)pe.ts);
4129#endif
4130
4131	ATH10K_DFS_STAT_INC(ar, pulses_detected);
4132
4133	if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe, &rs)) {
4134		ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4135			   "dfs no pulse pattern detected, yet\n");
4136		return;
4137	}
4138
4139	if ((test_bit(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, ar->wmi.svc_map)) &&
4140	    ar->dfs_detector->region == NL80211_DFS_FCC) {
4141		/* Consecutive radar indications need not be
4142		 * sent to the firmware until we get confirmation
4143		 * for the previous detected radar.
4144		 */
4145		spin_lock_bh(&ar->data_lock);
4146		if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_IDLE) {
4147			spin_unlock_bh(&ar->data_lock);
4148			return;
4149		}
4150		ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_INPROGRESS;
4151		radar_info = &ar->last_radar_info;
4152
4153		radar_info->pri_min = rs.pri_min;
4154		radar_info->pri_max = rs.pri_max;
4155		radar_info->width_min = rs.width_min;
4156		radar_info->width_max = rs.width_max;
4157		/*TODO Find sidx_min and sidx_max */
4158		radar_info->sidx_min = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
4159		radar_info->sidx_max = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
4160
4161		ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4162			   "sending wmi radar found cmd pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
4163			   radar_info->pri_min, radar_info->pri_max,
4164			   radar_info->width_min, radar_info->width_max,
4165			   radar_info->sidx_min, radar_info->sidx_max);
4166		ieee80211_queue_work(ar->hw, &ar->radar_confirmation_work);
4167		spin_unlock_bh(&ar->data_lock);
4168		return;
4169	}
4170
4171radar_detected:
4172	ath10k_radar_detected(ar);
4173}
4174
4175static int ath10k_dfs_fft_report(struct ath10k *ar,
4176				 struct wmi_phyerr_ev_arg *phyerr,
4177				 const struct phyerr_fft_report *fftr,
4178				 u64 tsf)
4179{
4180	u32 reg0, reg1;
4181	u8 rssi, peak_mag;
4182
4183	reg0 = __le32_to_cpu(fftr->reg0);
4184	reg1 = __le32_to_cpu(fftr->reg1);
4185	rssi = phyerr->rssi_combined;
4186
4187	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4188		   "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n",
4189		   MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB),
4190		   MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB),
4191		   MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX),
4192		   MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX));
4193	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4194		   "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n",
4195		   MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB),
4196		   MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB),
4197		   MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG),
4198		   MS(reg1, SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB));
4199
4200	peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG);
4201
4202	/* false event detection */
4203	if (rssi == DFS_RSSI_POSSIBLY_FALSE &&
4204	    peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) {
4205		ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs false pulse detected\n");
4206		ATH10K_DFS_STAT_INC(ar, pulses_discarded);
4207		return -EINVAL;
4208	}
4209
4210	return 0;
4211}
4212
4213void ath10k_wmi_event_dfs(struct ath10k *ar,
4214			  struct wmi_phyerr_ev_arg *phyerr,
4215			  u64 tsf)
4216{
4217	int buf_len, tlv_len, res, i = 0;
4218	const struct phyerr_tlv *tlv;
4219	const struct phyerr_radar_report *rr;
4220	const struct phyerr_fft_report *fftr;
4221	const u8 *tlv_buf;
4222
4223	buf_len = phyerr->buf_len;
4224	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4225#if defined(__linux__)
4226		   "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n",
4227		   phyerr->phy_err_code, phyerr->rssi_combined,
4228		   phyerr->tsf_timestamp, tsf, buf_len);
4229#elif defined(__FreeBSD__)
4230		   "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%jX len %d\n",
4231		   phyerr->phy_err_code, phyerr->rssi_combined,
4232		   phyerr->tsf_timestamp, (uintmax_t)tsf, buf_len);
4233#endif
4234
4235	/* Skip event if DFS disabled */
4236	if (!IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED))
4237		return;
4238
4239	ATH10K_DFS_STAT_INC(ar, pulses_total);
4240
4241	while (i < buf_len) {
4242		if (i + sizeof(*tlv) > buf_len) {
4243			ath10k_warn(ar, "too short buf for tlv header (%d)\n",
4244				    i);
4245			return;
4246		}
4247
4248#if defined(__linux__)
4249		tlv = (struct phyerr_tlv *)&phyerr->buf[i];
4250#elif defined(__FreeBSD__)
4251		tlv = (const struct phyerr_tlv *)&phyerr->buf[i];
4252#endif
4253		tlv_len = __le16_to_cpu(tlv->len);
4254		tlv_buf = &phyerr->buf[i + sizeof(*tlv)];
4255		ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4256			   "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n",
4257			   tlv_len, tlv->tag, tlv->sig);
4258
4259		switch (tlv->tag) {
4260		case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY:
4261			if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) {
4262				ath10k_warn(ar, "too short radar pulse summary (%d)\n",
4263					    i);
4264				return;
4265			}
4266
4267#if defined(__linux__)
4268			rr = (struct phyerr_radar_report *)tlv_buf;
4269#elif defined(__FreeBSD__)
4270			rr = (const struct phyerr_radar_report *)tlv_buf;
4271#endif
4272			ath10k_dfs_radar_report(ar, phyerr, rr, tsf);
4273			break;
4274		case PHYERR_TLV_TAG_SEARCH_FFT_REPORT:
4275			if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) {
4276				ath10k_warn(ar, "too short fft report (%d)\n",
4277					    i);
4278				return;
4279			}
4280
4281#if defined(__linux__)
4282			fftr = (struct phyerr_fft_report *)tlv_buf;
4283#elif defined(__FreeBSD__)
4284			fftr = (const struct phyerr_fft_report *)tlv_buf;
4285#endif
4286			res = ath10k_dfs_fft_report(ar, phyerr, fftr, tsf);
4287			if (res)
4288				return;
4289			break;
4290		}
4291
4292		i += sizeof(*tlv) + tlv_len;
4293	}
4294}
4295
4296void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
4297				    struct wmi_phyerr_ev_arg *phyerr,
4298				    u64 tsf)
4299{
4300	int buf_len, tlv_len, res, i = 0;
4301#if defined(__linux__)
4302	struct phyerr_tlv *tlv;
4303#elif defined(__FreeBSD__)
4304	const struct phyerr_tlv *tlv;
4305#endif
4306	const void *tlv_buf;
4307	const struct phyerr_fft_report *fftr;
4308	size_t fftr_len;
4309
4310	buf_len = phyerr->buf_len;
4311
4312	while (i < buf_len) {
4313		if (i + sizeof(*tlv) > buf_len) {
4314			ath10k_warn(ar, "failed to parse phyerr tlv header at byte %d\n",
4315				    i);
4316			return;
4317		}
4318
4319#if defined(__linux__)
4320		tlv = (struct phyerr_tlv *)&phyerr->buf[i];
4321#elif defined(__FreeBSD__)
4322		tlv = (const struct phyerr_tlv *)&phyerr->buf[i];
4323#endif
4324		tlv_len = __le16_to_cpu(tlv->len);
4325		tlv_buf = &phyerr->buf[i + sizeof(*tlv)];
4326
4327		if (i + sizeof(*tlv) + tlv_len > buf_len) {
4328			ath10k_warn(ar, "failed to parse phyerr tlv payload at byte %d\n",
4329				    i);
4330			return;
4331		}
4332
4333		switch (tlv->tag) {
4334		case PHYERR_TLV_TAG_SEARCH_FFT_REPORT:
4335			if (sizeof(*fftr) > tlv_len) {
4336				ath10k_warn(ar, "failed to parse fft report at byte %d\n",
4337					    i);
4338				return;
4339			}
4340
4341			fftr_len = tlv_len - sizeof(*fftr);
4342			fftr = tlv_buf;
4343			res = ath10k_spectral_process_fft(ar, phyerr,
4344							  fftr, fftr_len,
4345							  tsf);
4346			if (res < 0) {
4347				ath10k_dbg(ar, ATH10K_DBG_WMI, "failed to process fft report: %d\n",
4348					   res);
4349				return;
4350			}
4351			break;
4352		}
4353
4354		i += sizeof(*tlv) + tlv_len;
4355	}
4356}
4357
4358static int ath10k_wmi_op_pull_phyerr_ev_hdr(struct ath10k *ar,
4359					    struct sk_buff *skb,
4360					    struct wmi_phyerr_hdr_arg *arg)
4361{
4362	struct wmi_phyerr_event *ev = (void *)skb->data;
4363
4364	if (skb->len < sizeof(*ev))
4365		return -EPROTO;
4366
4367	arg->num_phyerrs = __le32_to_cpu(ev->num_phyerrs);
4368	arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32);
4369	arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32);
4370	arg->buf_len = skb->len - sizeof(*ev);
4371	arg->phyerrs = ev->phyerrs;
4372
4373	return 0;
4374}
4375
4376static int ath10k_wmi_10_4_op_pull_phyerr_ev_hdr(struct ath10k *ar,
4377						 struct sk_buff *skb,
4378						 struct wmi_phyerr_hdr_arg *arg)
4379{
4380	struct wmi_10_4_phyerr_event *ev = (void *)skb->data;
4381
4382	if (skb->len < sizeof(*ev))
4383		return -EPROTO;
4384
4385	/* 10.4 firmware always reports only one phyerr */
4386	arg->num_phyerrs = 1;
4387
4388	arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32);
4389	arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32);
4390	arg->buf_len = skb->len;
4391	arg->phyerrs = skb->data;
4392
4393	return 0;
4394}
4395
4396int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar,
4397				 const void *phyerr_buf,
4398				 int left_len,
4399				 struct wmi_phyerr_ev_arg *arg)
4400{
4401	const struct wmi_phyerr *phyerr = phyerr_buf;
4402	int i;
4403
4404	if (left_len < sizeof(*phyerr)) {
4405		ath10k_warn(ar, "wrong phyerr event head len %d (need: >=%zd)\n",
4406			    left_len, sizeof(*phyerr));
4407		return -EINVAL;
4408	}
4409
4410	arg->tsf_timestamp = __le32_to_cpu(phyerr->tsf_timestamp);
4411	arg->freq1 = __le16_to_cpu(phyerr->freq1);
4412	arg->freq2 = __le16_to_cpu(phyerr->freq2);
4413	arg->rssi_combined = phyerr->rssi_combined;
4414	arg->chan_width_mhz = phyerr->chan_width_mhz;
4415	arg->buf_len = __le32_to_cpu(phyerr->buf_len);
4416	arg->buf = phyerr->buf;
4417	arg->hdr_len = sizeof(*phyerr);
4418
4419	for (i = 0; i < 4; i++)
4420		arg->nf_chains[i] = __le16_to_cpu(phyerr->nf_chains[i]);
4421
4422	switch (phyerr->phy_err_code) {
4423	case PHY_ERROR_GEN_SPECTRAL_SCAN:
4424		arg->phy_err_code = PHY_ERROR_SPECTRAL_SCAN;
4425		break;
4426	case PHY_ERROR_GEN_FALSE_RADAR_EXT:
4427		arg->phy_err_code = PHY_ERROR_FALSE_RADAR_EXT;
4428		break;
4429	case PHY_ERROR_GEN_RADAR:
4430		arg->phy_err_code = PHY_ERROR_RADAR;
4431		break;
4432	default:
4433		arg->phy_err_code = PHY_ERROR_UNKNOWN;
4434		break;
4435	}
4436
4437	return 0;
4438}
4439
4440static int ath10k_wmi_10_4_op_pull_phyerr_ev(struct ath10k *ar,
4441					     const void *phyerr_buf,
4442					     int left_len,
4443					     struct wmi_phyerr_ev_arg *arg)
4444{
4445	const struct wmi_10_4_phyerr_event *phyerr = phyerr_buf;
4446	u32 phy_err_mask;
4447	int i;
4448
4449	if (left_len < sizeof(*phyerr)) {
4450		ath10k_warn(ar, "wrong phyerr event head len %d (need: >=%zd)\n",
4451			    left_len, sizeof(*phyerr));
4452		return -EINVAL;
4453	}
4454
4455	arg->tsf_timestamp = __le32_to_cpu(phyerr->tsf_timestamp);
4456	arg->freq1 = __le16_to_cpu(phyerr->freq1);
4457	arg->freq2 = __le16_to_cpu(phyerr->freq2);
4458	arg->rssi_combined = phyerr->rssi_combined;
4459	arg->chan_width_mhz = phyerr->chan_width_mhz;
4460	arg->buf_len = __le32_to_cpu(phyerr->buf_len);
4461	arg->buf = phyerr->buf;
4462	arg->hdr_len = sizeof(*phyerr);
4463
4464	for (i = 0; i < 4; i++)
4465		arg->nf_chains[i] = __le16_to_cpu(phyerr->nf_chains[i]);
4466
4467	phy_err_mask = __le32_to_cpu(phyerr->phy_err_mask[0]);
4468
4469	if (phy_err_mask & PHY_ERROR_10_4_SPECTRAL_SCAN_MASK)
4470		arg->phy_err_code = PHY_ERROR_SPECTRAL_SCAN;
4471	else if (phy_err_mask & PHY_ERROR_10_4_RADAR_MASK)
4472		arg->phy_err_code = PHY_ERROR_RADAR;
4473	else
4474		arg->phy_err_code = PHY_ERROR_UNKNOWN;
4475
4476	return 0;
4477}
4478
4479void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
4480{
4481	struct wmi_phyerr_hdr_arg hdr_arg = {};
4482	struct wmi_phyerr_ev_arg phyerr_arg = {};
4483#if defined(__linux__)
4484	const void *phyerr;
4485#elif defined(__FreeBSD__)
4486	const u8 *phyerr;
4487#endif
4488	u32 count, i, buf_len, phy_err_code;
4489	u64 tsf;
4490	int left_len, ret;
4491
4492	ATH10K_DFS_STAT_INC(ar, phy_errors);
4493
4494	ret = ath10k_wmi_pull_phyerr_hdr(ar, skb, &hdr_arg);
4495	if (ret) {
4496		ath10k_warn(ar, "failed to parse phyerr event hdr: %d\n", ret);
4497		return;
4498	}
4499
4500	/* Check number of included events */
4501	count = hdr_arg.num_phyerrs;
4502
4503	left_len = hdr_arg.buf_len;
4504
4505	tsf = hdr_arg.tsf_u32;
4506	tsf <<= 32;
4507	tsf |= hdr_arg.tsf_l32;
4508
4509	ath10k_dbg(ar, ATH10K_DBG_WMI,
4510#if defined(__linux__)
4511		   "wmi event phyerr count %d tsf64 0x%llX\n",
4512		   count, tsf);
4513#elif defined(__FreeBSD__)
4514		   "wmi event phyerr count %d tsf64 0x%jX\n",
4515		   count, (uintmax_t)tsf);
4516#endif
4517
4518	phyerr = hdr_arg.phyerrs;
4519	for (i = 0; i < count; i++) {
4520		ret = ath10k_wmi_pull_phyerr(ar, phyerr, left_len, &phyerr_arg);
4521		if (ret) {
4522			ath10k_warn(ar, "failed to parse phyerr event (%d)\n",
4523				    i);
4524			return;
4525		}
4526
4527		left_len -= phyerr_arg.hdr_len;
4528		buf_len = phyerr_arg.buf_len;
4529		phy_err_code = phyerr_arg.phy_err_code;
4530
4531		if (left_len < buf_len) {
4532			ath10k_warn(ar, "single event (%d) wrong buf len\n", i);
4533			return;
4534		}
4535
4536		left_len -= buf_len;
4537
4538		switch (phy_err_code) {
4539		case PHY_ERROR_RADAR:
4540			ath10k_wmi_event_dfs(ar, &phyerr_arg, tsf);
4541			break;
4542		case PHY_ERROR_SPECTRAL_SCAN:
4543			ath10k_wmi_event_spectral_scan(ar, &phyerr_arg, tsf);
4544			break;
4545		case PHY_ERROR_FALSE_RADAR_EXT:
4546			ath10k_wmi_event_dfs(ar, &phyerr_arg, tsf);
4547			ath10k_wmi_event_spectral_scan(ar, &phyerr_arg, tsf);
4548			break;
4549		default:
4550			break;
4551		}
4552
4553		phyerr = phyerr + phyerr_arg.hdr_len + buf_len;
4554	}
4555}
4556
4557static int
4558ath10k_wmi_10_4_op_pull_dfs_status_ev(struct ath10k *ar, struct sk_buff *skb,
4559				      struct wmi_dfs_status_ev_arg *arg)
4560{
4561	struct wmi_dfs_status_ev_arg *ev = (void *)skb->data;
4562
4563	if (skb->len < sizeof(*ev))
4564		return -EPROTO;
4565
4566	arg->status = ev->status;
4567
4568	return 0;
4569}
4570
4571static void
4572ath10k_wmi_event_dfs_status_check(struct ath10k *ar, struct sk_buff *skb)
4573{
4574	struct wmi_dfs_status_ev_arg status_arg = {};
4575	int ret;
4576
4577	ret = ath10k_wmi_pull_dfs_status(ar, skb, &status_arg);
4578
4579	if (ret) {
4580		ath10k_warn(ar, "failed to parse dfs status event: %d\n", ret);
4581		return;
4582	}
4583
4584	ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
4585		   "dfs status event received from fw: %d\n",
4586		   status_arg.status);
4587
4588	/* Even in case of radar detection failure we follow the same
4589	 * behaviour as if radar is detected i.e to switch to a different
4590	 * channel.
4591	 */
4592	if (status_arg.status == WMI_HW_RADAR_DETECTED ||
4593	    status_arg.status == WMI_RADAR_DETECTION_FAIL)
4594		ath10k_radar_detected(ar);
4595	complete(&ar->wmi.radar_confirm);
4596}
4597
4598void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
4599{
4600	struct wmi_roam_ev_arg arg = {};
4601	int ret;
4602	u32 vdev_id;
4603	u32 reason;
4604	s32 rssi;
4605
4606	ret = ath10k_wmi_pull_roam_ev(ar, skb, &arg);
4607	if (ret) {
4608		ath10k_warn(ar, "failed to parse roam event: %d\n", ret);
4609		return;
4610	}
4611
4612	vdev_id = __le32_to_cpu(arg.vdev_id);
4613	reason = __le32_to_cpu(arg.reason);
4614	rssi = __le32_to_cpu(arg.rssi);
4615	rssi += WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT;
4616
4617	ath10k_dbg(ar, ATH10K_DBG_WMI,
4618		   "wmi roam event vdev %u reason 0x%08x rssi %d\n",
4619		   vdev_id, reason, rssi);
4620
4621	if (reason >= WMI_ROAM_REASON_MAX)
4622		ath10k_warn(ar, "ignoring unknown roam event reason %d on vdev %i\n",
4623			    reason, vdev_id);
4624
4625	switch (reason) {
4626	case WMI_ROAM_REASON_BEACON_MISS:
4627		ath10k_mac_handle_beacon_miss(ar, vdev_id);
4628		break;
4629	case WMI_ROAM_REASON_BETTER_AP:
4630	case WMI_ROAM_REASON_LOW_RSSI:
4631	case WMI_ROAM_REASON_SUITABLE_AP_FOUND:
4632	case WMI_ROAM_REASON_HO_FAILED:
4633		ath10k_warn(ar, "ignoring not implemented roam event reason %d on vdev %i\n",
4634			    reason, vdev_id);
4635		break;
4636	}
4637}
4638
4639void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb)
4640{
4641	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
4642}
4643
4644void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb)
4645{
4646	char buf[101], c;
4647	int i;
4648
4649	for (i = 0; i < sizeof(buf) - 1; i++) {
4650		if (i >= skb->len)
4651			break;
4652
4653		c = skb->data[i];
4654
4655		if (c == '\0')
4656			break;
4657
4658		if (isascii(c) && isprint(c))
4659			buf[i] = c;
4660		else
4661			buf[i] = '.';
4662	}
4663
4664	if (i == sizeof(buf) - 1)
4665		ath10k_warn(ar, "wmi debug print truncated: %d\n", skb->len);
4666
4667	/* for some reason the debug prints end with \n, remove that */
4668	if (skb->data[i - 1] == '\n')
4669		i--;
4670
4671	/* the last byte is always reserved for the null character */
4672	buf[i] = '\0';
4673
4674	ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf);
4675}
4676
4677void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
4678{
4679	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n");
4680}
4681
4682void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb)
4683{
4684	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n");
4685}
4686
4687void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
4688					     struct sk_buff *skb)
4689{
4690	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
4691}
4692
4693void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
4694					     struct sk_buff *skb)
4695{
4696	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
4697}
4698
4699void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb)
4700{
4701	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n");
4702}
4703
4704void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb)
4705{
4706	struct wmi_wow_ev_arg ev = {};
4707	int ret;
4708
4709	complete(&ar->wow.wakeup_completed);
4710
4711	ret = ath10k_wmi_pull_wow_event(ar, skb, &ev);
4712	if (ret) {
4713		ath10k_warn(ar, "failed to parse wow wakeup event: %d\n", ret);
4714		return;
4715	}
4716
4717	ath10k_dbg(ar, ATH10K_DBG_WMI, "wow wakeup host reason %s\n",
4718		   wow_reason(ev.wake_reason));
4719}
4720
4721void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb)
4722{
4723	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n");
4724}
4725
4726static u8 ath10k_tpc_config_get_rate(struct ath10k *ar,
4727				     struct wmi_pdev_tpc_config_event *ev,
4728				     u32 rate_idx, u32 num_chains,
4729				     u32 rate_code, u8 type)
4730{
4731	u8 tpc, num_streams, preamble, ch, stm_idx;
4732
4733	num_streams = ATH10K_HW_NSS(rate_code);
4734	preamble = ATH10K_HW_PREAMBLE(rate_code);
4735	ch = num_chains - 1;
4736
4737	tpc = min_t(u8, ev->rates_array[rate_idx], ev->max_reg_allow_pow[ch]);
4738
4739	if (__le32_to_cpu(ev->num_tx_chain) <= 1)
4740		goto out;
4741
4742	if (preamble == WMI_RATE_PREAMBLE_CCK)
4743		goto out;
4744
4745	stm_idx = num_streams - 1;
4746	if (num_chains <= num_streams)
4747		goto out;
4748
4749	switch (type) {
4750	case WMI_TPC_TABLE_TYPE_STBC:
4751		tpc = min_t(u8, tpc,
4752			    ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx]);
4753		break;
4754	case WMI_TPC_TABLE_TYPE_TXBF:
4755		tpc = min_t(u8, tpc,
4756			    ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx]);
4757		break;
4758	case WMI_TPC_TABLE_TYPE_CDD:
4759		tpc = min_t(u8, tpc,
4760			    ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx]);
4761		break;
4762	default:
4763		ath10k_warn(ar, "unknown wmi tpc table type: %d\n", type);
4764		tpc = 0;
4765		break;
4766	}
4767
4768out:
4769	return tpc;
4770}
4771
4772static void ath10k_tpc_config_disp_tables(struct ath10k *ar,
4773					  struct wmi_pdev_tpc_config_event *ev,
4774					  struct ath10k_tpc_stats *tpc_stats,
4775					  u8 *rate_code, u16 *pream_table, u8 type)
4776{
4777	u32 i, j, pream_idx, flags;
4778	u8 tpc[WMI_TPC_TX_N_CHAIN];
4779	char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
4780	char buff[WMI_TPC_BUF_SIZE];
4781
4782	flags = __le32_to_cpu(ev->flags);
4783
4784	switch (type) {
4785	case WMI_TPC_TABLE_TYPE_CDD:
4786		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
4787			ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
4788			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4789			return;
4790		}
4791		break;
4792	case WMI_TPC_TABLE_TYPE_STBC:
4793		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
4794			ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
4795			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4796			return;
4797		}
4798		break;
4799	case WMI_TPC_TABLE_TYPE_TXBF:
4800		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
4801			ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
4802			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4803			return;
4804		}
4805		break;
4806	default:
4807		ath10k_dbg(ar, ATH10K_DBG_WMI,
4808			   "invalid table type in wmi tpc event: %d\n", type);
4809		return;
4810	}
4811
4812	pream_idx = 0;
4813	for (i = 0; i < tpc_stats->rate_max; i++) {
4814		memset(tpc_value, 0, sizeof(tpc_value));
4815		memset(buff, 0, sizeof(buff));
4816		if (i == pream_table[pream_idx])
4817			pream_idx++;
4818
4819		for (j = 0; j < tpc_stats->num_tx_chain; j++) {
4820			tpc[j] = ath10k_tpc_config_get_rate(ar, ev, i, j + 1,
4821							    rate_code[i],
4822							    type);
4823			snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
4824			strlcat(tpc_value, buff, sizeof(tpc_value));
4825		}
4826		tpc_stats->tpc_table[type].pream_idx[i] = pream_idx;
4827		tpc_stats->tpc_table[type].rate_code[i] = rate_code[i];
4828		memcpy(tpc_stats->tpc_table[type].tpc_value[i],
4829		       tpc_value, sizeof(tpc_value));
4830	}
4831}
4832
4833void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
4834					 u32 num_tx_chain)
4835{
4836	u32 i, j, pream_idx;
4837	u8 rate_idx;
4838
4839	/* Create the rate code table based on the chains supported */
4840	rate_idx = 0;
4841	pream_idx = 0;
4842
4843	/* Fill CCK rate code */
4844	for (i = 0; i < 4; i++) {
4845		rate_code[rate_idx] =
4846			ATH10K_HW_RATECODE(i, 0, WMI_RATE_PREAMBLE_CCK);
4847		rate_idx++;
4848	}
4849	pream_table[pream_idx] = rate_idx;
4850	pream_idx++;
4851
4852	/* Fill OFDM rate code */
4853	for (i = 0; i < 8; i++) {
4854		rate_code[rate_idx] =
4855			ATH10K_HW_RATECODE(i, 0, WMI_RATE_PREAMBLE_OFDM);
4856		rate_idx++;
4857	}
4858	pream_table[pream_idx] = rate_idx;
4859	pream_idx++;
4860
4861	/* Fill HT20 rate code */
4862	for (i = 0; i < num_tx_chain; i++) {
4863		for (j = 0; j < 8; j++) {
4864			rate_code[rate_idx] =
4865			ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_HT);
4866			rate_idx++;
4867		}
4868	}
4869	pream_table[pream_idx] = rate_idx;
4870	pream_idx++;
4871
4872	/* Fill HT40 rate code */
4873	for (i = 0; i < num_tx_chain; i++) {
4874		for (j = 0; j < 8; j++) {
4875			rate_code[rate_idx] =
4876			ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_HT);
4877			rate_idx++;
4878		}
4879	}
4880	pream_table[pream_idx] = rate_idx;
4881	pream_idx++;
4882
4883	/* Fill VHT20 rate code */
4884	for (i = 0; i < num_tx_chain; i++) {
4885		for (j = 0; j < 10; j++) {
4886			rate_code[rate_idx] =
4887			ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
4888			rate_idx++;
4889		}
4890	}
4891	pream_table[pream_idx] = rate_idx;
4892	pream_idx++;
4893
4894	/* Fill VHT40 rate code */
4895	for (i = 0; i < num_tx_chain; i++) {
4896		for (j = 0; j < 10; j++) {
4897			rate_code[rate_idx] =
4898			ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
4899			rate_idx++;
4900		}
4901	}
4902	pream_table[pream_idx] = rate_idx;
4903	pream_idx++;
4904
4905	/* Fill VHT80 rate code */
4906	for (i = 0; i < num_tx_chain; i++) {
4907		for (j = 0; j < 10; j++) {
4908			rate_code[rate_idx] =
4909			ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
4910			rate_idx++;
4911		}
4912	}
4913	pream_table[pream_idx] = rate_idx;
4914	pream_idx++;
4915
4916	rate_code[rate_idx++] =
4917		ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_CCK);
4918	rate_code[rate_idx++] =
4919		ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
4920	rate_code[rate_idx++] =
4921		ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_CCK);
4922	rate_code[rate_idx++] =
4923		ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
4924	rate_code[rate_idx++] =
4925		ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
4926
4927	pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END;
4928}
4929
4930void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4931{
4932	u32 num_tx_chain, rate_max;
4933	u8 rate_code[WMI_TPC_RATE_MAX];
4934	u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
4935	struct wmi_pdev_tpc_config_event *ev;
4936	struct ath10k_tpc_stats *tpc_stats;
4937
4938	ev = (struct wmi_pdev_tpc_config_event *)skb->data;
4939
4940	num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
4941
4942	if (num_tx_chain > WMI_TPC_TX_N_CHAIN) {
4943		ath10k_warn(ar, "number of tx chain is %d greater than TPC configured tx chain %d\n",
4944			    num_tx_chain, WMI_TPC_TX_N_CHAIN);
4945		return;
4946	}
4947
4948	rate_max = __le32_to_cpu(ev->rate_max);
4949	if (rate_max > WMI_TPC_RATE_MAX) {
4950		ath10k_warn(ar, "number of rate is %d greater than TPC configured rate %d\n",
4951			    rate_max, WMI_TPC_RATE_MAX);
4952		rate_max = WMI_TPC_RATE_MAX;
4953	}
4954
4955	tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
4956	if (!tpc_stats)
4957		return;
4958
4959	ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
4960					    num_tx_chain);
4961
4962	tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
4963	tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
4964	tpc_stats->ctl = __le32_to_cpu(ev->ctl);
4965	tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
4966	tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
4967	tpc_stats->twice_antenna_reduction =
4968		__le32_to_cpu(ev->twice_antenna_reduction);
4969	tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
4970	tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
4971	tpc_stats->num_tx_chain = num_tx_chain;
4972	tpc_stats->rate_max = rate_max;
4973
4974	ath10k_tpc_config_disp_tables(ar, ev, tpc_stats,
4975				      rate_code, pream_table,
4976				      WMI_TPC_TABLE_TYPE_CDD);
4977	ath10k_tpc_config_disp_tables(ar, ev,  tpc_stats,
4978				      rate_code, pream_table,
4979				      WMI_TPC_TABLE_TYPE_STBC);
4980	ath10k_tpc_config_disp_tables(ar, ev, tpc_stats,
4981				      rate_code, pream_table,
4982				      WMI_TPC_TABLE_TYPE_TXBF);
4983
4984	ath10k_debug_tpc_stats_process(ar, tpc_stats);
4985
4986	ath10k_dbg(ar, ATH10K_DBG_WMI,
4987		   "wmi event tpc config channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
4988		   __le32_to_cpu(ev->chan_freq),
4989		   __le32_to_cpu(ev->phy_mode),
4990		   __le32_to_cpu(ev->ctl),
4991		   __le32_to_cpu(ev->reg_domain),
4992		   a_sle32_to_cpu(ev->twice_antenna_gain),
4993		   __le32_to_cpu(ev->twice_antenna_reduction),
4994		   __le32_to_cpu(ev->power_limit),
4995		   __le32_to_cpu(ev->twice_max_rd_power) / 2,
4996		   __le32_to_cpu(ev->num_tx_chain),
4997		   __le32_to_cpu(ev->rate_max));
4998}
4999
5000static u8
5001ath10k_wmi_tpc_final_get_rate(struct ath10k *ar,
5002			      struct wmi_pdev_tpc_final_table_event *ev,
5003			      u32 rate_idx, u32 num_chains,
5004			      u32 rate_code, u8 type, u32 pream_idx)
5005{
5006	u8 tpc, num_streams, preamble, ch, stm_idx;
5007	s8 pow_agcdd, pow_agstbc, pow_agtxbf;
5008	int pream;
5009
5010	num_streams = ATH10K_HW_NSS(rate_code);
5011	preamble = ATH10K_HW_PREAMBLE(rate_code);
5012	ch = num_chains - 1;
5013	stm_idx = num_streams - 1;
5014	pream = -1;
5015
5016	if (__le32_to_cpu(ev->chan_freq) <= 2483) {
5017		switch (pream_idx) {
5018		case WMI_TPC_PREAM_2GHZ_CCK:
5019			pream = 0;
5020			break;
5021		case WMI_TPC_PREAM_2GHZ_OFDM:
5022			pream = 1;
5023			break;
5024		case WMI_TPC_PREAM_2GHZ_HT20:
5025		case WMI_TPC_PREAM_2GHZ_VHT20:
5026			pream = 2;
5027			break;
5028		case WMI_TPC_PREAM_2GHZ_HT40:
5029		case WMI_TPC_PREAM_2GHZ_VHT40:
5030			pream = 3;
5031			break;
5032		case WMI_TPC_PREAM_2GHZ_VHT80:
5033			pream = 4;
5034			break;
5035		default:
5036			pream = -1;
5037			break;
5038		}
5039	}
5040
5041	if (__le32_to_cpu(ev->chan_freq) >= 5180) {
5042		switch (pream_idx) {
5043		case WMI_TPC_PREAM_5GHZ_OFDM:
5044			pream = 0;
5045			break;
5046		case WMI_TPC_PREAM_5GHZ_HT20:
5047		case WMI_TPC_PREAM_5GHZ_VHT20:
5048			pream = 1;
5049			break;
5050		case WMI_TPC_PREAM_5GHZ_HT40:
5051		case WMI_TPC_PREAM_5GHZ_VHT40:
5052			pream = 2;
5053			break;
5054		case WMI_TPC_PREAM_5GHZ_VHT80:
5055			pream = 3;
5056			break;
5057		case WMI_TPC_PREAM_5GHZ_HTCUP:
5058			pream = 4;
5059			break;
5060		default:
5061			pream = -1;
5062			break;
5063		}
5064	}
5065
5066	if (pream == -1) {
5067		ath10k_warn(ar, "unknown wmi tpc final index and frequency: %u, %u\n",
5068			    pream_idx, __le32_to_cpu(ev->chan_freq));
5069		tpc = 0;
5070		goto out;
5071	}
5072
5073	if (pream == 4)
5074		tpc = min_t(u8, ev->rates_array[rate_idx],
5075			    ev->max_reg_allow_pow[ch]);
5076	else
5077		tpc = min_t(u8, min_t(u8, ev->rates_array[rate_idx],
5078				      ev->max_reg_allow_pow[ch]),
5079			    ev->ctl_power_table[0][pream][stm_idx]);
5080
5081	if (__le32_to_cpu(ev->num_tx_chain) <= 1)
5082		goto out;
5083
5084	if (preamble == WMI_RATE_PREAMBLE_CCK)
5085		goto out;
5086
5087	if (num_chains <= num_streams)
5088		goto out;
5089
5090	switch (type) {
5091	case WMI_TPC_TABLE_TYPE_STBC:
5092		pow_agstbc = ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx];
5093		if (pream == 4)
5094			tpc = min_t(u8, tpc, pow_agstbc);
5095		else
5096			tpc = min_t(u8, min_t(u8, tpc, pow_agstbc),
5097				    ev->ctl_power_table[0][pream][stm_idx]);
5098		break;
5099	case WMI_TPC_TABLE_TYPE_TXBF:
5100		pow_agtxbf = ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx];
5101		if (pream == 4)
5102			tpc = min_t(u8, tpc, pow_agtxbf);
5103		else
5104			tpc = min_t(u8, min_t(u8, tpc, pow_agtxbf),
5105				    ev->ctl_power_table[1][pream][stm_idx]);
5106		break;
5107	case WMI_TPC_TABLE_TYPE_CDD:
5108		pow_agcdd = ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx];
5109		if (pream == 4)
5110			tpc = min_t(u8, tpc, pow_agcdd);
5111		else
5112			tpc = min_t(u8, min_t(u8, tpc, pow_agcdd),
5113				    ev->ctl_power_table[0][pream][stm_idx]);
5114		break;
5115	default:
5116		ath10k_warn(ar, "unknown wmi tpc final table type: %d\n", type);
5117		tpc = 0;
5118		break;
5119	}
5120
5121out:
5122	return tpc;
5123}
5124
5125static void
5126ath10k_wmi_tpc_stats_final_disp_tables(struct ath10k *ar,
5127				       struct wmi_pdev_tpc_final_table_event *ev,
5128				       struct ath10k_tpc_stats_final *tpc_stats,
5129				       u8 *rate_code, u16 *pream_table, u8 type)
5130{
5131	u32 i, j, pream_idx, flags;
5132	u8 tpc[WMI_TPC_TX_N_CHAIN];
5133	char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
5134	char buff[WMI_TPC_BUF_SIZE];
5135
5136	flags = __le32_to_cpu(ev->flags);
5137
5138	switch (type) {
5139	case WMI_TPC_TABLE_TYPE_CDD:
5140		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
5141			ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
5142			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
5143			return;
5144		}
5145		break;
5146	case WMI_TPC_TABLE_TYPE_STBC:
5147		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
5148			ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
5149			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
5150			return;
5151		}
5152		break;
5153	case WMI_TPC_TABLE_TYPE_TXBF:
5154		if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
5155			ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
5156			tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
5157			return;
5158		}
5159		break;
5160	default:
5161		ath10k_dbg(ar, ATH10K_DBG_WMI,
5162			   "invalid table type in wmi tpc event: %d\n", type);
5163		return;
5164	}
5165
5166	pream_idx = 0;
5167	for (i = 0; i < tpc_stats->rate_max; i++) {
5168		memset(tpc_value, 0, sizeof(tpc_value));
5169		memset(buff, 0, sizeof(buff));
5170		if (i == pream_table[pream_idx])
5171			pream_idx++;
5172
5173		for (j = 0; j < tpc_stats->num_tx_chain; j++) {
5174			tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1,
5175							       rate_code[i],
5176							       type, pream_idx);
5177			snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
5178			strlcat(tpc_value, buff, sizeof(tpc_value));
5179		}
5180		tpc_stats->tpc_table_final[type].pream_idx[i] = pream_idx;
5181		tpc_stats->tpc_table_final[type].rate_code[i] = rate_code[i];
5182		memcpy(tpc_stats->tpc_table_final[type].tpc_value[i],
5183		       tpc_value, sizeof(tpc_value));
5184	}
5185}
5186
5187void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb)
5188{
5189	u32 num_tx_chain, rate_max;
5190	u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
5191	u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
5192	struct wmi_pdev_tpc_final_table_event *ev;
5193	struct ath10k_tpc_stats_final *tpc_stats;
5194
5195	ev = (struct wmi_pdev_tpc_final_table_event *)skb->data;
5196
5197	num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
5198	if (num_tx_chain > WMI_TPC_TX_N_CHAIN) {
5199		ath10k_warn(ar, "number of tx chain is %d greater than TPC final configured tx chain %d\n",
5200			    num_tx_chain, WMI_TPC_TX_N_CHAIN);
5201		return;
5202	}
5203
5204	rate_max = __le32_to_cpu(ev->rate_max);
5205	if (rate_max > WMI_TPC_FINAL_RATE_MAX) {
5206		ath10k_warn(ar, "number of rate is %d greater than TPC final configured rate %d\n",
5207			    rate_max, WMI_TPC_FINAL_RATE_MAX);
5208		rate_max = WMI_TPC_FINAL_RATE_MAX;
5209	}
5210
5211	tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
5212	if (!tpc_stats)
5213		return;
5214
5215	ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
5216					    num_tx_chain);
5217
5218	tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
5219	tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
5220	tpc_stats->ctl = __le32_to_cpu(ev->ctl);
5221	tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
5222	tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
5223	tpc_stats->twice_antenna_reduction =
5224		__le32_to_cpu(ev->twice_antenna_reduction);
5225	tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
5226	tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
5227	tpc_stats->num_tx_chain = num_tx_chain;
5228	tpc_stats->rate_max = rate_max;
5229
5230	ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
5231					       rate_code, pream_table,
5232					       WMI_TPC_TABLE_TYPE_CDD);
5233	ath10k_wmi_tpc_stats_final_disp_tables(ar, ev,  tpc_stats,
5234					       rate_code, pream_table,
5235					       WMI_TPC_TABLE_TYPE_STBC);
5236	ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
5237					       rate_code, pream_table,
5238					       WMI_TPC_TABLE_TYPE_TXBF);
5239
5240	ath10k_debug_tpc_stats_final_process(ar, tpc_stats);
5241
5242	ath10k_dbg(ar, ATH10K_DBG_WMI,
5243		   "wmi event tpc final table channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
5244		   __le32_to_cpu(ev->chan_freq),
5245		   __le32_to_cpu(ev->phy_mode),
5246		   __le32_to_cpu(ev->ctl),
5247		   __le32_to_cpu(ev->reg_domain),
5248		   a_sle32_to_cpu(ev->twice_antenna_gain),
5249		   __le32_to_cpu(ev->twice_antenna_reduction),
5250		   __le32_to_cpu(ev->power_limit),
5251		   __le32_to_cpu(ev->twice_max_rd_power) / 2,
5252		   __le32_to_cpu(ev->num_tx_chain),
5253		   __le32_to_cpu(ev->rate_max));
5254}
5255
5256static void
5257ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb)
5258{
5259	struct wmi_tdls_peer_event *ev;
5260	struct ath10k_peer *peer;
5261	struct ath10k_vif *arvif;
5262	int vdev_id;
5263	int peer_status;
5264	int peer_reason;
5265	u8 reason;
5266
5267	if (skb->len < sizeof(*ev)) {
5268		ath10k_err(ar, "received tdls peer event with invalid size (%d bytes)\n",
5269			   skb->len);
5270		return;
5271	}
5272
5273	ev = (struct wmi_tdls_peer_event *)skb->data;
5274	vdev_id = __le32_to_cpu(ev->vdev_id);
5275	peer_status = __le32_to_cpu(ev->peer_status);
5276	peer_reason = __le32_to_cpu(ev->peer_reason);
5277
5278	spin_lock_bh(&ar->data_lock);
5279	peer = ath10k_peer_find(ar, vdev_id, ev->peer_macaddr.addr);
5280	spin_unlock_bh(&ar->data_lock);
5281
5282	if (!peer) {
5283		ath10k_warn(ar, "failed to find peer entry for %pM\n",
5284			    ev->peer_macaddr.addr);
5285		return;
5286	}
5287
5288	switch (peer_status) {
5289	case WMI_TDLS_SHOULD_TEARDOWN:
5290		switch (peer_reason) {
5291		case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
5292		case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
5293		case WMI_TDLS_TEARDOWN_REASON_RSSI:
5294			reason = WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE;
5295			break;
5296		default:
5297			reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
5298			break;
5299		}
5300
5301		arvif = ath10k_get_arvif(ar, vdev_id);
5302		if (!arvif) {
5303			ath10k_warn(ar, "received tdls peer event for invalid vdev id %u\n",
5304				    vdev_id);
5305			return;
5306		}
5307
5308		ieee80211_tdls_oper_request(arvif->vif, ev->peer_macaddr.addr,
5309					    NL80211_TDLS_TEARDOWN, reason,
5310					    GFP_ATOMIC);
5311
5312		ath10k_dbg(ar, ATH10K_DBG_WMI,
5313			   "received tdls teardown event for peer %pM reason %u\n",
5314			   ev->peer_macaddr.addr, peer_reason);
5315		break;
5316	default:
5317		ath10k_dbg(ar, ATH10K_DBG_WMI,
5318			   "received unknown tdls peer event %u\n",
5319			   peer_status);
5320		break;
5321	}
5322}
5323
5324static void
5325ath10k_wmi_event_peer_sta_ps_state_chg(struct ath10k *ar, struct sk_buff *skb)
5326{
5327	struct wmi_peer_sta_ps_state_chg_event *ev;
5328	struct ieee80211_sta *sta;
5329	struct ath10k_sta *arsta;
5330	u8 peer_addr[ETH_ALEN];
5331
5332	lockdep_assert_held(&ar->data_lock);
5333
5334	ev = (struct wmi_peer_sta_ps_state_chg_event *)skb->data;
5335	ether_addr_copy(peer_addr, ev->peer_macaddr.addr);
5336
5337	rcu_read_lock();
5338
5339	sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer_addr, NULL);
5340
5341	if (!sta) {
5342		ath10k_warn(ar, "failed to find station entry %pM\n",
5343			    peer_addr);
5344		goto exit;
5345	}
5346
5347	arsta = (struct ath10k_sta *)sta->drv_priv;
5348	arsta->peer_ps_state = __le32_to_cpu(ev->peer_ps_state);
5349
5350exit:
5351	rcu_read_unlock();
5352}
5353
5354void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb)
5355{
5356	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n");
5357}
5358
5359void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, struct sk_buff *skb)
5360{
5361	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
5362}
5363
5364void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb)
5365{
5366	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n");
5367}
5368
5369void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb)
5370{
5371	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n");
5372}
5373
5374void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb)
5375{
5376	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n");
5377}
5378
5379void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
5380						struct sk_buff *skb)
5381{
5382	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
5383}
5384
5385void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb)
5386{
5387	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n");
5388}
5389
5390void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb)
5391{
5392	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n");
5393}
5394
5395void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb)
5396{
5397	ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
5398}
5399
5400static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id,
5401				  u32 num_units, u32 unit_len)
5402{
5403	dma_addr_t paddr;
5404	u32 pool_size;
5405	int idx = ar->wmi.num_mem_chunks;
5406	void *vaddr;
5407
5408	pool_size = num_units * round_up(unit_len, 4);
5409	vaddr = dma_alloc_coherent(ar->dev, pool_size, &paddr, GFP_KERNEL);
5410
5411	if (!vaddr)
5412		return -ENOMEM;
5413
5414	ar->wmi.mem_chunks[idx].vaddr = vaddr;
5415	ar->wmi.mem_chunks[idx].paddr = paddr;
5416	ar->wmi.mem_chunks[idx].len = pool_size;
5417	ar->wmi.mem_chunks[idx].req_id = req_id;
5418	ar->wmi.num_mem_chunks++;
5419
5420	return num_units;
5421}
5422
5423static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
5424				     u32 num_units, u32 unit_len)
5425{
5426	int ret;
5427
5428	while (num_units) {
5429		ret = ath10k_wmi_alloc_chunk(ar, req_id, num_units, unit_len);
5430		if (ret < 0)
5431			return ret;
5432
5433		num_units -= ret;
5434	}
5435
5436	return 0;
5437}
5438
5439static bool
5440ath10k_wmi_is_host_mem_allocated(struct ath10k *ar,
5441				 const struct wlan_host_mem_req **mem_reqs,
5442				 u32 num_mem_reqs)
5443{
5444	u32 req_id, num_units, unit_size, num_unit_info;
5445	u32 pool_size;
5446	int i, j;
5447	bool found;
5448
5449	if (ar->wmi.num_mem_chunks != num_mem_reqs)
5450		return false;
5451
5452	for (i = 0; i < num_mem_reqs; ++i) {
5453		req_id = __le32_to_cpu(mem_reqs[i]->req_id);
5454		num_units = __le32_to_cpu(mem_reqs[i]->num_units);
5455		unit_size = __le32_to_cpu(mem_reqs[i]->unit_size);
5456		num_unit_info = __le32_to_cpu(mem_reqs[i]->num_unit_info);
5457
5458		if (num_unit_info & NUM_UNITS_IS_NUM_ACTIVE_PEERS) {
5459			if (ar->num_active_peers)
5460				num_units = ar->num_active_peers + 1;
5461			else
5462				num_units = ar->max_num_peers + 1;
5463		} else if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) {
5464			num_units = ar->max_num_peers + 1;
5465		} else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) {
5466			num_units = ar->max_num_vdevs + 1;
5467		}
5468
5469		found = false;
5470		for (j = 0; j < ar->wmi.num_mem_chunks; j++) {
5471			if (ar->wmi.mem_chunks[j].req_id == req_id) {
5472				pool_size = num_units * round_up(unit_size, 4);
5473				if (ar->wmi.mem_chunks[j].len == pool_size) {
5474					found = true;
5475					break;
5476				}
5477			}
5478		}
5479		if (!found)
5480			return false;
5481	}
5482
5483	return true;
5484}
5485
5486static int
5487ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
5488				   struct wmi_svc_rdy_ev_arg *arg)
5489{
5490	struct wmi_service_ready_event *ev;
5491	size_t i, n;
5492
5493	if (skb->len < sizeof(*ev))
5494		return -EPROTO;
5495
5496	ev = (void *)skb->data;
5497	skb_pull(skb, sizeof(*ev));
5498	arg->min_tx_power = ev->hw_min_tx_power;
5499	arg->max_tx_power = ev->hw_max_tx_power;
5500	arg->ht_cap = ev->ht_cap_info;
5501	arg->vht_cap = ev->vht_cap_info;
5502	arg->vht_supp_mcs = ev->vht_supp_mcs;
5503	arg->sw_ver0 = ev->sw_version;
5504	arg->sw_ver1 = ev->sw_version_1;
5505	arg->phy_capab = ev->phy_capability;
5506	arg->num_rf_chains = ev->num_rf_chains;
5507	arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
5508	arg->low_2ghz_chan = ev->hal_reg_capabilities.low_2ghz_chan;
5509	arg->high_2ghz_chan = ev->hal_reg_capabilities.high_2ghz_chan;
5510	arg->low_5ghz_chan = ev->hal_reg_capabilities.low_5ghz_chan;
5511	arg->high_5ghz_chan = ev->hal_reg_capabilities.high_5ghz_chan;
5512	arg->num_mem_reqs = ev->num_mem_reqs;
5513	arg->service_map = ev->wmi_service_bitmap;
5514	arg->service_map_len = sizeof(ev->wmi_service_bitmap);
5515
5516	n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
5517		  ARRAY_SIZE(arg->mem_reqs));
5518	for (i = 0; i < n; i++)
5519		arg->mem_reqs[i] = &ev->mem_reqs[i];
5520
5521	if (skb->len <
5522	    __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
5523		return -EPROTO;
5524
5525	return 0;
5526}
5527
5528static int
5529ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
5530				  struct wmi_svc_rdy_ev_arg *arg)
5531{
5532	struct wmi_10x_service_ready_event *ev;
5533	int i, n;
5534
5535	if (skb->len < sizeof(*ev))
5536		return -EPROTO;
5537
5538	ev = (void *)skb->data;
5539	skb_pull(skb, sizeof(*ev));
5540	arg->min_tx_power = ev->hw_min_tx_power;
5541	arg->max_tx_power = ev->hw_max_tx_power;
5542	arg->ht_cap = ev->ht_cap_info;
5543	arg->vht_cap = ev->vht_cap_info;
5544	arg->vht_supp_mcs = ev->vht_supp_mcs;
5545	arg->sw_ver0 = ev->sw_version;
5546	arg->phy_capab = ev->phy_capability;
5547	arg->num_rf_chains = ev->num_rf_chains;
5548	arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
5549	arg->low_2ghz_chan = ev->hal_reg_capabilities.low_2ghz_chan;
5550	arg->high_2ghz_chan = ev->hal_reg_capabilities.high_2ghz_chan;
5551	arg->low_5ghz_chan = ev->hal_reg_capabilities.low_5ghz_chan;
5552	arg->high_5ghz_chan = ev->hal_reg_capabilities.high_5ghz_chan;
5553	arg->num_mem_reqs = ev->num_mem_reqs;
5554	arg->service_map = ev->wmi_service_bitmap;
5555	arg->service_map_len = sizeof(ev->wmi_service_bitmap);
5556
5557	/* Deliberately skipping ev->sys_cap_info as WMI and WMI-TLV have
5558	 * different values. We would need a translation to handle that,
5559	 * but as we don't currently need anything from sys_cap_info from
5560	 * WMI interface (only from WMI-TLV) safest it to skip it.
5561	 */
5562
5563	n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
5564		  ARRAY_SIZE(arg->mem_reqs));
5565	for (i = 0; i < n; i++)
5566		arg->mem_reqs[i] = &ev->mem_reqs[i];
5567
5568	if (skb->len <
5569	    __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
5570		return -EPROTO;
5571
5572	return 0;
5573}
5574
5575static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
5576{
5577	struct ath10k *ar = container_of(work, struct ath10k, svc_rdy_work);
5578	struct sk_buff *skb = ar->svc_rdy_skb;
5579	struct wmi_svc_rdy_ev_arg arg = {};
5580	u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
5581	int ret;
5582	bool allocated;
5583
5584	if (!skb) {
5585		ath10k_warn(ar, "invalid service ready event skb\n");
5586		return;
5587	}
5588
5589	ret = ath10k_wmi_pull_svc_rdy(ar, skb, &arg);
5590	if (ret) {
5591		ath10k_warn(ar, "failed to parse service ready: %d\n", ret);
5592		return;
5593	}
5594
5595	ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map,
5596			   arg.service_map_len);
5597
5598	ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power);
5599	ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power);
5600	ar->ht_cap_info = __le32_to_cpu(arg.ht_cap);
5601	ar->vht_cap_info = __le32_to_cpu(arg.vht_cap);
5602	ar->vht_supp_mcs = __le32_to_cpu(arg.vht_supp_mcs);
5603	ar->fw_version_major =
5604		(__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24;
5605	ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff);
5606	ar->fw_version_release =
5607		(__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16;
5608	ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff);
5609	ar->phy_capability = __le32_to_cpu(arg.phy_capab);
5610	ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains);
5611	ar->hw_eeprom_rd = __le32_to_cpu(arg.eeprom_rd);
5612	ar->low_2ghz_chan = __le32_to_cpu(arg.low_2ghz_chan);
5613	ar->high_2ghz_chan = __le32_to_cpu(arg.high_2ghz_chan);
5614	ar->low_5ghz_chan = __le32_to_cpu(arg.low_5ghz_chan);
5615	ar->high_5ghz_chan = __le32_to_cpu(arg.high_5ghz_chan);
5616	ar->sys_cap_info = __le32_to_cpu(arg.sys_cap_info);
5617
5618	ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
5619			arg.service_map, arg.service_map_len);
5620	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sys_cap_info 0x%x\n",
5621		   ar->sys_cap_info);
5622
5623	if (ar->num_rf_chains > ar->max_spatial_stream) {
5624		ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n",
5625			    ar->num_rf_chains, ar->max_spatial_stream);
5626		ar->num_rf_chains = ar->max_spatial_stream;
5627	}
5628
5629	if (!ar->cfg_tx_chainmask) {
5630		ar->cfg_tx_chainmask = (1 << ar->num_rf_chains) - 1;
5631		ar->cfg_rx_chainmask = (1 << ar->num_rf_chains) - 1;
5632	}
5633
5634	if (strlen(ar->hw->wiphy->fw_version) == 0) {
5635		snprintf(ar->hw->wiphy->fw_version,
5636			 sizeof(ar->hw->wiphy->fw_version),
5637			 "%u.%u.%u.%u",
5638			 ar->fw_version_major,
5639			 ar->fw_version_minor,
5640			 ar->fw_version_release,
5641			 ar->fw_version_build);
5642	}
5643
5644	num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs);
5645	if (num_mem_reqs > WMI_MAX_MEM_REQS) {
5646		ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n",
5647			    num_mem_reqs);
5648		return;
5649	}
5650
5651	if (test_bit(WMI_SERVICE_PEER_CACHING, ar->wmi.svc_map)) {
5652		if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
5653			     ar->running_fw->fw_file.fw_features))
5654			ar->num_active_peers = TARGET_10_4_QCACHE_ACTIVE_PEERS_PFC +
5655					       ar->max_num_vdevs;
5656		else
5657			ar->num_active_peers = TARGET_10_4_QCACHE_ACTIVE_PEERS +
5658					       ar->max_num_vdevs;
5659
5660		ar->max_num_peers = TARGET_10_4_NUM_QCACHE_PEERS_MAX +
5661				    ar->max_num_vdevs;
5662		ar->num_tids = ar->num_active_peers * 2;
5663		ar->max_num_stations = TARGET_10_4_NUM_QCACHE_PEERS_MAX;
5664	}
5665
5666	/* TODO: Adjust max peer count for cases like WMI_SERVICE_RATECTRL_CACHE
5667	 * and WMI_SERVICE_IRAM_TIDS, etc.
5668	 */
5669
5670	allocated = ath10k_wmi_is_host_mem_allocated(ar, arg.mem_reqs,
5671						     num_mem_reqs);
5672	if (allocated)
5673		goto skip_mem_alloc;
5674
5675	/* Either this event is received during boot time or there is a change
5676	 * in memory requirement from firmware when compared to last request.
5677	 * Free any old memory and do a fresh allocation based on the current
5678	 * memory requirement.
5679	 */
5680	ath10k_wmi_free_host_mem(ar);
5681
5682	for (i = 0; i < num_mem_reqs; ++i) {
5683		req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id);
5684		num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units);
5685		unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size);
5686		num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info);
5687
5688		if (num_unit_info & NUM_UNITS_IS_NUM_ACTIVE_PEERS) {
5689			if (ar->num_active_peers)
5690				num_units = ar->num_active_peers + 1;
5691			else
5692				num_units = ar->max_num_peers + 1;
5693		} else if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) {
5694			/* number of units to allocate is number of
5695			 * peers, 1 extra for self peer on target
5696			 * this needs to be tied, host and target
5697			 * can get out of sync
5698			 */
5699			num_units = ar->max_num_peers + 1;
5700		} else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) {
5701			num_units = ar->max_num_vdevs + 1;
5702		}
5703
5704		ath10k_dbg(ar, ATH10K_DBG_WMI,
5705			   "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n",
5706			   req_id,
5707			   __le32_to_cpu(arg.mem_reqs[i]->num_units),
5708			   num_unit_info,
5709			   unit_size,
5710			   num_units);
5711
5712		ret = ath10k_wmi_alloc_host_mem(ar, req_id, num_units,
5713						unit_size);
5714		if (ret)
5715			return;
5716	}
5717
5718skip_mem_alloc:
5719	ath10k_dbg(ar, ATH10K_DBG_WMI,
5720		   "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_mcs 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x fw_build 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x low_2ghz_chan %d high_2ghz_chan %d low_5ghz_chan %d high_5ghz_chan %d num_mem_reqs 0x%08x\n",
5721		   __le32_to_cpu(arg.min_tx_power),
5722		   __le32_to_cpu(arg.max_tx_power),
5723		   __le32_to_cpu(arg.ht_cap),
5724		   __le32_to_cpu(arg.vht_cap),
5725		   __le32_to_cpu(arg.vht_supp_mcs),
5726		   __le32_to_cpu(arg.sw_ver0),
5727		   __le32_to_cpu(arg.sw_ver1),
5728		   __le32_to_cpu(arg.fw_build),
5729		   __le32_to_cpu(arg.phy_capab),
5730		   __le32_to_cpu(arg.num_rf_chains),
5731		   __le32_to_cpu(arg.eeprom_rd),
5732		   __le32_to_cpu(arg.low_2ghz_chan),
5733		   __le32_to_cpu(arg.high_2ghz_chan),
5734		   __le32_to_cpu(arg.low_5ghz_chan),
5735		   __le32_to_cpu(arg.high_5ghz_chan),
5736		   __le32_to_cpu(arg.num_mem_reqs));
5737
5738	dev_kfree_skb(skb);
5739	ar->svc_rdy_skb = NULL;
5740	complete(&ar->wmi.service_ready);
5741}
5742
5743void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb)
5744{
5745	ar->svc_rdy_skb = skb;
5746	queue_work(ar->workqueue_aux, &ar->svc_rdy_work);
5747}
5748
5749static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
5750				     struct wmi_rdy_ev_arg *arg)
5751{
5752	struct wmi_ready_event *ev = (void *)skb->data;
5753
5754	if (skb->len < sizeof(*ev))
5755		return -EPROTO;
5756
5757	skb_pull(skb, sizeof(*ev));
5758	arg->sw_version = ev->sw_version;
5759	arg->abi_version = ev->abi_version;
5760	arg->status = ev->status;
5761	arg->mac_addr = ev->mac_addr.addr;
5762
5763	return 0;
5764}
5765
5766static int ath10k_wmi_op_pull_roam_ev(struct ath10k *ar, struct sk_buff *skb,
5767				      struct wmi_roam_ev_arg *arg)
5768{
5769	struct wmi_roam_ev *ev = (void *)skb->data;
5770
5771	if (skb->len < sizeof(*ev))
5772		return -EPROTO;
5773
5774	skb_pull(skb, sizeof(*ev));
5775	arg->vdev_id = ev->vdev_id;
5776	arg->reason = ev->reason;
5777
5778	return 0;
5779}
5780
5781static int ath10k_wmi_op_pull_echo_ev(struct ath10k *ar,
5782				      struct sk_buff *skb,
5783				      struct wmi_echo_ev_arg *arg)
5784{
5785	struct wmi_echo_event *ev = (void *)skb->data;
5786
5787	arg->value = ev->value;
5788
5789	return 0;
5790}
5791
5792int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
5793{
5794	struct wmi_rdy_ev_arg arg = {};
5795	int ret;
5796
5797	ret = ath10k_wmi_pull_rdy(ar, skb, &arg);
5798	if (ret) {
5799		ath10k_warn(ar, "failed to parse ready event: %d\n", ret);
5800		return ret;
5801	}
5802
5803	ath10k_dbg(ar, ATH10K_DBG_WMI,
5804		   "wmi event ready sw_version 0x%08x abi_version %u mac_addr %pM status %d\n",
5805		   __le32_to_cpu(arg.sw_version),
5806		   __le32_to_cpu(arg.abi_version),
5807		   arg.mac_addr,
5808		   __le32_to_cpu(arg.status));
5809
5810	if (is_zero_ether_addr(ar->mac_addr))
5811		ether_addr_copy(ar->mac_addr, arg.mac_addr);
5812	complete(&ar->wmi.unified_ready);
5813	return 0;
5814}
5815
5816void ath10k_wmi_event_service_available(struct ath10k *ar, struct sk_buff *skb)
5817{
5818	int ret;
5819	struct wmi_svc_avail_ev_arg arg = {};
5820
5821	ret = ath10k_wmi_pull_svc_avail(ar, skb, &arg);
5822	if (ret) {
5823		ath10k_warn(ar, "failed to parse service available event: %d\n",
5824			    ret);
5825	}
5826
5827	/*
5828	 * Initialization of "arg.service_map_ext_valid" to ZERO is necessary
5829	 * for the below logic to work.
5830	 */
5831	if (arg.service_map_ext_valid)
5832		ath10k_wmi_map_svc_ext(ar, arg.service_map_ext, ar->wmi.svc_map,
5833				       __le32_to_cpu(arg.service_map_ext_len));
5834}
5835
5836static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
5837{
5838	const struct wmi_pdev_temperature_event *ev;
5839
5840	ev = (struct wmi_pdev_temperature_event *)skb->data;
5841	if (WARN_ON(skb->len < sizeof(*ev)))
5842		return -EPROTO;
5843
5844	ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
5845	return 0;
5846}
5847
5848static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
5849					       struct sk_buff *skb)
5850{
5851	struct wmi_pdev_bss_chan_info_event *ev;
5852	struct survey_info *survey;
5853	u64 busy, total, tx, rx, rx_bss;
5854	u32 freq, noise_floor;
5855	u32 cc_freq_hz = ar->hw_params.channel_counters_freq_hz;
5856	int idx;
5857
5858	ev = (struct wmi_pdev_bss_chan_info_event *)skb->data;
5859	if (WARN_ON(skb->len < sizeof(*ev)))
5860		return -EPROTO;
5861
5862	freq        = __le32_to_cpu(ev->freq);
5863	noise_floor = __le32_to_cpu(ev->noise_floor);
5864	busy        = __le64_to_cpu(ev->cycle_busy);
5865	total       = __le64_to_cpu(ev->cycle_total);
5866	tx          = __le64_to_cpu(ev->cycle_tx);
5867	rx          = __le64_to_cpu(ev->cycle_rx);
5868	rx_bss      = __le64_to_cpu(ev->cycle_rx_bss);
5869
5870	ath10k_dbg(ar, ATH10K_DBG_WMI,
5871#if defined(__linux__)
5872		   "wmi event pdev bss chan info:\n freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
5873		   freq, noise_floor, busy, total, tx, rx, rx_bss);
5874#elif defined(__FreeBSD__)
5875		   "wmi event pdev bss chan info:\n freq: %d noise: %d cycle: busy %ju total %ju tx %ju rx %ju rx_bss %ju\n",
5876		   freq, noise_floor, (uintmax_t)busy, (uintmax_t)total, (uintmax_t)tx, (uintmax_t)rx, (uintmax_t)rx_bss);
5877#endif
5878
5879	spin_lock_bh(&ar->data_lock);
5880	idx = freq_to_idx(ar, freq);
5881	if (idx >= ARRAY_SIZE(ar->survey)) {
5882		ath10k_warn(ar, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
5883			    freq, idx);
5884		goto exit;
5885	}
5886
5887	survey = &ar->survey[idx];
5888
5889	survey->noise     = noise_floor;
5890	survey->time      = div_u64(total, cc_freq_hz);
5891	survey->time_busy = div_u64(busy, cc_freq_hz);
5892	survey->time_rx   = div_u64(rx_bss, cc_freq_hz);
5893	survey->time_tx   = div_u64(tx, cc_freq_hz);
5894	survey->filled   |= (SURVEY_INFO_NOISE_DBM |
5895			     SURVEY_INFO_TIME |
5896			     SURVEY_INFO_TIME_BUSY |
5897			     SURVEY_INFO_TIME_RX |
5898			     SURVEY_INFO_TIME_TX);
5899exit:
5900	spin_unlock_bh(&ar->data_lock);
5901	complete(&ar->bss_survey_done);
5902	return 0;
5903}
5904
5905static inline void ath10k_wmi_queue_set_coverage_class_work(struct ath10k *ar)
5906{
5907	if (ar->hw_params.hw_ops->set_coverage_class) {
5908		spin_lock_bh(&ar->data_lock);
5909
5910		/* This call only ensures that the modified coverage class
5911		 * persists in case the firmware sets the registers back to
5912		 * their default value. So calling it is only necessary if the
5913		 * coverage class has a non-zero value.
5914		 */
5915		if (ar->fw_coverage.coverage_class)
5916			queue_work(ar->workqueue, &ar->set_coverage_class_work);
5917
5918		spin_unlock_bh(&ar->data_lock);
5919	}
5920}
5921
5922static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
5923{
5924	struct wmi_cmd_hdr *cmd_hdr;
5925	enum wmi_event_id id;
5926
5927	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
5928	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
5929
5930	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
5931		goto out;
5932
5933	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
5934
5935	switch (id) {
5936	case WMI_MGMT_RX_EVENTID:
5937		ath10k_wmi_event_mgmt_rx(ar, skb);
5938		/* mgmt_rx() owns the skb now! */
5939		return;
5940	case WMI_SCAN_EVENTID:
5941		ath10k_wmi_event_scan(ar, skb);
5942		ath10k_wmi_queue_set_coverage_class_work(ar);
5943		break;
5944	case WMI_CHAN_INFO_EVENTID:
5945		ath10k_wmi_event_chan_info(ar, skb);
5946		break;
5947	case WMI_ECHO_EVENTID:
5948		ath10k_wmi_event_echo(ar, skb);
5949		break;
5950	case WMI_DEBUG_MESG_EVENTID:
5951		ath10k_wmi_event_debug_mesg(ar, skb);
5952		ath10k_wmi_queue_set_coverage_class_work(ar);
5953#if defined(CONFIG_FWLOG)
5954		return;
5955#else
5956		break;
5957#endif
5958	case WMI_UPDATE_STATS_EVENTID:
5959		ath10k_wmi_event_update_stats(ar, skb);
5960		break;
5961	case WMI_VDEV_START_RESP_EVENTID:
5962		ath10k_wmi_event_vdev_start_resp(ar, skb);
5963		ath10k_wmi_queue_set_coverage_class_work(ar);
5964		break;
5965	case WMI_VDEV_STOPPED_EVENTID:
5966		ath10k_wmi_event_vdev_stopped(ar, skb);
5967		ath10k_wmi_queue_set_coverage_class_work(ar);
5968		break;
5969	case WMI_PEER_STA_KICKOUT_EVENTID:
5970		ath10k_wmi_event_peer_sta_kickout(ar, skb);
5971		break;
5972	case WMI_HOST_SWBA_EVENTID:
5973		ath10k_wmi_event_host_swba(ar, skb);
5974		break;
5975	case WMI_TBTTOFFSET_UPDATE_EVENTID:
5976		ath10k_wmi_event_tbttoffset_update(ar, skb);
5977		break;
5978	case WMI_PHYERR_EVENTID:
5979		ath10k_wmi_event_phyerr(ar, skb);
5980		break;
5981	case WMI_ROAM_EVENTID:
5982		ath10k_wmi_event_roam(ar, skb);
5983		ath10k_wmi_queue_set_coverage_class_work(ar);
5984		break;
5985	case WMI_PROFILE_MATCH:
5986		ath10k_wmi_event_profile_match(ar, skb);
5987		break;
5988	case WMI_DEBUG_PRINT_EVENTID:
5989		ath10k_wmi_event_debug_print(ar, skb);
5990		ath10k_wmi_queue_set_coverage_class_work(ar);
5991		break;
5992	case WMI_PDEV_QVIT_EVENTID:
5993		ath10k_wmi_event_pdev_qvit(ar, skb);
5994		break;
5995	case WMI_WLAN_PROFILE_DATA_EVENTID:
5996		ath10k_wmi_event_wlan_profile_data(ar, skb);
5997		break;
5998	case WMI_RTT_MEASUREMENT_REPORT_EVENTID:
5999		ath10k_wmi_event_rtt_measurement_report(ar, skb);
6000		break;
6001	case WMI_TSF_MEASUREMENT_REPORT_EVENTID:
6002		ath10k_wmi_event_tsf_measurement_report(ar, skb);
6003		break;
6004	case WMI_RTT_ERROR_REPORT_EVENTID:
6005		ath10k_wmi_event_rtt_error_report(ar, skb);
6006		break;
6007	case WMI_WOW_WAKEUP_HOST_EVENTID:
6008		ath10k_wmi_event_wow_wakeup_host(ar, skb);
6009		break;
6010	case WMI_DCS_INTERFERENCE_EVENTID:
6011		ath10k_wmi_event_dcs_interference(ar, skb);
6012		break;
6013	case WMI_PDEV_TPC_CONFIG_EVENTID:
6014		ath10k_wmi_event_pdev_tpc_config(ar, skb);
6015		break;
6016	case WMI_PDEV_FTM_INTG_EVENTID:
6017		ath10k_wmi_event_pdev_ftm_intg(ar, skb);
6018		break;
6019	case WMI_GTK_OFFLOAD_STATUS_EVENTID:
6020		ath10k_wmi_event_gtk_offload_status(ar, skb);
6021		break;
6022	case WMI_GTK_REKEY_FAIL_EVENTID:
6023		ath10k_wmi_event_gtk_rekey_fail(ar, skb);
6024		break;
6025	case WMI_TX_DELBA_COMPLETE_EVENTID:
6026		ath10k_wmi_event_delba_complete(ar, skb);
6027		break;
6028	case WMI_TX_ADDBA_COMPLETE_EVENTID:
6029		ath10k_wmi_event_addba_complete(ar, skb);
6030		break;
6031	case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
6032		ath10k_wmi_event_vdev_install_key_complete(ar, skb);
6033		break;
6034	case WMI_SERVICE_READY_EVENTID:
6035		ath10k_wmi_event_service_ready(ar, skb);
6036		return;
6037	case WMI_READY_EVENTID:
6038		ath10k_wmi_event_ready(ar, skb);
6039		ath10k_wmi_queue_set_coverage_class_work(ar);
6040		break;
6041	case WMI_SERVICE_AVAILABLE_EVENTID:
6042		ath10k_wmi_event_service_available(ar, skb);
6043		break;
6044	default:
6045		ath10k_warn(ar, "Unknown eventid: %d\n", id);
6046		break;
6047	}
6048
6049out:
6050	dev_kfree_skb(skb);
6051}
6052
6053static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
6054{
6055	struct wmi_cmd_hdr *cmd_hdr;
6056	enum wmi_10x_event_id id;
6057	bool consumed;
6058
6059	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
6060	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
6061
6062	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
6063		goto out;
6064
6065	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
6066
6067	consumed = ath10k_tm_event_wmi(ar, id, skb);
6068
6069	/* Ready event must be handled normally also in UTF mode so that we
6070	 * know the UTF firmware has booted, others we are just bypass WMI
6071	 * events to testmode.
6072	 */
6073	if (consumed && id != WMI_10X_READY_EVENTID) {
6074		ath10k_dbg(ar, ATH10K_DBG_WMI,
6075			   "wmi testmode consumed 0x%x\n", id);
6076		goto out;
6077	}
6078
6079	switch (id) {
6080	case WMI_10X_MGMT_RX_EVENTID:
6081		ath10k_wmi_event_mgmt_rx(ar, skb);
6082		/* mgmt_rx() owns the skb now! */
6083		return;
6084	case WMI_10X_SCAN_EVENTID:
6085		ath10k_wmi_event_scan(ar, skb);
6086		ath10k_wmi_queue_set_coverage_class_work(ar);
6087		break;
6088	case WMI_10X_CHAN_INFO_EVENTID:
6089		ath10k_wmi_event_chan_info(ar, skb);
6090		break;
6091	case WMI_10X_ECHO_EVENTID:
6092		ath10k_wmi_event_echo(ar, skb);
6093		break;
6094	case WMI_10X_DEBUG_MESG_EVENTID:
6095		ath10k_wmi_event_debug_mesg(ar, skb);
6096		ath10k_wmi_queue_set_coverage_class_work(ar);
6097#if defined(CONFIG_FWLOG)
6098		return;
6099#else
6100		break;
6101#endif
6102	case WMI_10X_UPDATE_STATS_EVENTID:
6103		ath10k_wmi_event_update_stats(ar, skb);
6104		break;
6105	case WMI_10X_VDEV_START_RESP_EVENTID:
6106		ath10k_wmi_event_vdev_start_resp(ar, skb);
6107		ath10k_wmi_queue_set_coverage_class_work(ar);
6108		break;
6109	case WMI_10X_VDEV_STOPPED_EVENTID:
6110		ath10k_wmi_event_vdev_stopped(ar, skb);
6111		ath10k_wmi_queue_set_coverage_class_work(ar);
6112		break;
6113	case WMI_10X_PEER_STA_KICKOUT_EVENTID:
6114		ath10k_wmi_event_peer_sta_kickout(ar, skb);
6115		break;
6116	case WMI_10X_HOST_SWBA_EVENTID:
6117		ath10k_wmi_event_host_swba(ar, skb);
6118		break;
6119	case WMI_10X_TBTTOFFSET_UPDATE_EVENTID:
6120		ath10k_wmi_event_tbttoffset_update(ar, skb);
6121		break;
6122	case WMI_10X_PHYERR_EVENTID:
6123		ath10k_wmi_event_phyerr(ar, skb);
6124		break;
6125	case WMI_10X_ROAM_EVENTID:
6126		ath10k_wmi_event_roam(ar, skb);
6127		ath10k_wmi_queue_set_coverage_class_work(ar);
6128		break;
6129	case WMI_10X_PROFILE_MATCH:
6130		ath10k_wmi_event_profile_match(ar, skb);
6131		break;
6132	case WMI_10X_DEBUG_PRINT_EVENTID:
6133		ath10k_wmi_event_debug_print(ar, skb);
6134		ath10k_wmi_queue_set_coverage_class_work(ar);
6135		break;
6136	case WMI_10X_PDEV_QVIT_EVENTID:
6137		ath10k_wmi_event_pdev_qvit(ar, skb);
6138		break;
6139	case WMI_10X_WLAN_PROFILE_DATA_EVENTID:
6140		ath10k_wmi_event_wlan_profile_data(ar, skb);
6141		break;
6142	case WMI_10X_RTT_MEASUREMENT_REPORT_EVENTID:
6143		ath10k_wmi_event_rtt_measurement_report(ar, skb);
6144		break;
6145	case WMI_10X_TSF_MEASUREMENT_REPORT_EVENTID:
6146		ath10k_wmi_event_tsf_measurement_report(ar, skb);
6147		break;
6148	case WMI_10X_RTT_ERROR_REPORT_EVENTID:
6149		ath10k_wmi_event_rtt_error_report(ar, skb);
6150		break;
6151	case WMI_10X_WOW_WAKEUP_HOST_EVENTID:
6152		ath10k_wmi_event_wow_wakeup_host(ar, skb);
6153		break;
6154	case WMI_10X_DCS_INTERFERENCE_EVENTID:
6155		ath10k_wmi_event_dcs_interference(ar, skb);
6156		break;
6157	case WMI_10X_PDEV_TPC_CONFIG_EVENTID:
6158		ath10k_wmi_event_pdev_tpc_config(ar, skb);
6159		break;
6160	case WMI_10X_INST_RSSI_STATS_EVENTID:
6161		ath10k_wmi_event_inst_rssi_stats(ar, skb);
6162		break;
6163	case WMI_10X_VDEV_STANDBY_REQ_EVENTID:
6164		ath10k_wmi_event_vdev_standby_req(ar, skb);
6165		break;
6166	case WMI_10X_VDEV_RESUME_REQ_EVENTID:
6167		ath10k_wmi_event_vdev_resume_req(ar, skb);
6168		break;
6169	case WMI_10X_SERVICE_READY_EVENTID:
6170		ath10k_wmi_event_service_ready(ar, skb);
6171		return;
6172	case WMI_10X_READY_EVENTID:
6173		ath10k_wmi_event_ready(ar, skb);
6174		ath10k_wmi_queue_set_coverage_class_work(ar);
6175		break;
6176	case WMI_10X_PDEV_UTF_EVENTID:
6177		/* ignore utf events */
6178		break;
6179	default:
6180		ath10k_warn(ar, "Unknown eventid: %d\n", id);
6181		break;
6182	}
6183
6184out:
6185	dev_kfree_skb(skb);
6186}
6187
6188static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
6189{
6190	struct wmi_cmd_hdr *cmd_hdr;
6191	enum wmi_10_2_event_id id;
6192	bool consumed;
6193
6194	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
6195	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
6196
6197	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
6198		goto out;
6199
6200	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
6201
6202	consumed = ath10k_tm_event_wmi(ar, id, skb);
6203
6204	/* Ready event must be handled normally also in UTF mode so that we
6205	 * know the UTF firmware has booted, others we are just bypass WMI
6206	 * events to testmode.
6207	 */
6208	if (consumed && id != WMI_10_2_READY_EVENTID) {
6209		ath10k_dbg(ar, ATH10K_DBG_WMI,
6210			   "wmi testmode consumed 0x%x\n", id);
6211		goto out;
6212	}
6213
6214	switch (id) {
6215	case WMI_10_2_MGMT_RX_EVENTID:
6216		ath10k_wmi_event_mgmt_rx(ar, skb);
6217		/* mgmt_rx() owns the skb now! */
6218		return;
6219	case WMI_10_2_SCAN_EVENTID:
6220		ath10k_wmi_event_scan(ar, skb);
6221		ath10k_wmi_queue_set_coverage_class_work(ar);
6222		break;
6223	case WMI_10_2_CHAN_INFO_EVENTID:
6224		ath10k_wmi_event_chan_info(ar, skb);
6225		break;
6226	case WMI_10_2_ECHO_EVENTID:
6227		ath10k_wmi_event_echo(ar, skb);
6228		break;
6229	case WMI_10_2_DEBUG_MESG_EVENTID:
6230		ath10k_wmi_event_debug_mesg(ar, skb);
6231		ath10k_wmi_queue_set_coverage_class_work(ar);
6232#if defined(CONFIG_FWLOG)
6233		return;
6234#else
6235		break;
6236#endif
6237	case WMI_10_2_UPDATE_STATS_EVENTID:
6238		ath10k_wmi_event_update_stats(ar, skb);
6239		break;
6240	case WMI_10_2_VDEV_START_RESP_EVENTID:
6241		ath10k_wmi_event_vdev_start_resp(ar, skb);
6242		ath10k_wmi_queue_set_coverage_class_work(ar);
6243		break;
6244	case WMI_10_2_VDEV_STOPPED_EVENTID:
6245		ath10k_wmi_event_vdev_stopped(ar, skb);
6246		ath10k_wmi_queue_set_coverage_class_work(ar);
6247		break;
6248	case WMI_10_2_PEER_STA_KICKOUT_EVENTID:
6249		ath10k_wmi_event_peer_sta_kickout(ar, skb);
6250		break;
6251	case WMI_10_2_HOST_SWBA_EVENTID:
6252		ath10k_wmi_event_host_swba(ar, skb);
6253		break;
6254	case WMI_10_2_TBTTOFFSET_UPDATE_EVENTID:
6255		ath10k_wmi_event_tbttoffset_update(ar, skb);
6256		break;
6257	case WMI_10_2_PHYERR_EVENTID:
6258		ath10k_wmi_event_phyerr(ar, skb);
6259		break;
6260	case WMI_10_2_ROAM_EVENTID:
6261		ath10k_wmi_event_roam(ar, skb);
6262		ath10k_wmi_queue_set_coverage_class_work(ar);
6263		break;
6264	case WMI_10_2_PROFILE_MATCH:
6265		ath10k_wmi_event_profile_match(ar, skb);
6266		break;
6267	case WMI_10_2_DEBUG_PRINT_EVENTID:
6268		ath10k_wmi_event_debug_print(ar, skb);
6269		ath10k_wmi_queue_set_coverage_class_work(ar);
6270		break;
6271	case WMI_10_2_PDEV_QVIT_EVENTID:
6272		ath10k_wmi_event_pdev_qvit(ar, skb);
6273		break;
6274	case WMI_10_2_WLAN_PROFILE_DATA_EVENTID:
6275		ath10k_wmi_event_wlan_profile_data(ar, skb);
6276		break;
6277	case WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID:
6278		ath10k_wmi_event_rtt_measurement_report(ar, skb);
6279		break;
6280	case WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID:
6281		ath10k_wmi_event_tsf_measurement_report(ar, skb);
6282		break;
6283	case WMI_10_2_RTT_ERROR_REPORT_EVENTID:
6284		ath10k_wmi_event_rtt_error_report(ar, skb);
6285		break;
6286	case WMI_10_2_WOW_WAKEUP_HOST_EVENTID:
6287		ath10k_wmi_event_wow_wakeup_host(ar, skb);
6288		break;
6289	case WMI_10_2_DCS_INTERFERENCE_EVENTID:
6290		ath10k_wmi_event_dcs_interference(ar, skb);
6291		break;
6292	case WMI_10_2_PDEV_TPC_CONFIG_EVENTID:
6293		ath10k_wmi_event_pdev_tpc_config(ar, skb);
6294		break;
6295	case WMI_10_2_INST_RSSI_STATS_EVENTID:
6296		ath10k_wmi_event_inst_rssi_stats(ar, skb);
6297		break;
6298	case WMI_10_2_VDEV_STANDBY_REQ_EVENTID:
6299		ath10k_wmi_event_vdev_standby_req(ar, skb);
6300		ath10k_wmi_queue_set_coverage_class_work(ar);
6301		break;
6302	case WMI_10_2_VDEV_RESUME_REQ_EVENTID:
6303		ath10k_wmi_event_vdev_resume_req(ar, skb);
6304		ath10k_wmi_queue_set_coverage_class_work(ar);
6305		break;
6306	case WMI_10_2_SERVICE_READY_EVENTID:
6307		ath10k_wmi_event_service_ready(ar, skb);
6308		return;
6309	case WMI_10_2_READY_EVENTID:
6310		ath10k_wmi_event_ready(ar, skb);
6311		ath10k_wmi_queue_set_coverage_class_work(ar);
6312		break;
6313	case WMI_10_2_PDEV_TEMPERATURE_EVENTID:
6314		ath10k_wmi_event_temperature(ar, skb);
6315		break;
6316	case WMI_10_2_PDEV_BSS_CHAN_INFO_EVENTID:
6317		ath10k_wmi_event_pdev_bss_chan_info(ar, skb);
6318		break;
6319	case WMI_10_2_RTT_KEEPALIVE_EVENTID:
6320	case WMI_10_2_GPIO_INPUT_EVENTID:
6321	case WMI_10_2_PEER_RATECODE_LIST_EVENTID:
6322	case WMI_10_2_GENERIC_BUFFER_EVENTID:
6323	case WMI_10_2_MCAST_BUF_RELEASE_EVENTID:
6324	case WMI_10_2_MCAST_LIST_AGEOUT_EVENTID:
6325	case WMI_10_2_WDS_PEER_EVENTID:
6326		ath10k_dbg(ar, ATH10K_DBG_WMI,
6327			   "received event id %d not implemented\n", id);
6328		break;
6329	case WMI_10_2_PEER_STA_PS_STATECHG_EVENTID:
6330		ath10k_wmi_event_peer_sta_ps_state_chg(ar, skb);
6331		break;
6332	default:
6333		ath10k_warn(ar, "Unknown eventid: %d\n", id);
6334		break;
6335	}
6336
6337out:
6338	dev_kfree_skb(skb);
6339}
6340
6341static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
6342{
6343	struct wmi_cmd_hdr *cmd_hdr;
6344	enum wmi_10_4_event_id id;
6345	bool consumed;
6346
6347	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
6348	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
6349
6350	if (!skb_pull(skb, sizeof(struct wmi_cmd_hdr)))
6351		goto out;
6352
6353	trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
6354
6355	consumed = ath10k_tm_event_wmi(ar, id, skb);
6356
6357	/* Ready event must be handled normally also in UTF mode so that we
6358	 * know the UTF firmware has booted, others we are just bypass WMI
6359	 * events to testmode.
6360	 */
6361	if (consumed && id != WMI_10_4_READY_EVENTID) {
6362		ath10k_dbg(ar, ATH10K_DBG_WMI,
6363			   "wmi testmode consumed 0x%x\n", id);
6364		goto out;
6365	}
6366
6367	switch (id) {
6368	case WMI_10_4_MGMT_RX_EVENTID:
6369		ath10k_wmi_event_mgmt_rx(ar, skb);
6370		/* mgmt_rx() owns the skb now! */
6371		return;
6372	case WMI_10_4_ECHO_EVENTID:
6373		ath10k_wmi_event_echo(ar, skb);
6374		break;
6375	case WMI_10_4_DEBUG_MESG_EVENTID:
6376		ath10k_wmi_event_debug_mesg(ar, skb);
6377		ath10k_wmi_queue_set_coverage_class_work(ar);
6378#if defined(CONFIG_FWLOG)
6379		return;
6380#else
6381		break;
6382#endif
6383	case WMI_10_4_SERVICE_READY_EVENTID:
6384		ath10k_wmi_event_service_ready(ar, skb);
6385		return;
6386	case WMI_10_4_SCAN_EVENTID:
6387		ath10k_wmi_event_scan(ar, skb);
6388		ath10k_wmi_queue_set_coverage_class_work(ar);
6389		break;
6390	case WMI_10_4_CHAN_INFO_EVENTID:
6391		ath10k_wmi_event_chan_info(ar, skb);
6392		break;
6393	case WMI_10_4_PHYERR_EVENTID:
6394		ath10k_wmi_event_phyerr(ar, skb);
6395		break;
6396	case WMI_10_4_READY_EVENTID:
6397		ath10k_wmi_event_ready(ar, skb);
6398		ath10k_wmi_queue_set_coverage_class_work(ar);
6399		break;
6400	case WMI_10_4_PEER_STA_KICKOUT_EVENTID:
6401		ath10k_wmi_event_peer_sta_kickout(ar, skb);
6402		break;
6403	case WMI_10_4_ROAM_EVENTID:
6404		ath10k_wmi_event_roam(ar, skb);
6405		ath10k_wmi_queue_set_coverage_class_work(ar);
6406		break;
6407	case WMI_10_4_HOST_SWBA_EVENTID:
6408		ath10k_wmi_event_host_swba(ar, skb);
6409		break;
6410	case WMI_10_4_TBTTOFFSET_UPDATE_EVENTID:
6411		ath10k_wmi_event_tbttoffset_update(ar, skb);
6412		break;
6413	case WMI_10_4_DEBUG_PRINT_EVENTID:
6414		ath10k_wmi_event_debug_print(ar, skb);
6415		ath10k_wmi_queue_set_coverage_class_work(ar);
6416		break;
6417	case WMI_10_4_VDEV_START_RESP_EVENTID:
6418		ath10k_wmi_event_vdev_start_resp(ar, skb);
6419		ath10k_wmi_queue_set_coverage_class_work(ar);
6420		break;
6421	case WMI_10_4_VDEV_STOPPED_EVENTID:
6422		ath10k_wmi_event_vdev_stopped(ar, skb);
6423		ath10k_wmi_queue_set_coverage_class_work(ar);
6424		break;
6425	case WMI_10_4_WOW_WAKEUP_HOST_EVENTID:
6426	case WMI_10_4_PEER_RATECODE_LIST_EVENTID:
6427	case WMI_10_4_WDS_PEER_EVENTID:
6428	case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID:
6429		ath10k_dbg(ar, ATH10K_DBG_WMI,
6430			   "received event id %d not implemented\n", id);
6431		break;
6432	case WMI_10_4_UPDATE_STATS_EVENTID:
6433		ath10k_wmi_event_update_stats(ar, skb);
6434		break;
6435	case WMI_10_4_PDEV_TEMPERATURE_EVENTID:
6436		ath10k_wmi_event_temperature(ar, skb);
6437		break;
6438	case WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID:
6439		ath10k_wmi_event_pdev_bss_chan_info(ar, skb);
6440		break;
6441	case WMI_10_4_PDEV_TPC_CONFIG_EVENTID:
6442		ath10k_wmi_event_pdev_tpc_config(ar, skb);
6443		break;
6444	case WMI_10_4_TDLS_PEER_EVENTID:
6445		ath10k_wmi_handle_tdls_peer_event(ar, skb);
6446		break;
6447	case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
6448		ath10k_wmi_event_tpc_final_table(ar, skb);
6449		break;
6450	case WMI_10_4_DFS_STATUS_CHECK_EVENTID:
6451		ath10k_wmi_event_dfs_status_check(ar, skb);
6452		break;
6453	case WMI_10_4_PEER_STA_PS_STATECHG_EVENTID:
6454		ath10k_wmi_event_peer_sta_ps_state_chg(ar, skb);
6455		break;
6456	default:
6457		ath10k_warn(ar, "Unknown eventid: %d\n", id);
6458		break;
6459	}
6460
6461out:
6462	dev_kfree_skb(skb);
6463}
6464
6465static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb)
6466{
6467	int ret;
6468
6469	ret = ath10k_wmi_rx(ar, skb);
6470	if (ret)
6471		ath10k_warn(ar, "failed to process wmi rx: %d\n", ret);
6472}
6473
6474int ath10k_wmi_connect(struct ath10k *ar)
6475{
6476	int status;
6477	struct ath10k_htc_svc_conn_req conn_req;
6478	struct ath10k_htc_svc_conn_resp conn_resp;
6479
6480	memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
6481
6482	memset(&conn_req, 0, sizeof(conn_req));
6483	memset(&conn_resp, 0, sizeof(conn_resp));
6484
6485	/* these fields are the same for all service endpoints */
6486	conn_req.ep_ops.ep_tx_complete = ath10k_wmi_htc_tx_complete;
6487	conn_req.ep_ops.ep_rx_complete = ath10k_wmi_process_rx;
6488	conn_req.ep_ops.ep_tx_credits = ath10k_wmi_op_ep_tx_credits;
6489
6490	/* connect to control service */
6491	conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
6492
6493	status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
6494	if (status) {
6495		ath10k_warn(ar, "failed to connect to WMI CONTROL service status: %d\n",
6496			    status);
6497		return status;
6498	}
6499
6500	ar->wmi.eid = conn_resp.eid;
6501	return 0;
6502}
6503
6504static struct sk_buff *
6505ath10k_wmi_op_gen_pdev_set_base_macaddr(struct ath10k *ar,
6506					const u8 macaddr[ETH_ALEN])
6507{
6508	struct wmi_pdev_set_base_macaddr_cmd *cmd;
6509	struct sk_buff *skb;
6510
6511	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6512	if (!skb)
6513		return ERR_PTR(-ENOMEM);
6514
6515	cmd = (struct wmi_pdev_set_base_macaddr_cmd *)skb->data;
6516	ether_addr_copy(cmd->mac_addr.addr, macaddr);
6517
6518	ath10k_dbg(ar, ATH10K_DBG_WMI,
6519		   "wmi pdev basemac %pM\n", macaddr);
6520	return skb;
6521}
6522
6523static struct sk_buff *
6524ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
6525			      u16 ctl2g, u16 ctl5g,
6526			      enum wmi_dfs_region dfs_reg)
6527{
6528	struct wmi_pdev_set_regdomain_cmd *cmd;
6529	struct sk_buff *skb;
6530
6531	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6532	if (!skb)
6533		return ERR_PTR(-ENOMEM);
6534
6535	cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data;
6536	cmd->reg_domain = __cpu_to_le32(rd);
6537	cmd->reg_domain_2G = __cpu_to_le32(rd2g);
6538	cmd->reg_domain_5G = __cpu_to_le32(rd5g);
6539	cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g);
6540	cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g);
6541
6542	ath10k_dbg(ar, ATH10K_DBG_WMI,
6543		   "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n",
6544		   rd, rd2g, rd5g, ctl2g, ctl5g);
6545	return skb;
6546}
6547
6548static struct sk_buff *
6549ath10k_wmi_10x_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16
6550				  rd5g, u16 ctl2g, u16 ctl5g,
6551				  enum wmi_dfs_region dfs_reg)
6552{
6553	struct wmi_pdev_set_regdomain_cmd_10x *cmd;
6554	struct sk_buff *skb;
6555
6556	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6557	if (!skb)
6558		return ERR_PTR(-ENOMEM);
6559
6560	cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data;
6561	cmd->reg_domain = __cpu_to_le32(rd);
6562	cmd->reg_domain_2G = __cpu_to_le32(rd2g);
6563	cmd->reg_domain_5G = __cpu_to_le32(rd5g);
6564	cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g);
6565	cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g);
6566	cmd->dfs_domain = __cpu_to_le32(dfs_reg);
6567
6568	ath10k_dbg(ar, ATH10K_DBG_WMI,
6569		   "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n",
6570		   rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg);
6571	return skb;
6572}
6573
6574static struct sk_buff *
6575ath10k_wmi_op_gen_pdev_suspend(struct ath10k *ar, u32 suspend_opt)
6576{
6577	struct wmi_pdev_suspend_cmd *cmd;
6578	struct sk_buff *skb;
6579
6580	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6581	if (!skb)
6582		return ERR_PTR(-ENOMEM);
6583
6584	cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
6585	cmd->suspend_opt = __cpu_to_le32(suspend_opt);
6586
6587	return skb;
6588}
6589
6590static struct sk_buff *
6591ath10k_wmi_op_gen_pdev_resume(struct ath10k *ar)
6592{
6593	struct sk_buff *skb;
6594
6595	skb = ath10k_wmi_alloc_skb(ar, 0);
6596	if (!skb)
6597		return ERR_PTR(-ENOMEM);
6598
6599	return skb;
6600}
6601
6602static struct sk_buff *
6603ath10k_wmi_op_gen_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
6604{
6605	struct wmi_pdev_set_param_cmd *cmd;
6606	struct sk_buff *skb;
6607
6608	if (id == WMI_PDEV_PARAM_UNSUPPORTED) {
6609		ath10k_warn(ar, "pdev param %d not supported by firmware\n",
6610			    id);
6611		return ERR_PTR(-EOPNOTSUPP);
6612	}
6613
6614	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6615	if (!skb)
6616		return ERR_PTR(-ENOMEM);
6617
6618	cmd = (struct wmi_pdev_set_param_cmd *)skb->data;
6619	cmd->param_id    = __cpu_to_le32(id);
6620	cmd->param_value = __cpu_to_le32(value);
6621
6622	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n",
6623		   id, value);
6624	return skb;
6625}
6626
6627void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
6628				    struct wmi_host_mem_chunks *chunks)
6629{
6630	struct host_memory_chunk *chunk;
6631	int i;
6632
6633	chunks->count = __cpu_to_le32(ar->wmi.num_mem_chunks);
6634
6635	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
6636		chunk = &chunks->items[i];
6637		chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
6638		chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len);
6639		chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
6640
6641		ath10k_dbg(ar, ATH10K_DBG_WMI,
6642			   "wmi chunk %d len %d requested, addr 0x%llx\n",
6643			   i,
6644			   ar->wmi.mem_chunks[i].len,
6645			   (unsigned long long)ar->wmi.mem_chunks[i].paddr);
6646	}
6647}
6648
6649static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar)
6650{
6651	struct wmi_init_cmd *cmd;
6652	struct sk_buff *buf;
6653	struct wmi_resource_config config = {};
6654	u32 val;
6655
6656	config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
6657	config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS);
6658	config.num_offload_peers = __cpu_to_le32(TARGET_NUM_OFFLOAD_PEERS);
6659
6660	config.num_offload_reorder_bufs =
6661		__cpu_to_le32(TARGET_NUM_OFFLOAD_REORDER_BUFS);
6662
6663	config.num_peer_keys = __cpu_to_le32(TARGET_NUM_PEER_KEYS);
6664	config.num_tids = __cpu_to_le32(TARGET_NUM_TIDS);
6665	config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT);
6666	config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK);
6667	config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK);
6668	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
6669	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
6670	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
6671	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_RX_TIMEOUT_HI_PRI);
6672	config.rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
6673	config.scan_max_pending_reqs =
6674		__cpu_to_le32(TARGET_SCAN_MAX_PENDING_REQS);
6675
6676	config.bmiss_offload_max_vdev =
6677		__cpu_to_le32(TARGET_BMISS_OFFLOAD_MAX_VDEV);
6678
6679	config.roam_offload_max_vdev =
6680		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_VDEV);
6681
6682	config.roam_offload_max_ap_profiles =
6683		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES);
6684
6685	config.num_mcast_groups = __cpu_to_le32(TARGET_NUM_MCAST_GROUPS);
6686	config.num_mcast_table_elems =
6687		__cpu_to_le32(TARGET_NUM_MCAST_TABLE_ELEMS);
6688
6689	config.mcast2ucast_mode = __cpu_to_le32(TARGET_MCAST2UCAST_MODE);
6690	config.tx_dbg_log_size = __cpu_to_le32(TARGET_TX_DBG_LOG_SIZE);
6691	config.num_wds_entries = __cpu_to_le32(TARGET_NUM_WDS_ENTRIES);
6692	config.dma_burst_size = __cpu_to_le32(TARGET_DMA_BURST_SIZE);
6693	config.mac_aggr_delim = __cpu_to_le32(TARGET_MAC_AGGR_DELIM);
6694
6695	val = TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
6696	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
6697
6698	config.vow_config = __cpu_to_le32(TARGET_VOW_CONFIG);
6699
6700	config.gtk_offload_max_vdev =
6701		__cpu_to_le32(TARGET_GTK_OFFLOAD_MAX_VDEV);
6702
6703	config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC);
6704	config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES);
6705
6706	buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
6707						   ar->wmi.num_mem_chunks));
6708	if (!buf)
6709		return ERR_PTR(-ENOMEM);
6710
6711	cmd = (struct wmi_init_cmd *)buf->data;
6712
6713	memcpy(&cmd->resource_config, &config, sizeof(config));
6714	ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
6715
6716	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n");
6717	return buf;
6718}
6719
6720static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
6721{
6722	struct wmi_init_cmd_10x *cmd;
6723	struct sk_buff *buf;
6724	struct wmi_resource_config_10x config = {};
6725	u32 val;
6726
6727	config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
6728	config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
6729	config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS);
6730	config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS);
6731	config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT);
6732	config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK);
6733	config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK);
6734	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6735	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6736	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6737	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI);
6738	config.rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
6739	config.scan_max_pending_reqs =
6740		__cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS);
6741
6742	config.bmiss_offload_max_vdev =
6743		__cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV);
6744
6745	config.roam_offload_max_vdev =
6746		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV);
6747
6748	config.roam_offload_max_ap_profiles =
6749		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES);
6750
6751	config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS);
6752	config.num_mcast_table_elems =
6753		__cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS);
6754
6755	config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE);
6756	config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE);
6757	config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES);
6758	config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE);
6759	config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM);
6760
6761	val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
6762	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
6763
6764	config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG);
6765
6766	config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC);
6767	config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES);
6768
6769	buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
6770						   ar->wmi.num_mem_chunks));
6771	if (!buf)
6772		return ERR_PTR(-ENOMEM);
6773
6774	cmd = (struct wmi_init_cmd_10x *)buf->data;
6775
6776	memcpy(&cmd->resource_config, &config, sizeof(config));
6777	ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
6778
6779	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n");
6780	return buf;
6781}
6782
6783static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
6784{
6785	struct wmi_init_cmd_10_2 *cmd;
6786	struct sk_buff *buf;
6787	struct wmi_resource_config_10x config = {};
6788	u32 val, features;
6789
6790	config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
6791	config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS);
6792
6793	if (ath10k_peer_stats_enabled(ar)) {
6794		config.num_peers = __cpu_to_le32(TARGET_10X_TX_STATS_NUM_PEERS);
6795		config.num_tids = __cpu_to_le32(TARGET_10X_TX_STATS_NUM_TIDS);
6796	} else {
6797		config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
6798		config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS);
6799	}
6800
6801	config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT);
6802	config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK);
6803	config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK);
6804	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6805	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6806	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
6807	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI);
6808	config.rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
6809
6810	config.scan_max_pending_reqs =
6811		__cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS);
6812
6813	config.bmiss_offload_max_vdev =
6814		__cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV);
6815
6816	config.roam_offload_max_vdev =
6817		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV);
6818
6819	config.roam_offload_max_ap_profiles =
6820		__cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES);
6821
6822	config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS);
6823	config.num_mcast_table_elems =
6824		__cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS);
6825
6826	config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE);
6827	config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE);
6828	config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES);
6829	config.dma_burst_size = __cpu_to_le32(TARGET_10_2_DMA_BURST_SIZE);
6830	config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM);
6831
6832	val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
6833	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
6834
6835	config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG);
6836
6837	config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC);
6838	config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES);
6839
6840	buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
6841						   ar->wmi.num_mem_chunks));
6842	if (!buf)
6843		return ERR_PTR(-ENOMEM);
6844
6845	cmd = (struct wmi_init_cmd_10_2 *)buf->data;
6846
6847	features = WMI_10_2_RX_BATCH_MODE;
6848
6849	if (test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) &&
6850	    test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
6851		features |= WMI_10_2_COEX_GPIO;
6852
6853	if (ath10k_peer_stats_enabled(ar))
6854		features |= WMI_10_2_PEER_STATS;
6855
6856	if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
6857		features |= WMI_10_2_BSS_CHAN_INFO;
6858
6859	cmd->resource_config.feature_mask = __cpu_to_le32(features);
6860
6861	memcpy(&cmd->resource_config.common, &config, sizeof(config));
6862	ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
6863
6864	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n");
6865	return buf;
6866}
6867
6868static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
6869{
6870	struct wmi_init_cmd_10_4 *cmd;
6871	struct sk_buff *buf;
6872	struct wmi_resource_config_10_4 config = {};
6873
6874	config.num_vdevs = __cpu_to_le32(ar->max_num_vdevs);
6875	config.num_peers = __cpu_to_le32(ar->max_num_peers);
6876	config.num_active_peers = __cpu_to_le32(ar->num_active_peers);
6877	config.num_tids = __cpu_to_le32(ar->num_tids);
6878
6879	config.num_offload_peers = __cpu_to_le32(TARGET_10_4_NUM_OFFLOAD_PEERS);
6880	config.num_offload_reorder_buffs =
6881			__cpu_to_le32(TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS);
6882	config.num_peer_keys  = __cpu_to_le32(TARGET_10_4_NUM_PEER_KEYS);
6883	config.ast_skid_limit = __cpu_to_le32(TARGET_10_4_AST_SKID_LIMIT);
6884	config.tx_chain_mask  = __cpu_to_le32(ar->hw_params.tx_chain_mask);
6885	config.rx_chain_mask  = __cpu_to_le32(ar->hw_params.rx_chain_mask);
6886
6887	config.rx_timeout_pri[0] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
6888	config.rx_timeout_pri[1] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
6889	config.rx_timeout_pri[2] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
6890	config.rx_timeout_pri[3] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_HI_PRI);
6891
6892	config.rx_decap_mode	    = __cpu_to_le32(ar->wmi.rx_decap_mode);
6893	config.scan_max_pending_req = __cpu_to_le32(TARGET_10_4_SCAN_MAX_REQS);
6894	config.bmiss_offload_max_vdev =
6895			__cpu_to_le32(TARGET_10_4_BMISS_OFFLOAD_MAX_VDEV);
6896	config.roam_offload_max_vdev  =
6897			__cpu_to_le32(TARGET_10_4_ROAM_OFFLOAD_MAX_VDEV);
6898	config.roam_offload_max_ap_profiles =
6899			__cpu_to_le32(TARGET_10_4_ROAM_OFFLOAD_MAX_PROFILES);
6900	config.num_mcast_groups = __cpu_to_le32(TARGET_10_4_NUM_MCAST_GROUPS);
6901	config.num_mcast_table_elems =
6902			__cpu_to_le32(TARGET_10_4_NUM_MCAST_TABLE_ELEMS);
6903
6904	config.mcast2ucast_mode = __cpu_to_le32(TARGET_10_4_MCAST2UCAST_MODE);
6905	config.tx_dbg_log_size  = __cpu_to_le32(TARGET_10_4_TX_DBG_LOG_SIZE);
6906	config.num_wds_entries  = __cpu_to_le32(TARGET_10_4_NUM_WDS_ENTRIES);
6907	config.dma_burst_size   = __cpu_to_le32(TARGET_10_4_DMA_BURST_SIZE);
6908	config.mac_aggr_delim   = __cpu_to_le32(TARGET_10_4_MAC_AGGR_DELIM);
6909
6910	config.rx_skip_defrag_timeout_dup_detection_check =
6911	  __cpu_to_le32(TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK);
6912
6913	config.vow_config = __cpu_to_le32(TARGET_10_4_VOW_CONFIG);
6914	config.gtk_offload_max_vdev =
6915			__cpu_to_le32(TARGET_10_4_GTK_OFFLOAD_MAX_VDEV);
6916	config.num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx);
6917	config.max_frag_entries = __cpu_to_le32(TARGET_10_4_11AC_TX_MAX_FRAGS);
6918	config.max_peer_ext_stats =
6919			__cpu_to_le32(TARGET_10_4_MAX_PEER_EXT_STATS);
6920	config.smart_ant_cap = __cpu_to_le32(TARGET_10_4_SMART_ANT_CAP);
6921
6922	config.bk_minfree = __cpu_to_le32(TARGET_10_4_BK_MIN_FREE);
6923	config.be_minfree = __cpu_to_le32(TARGET_10_4_BE_MIN_FREE);
6924	config.vi_minfree = __cpu_to_le32(TARGET_10_4_VI_MIN_FREE);
6925	config.vo_minfree = __cpu_to_le32(TARGET_10_4_VO_MIN_FREE);
6926
6927	config.rx_batchmode = __cpu_to_le32(TARGET_10_4_RX_BATCH_MODE);
6928	config.tt_support =
6929			__cpu_to_le32(TARGET_10_4_THERMAL_THROTTLING_CONFIG);
6930	config.atf_config = __cpu_to_le32(TARGET_10_4_ATF_CONFIG);
6931	config.iphdr_pad_config = __cpu_to_le32(TARGET_10_4_IPHDR_PAD_CONFIG);
6932	config.qwrap_config = __cpu_to_le32(TARGET_10_4_QWRAP_CONFIG);
6933
6934	buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
6935						   ar->wmi.num_mem_chunks));
6936	if (!buf)
6937		return ERR_PTR(-ENOMEM);
6938
6939	cmd = (struct wmi_init_cmd_10_4 *)buf->data;
6940	memcpy(&cmd->resource_config, &config, sizeof(config));
6941	ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
6942
6943	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.4\n");
6944	return buf;
6945}
6946
6947int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg)
6948{
6949	if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN)
6950		return -EINVAL;
6951	if (arg->n_channels > ARRAY_SIZE(arg->channels))
6952		return -EINVAL;
6953	if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID)
6954		return -EINVAL;
6955	if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID)
6956		return -EINVAL;
6957
6958	return 0;
6959}
6960
6961static size_t
6962ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg)
6963{
6964	int len = 0;
6965
6966	if (arg->ie_len) {
6967		len += sizeof(struct wmi_ie_data);
6968		len += roundup(arg->ie_len, 4);
6969	}
6970
6971	if (arg->n_channels) {
6972		len += sizeof(struct wmi_chan_list);
6973		len += sizeof(__le32) * arg->n_channels;
6974	}
6975
6976	if (arg->n_ssids) {
6977		len += sizeof(struct wmi_ssid_list);
6978		len += sizeof(struct wmi_ssid) * arg->n_ssids;
6979	}
6980
6981	if (arg->n_bssids) {
6982		len += sizeof(struct wmi_bssid_list);
6983		len += sizeof(struct wmi_mac_addr) * arg->n_bssids;
6984	}
6985
6986	return len;
6987}
6988
6989void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
6990				      const struct wmi_start_scan_arg *arg)
6991{
6992	u32 scan_id;
6993	u32 scan_req_id;
6994
6995	scan_id  = WMI_HOST_SCAN_REQ_ID_PREFIX;
6996	scan_id |= arg->scan_id;
6997
6998	scan_req_id  = WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
6999	scan_req_id |= arg->scan_req_id;
7000
7001	cmn->scan_id            = __cpu_to_le32(scan_id);
7002	cmn->scan_req_id        = __cpu_to_le32(scan_req_id);
7003	cmn->vdev_id            = __cpu_to_le32(arg->vdev_id);
7004	cmn->scan_priority      = __cpu_to_le32(arg->scan_priority);
7005	cmn->notify_scan_events = __cpu_to_le32(arg->notify_scan_events);
7006	cmn->dwell_time_active  = __cpu_to_le32(arg->dwell_time_active);
7007	cmn->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive);
7008	cmn->min_rest_time      = __cpu_to_le32(arg->min_rest_time);
7009	cmn->max_rest_time      = __cpu_to_le32(arg->max_rest_time);
7010	cmn->repeat_probe_time  = __cpu_to_le32(arg->repeat_probe_time);
7011	cmn->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time);
7012	cmn->idle_time          = __cpu_to_le32(arg->idle_time);
7013	cmn->max_scan_time      = __cpu_to_le32(arg->max_scan_time);
7014	cmn->probe_delay        = __cpu_to_le32(arg->probe_delay);
7015	cmn->scan_ctrl_flags    = __cpu_to_le32(arg->scan_ctrl_flags);
7016}
7017
7018static void
7019ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs,
7020			       const struct wmi_start_scan_arg *arg)
7021{
7022	struct wmi_ie_data *ie;
7023	struct wmi_chan_list *channels;
7024	struct wmi_ssid_list *ssids;
7025	struct wmi_bssid_list *bssids;
7026#if defined(__linux__)
7027	void *ptr = tlvs->tlvs;
7028#elif defined(__FreeBSD__)
7029	u8 *ptr = (void *)tlvs->tlvs;
7030#endif
7031	int i;
7032
7033	if (arg->n_channels) {
7034#if defined(__linux__)
7035		channels = ptr;
7036#elif defined(__FreeBSD__)
7037		channels = (void *)ptr;
7038#endif
7039		channels->tag = __cpu_to_le32(WMI_CHAN_LIST_TAG);
7040		channels->num_chan = __cpu_to_le32(arg->n_channels);
7041
7042		for (i = 0; i < arg->n_channels; i++)
7043			channels->channel_list[i].freq =
7044				__cpu_to_le16(arg->channels[i]);
7045
7046		ptr += sizeof(*channels);
7047		ptr += sizeof(__le32) * arg->n_channels;
7048	}
7049
7050	if (arg->n_ssids) {
7051#if defined(__linux__)
7052		ssids = ptr;
7053#elif defined(__FreeBSD__)
7054		ssids = (void *)ptr;
7055#endif
7056		ssids->tag = __cpu_to_le32(WMI_SSID_LIST_TAG);
7057		ssids->num_ssids = __cpu_to_le32(arg->n_ssids);
7058
7059		for (i = 0; i < arg->n_ssids; i++) {
7060			ssids->ssids[i].ssid_len =
7061				__cpu_to_le32(arg->ssids[i].len);
7062			memcpy(&ssids->ssids[i].ssid,
7063			       arg->ssids[i].ssid,
7064			       arg->ssids[i].len);
7065		}
7066
7067		ptr += sizeof(*ssids);
7068		ptr += sizeof(struct wmi_ssid) * arg->n_ssids;
7069	}
7070
7071	if (arg->n_bssids) {
7072#if defined(__linux__)
7073		bssids = ptr;
7074#elif defined(__FreeBSD__)
7075		bssids = (void *)ptr;
7076#endif
7077		bssids->tag = __cpu_to_le32(WMI_BSSID_LIST_TAG);
7078		bssids->num_bssid = __cpu_to_le32(arg->n_bssids);
7079
7080		for (i = 0; i < arg->n_bssids; i++)
7081			ether_addr_copy(bssids->bssid_list[i].addr,
7082					arg->bssids[i].bssid);
7083
7084		ptr += sizeof(*bssids);
7085		ptr += sizeof(struct wmi_mac_addr) * arg->n_bssids;
7086	}
7087
7088	if (arg->ie_len) {
7089#if defined(__linux__)
7090		ie = ptr;
7091#elif defined(__FreeBSD__)
7092		ie = (void *)ptr;
7093#endif
7094		ie->tag = __cpu_to_le32(WMI_IE_TAG);
7095		ie->ie_len = __cpu_to_le32(arg->ie_len);
7096		memcpy(ie->ie_data, arg->ie, arg->ie_len);
7097
7098		ptr += sizeof(*ie);
7099		ptr += roundup(arg->ie_len, 4);
7100	}
7101}
7102
7103static struct sk_buff *
7104ath10k_wmi_op_gen_start_scan(struct ath10k *ar,
7105			     const struct wmi_start_scan_arg *arg)
7106{
7107	struct wmi_start_scan_cmd *cmd;
7108	struct sk_buff *skb;
7109	size_t len;
7110	int ret;
7111
7112	ret = ath10k_wmi_start_scan_verify(arg);
7113	if (ret)
7114		return ERR_PTR(ret);
7115
7116	len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
7117	skb = ath10k_wmi_alloc_skb(ar, len);
7118	if (!skb)
7119		return ERR_PTR(-ENOMEM);
7120
7121	cmd = (struct wmi_start_scan_cmd *)skb->data;
7122
7123	ath10k_wmi_put_start_scan_common(&cmd->common, arg);
7124	ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
7125
7126	cmd->burst_duration_ms = __cpu_to_le32(0);
7127
7128	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n");
7129	return skb;
7130}
7131
7132static struct sk_buff *
7133ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar,
7134				 const struct wmi_start_scan_arg *arg)
7135{
7136	struct wmi_10x_start_scan_cmd *cmd;
7137	struct sk_buff *skb;
7138	size_t len;
7139	int ret;
7140
7141	ret = ath10k_wmi_start_scan_verify(arg);
7142	if (ret)
7143		return ERR_PTR(ret);
7144
7145	len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
7146	skb = ath10k_wmi_alloc_skb(ar, len);
7147	if (!skb)
7148		return ERR_PTR(-ENOMEM);
7149
7150	cmd = (struct wmi_10x_start_scan_cmd *)skb->data;
7151
7152	ath10k_wmi_put_start_scan_common(&cmd->common, arg);
7153	ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
7154
7155	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n");
7156	return skb;
7157}
7158
7159void ath10k_wmi_start_scan_init(struct ath10k *ar,
7160				struct wmi_start_scan_arg *arg)
7161{
7162	/* setup commonly used values */
7163	arg->scan_req_id = 1;
7164	arg->scan_priority = WMI_SCAN_PRIORITY_LOW;
7165	arg->dwell_time_active = 50;
7166	arg->dwell_time_passive = 150;
7167	arg->min_rest_time = 50;
7168	arg->max_rest_time = 500;
7169	arg->repeat_probe_time = 0;
7170	arg->probe_spacing_time = 0;
7171	arg->idle_time = 0;
7172	arg->max_scan_time = 20000;
7173	arg->probe_delay = 5;
7174	arg->notify_scan_events = WMI_SCAN_EVENT_STARTED
7175		| WMI_SCAN_EVENT_COMPLETED
7176		| WMI_SCAN_EVENT_BSS_CHANNEL
7177		| WMI_SCAN_EVENT_FOREIGN_CHANNEL
7178		| WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT
7179		| WMI_SCAN_EVENT_DEQUEUED;
7180	arg->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
7181	arg->n_bssids = 1;
7182	arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF";
7183}
7184
7185static struct sk_buff *
7186ath10k_wmi_op_gen_stop_scan(struct ath10k *ar,
7187			    const struct wmi_stop_scan_arg *arg)
7188{
7189	struct wmi_stop_scan_cmd *cmd;
7190	struct sk_buff *skb;
7191	u32 scan_id;
7192	u32 req_id;
7193
7194	if (arg->req_id > 0xFFF)
7195		return ERR_PTR(-EINVAL);
7196	if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
7197		return ERR_PTR(-EINVAL);
7198
7199	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7200	if (!skb)
7201		return ERR_PTR(-ENOMEM);
7202
7203	scan_id = arg->u.scan_id;
7204	scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
7205
7206	req_id = arg->req_id;
7207	req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
7208
7209	cmd = (struct wmi_stop_scan_cmd *)skb->data;
7210	cmd->req_type    = __cpu_to_le32(arg->req_type);
7211	cmd->vdev_id     = __cpu_to_le32(arg->u.vdev_id);
7212	cmd->scan_id     = __cpu_to_le32(scan_id);
7213	cmd->scan_req_id = __cpu_to_le32(req_id);
7214
7215	ath10k_dbg(ar, ATH10K_DBG_WMI,
7216		   "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n",
7217		   arg->req_id, arg->req_type, arg->u.scan_id);
7218	return skb;
7219}
7220
7221static struct sk_buff *
7222ath10k_wmi_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id,
7223			      enum wmi_vdev_type type,
7224			      enum wmi_vdev_subtype subtype,
7225			      const u8 macaddr[ETH_ALEN])
7226{
7227	struct wmi_vdev_create_cmd *cmd;
7228	struct sk_buff *skb;
7229
7230	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7231	if (!skb)
7232		return ERR_PTR(-ENOMEM);
7233
7234	cmd = (struct wmi_vdev_create_cmd *)skb->data;
7235	cmd->vdev_id      = __cpu_to_le32(vdev_id);
7236	cmd->vdev_type    = __cpu_to_le32(type);
7237	cmd->vdev_subtype = __cpu_to_le32(subtype);
7238	ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
7239
7240	ath10k_dbg(ar, ATH10K_DBG_WMI,
7241		   "WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
7242		   vdev_id, type, subtype, macaddr);
7243	return skb;
7244}
7245
7246static struct sk_buff *
7247ath10k_wmi_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
7248{
7249	struct wmi_vdev_delete_cmd *cmd;
7250	struct sk_buff *skb;
7251
7252	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7253	if (!skb)
7254		return ERR_PTR(-ENOMEM);
7255
7256	cmd = (struct wmi_vdev_delete_cmd *)skb->data;
7257	cmd->vdev_id = __cpu_to_le32(vdev_id);
7258
7259	ath10k_dbg(ar, ATH10K_DBG_WMI,
7260		   "WMI vdev delete id %d\n", vdev_id);
7261	return skb;
7262}
7263
7264static struct sk_buff *
7265ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
7266			     const struct wmi_vdev_start_request_arg *arg,
7267			     bool restart)
7268{
7269	struct wmi_vdev_start_request_cmd *cmd;
7270	struct sk_buff *skb;
7271	const char *cmdname;
7272	u32 flags = 0;
7273
7274	if (WARN_ON(arg->hidden_ssid && !arg->ssid))
7275		return ERR_PTR(-EINVAL);
7276	if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
7277		return ERR_PTR(-EINVAL);
7278
7279	if (restart)
7280		cmdname = "restart";
7281	else
7282		cmdname = "start";
7283
7284	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7285	if (!skb)
7286		return ERR_PTR(-ENOMEM);
7287
7288	if (arg->hidden_ssid)
7289		flags |= WMI_VDEV_START_HIDDEN_SSID;
7290	if (arg->pmf_enabled)
7291		flags |= WMI_VDEV_START_PMF_ENABLED;
7292
7293	cmd = (struct wmi_vdev_start_request_cmd *)skb->data;
7294	cmd->vdev_id         = __cpu_to_le32(arg->vdev_id);
7295	cmd->disable_hw_ack  = __cpu_to_le32(arg->disable_hw_ack);
7296	cmd->beacon_interval = __cpu_to_le32(arg->bcn_intval);
7297	cmd->dtim_period     = __cpu_to_le32(arg->dtim_period);
7298	cmd->flags           = __cpu_to_le32(flags);
7299	cmd->bcn_tx_rate     = __cpu_to_le32(arg->bcn_tx_rate);
7300	cmd->bcn_tx_power    = __cpu_to_le32(arg->bcn_tx_power);
7301
7302	if (arg->ssid) {
7303		cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
7304		memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
7305	}
7306
7307	ath10k_wmi_put_wmi_channel(ar, &cmd->chan, &arg->channel);
7308
7309	ath10k_dbg(ar, ATH10K_DBG_WMI,
7310		   "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n",
7311		   cmdname, arg->vdev_id,
7312		   flags, arg->channel.freq, arg->channel.mode,
7313		   cmd->chan.flags, arg->channel.max_power);
7314
7315	return skb;
7316}
7317
7318static struct sk_buff *
7319ath10k_wmi_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
7320{
7321	struct wmi_vdev_stop_cmd *cmd;
7322	struct sk_buff *skb;
7323
7324	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7325	if (!skb)
7326		return ERR_PTR(-ENOMEM);
7327
7328	cmd = (struct wmi_vdev_stop_cmd *)skb->data;
7329	cmd->vdev_id = __cpu_to_le32(vdev_id);
7330
7331	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id);
7332	return skb;
7333}
7334
7335static struct sk_buff *
7336ath10k_wmi_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
7337			  const u8 *bssid)
7338{
7339	struct wmi_vdev_up_cmd *cmd;
7340	struct sk_buff *skb;
7341
7342	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7343	if (!skb)
7344		return ERR_PTR(-ENOMEM);
7345
7346	cmd = (struct wmi_vdev_up_cmd *)skb->data;
7347	cmd->vdev_id       = __cpu_to_le32(vdev_id);
7348	cmd->vdev_assoc_id = __cpu_to_le32(aid);
7349	ether_addr_copy(cmd->vdev_bssid.addr, bssid);
7350
7351	ath10k_dbg(ar, ATH10K_DBG_WMI,
7352		   "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
7353		   vdev_id, aid, bssid);
7354	return skb;
7355}
7356
7357static struct sk_buff *
7358ath10k_wmi_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
7359{
7360	struct wmi_vdev_down_cmd *cmd;
7361	struct sk_buff *skb;
7362
7363	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7364	if (!skb)
7365		return ERR_PTR(-ENOMEM);
7366
7367	cmd = (struct wmi_vdev_down_cmd *)skb->data;
7368	cmd->vdev_id = __cpu_to_le32(vdev_id);
7369
7370	ath10k_dbg(ar, ATH10K_DBG_WMI,
7371		   "wmi mgmt vdev down id 0x%x\n", vdev_id);
7372	return skb;
7373}
7374
7375static struct sk_buff *
7376ath10k_wmi_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
7377				 u32 param_id, u32 param_value)
7378{
7379	struct wmi_vdev_set_param_cmd *cmd;
7380	struct sk_buff *skb;
7381
7382	if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) {
7383		ath10k_dbg(ar, ATH10K_DBG_WMI,
7384			   "vdev param %d not supported by firmware\n",
7385			    param_id);
7386		return ERR_PTR(-EOPNOTSUPP);
7387	}
7388
7389	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7390	if (!skb)
7391		return ERR_PTR(-ENOMEM);
7392
7393	cmd = (struct wmi_vdev_set_param_cmd *)skb->data;
7394	cmd->vdev_id     = __cpu_to_le32(vdev_id);
7395	cmd->param_id    = __cpu_to_le32(param_id);
7396	cmd->param_value = __cpu_to_le32(param_value);
7397
7398	ath10k_dbg(ar, ATH10K_DBG_WMI,
7399		   "wmi vdev id 0x%x set param %d value %d\n",
7400		   vdev_id, param_id, param_value);
7401	return skb;
7402}
7403
7404static struct sk_buff *
7405ath10k_wmi_op_gen_vdev_install_key(struct ath10k *ar,
7406				   const struct wmi_vdev_install_key_arg *arg)
7407{
7408	struct wmi_vdev_install_key_cmd *cmd;
7409	struct sk_buff *skb;
7410
7411	if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
7412		return ERR_PTR(-EINVAL);
7413	if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
7414		return ERR_PTR(-EINVAL);
7415
7416	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len);
7417	if (!skb)
7418		return ERR_PTR(-ENOMEM);
7419
7420	cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
7421	cmd->vdev_id       = __cpu_to_le32(arg->vdev_id);
7422	cmd->key_idx       = __cpu_to_le32(arg->key_idx);
7423	cmd->key_flags     = __cpu_to_le32(arg->key_flags);
7424	cmd->key_cipher    = __cpu_to_le32(arg->key_cipher);
7425	cmd->key_len       = __cpu_to_le32(arg->key_len);
7426	cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
7427	cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
7428
7429	if (arg->macaddr)
7430		ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
7431	if (arg->key_data)
7432		memcpy(cmd->key_data, arg->key_data, arg->key_len);
7433
7434	ath10k_dbg(ar, ATH10K_DBG_WMI,
7435		   "wmi vdev install key idx %d cipher %d len %d\n",
7436		   arg->key_idx, arg->key_cipher, arg->key_len);
7437	return skb;
7438}
7439
7440static struct sk_buff *
7441ath10k_wmi_op_gen_vdev_spectral_conf(struct ath10k *ar,
7442				     const struct wmi_vdev_spectral_conf_arg *arg)
7443{
7444	struct wmi_vdev_spectral_conf_cmd *cmd;
7445	struct sk_buff *skb;
7446
7447	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7448	if (!skb)
7449		return ERR_PTR(-ENOMEM);
7450
7451	cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data;
7452	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
7453	cmd->scan_count = __cpu_to_le32(arg->scan_count);
7454	cmd->scan_period = __cpu_to_le32(arg->scan_period);
7455	cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
7456	cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
7457	cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
7458	cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
7459	cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
7460	cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
7461	cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
7462	cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
7463	cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
7464	cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
7465	cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
7466	cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
7467	cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
7468	cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
7469	cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
7470	cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
7471
7472	return skb;
7473}
7474
7475static struct sk_buff *
7476ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
7477				       u32 trigger, u32 enable)
7478{
7479	struct wmi_vdev_spectral_enable_cmd *cmd;
7480	struct sk_buff *skb;
7481
7482	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7483	if (!skb)
7484		return ERR_PTR(-ENOMEM);
7485
7486	cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data;
7487	cmd->vdev_id = __cpu_to_le32(vdev_id);
7488	cmd->trigger_cmd = __cpu_to_le32(trigger);
7489	cmd->enable_cmd = __cpu_to_le32(enable);
7490
7491	return skb;
7492}
7493
7494static struct sk_buff *
7495ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
7496			      const u8 peer_addr[ETH_ALEN],
7497			      enum wmi_peer_type peer_type)
7498{
7499	struct wmi_peer_create_cmd *cmd;
7500	struct sk_buff *skb;
7501
7502	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7503	if (!skb)
7504		return ERR_PTR(-ENOMEM);
7505
7506	cmd = (struct wmi_peer_create_cmd *)skb->data;
7507	cmd->vdev_id = __cpu_to_le32(vdev_id);
7508	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
7509	cmd->peer_type = __cpu_to_le32(peer_type);
7510
7511	ath10k_dbg(ar, ATH10K_DBG_WMI,
7512		   "wmi peer create vdev_id %d peer_addr %pM\n",
7513		   vdev_id, peer_addr);
7514	return skb;
7515}
7516
7517static struct sk_buff *
7518ath10k_wmi_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
7519			      const u8 peer_addr[ETH_ALEN])
7520{
7521	struct wmi_peer_delete_cmd *cmd;
7522	struct sk_buff *skb;
7523
7524	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7525	if (!skb)
7526		return ERR_PTR(-ENOMEM);
7527
7528	cmd = (struct wmi_peer_delete_cmd *)skb->data;
7529	cmd->vdev_id = __cpu_to_le32(vdev_id);
7530	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
7531
7532	ath10k_dbg(ar, ATH10K_DBG_WMI,
7533		   "wmi peer delete vdev_id %d peer_addr %pM\n",
7534		   vdev_id, peer_addr);
7535	return skb;
7536}
7537
7538static struct sk_buff *
7539ath10k_wmi_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
7540			     const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
7541{
7542	struct wmi_peer_flush_tids_cmd *cmd;
7543	struct sk_buff *skb;
7544
7545	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7546	if (!skb)
7547		return ERR_PTR(-ENOMEM);
7548
7549	cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
7550	cmd->vdev_id         = __cpu_to_le32(vdev_id);
7551	cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
7552	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
7553
7554	ath10k_dbg(ar, ATH10K_DBG_WMI,
7555		   "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
7556		   vdev_id, peer_addr, tid_bitmap);
7557	return skb;
7558}
7559
7560static struct sk_buff *
7561ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
7562				 const u8 *peer_addr,
7563				 enum wmi_peer_param param_id,
7564				 u32 param_value)
7565{
7566	struct wmi_peer_set_param_cmd *cmd;
7567	struct sk_buff *skb;
7568
7569	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7570	if (!skb)
7571		return ERR_PTR(-ENOMEM);
7572
7573	cmd = (struct wmi_peer_set_param_cmd *)skb->data;
7574	cmd->vdev_id     = __cpu_to_le32(vdev_id);
7575	cmd->param_id    = __cpu_to_le32(param_id);
7576	cmd->param_value = __cpu_to_le32(param_value);
7577	ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
7578
7579	ath10k_dbg(ar, ATH10K_DBG_WMI,
7580		   "wmi vdev %d peer 0x%pM set param %d value %d\n",
7581		   vdev_id, peer_addr, param_id, param_value);
7582	return skb;
7583}
7584
7585static struct sk_buff *
7586ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
7587			     enum wmi_sta_ps_mode psmode)
7588{
7589	struct wmi_sta_powersave_mode_cmd *cmd;
7590	struct sk_buff *skb;
7591
7592	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7593	if (!skb)
7594		return ERR_PTR(-ENOMEM);
7595
7596	cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data;
7597	cmd->vdev_id     = __cpu_to_le32(vdev_id);
7598	cmd->sta_ps_mode = __cpu_to_le32(psmode);
7599
7600	ath10k_dbg(ar, ATH10K_DBG_WMI,
7601		   "wmi set powersave id 0x%x mode %d\n",
7602		   vdev_id, psmode);
7603	return skb;
7604}
7605
7606static struct sk_buff *
7607ath10k_wmi_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
7608			     enum wmi_sta_powersave_param param_id,
7609			     u32 value)
7610{
7611	struct wmi_sta_powersave_param_cmd *cmd;
7612	struct sk_buff *skb;
7613
7614	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7615	if (!skb)
7616		return ERR_PTR(-ENOMEM);
7617
7618	cmd = (struct wmi_sta_powersave_param_cmd *)skb->data;
7619	cmd->vdev_id     = __cpu_to_le32(vdev_id);
7620	cmd->param_id    = __cpu_to_le32(param_id);
7621	cmd->param_value = __cpu_to_le32(value);
7622
7623	ath10k_dbg(ar, ATH10K_DBG_STA,
7624		   "wmi sta ps param vdev_id 0x%x param %d value %d\n",
7625		   vdev_id, param_id, value);
7626	return skb;
7627}
7628
7629static struct sk_buff *
7630ath10k_wmi_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
7631			    enum wmi_ap_ps_peer_param param_id, u32 value)
7632{
7633	struct wmi_ap_ps_peer_cmd *cmd;
7634	struct sk_buff *skb;
7635
7636	if (!mac)
7637		return ERR_PTR(-EINVAL);
7638
7639	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7640	if (!skb)
7641		return ERR_PTR(-ENOMEM);
7642
7643	cmd = (struct wmi_ap_ps_peer_cmd *)skb->data;
7644	cmd->vdev_id = __cpu_to_le32(vdev_id);
7645	cmd->param_id = __cpu_to_le32(param_id);
7646	cmd->param_value = __cpu_to_le32(value);
7647	ether_addr_copy(cmd->peer_macaddr.addr, mac);
7648
7649	ath10k_dbg(ar, ATH10K_DBG_WMI,
7650		   "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
7651		   vdev_id, param_id, value, mac);
7652	return skb;
7653}
7654
7655static struct sk_buff *
7656ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
7657				 const struct wmi_scan_chan_list_arg *arg)
7658{
7659	struct wmi_scan_chan_list_cmd *cmd;
7660	struct sk_buff *skb;
7661	struct wmi_channel_arg *ch;
7662	struct wmi_channel *ci;
7663	int i;
7664
7665	skb = ath10k_wmi_alloc_skb(ar, struct_size(cmd, chan_info, arg->n_channels));
7666	if (!skb)
7667		return ERR_PTR(-EINVAL);
7668
7669	cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
7670	cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
7671
7672	for (i = 0; i < arg->n_channels; i++) {
7673		ch = &arg->channels[i];
7674		ci = &cmd->chan_info[i];
7675
7676		ath10k_wmi_put_wmi_channel(ar, ci, ch);
7677	}
7678
7679	return skb;
7680}
7681
7682static void
7683ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf,
7684			   const struct wmi_peer_assoc_complete_arg *arg)
7685{
7686	struct wmi_common_peer_assoc_complete_cmd *cmd = buf;
7687
7688	cmd->vdev_id            = __cpu_to_le32(arg->vdev_id);
7689	cmd->peer_new_assoc     = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
7690	cmd->peer_associd       = __cpu_to_le32(arg->peer_aid);
7691	cmd->peer_flags         = __cpu_to_le32(arg->peer_flags);
7692	cmd->peer_caps          = __cpu_to_le32(arg->peer_caps);
7693	cmd->peer_listen_intval = __cpu_to_le32(arg->peer_listen_intval);
7694	cmd->peer_ht_caps       = __cpu_to_le32(arg->peer_ht_caps);
7695	cmd->peer_max_mpdu      = __cpu_to_le32(arg->peer_max_mpdu);
7696	cmd->peer_mpdu_density  = __cpu_to_le32(arg->peer_mpdu_density);
7697	cmd->peer_rate_caps     = __cpu_to_le32(arg->peer_rate_caps);
7698	cmd->peer_nss           = __cpu_to_le32(arg->peer_num_spatial_streams);
7699	cmd->peer_vht_caps      = __cpu_to_le32(arg->peer_vht_caps);
7700	cmd->peer_phymode       = __cpu_to_le32(arg->peer_phymode);
7701
7702	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
7703
7704	cmd->peer_legacy_rates.num_rates =
7705		__cpu_to_le32(arg->peer_legacy_rates.num_rates);
7706	memcpy(cmd->peer_legacy_rates.rates, arg->peer_legacy_rates.rates,
7707	       arg->peer_legacy_rates.num_rates);
7708
7709	cmd->peer_ht_rates.num_rates =
7710		__cpu_to_le32(arg->peer_ht_rates.num_rates);
7711	memcpy(cmd->peer_ht_rates.rates, arg->peer_ht_rates.rates,
7712	       arg->peer_ht_rates.num_rates);
7713
7714	cmd->peer_vht_rates.rx_max_rate =
7715		__cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
7716	cmd->peer_vht_rates.rx_mcs_set =
7717		__cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
7718	cmd->peer_vht_rates.tx_max_rate =
7719		__cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
7720	cmd->peer_vht_rates.tx_mcs_set =
7721		__cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
7722}
7723
7724static void
7725ath10k_wmi_peer_assoc_fill_main(struct ath10k *ar, void *buf,
7726				const struct wmi_peer_assoc_complete_arg *arg)
7727{
7728	struct wmi_main_peer_assoc_complete_cmd *cmd = buf;
7729
7730	ath10k_wmi_peer_assoc_fill(ar, buf, arg);
7731	memset(cmd->peer_ht_info, 0, sizeof(cmd->peer_ht_info));
7732}
7733
7734static void
7735ath10k_wmi_peer_assoc_fill_10_1(struct ath10k *ar, void *buf,
7736				const struct wmi_peer_assoc_complete_arg *arg)
7737{
7738	ath10k_wmi_peer_assoc_fill(ar, buf, arg);
7739}
7740
7741static void
7742ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf,
7743				const struct wmi_peer_assoc_complete_arg *arg)
7744{
7745	struct wmi_10_2_peer_assoc_complete_cmd *cmd = buf;
7746	int max_mcs, max_nss;
7747	u32 info0;
7748
7749	/* TODO: Is using max values okay with firmware? */
7750	max_mcs = 0xf;
7751	max_nss = 0xf;
7752
7753	info0 = SM(max_mcs, WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX) |
7754		SM(max_nss, WMI_PEER_ASSOC_INFO0_MAX_NSS);
7755
7756	ath10k_wmi_peer_assoc_fill(ar, buf, arg);
7757	cmd->info0 = __cpu_to_le32(info0);
7758}
7759
7760static void
7761ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
7762				const struct wmi_peer_assoc_complete_arg *arg)
7763{
7764	struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
7765
7766	ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
7767	cmd->peer_bw_rxnss_override =
7768		__cpu_to_le32(arg->peer_bw_rxnss_override);
7769}
7770
7771static int
7772ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
7773{
7774	if (arg->peer_mpdu_density > 16)
7775		return -EINVAL;
7776	if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
7777		return -EINVAL;
7778	if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
7779		return -EINVAL;
7780
7781	return 0;
7782}
7783
7784static struct sk_buff *
7785ath10k_wmi_op_gen_peer_assoc(struct ath10k *ar,
7786			     const struct wmi_peer_assoc_complete_arg *arg)
7787{
7788	size_t len = sizeof(struct wmi_main_peer_assoc_complete_cmd);
7789	struct sk_buff *skb;
7790	int ret;
7791
7792	ret = ath10k_wmi_peer_assoc_check_arg(arg);
7793	if (ret)
7794		return ERR_PTR(ret);
7795
7796	skb = ath10k_wmi_alloc_skb(ar, len);
7797	if (!skb)
7798		return ERR_PTR(-ENOMEM);
7799
7800	ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg);
7801
7802	ath10k_dbg(ar, ATH10K_DBG_WMI,
7803		   "wmi peer assoc vdev %d addr %pM (%s)\n",
7804		   arg->vdev_id, arg->addr,
7805		   arg->peer_reassoc ? "reassociate" : "new");
7806	return skb;
7807}
7808
7809static struct sk_buff *
7810ath10k_wmi_10_1_op_gen_peer_assoc(struct ath10k *ar,
7811				  const struct wmi_peer_assoc_complete_arg *arg)
7812{
7813	size_t len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd);
7814	struct sk_buff *skb;
7815	int ret;
7816
7817	ret = ath10k_wmi_peer_assoc_check_arg(arg);
7818	if (ret)
7819		return ERR_PTR(ret);
7820
7821	skb = ath10k_wmi_alloc_skb(ar, len);
7822	if (!skb)
7823		return ERR_PTR(-ENOMEM);
7824
7825	ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg);
7826
7827	ath10k_dbg(ar, ATH10K_DBG_WMI,
7828		   "wmi peer assoc vdev %d addr %pM (%s)\n",
7829		   arg->vdev_id, arg->addr,
7830		   arg->peer_reassoc ? "reassociate" : "new");
7831	return skb;
7832}
7833
7834static struct sk_buff *
7835ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
7836				  const struct wmi_peer_assoc_complete_arg *arg)
7837{
7838	size_t len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd);
7839	struct sk_buff *skb;
7840	int ret;
7841
7842	ret = ath10k_wmi_peer_assoc_check_arg(arg);
7843	if (ret)
7844		return ERR_PTR(ret);
7845
7846	skb = ath10k_wmi_alloc_skb(ar, len);
7847	if (!skb)
7848		return ERR_PTR(-ENOMEM);
7849
7850	ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg);
7851
7852	ath10k_dbg(ar, ATH10K_DBG_WMI,
7853		   "wmi peer assoc vdev %d addr %pM (%s)\n",
7854		   arg->vdev_id, arg->addr,
7855		   arg->peer_reassoc ? "reassociate" : "new");
7856	return skb;
7857}
7858
7859static struct sk_buff *
7860ath10k_wmi_10_4_op_gen_peer_assoc(struct ath10k *ar,
7861				  const struct wmi_peer_assoc_complete_arg *arg)
7862{
7863	size_t len = sizeof(struct wmi_10_4_peer_assoc_complete_cmd);
7864	struct sk_buff *skb;
7865	int ret;
7866
7867	ret = ath10k_wmi_peer_assoc_check_arg(arg);
7868	if (ret)
7869		return ERR_PTR(ret);
7870
7871	skb = ath10k_wmi_alloc_skb(ar, len);
7872	if (!skb)
7873		return ERR_PTR(-ENOMEM);
7874
7875	ath10k_wmi_peer_assoc_fill_10_4(ar, skb->data, arg);
7876
7877	ath10k_dbg(ar, ATH10K_DBG_WMI,
7878		   "wmi peer assoc vdev %d addr %pM (%s)\n",
7879		   arg->vdev_id, arg->addr,
7880		   arg->peer_reassoc ? "reassociate" : "new");
7881	return skb;
7882}
7883
7884static struct sk_buff *
7885ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
7886{
7887	struct sk_buff *skb;
7888
7889	skb = ath10k_wmi_alloc_skb(ar, 0);
7890	if (!skb)
7891		return ERR_PTR(-ENOMEM);
7892
7893	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature\n");
7894	return skb;
7895}
7896
7897static struct sk_buff *
7898ath10k_wmi_10_2_op_gen_pdev_bss_chan_info(struct ath10k *ar,
7899					  enum wmi_bss_survey_req_type type)
7900{
7901	struct wmi_pdev_chan_info_req_cmd *cmd;
7902	struct sk_buff *skb;
7903
7904	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7905	if (!skb)
7906		return ERR_PTR(-ENOMEM);
7907
7908	cmd = (struct wmi_pdev_chan_info_req_cmd *)skb->data;
7909	cmd->type = __cpu_to_le32(type);
7910
7911	ath10k_dbg(ar, ATH10K_DBG_WMI,
7912		   "wmi pdev bss info request type %d\n", type);
7913
7914	return skb;
7915}
7916
7917/* This function assumes the beacon is already DMA mapped */
7918static struct sk_buff *
7919ath10k_wmi_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, const void *bcn,
7920			     size_t bcn_len, u32 bcn_paddr, bool dtim_zero,
7921			     bool deliver_cab)
7922{
7923	struct wmi_bcn_tx_ref_cmd *cmd;
7924	struct sk_buff *skb;
7925#if defined(__linux__)
7926	struct ieee80211_hdr *hdr;
7927#elif defined(__FreeBSD__)
7928	const struct ieee80211_hdr *hdr;
7929#endif
7930	u16 fc;
7931
7932	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7933	if (!skb)
7934		return ERR_PTR(-ENOMEM);
7935
7936#if defined(__linux__)
7937	hdr = (struct ieee80211_hdr *)bcn;
7938#elif defined(__FreeBSD__)
7939	hdr = (const struct ieee80211_hdr *)bcn;
7940#endif
7941	fc = le16_to_cpu(hdr->frame_control);
7942
7943	cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data;
7944	cmd->vdev_id = __cpu_to_le32(vdev_id);
7945	cmd->data_len = __cpu_to_le32(bcn_len);
7946	cmd->data_ptr = __cpu_to_le32(bcn_paddr);
7947	cmd->msdu_id = 0;
7948	cmd->frame_control = __cpu_to_le32(fc);
7949	cmd->flags = 0;
7950	cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA);
7951
7952	if (dtim_zero)
7953		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
7954
7955	if (deliver_cab)
7956		cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
7957
7958	return skb;
7959}
7960
7961void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params,
7962			      const struct wmi_wmm_params_arg *arg)
7963{
7964	params->cwmin  = __cpu_to_le32(arg->cwmin);
7965	params->cwmax  = __cpu_to_le32(arg->cwmax);
7966	params->aifs   = __cpu_to_le32(arg->aifs);
7967	params->txop   = __cpu_to_le32(arg->txop);
7968	params->acm    = __cpu_to_le32(arg->acm);
7969	params->no_ack = __cpu_to_le32(arg->no_ack);
7970}
7971
7972static struct sk_buff *
7973ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
7974			       const struct wmi_wmm_params_all_arg *arg)
7975{
7976	struct wmi_pdev_set_wmm_params *cmd;
7977	struct sk_buff *skb;
7978
7979	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7980	if (!skb)
7981		return ERR_PTR(-ENOMEM);
7982
7983	cmd = (struct wmi_pdev_set_wmm_params *)skb->data;
7984	ath10k_wmi_set_wmm_param(&cmd->ac_be, &arg->ac_be);
7985	ath10k_wmi_set_wmm_param(&cmd->ac_bk, &arg->ac_bk);
7986	ath10k_wmi_set_wmm_param(&cmd->ac_vi, &arg->ac_vi);
7987	ath10k_wmi_set_wmm_param(&cmd->ac_vo, &arg->ac_vo);
7988
7989	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n");
7990	return skb;
7991}
7992
7993static struct sk_buff *
7994ath10k_wmi_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
7995{
7996	struct wmi_request_stats_cmd *cmd;
7997	struct sk_buff *skb;
7998
7999	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8000	if (!skb)
8001		return ERR_PTR(-ENOMEM);
8002
8003	cmd = (struct wmi_request_stats_cmd *)skb->data;
8004	cmd->stats_id = __cpu_to_le32(stats_mask);
8005
8006	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats 0x%08x\n",
8007		   stats_mask);
8008	return skb;
8009}
8010
8011static struct sk_buff *
8012ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar,
8013				enum wmi_force_fw_hang_type type, u32 delay_ms)
8014{
8015	struct wmi_force_fw_hang_cmd *cmd;
8016	struct sk_buff *skb;
8017
8018	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8019	if (!skb)
8020		return ERR_PTR(-ENOMEM);
8021
8022	cmd = (struct wmi_force_fw_hang_cmd *)skb->data;
8023	cmd->type = __cpu_to_le32(type);
8024	cmd->delay_ms = __cpu_to_le32(delay_ms);
8025
8026	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n",
8027		   type, delay_ms);
8028	return skb;
8029}
8030
8031static struct sk_buff *
8032ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
8033			     u32 log_level)
8034{
8035	struct wmi_dbglog_cfg_cmd *cmd;
8036	struct sk_buff *skb;
8037	u32 cfg;
8038
8039	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8040	if (!skb)
8041		return ERR_PTR(-ENOMEM);
8042
8043	cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;
8044
8045	if (module_enable) {
8046		cfg = SM(log_level,
8047			 ATH10K_DBGLOG_CFG_LOG_LVL);
8048	} else {
8049		/* set back defaults, all modules with WARN level */
8050		cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,
8051			 ATH10K_DBGLOG_CFG_LOG_LVL);
8052		module_enable = ~0;
8053	}
8054
8055	cmd->module_enable = __cpu_to_le32(module_enable);
8056	cmd->module_valid = __cpu_to_le32(~0);
8057	cmd->config_enable = __cpu_to_le32(cfg);
8058	cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);
8059
8060	ath10k_dbg(ar, ATH10K_DBG_WMI,
8061		   "wmi dbglog cfg modules %08x %08x config %08x %08x\n",
8062		   __le32_to_cpu(cmd->module_enable),
8063		   __le32_to_cpu(cmd->module_valid),
8064		   __le32_to_cpu(cmd->config_enable),
8065		   __le32_to_cpu(cmd->config_valid));
8066	return skb;
8067}
8068
8069static struct sk_buff *
8070ath10k_wmi_10_4_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
8071				  u32 log_level)
8072{
8073	struct wmi_10_4_dbglog_cfg_cmd *cmd;
8074	struct sk_buff *skb;
8075	u32 cfg;
8076
8077	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8078	if (!skb)
8079		return ERR_PTR(-ENOMEM);
8080
8081	cmd = (struct wmi_10_4_dbglog_cfg_cmd *)skb->data;
8082
8083	if (module_enable) {
8084		cfg = SM(log_level,
8085			 ATH10K_DBGLOG_CFG_LOG_LVL);
8086	} else {
8087		/* set back defaults, all modules with WARN level */
8088		cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,
8089			 ATH10K_DBGLOG_CFG_LOG_LVL);
8090		module_enable = ~0;
8091	}
8092
8093	cmd->module_enable = __cpu_to_le64(module_enable);
8094	cmd->module_valid = __cpu_to_le64(~0);
8095	cmd->config_enable = __cpu_to_le32(cfg);
8096	cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);
8097
8098	ath10k_dbg(ar, ATH10K_DBG_WMI,
8099#if defined(__linux__)
8100		   "wmi dbglog cfg modules 0x%016llx 0x%016llx config %08x %08x\n",
8101		   __le64_to_cpu(cmd->module_enable),
8102		   __le64_to_cpu(cmd->module_valid),
8103#elif defined(__FreeBSD__)
8104		   "wmi dbglog cfg modules 0x%016jx 0x%016jx config %08x %08x\n",
8105		   (uintmax_t)__le64_to_cpu(cmd->module_enable),
8106		   (uintmax_t)__le64_to_cpu(cmd->module_valid),
8107#endif
8108		   __le32_to_cpu(cmd->config_enable),
8109		   __le32_to_cpu(cmd->config_valid));
8110	return skb;
8111}
8112
8113static struct sk_buff *
8114ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap)
8115{
8116	struct wmi_pdev_pktlog_enable_cmd *cmd;
8117	struct sk_buff *skb;
8118
8119	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8120	if (!skb)
8121		return ERR_PTR(-ENOMEM);
8122
8123	ev_bitmap &= ATH10K_PKTLOG_ANY;
8124
8125	cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data;
8126	cmd->ev_bitmap = __cpu_to_le32(ev_bitmap);
8127
8128	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi enable pktlog filter 0x%08x\n",
8129		   ev_bitmap);
8130	return skb;
8131}
8132
8133static struct sk_buff *
8134ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar)
8135{
8136	struct sk_buff *skb;
8137
8138	skb = ath10k_wmi_alloc_skb(ar, 0);
8139	if (!skb)
8140		return ERR_PTR(-ENOMEM);
8141
8142	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n");
8143	return skb;
8144}
8145
8146static struct sk_buff *
8147ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
8148				      u32 duration, u32 next_offset,
8149				      u32 enabled)
8150{
8151	struct wmi_pdev_set_quiet_cmd *cmd;
8152	struct sk_buff *skb;
8153
8154	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8155	if (!skb)
8156		return ERR_PTR(-ENOMEM);
8157
8158	cmd = (struct wmi_pdev_set_quiet_cmd *)skb->data;
8159	cmd->period = __cpu_to_le32(period);
8160	cmd->duration = __cpu_to_le32(duration);
8161	cmd->next_start = __cpu_to_le32(next_offset);
8162	cmd->enabled = __cpu_to_le32(enabled);
8163
8164	ath10k_dbg(ar, ATH10K_DBG_WMI,
8165		   "wmi quiet param: period %u duration %u enabled %d\n",
8166		   period, duration, enabled);
8167	return skb;
8168}
8169
8170static struct sk_buff *
8171ath10k_wmi_op_gen_addba_clear_resp(struct ath10k *ar, u32 vdev_id,
8172				   const u8 *mac)
8173{
8174	struct wmi_addba_clear_resp_cmd *cmd;
8175	struct sk_buff *skb;
8176
8177	if (!mac)
8178		return ERR_PTR(-EINVAL);
8179
8180	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8181	if (!skb)
8182		return ERR_PTR(-ENOMEM);
8183
8184	cmd = (struct wmi_addba_clear_resp_cmd *)skb->data;
8185	cmd->vdev_id = __cpu_to_le32(vdev_id);
8186	ether_addr_copy(cmd->peer_macaddr.addr, mac);
8187
8188	ath10k_dbg(ar, ATH10K_DBG_WMI,
8189		   "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n",
8190		   vdev_id, mac);
8191	return skb;
8192}
8193
8194static struct sk_buff *
8195ath10k_wmi_op_gen_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
8196			     u32 tid, u32 buf_size)
8197{
8198	struct wmi_addba_send_cmd *cmd;
8199	struct sk_buff *skb;
8200
8201	if (!mac)
8202		return ERR_PTR(-EINVAL);
8203
8204	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8205	if (!skb)
8206		return ERR_PTR(-ENOMEM);
8207
8208	cmd = (struct wmi_addba_send_cmd *)skb->data;
8209	cmd->vdev_id = __cpu_to_le32(vdev_id);
8210	ether_addr_copy(cmd->peer_macaddr.addr, mac);
8211	cmd->tid = __cpu_to_le32(tid);
8212	cmd->buffersize = __cpu_to_le32(buf_size);
8213
8214	ath10k_dbg(ar, ATH10K_DBG_WMI,
8215		   "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
8216		   vdev_id, mac, tid, buf_size);
8217	return skb;
8218}
8219
8220static struct sk_buff *
8221ath10k_wmi_op_gen_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac,
8222				 u32 tid, u32 status)
8223{
8224	struct wmi_addba_setresponse_cmd *cmd;
8225	struct sk_buff *skb;
8226
8227	if (!mac)
8228		return ERR_PTR(-EINVAL);
8229
8230	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8231	if (!skb)
8232		return ERR_PTR(-ENOMEM);
8233
8234	cmd = (struct wmi_addba_setresponse_cmd *)skb->data;
8235	cmd->vdev_id = __cpu_to_le32(vdev_id);
8236	ether_addr_copy(cmd->peer_macaddr.addr, mac);
8237	cmd->tid = __cpu_to_le32(tid);
8238	cmd->statuscode = __cpu_to_le32(status);
8239
8240	ath10k_dbg(ar, ATH10K_DBG_WMI,
8241		   "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
8242		   vdev_id, mac, tid, status);
8243	return skb;
8244}
8245
8246static struct sk_buff *
8247ath10k_wmi_op_gen_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
8248			     u32 tid, u32 initiator, u32 reason)
8249{
8250	struct wmi_delba_send_cmd *cmd;
8251	struct sk_buff *skb;
8252
8253	if (!mac)
8254		return ERR_PTR(-EINVAL);
8255
8256	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8257	if (!skb)
8258		return ERR_PTR(-ENOMEM);
8259
8260	cmd = (struct wmi_delba_send_cmd *)skb->data;
8261	cmd->vdev_id = __cpu_to_le32(vdev_id);
8262	ether_addr_copy(cmd->peer_macaddr.addr, mac);
8263	cmd->tid = __cpu_to_le32(tid);
8264	cmd->initiator = __cpu_to_le32(initiator);
8265	cmd->reasoncode = __cpu_to_le32(reason);
8266
8267	ath10k_dbg(ar, ATH10K_DBG_WMI,
8268		   "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
8269		   vdev_id, mac, tid, initiator, reason);
8270	return skb;
8271}
8272
8273static struct sk_buff *
8274ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config(struct ath10k *ar, u32 param)
8275{
8276	struct wmi_pdev_get_tpc_config_cmd *cmd;
8277	struct sk_buff *skb;
8278
8279	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8280	if (!skb)
8281		return ERR_PTR(-ENOMEM);
8282
8283	cmd = (struct wmi_pdev_get_tpc_config_cmd *)skb->data;
8284	cmd->param = __cpu_to_le32(param);
8285
8286	ath10k_dbg(ar, ATH10K_DBG_WMI,
8287		   "wmi pdev get tpc config param %d\n", param);
8288	return skb;
8289}
8290
8291static void
8292ath10k_wmi_fw_pdev_base_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
8293				   char *buf, u32 *length)
8294{
8295	u32 len = *length;
8296	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8297
8298	len += scnprintf(buf + len, buf_len - len, "\n");
8299	len += scnprintf(buf + len, buf_len - len, "%30s\n",
8300			"ath10k PDEV stats");
8301	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8302			"=================");
8303
8304	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8305			"Channel noise floor", pdev->ch_noise_floor);
8306	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8307			"Channel TX power", pdev->chan_tx_power);
8308	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8309			"TX frame count", pdev->tx_frame_count);
8310	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8311			"RX frame count", pdev->rx_frame_count);
8312	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8313			"RX clear count", pdev->rx_clear_count);
8314	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8315			"Cycle count", pdev->cycle_count);
8316	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8317			"PHY error count", pdev->phy_err_count);
8318
8319	*length = len;
8320}
8321
8322static void
8323ath10k_wmi_fw_pdev_extra_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
8324				    char *buf, u32 *length)
8325{
8326	u32 len = *length;
8327	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8328
8329	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8330			"RTS bad count", pdev->rts_bad);
8331	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8332			"RTS good count", pdev->rts_good);
8333	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8334			"FCS bad count", pdev->fcs_bad);
8335	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8336			"No beacon count", pdev->no_beacons);
8337	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
8338			"MIB int count", pdev->mib_int_count);
8339
8340	len += scnprintf(buf + len, buf_len - len, "\n");
8341	*length = len;
8342}
8343
8344static void
8345ath10k_wmi_fw_pdev_tx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
8346				 char *buf, u32 *length)
8347{
8348	u32 len = *length;
8349	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8350
8351	len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
8352			 "ath10k PDEV TX stats");
8353	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8354				 "=================");
8355
8356	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8357			 "HTT cookies queued", pdev->comp_queued);
8358	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8359			 "HTT cookies disp.", pdev->comp_delivered);
8360	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8361			 "MSDU queued", pdev->msdu_enqued);
8362	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8363			 "MPDU queued", pdev->mpdu_enqued);
8364	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8365			 "MSDUs dropped", pdev->wmm_drop);
8366	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8367			 "Local enqued", pdev->local_enqued);
8368	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8369			 "Local freed", pdev->local_freed);
8370	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8371			 "HW queued", pdev->hw_queued);
8372	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8373			 "PPDUs reaped", pdev->hw_reaped);
8374	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8375			 "Num underruns", pdev->underrun);
8376	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8377			 "PPDUs cleaned", pdev->tx_abort);
8378	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8379			 "MPDUs requeued", pdev->mpdus_requeued);
8380	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8381			 "Excessive retries", pdev->tx_ko);
8382	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8383			 "HW rate", pdev->data_rc);
8384	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8385			 "Sched self triggers", pdev->self_triggers);
8386	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8387			 "Dropped due to SW retries",
8388			 pdev->sw_retry_failure);
8389	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8390			 "Illegal rate phy errors",
8391			 pdev->illgl_rate_phy_err);
8392	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8393			 "Pdev continuous xretry", pdev->pdev_cont_xretry);
8394	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8395			 "TX timeout", pdev->pdev_tx_timeout);
8396	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8397			 "PDEV resets", pdev->pdev_resets);
8398	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8399			 "PHY underrun", pdev->phy_underrun);
8400	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8401			 "MPDU is more than txop limit", pdev->txop_ovf);
8402	*length = len;
8403}
8404
8405static void
8406ath10k_wmi_fw_pdev_rx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
8407				 char *buf, u32 *length)
8408{
8409	u32 len = *length;
8410	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8411
8412	len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
8413			 "ath10k PDEV RX stats");
8414	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8415				 "=================");
8416
8417	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8418			 "Mid PPDU route change",
8419			 pdev->mid_ppdu_route_change);
8420	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8421			 "Tot. number of statuses", pdev->status_rcvd);
8422	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8423			 "Extra frags on rings 0", pdev->r0_frags);
8424	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8425			 "Extra frags on rings 1", pdev->r1_frags);
8426	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8427			 "Extra frags on rings 2", pdev->r2_frags);
8428	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8429			 "Extra frags on rings 3", pdev->r3_frags);
8430	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8431			 "MSDUs delivered to HTT", pdev->htt_msdus);
8432	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8433			 "MPDUs delivered to HTT", pdev->htt_mpdus);
8434	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8435			 "MSDUs delivered to stack", pdev->loc_msdus);
8436	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8437			 "MPDUs delivered to stack", pdev->loc_mpdus);
8438	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8439			 "Oversized AMSDUs", pdev->oversize_amsdu);
8440	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8441			 "PHY errors", pdev->phy_errs);
8442	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8443			 "PHY errors drops", pdev->phy_err_drop);
8444	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8445			 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
8446	*length = len;
8447}
8448
8449static void
8450ath10k_wmi_fw_vdev_stats_fill(const struct ath10k_fw_stats_vdev *vdev,
8451			      char *buf, u32 *length)
8452{
8453	u32 len = *length;
8454	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8455	int i;
8456
8457	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8458			"vdev id", vdev->vdev_id);
8459	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8460			"beacon snr", vdev->beacon_snr);
8461	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8462			"data snr", vdev->data_snr);
8463	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8464			"num rx frames", vdev->num_rx_frames);
8465	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8466			"num rts fail", vdev->num_rts_fail);
8467	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8468			"num rts success", vdev->num_rts_success);
8469	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8470			"num rx err", vdev->num_rx_err);
8471	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8472			"num rx discard", vdev->num_rx_discard);
8473	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8474			"num tx not acked", vdev->num_tx_not_acked);
8475
8476	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
8477		len += scnprintf(buf + len, buf_len - len,
8478				"%25s [%02d] %u\n",
8479				"num tx frames", i,
8480				vdev->num_tx_frames[i]);
8481
8482	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
8483		len += scnprintf(buf + len, buf_len - len,
8484				"%25s [%02d] %u\n",
8485				"num tx frames retries", i,
8486				vdev->num_tx_frames_retries[i]);
8487
8488	for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
8489		len += scnprintf(buf + len, buf_len - len,
8490				"%25s [%02d] %u\n",
8491				"num tx frames failures", i,
8492				vdev->num_tx_frames_failures[i]);
8493
8494	for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
8495		len += scnprintf(buf + len, buf_len - len,
8496				"%25s [%02d] 0x%08x\n",
8497				"tx rate history", i,
8498				vdev->tx_rate_history[i]);
8499
8500	for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
8501		len += scnprintf(buf + len, buf_len - len,
8502				"%25s [%02d] %u\n",
8503				"beacon rssi history", i,
8504				vdev->beacon_rssi_history[i]);
8505
8506	len += scnprintf(buf + len, buf_len - len, "\n");
8507	*length = len;
8508}
8509
8510static void
8511ath10k_wmi_fw_peer_stats_fill(const struct ath10k_fw_stats_peer *peer,
8512			      char *buf, u32 *length, bool extended_peer)
8513{
8514	u32 len = *length;
8515	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8516
8517	len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
8518			"Peer MAC address", peer->peer_macaddr);
8519	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8520			"Peer RSSI", peer->peer_rssi);
8521	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8522			"Peer TX rate", peer->peer_tx_rate);
8523	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8524			"Peer RX rate", peer->peer_rx_rate);
8525	if (!extended_peer)
8526		len += scnprintf(buf + len, buf_len - len, "%30s %llu\n",
8527				"Peer RX duration", peer->rx_duration);
8528
8529	len += scnprintf(buf + len, buf_len - len, "\n");
8530	*length = len;
8531}
8532
8533static void
8534ath10k_wmi_fw_extd_peer_stats_fill(const struct ath10k_fw_extd_stats_peer *peer,
8535				   char *buf, u32 *length)
8536{
8537	u32 len = *length;
8538	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8539
8540	len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
8541			"Peer MAC address", peer->peer_macaddr);
8542	len += scnprintf(buf + len, buf_len - len, "%30s %llu\n",
8543			"Peer RX duration", peer->rx_duration);
8544}
8545
8546void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
8547				      struct ath10k_fw_stats *fw_stats,
8548				      char *buf)
8549{
8550	u32 len = 0;
8551	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8552	const struct ath10k_fw_stats_pdev *pdev;
8553	const struct ath10k_fw_stats_vdev *vdev;
8554	const struct ath10k_fw_stats_peer *peer;
8555	size_t num_peers;
8556	size_t num_vdevs;
8557
8558	spin_lock_bh(&ar->data_lock);
8559
8560	pdev = list_first_entry_or_null(&fw_stats->pdevs,
8561					struct ath10k_fw_stats_pdev, list);
8562	if (!pdev) {
8563		ath10k_warn(ar, "failed to get pdev stats\n");
8564		goto unlock;
8565	}
8566
8567	num_peers = list_count_nodes(&fw_stats->peers);
8568	num_vdevs = list_count_nodes(&fw_stats->vdevs);
8569
8570	ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
8571	ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
8572	ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
8573
8574	len += scnprintf(buf + len, buf_len - len, "\n");
8575	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8576			 "ath10k VDEV stats", num_vdevs);
8577	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8578				 "=================");
8579
8580	list_for_each_entry(vdev, &fw_stats->vdevs, list) {
8581		ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
8582	}
8583
8584	len += scnprintf(buf + len, buf_len - len, "\n");
8585	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8586			 "ath10k PEER stats", num_peers);
8587	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8588				 "=================");
8589
8590	list_for_each_entry(peer, &fw_stats->peers, list) {
8591		ath10k_wmi_fw_peer_stats_fill(peer, buf, &len,
8592					      fw_stats->extended);
8593	}
8594
8595unlock:
8596	spin_unlock_bh(&ar->data_lock);
8597
8598	if (len >= buf_len)
8599		buf[len - 1] = 0;
8600	else
8601		buf[len] = 0;
8602}
8603
8604void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
8605				     struct ath10k_fw_stats *fw_stats,
8606				     char *buf)
8607{
8608	unsigned int len = 0;
8609	unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
8610	const struct ath10k_fw_stats_pdev *pdev;
8611	const struct ath10k_fw_stats_vdev *vdev;
8612	const struct ath10k_fw_stats_peer *peer;
8613	size_t num_peers;
8614	size_t num_vdevs;
8615
8616	spin_lock_bh(&ar->data_lock);
8617
8618	pdev = list_first_entry_or_null(&fw_stats->pdevs,
8619					struct ath10k_fw_stats_pdev, list);
8620	if (!pdev) {
8621		ath10k_warn(ar, "failed to get pdev stats\n");
8622		goto unlock;
8623	}
8624
8625	num_peers = list_count_nodes(&fw_stats->peers);
8626	num_vdevs = list_count_nodes(&fw_stats->vdevs);
8627
8628	ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
8629	ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
8630	ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
8631	ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
8632
8633	len += scnprintf(buf + len, buf_len - len, "\n");
8634	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8635			 "ath10k VDEV stats", num_vdevs);
8636	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8637				 "=================");
8638
8639	list_for_each_entry(vdev, &fw_stats->vdevs, list) {
8640		ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
8641	}
8642
8643	len += scnprintf(buf + len, buf_len - len, "\n");
8644	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8645			 "ath10k PEER stats", num_peers);
8646	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8647				 "=================");
8648
8649	list_for_each_entry(peer, &fw_stats->peers, list) {
8650		ath10k_wmi_fw_peer_stats_fill(peer, buf, &len,
8651					      fw_stats->extended);
8652	}
8653
8654unlock:
8655	spin_unlock_bh(&ar->data_lock);
8656
8657	if (len >= buf_len)
8658		buf[len - 1] = 0;
8659	else
8660		buf[len] = 0;
8661}
8662
8663static struct sk_buff *
8664ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
8665					   u32 detect_level, u32 detect_margin)
8666{
8667	struct wmi_pdev_set_adaptive_cca_params *cmd;
8668	struct sk_buff *skb;
8669
8670	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8671	if (!skb)
8672		return ERR_PTR(-ENOMEM);
8673
8674	cmd = (struct wmi_pdev_set_adaptive_cca_params *)skb->data;
8675	cmd->enable = __cpu_to_le32(enable);
8676	cmd->cca_detect_level = __cpu_to_le32(detect_level);
8677	cmd->cca_detect_margin = __cpu_to_le32(detect_margin);
8678
8679	ath10k_dbg(ar, ATH10K_DBG_WMI,
8680		   "wmi pdev set adaptive cca params enable:%d detection level:%d detection margin:%d\n",
8681		   enable, detect_level, detect_margin);
8682	return skb;
8683}
8684
8685static void
8686ath10k_wmi_fw_vdev_stats_extd_fill(const struct ath10k_fw_stats_vdev_extd *vdev,
8687				   char *buf, u32 *length)
8688{
8689	u32 len = *length;
8690	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8691	u32 val;
8692
8693	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8694			 "vdev id", vdev->vdev_id);
8695	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8696			 "ppdu aggr count", vdev->ppdu_aggr_cnt);
8697	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8698			 "ppdu noack", vdev->ppdu_noack);
8699	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8700			 "mpdu queued", vdev->mpdu_queued);
8701	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8702			 "ppdu nonaggr count", vdev->ppdu_nonaggr_cnt);
8703	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8704			 "mpdu sw requeued", vdev->mpdu_sw_requeued);
8705	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8706			 "mpdu success retry", vdev->mpdu_suc_retry);
8707	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8708			 "mpdu success multitry", vdev->mpdu_suc_multitry);
8709	len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8710			 "mpdu fail retry", vdev->mpdu_fail_retry);
8711	val = vdev->tx_ftm_suc;
8712	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8713		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8714				 "tx ftm success",
8715				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8716	val = vdev->tx_ftm_suc_retry;
8717	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8718		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8719				 "tx ftm success retry",
8720				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8721	val = vdev->tx_ftm_fail;
8722	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8723		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8724				 "tx ftm fail",
8725				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8726	val = vdev->rx_ftmr_cnt;
8727	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8728		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8729				 "rx ftm request count",
8730				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8731	val = vdev->rx_ftmr_dup_cnt;
8732	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8733		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8734				 "rx ftm request dup count",
8735				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8736	val = vdev->rx_iftmr_cnt;
8737	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8738		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8739				 "rx initial ftm req count",
8740				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8741	val = vdev->rx_iftmr_dup_cnt;
8742	if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
8743		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
8744				 "rx initial ftm req dup cnt",
8745				 MS(val, WMI_VDEV_STATS_FTM_COUNT));
8746	len += scnprintf(buf + len, buf_len - len, "\n");
8747
8748	*length = len;
8749}
8750
8751void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
8752				      struct ath10k_fw_stats *fw_stats,
8753				      char *buf)
8754{
8755	u32 len = 0;
8756	u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
8757	const struct ath10k_fw_stats_pdev *pdev;
8758	const struct ath10k_fw_stats_vdev_extd *vdev;
8759	const struct ath10k_fw_stats_peer *peer;
8760	const struct ath10k_fw_extd_stats_peer *extd_peer;
8761	size_t num_peers;
8762	size_t num_vdevs;
8763
8764	spin_lock_bh(&ar->data_lock);
8765
8766	pdev = list_first_entry_or_null(&fw_stats->pdevs,
8767					struct ath10k_fw_stats_pdev, list);
8768	if (!pdev) {
8769		ath10k_warn(ar, "failed to get pdev stats\n");
8770		goto unlock;
8771	}
8772
8773	num_peers = list_count_nodes(&fw_stats->peers);
8774	num_vdevs = list_count_nodes(&fw_stats->vdevs);
8775
8776	ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
8777	ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
8778	ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
8779
8780	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8781			"HW paused", pdev->hw_paused);
8782	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8783			"Seqs posted", pdev->seq_posted);
8784	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8785			"Seqs failed queueing", pdev->seq_failed_queueing);
8786	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8787			"Seqs completed", pdev->seq_completed);
8788	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8789			"Seqs restarted", pdev->seq_restarted);
8790	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8791			"MU Seqs posted", pdev->mu_seq_posted);
8792	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8793			"MPDUs SW flushed", pdev->mpdus_sw_flush);
8794	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8795			"MPDUs HW filtered", pdev->mpdus_hw_filter);
8796	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8797			"MPDUs truncated", pdev->mpdus_truncated);
8798	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8799			"MPDUs receive no ACK", pdev->mpdus_ack_failed);
8800	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8801			"MPDUs expired", pdev->mpdus_expired);
8802
8803	ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
8804	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
8805			"Num Rx Overflow errors", pdev->rx_ovfl_errs);
8806
8807	len += scnprintf(buf + len, buf_len - len, "\n");
8808	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8809			"ath10k VDEV stats", num_vdevs);
8810	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8811				"=================");
8812	list_for_each_entry(vdev, &fw_stats->vdevs, list) {
8813		ath10k_wmi_fw_vdev_stats_extd_fill(vdev, buf, &len);
8814	}
8815
8816	len += scnprintf(buf + len, buf_len - len, "\n");
8817	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
8818			"ath10k PEER stats", num_peers);
8819	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
8820				"=================");
8821
8822	list_for_each_entry(peer, &fw_stats->peers, list) {
8823		ath10k_wmi_fw_peer_stats_fill(peer, buf, &len,
8824					      fw_stats->extended);
8825	}
8826
8827	if (fw_stats->extended) {
8828		list_for_each_entry(extd_peer, &fw_stats->peers_extd, list) {
8829			ath10k_wmi_fw_extd_peer_stats_fill(extd_peer, buf,
8830							   &len);
8831		}
8832	}
8833
8834unlock:
8835	spin_unlock_bh(&ar->data_lock);
8836
8837	if (len >= buf_len)
8838		buf[len - 1] = 0;
8839	else
8840		buf[len] = 0;
8841}
8842
8843int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
8844				   enum wmi_vdev_subtype subtype)
8845{
8846	switch (subtype) {
8847	case WMI_VDEV_SUBTYPE_NONE:
8848		return WMI_VDEV_SUBTYPE_LEGACY_NONE;
8849	case WMI_VDEV_SUBTYPE_P2P_DEVICE:
8850		return WMI_VDEV_SUBTYPE_LEGACY_P2P_DEV;
8851	case WMI_VDEV_SUBTYPE_P2P_CLIENT:
8852		return WMI_VDEV_SUBTYPE_LEGACY_P2P_CLI;
8853	case WMI_VDEV_SUBTYPE_P2P_GO:
8854		return WMI_VDEV_SUBTYPE_LEGACY_P2P_GO;
8855	case WMI_VDEV_SUBTYPE_PROXY_STA:
8856		return WMI_VDEV_SUBTYPE_LEGACY_PROXY_STA;
8857	case WMI_VDEV_SUBTYPE_MESH_11S:
8858	case WMI_VDEV_SUBTYPE_MESH_NON_11S:
8859		return -ENOTSUPP;
8860	}
8861	return -ENOTSUPP;
8862}
8863
8864static int ath10k_wmi_10_2_4_op_get_vdev_subtype(struct ath10k *ar,
8865						 enum wmi_vdev_subtype subtype)
8866{
8867	switch (subtype) {
8868	case WMI_VDEV_SUBTYPE_NONE:
8869		return WMI_VDEV_SUBTYPE_10_2_4_NONE;
8870	case WMI_VDEV_SUBTYPE_P2P_DEVICE:
8871		return WMI_VDEV_SUBTYPE_10_2_4_P2P_DEV;
8872	case WMI_VDEV_SUBTYPE_P2P_CLIENT:
8873		return WMI_VDEV_SUBTYPE_10_2_4_P2P_CLI;
8874	case WMI_VDEV_SUBTYPE_P2P_GO:
8875		return WMI_VDEV_SUBTYPE_10_2_4_P2P_GO;
8876	case WMI_VDEV_SUBTYPE_PROXY_STA:
8877		return WMI_VDEV_SUBTYPE_10_2_4_PROXY_STA;
8878	case WMI_VDEV_SUBTYPE_MESH_11S:
8879		return WMI_VDEV_SUBTYPE_10_2_4_MESH_11S;
8880	case WMI_VDEV_SUBTYPE_MESH_NON_11S:
8881		return -ENOTSUPP;
8882	}
8883	return -ENOTSUPP;
8884}
8885
8886static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
8887					       enum wmi_vdev_subtype subtype)
8888{
8889	switch (subtype) {
8890	case WMI_VDEV_SUBTYPE_NONE:
8891		return WMI_VDEV_SUBTYPE_10_4_NONE;
8892	case WMI_VDEV_SUBTYPE_P2P_DEVICE:
8893		return WMI_VDEV_SUBTYPE_10_4_P2P_DEV;
8894	case WMI_VDEV_SUBTYPE_P2P_CLIENT:
8895		return WMI_VDEV_SUBTYPE_10_4_P2P_CLI;
8896	case WMI_VDEV_SUBTYPE_P2P_GO:
8897		return WMI_VDEV_SUBTYPE_10_4_P2P_GO;
8898	case WMI_VDEV_SUBTYPE_PROXY_STA:
8899		return WMI_VDEV_SUBTYPE_10_4_PROXY_STA;
8900	case WMI_VDEV_SUBTYPE_MESH_11S:
8901		return WMI_VDEV_SUBTYPE_10_4_MESH_11S;
8902	case WMI_VDEV_SUBTYPE_MESH_NON_11S:
8903		return WMI_VDEV_SUBTYPE_10_4_MESH_NON_11S;
8904	}
8905	return -ENOTSUPP;
8906}
8907
8908static struct sk_buff *
8909ath10k_wmi_10_4_ext_resource_config(struct ath10k *ar,
8910				    enum wmi_host_platform_type type,
8911				    u32 fw_feature_bitmap)
8912{
8913	struct wmi_ext_resource_config_10_4_cmd *cmd;
8914	struct sk_buff *skb;
8915	u32 num_tdls_sleep_sta = 0;
8916
8917	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8918	if (!skb)
8919		return ERR_PTR(-ENOMEM);
8920
8921	if (test_bit(WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, ar->wmi.svc_map))
8922		num_tdls_sleep_sta = TARGET_10_4_NUM_TDLS_SLEEP_STA;
8923
8924	cmd = (struct wmi_ext_resource_config_10_4_cmd *)skb->data;
8925	cmd->host_platform_config = __cpu_to_le32(type);
8926	cmd->fw_feature_bitmap = __cpu_to_le32(fw_feature_bitmap);
8927	cmd->wlan_gpio_priority = __cpu_to_le32(ar->coex_gpio_pin);
8928	cmd->coex_version = __cpu_to_le32(WMI_NO_COEX_VERSION_SUPPORT);
8929	cmd->coex_gpio_pin1 = __cpu_to_le32(-1);
8930	cmd->coex_gpio_pin2 = __cpu_to_le32(-1);
8931	cmd->coex_gpio_pin3 = __cpu_to_le32(-1);
8932	cmd->num_tdls_vdevs = __cpu_to_le32(TARGET_10_4_NUM_TDLS_VDEVS);
8933	cmd->num_tdls_conn_table_entries = __cpu_to_le32(20);
8934	cmd->max_tdls_concurrent_sleep_sta = __cpu_to_le32(num_tdls_sleep_sta);
8935	cmd->max_tdls_concurrent_buffer_sta =
8936			__cpu_to_le32(TARGET_10_4_NUM_TDLS_BUFFER_STA);
8937
8938	ath10k_dbg(ar, ATH10K_DBG_WMI,
8939		   "wmi ext resource config host type %d firmware feature bitmap %08x\n",
8940		   type, fw_feature_bitmap);
8941	return skb;
8942}
8943
8944static struct sk_buff *
8945ath10k_wmi_10_4_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
8946					 enum wmi_tdls_state state)
8947{
8948	struct wmi_10_4_tdls_set_state_cmd *cmd;
8949	struct sk_buff *skb;
8950	u32 options = 0;
8951
8952	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8953	if (!skb)
8954		return ERR_PTR(-ENOMEM);
8955
8956	if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map) &&
8957	    state == WMI_TDLS_ENABLE_ACTIVE)
8958		state = WMI_TDLS_ENABLE_PASSIVE;
8959
8960	if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
8961		options |= WMI_TDLS_BUFFER_STA_EN;
8962
8963	cmd = (struct wmi_10_4_tdls_set_state_cmd *)skb->data;
8964	cmd->vdev_id = __cpu_to_le32(vdev_id);
8965	cmd->state = __cpu_to_le32(state);
8966	cmd->notification_interval_ms = __cpu_to_le32(5000);
8967	cmd->tx_discovery_threshold = __cpu_to_le32(100);
8968	cmd->tx_teardown_threshold = __cpu_to_le32(5);
8969	cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
8970	cmd->rssi_delta = __cpu_to_le32(-20);
8971	cmd->tdls_options = __cpu_to_le32(options);
8972	cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
8973	cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
8974	cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
8975	cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
8976	cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
8977	cmd->teardown_notification_ms = __cpu_to_le32(10);
8978	cmd->tdls_peer_kickout_threshold = __cpu_to_le32(96);
8979
8980	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi update fw tdls state %d for vdev %i\n",
8981		   state, vdev_id);
8982	return skb;
8983}
8984
8985static u32 ath10k_wmi_prepare_peer_qos(u8 uapsd_queues, u8 sp)
8986{
8987	u32 peer_qos = 0;
8988
8989	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
8990		peer_qos |= WMI_TDLS_PEER_QOS_AC_VO;
8991	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
8992		peer_qos |= WMI_TDLS_PEER_QOS_AC_VI;
8993	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
8994		peer_qos |= WMI_TDLS_PEER_QOS_AC_BK;
8995	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
8996		peer_qos |= WMI_TDLS_PEER_QOS_AC_BE;
8997
8998	peer_qos |= SM(sp, WMI_TDLS_PEER_SP);
8999
9000	return peer_qos;
9001}
9002
9003static struct sk_buff *
9004ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
9005{
9006	struct wmi_pdev_get_tpc_table_cmd *cmd;
9007	struct sk_buff *skb;
9008
9009	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
9010	if (!skb)
9011		return ERR_PTR(-ENOMEM);
9012
9013	cmd = (struct wmi_pdev_get_tpc_table_cmd *)skb->data;
9014	cmd->param = __cpu_to_le32(param);
9015
9016	ath10k_dbg(ar, ATH10K_DBG_WMI,
9017		   "wmi pdev get tpc table param:%d\n", param);
9018	return skb;
9019}
9020
9021static struct sk_buff *
9022ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
9023				     const struct wmi_tdls_peer_update_cmd_arg *arg,
9024				     const struct wmi_tdls_peer_capab_arg *cap,
9025				     const struct wmi_channel_arg *chan_arg)
9026{
9027	struct wmi_10_4_tdls_peer_update_cmd *cmd;
9028	struct wmi_tdls_peer_capabilities *peer_cap;
9029	struct wmi_channel *chan;
9030	struct sk_buff *skb;
9031	u32 peer_qos;
9032	int len, chan_len;
9033	int i;
9034
9035	/* tdls peer update cmd has place holder for one channel*/
9036	chan_len = cap->peer_chan_len ? (cap->peer_chan_len - 1) : 0;
9037
9038	len = sizeof(*cmd) + chan_len * sizeof(*chan);
9039
9040	skb = ath10k_wmi_alloc_skb(ar, len);
9041	if (!skb)
9042		return ERR_PTR(-ENOMEM);
9043
9044	memset(skb->data, 0, sizeof(*cmd));
9045
9046	cmd = (struct wmi_10_4_tdls_peer_update_cmd *)skb->data;
9047	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
9048	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
9049	cmd->peer_state = __cpu_to_le32(arg->peer_state);
9050
9051	peer_qos = ath10k_wmi_prepare_peer_qos(cap->peer_uapsd_queues,
9052					       cap->peer_max_sp);
9053
9054	peer_cap = &cmd->peer_capab;
9055	peer_cap->peer_qos = __cpu_to_le32(peer_qos);
9056	peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
9057	peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
9058	peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
9059	peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
9060	peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
9061	peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
9062
9063	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
9064		peer_cap->peer_operclass[i] = cap->peer_operclass[i];
9065
9066	peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
9067	peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
9068	peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
9069
9070	for (i = 0; i < cap->peer_chan_len; i++) {
9071		chan = (struct wmi_channel *)&peer_cap->peer_chan_list[i];
9072		ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
9073	}
9074
9075	ath10k_dbg(ar, ATH10K_DBG_WMI,
9076		   "wmi tdls peer update vdev %i state %d n_chans %u\n",
9077		   arg->vdev_id, arg->peer_state, cap->peer_chan_len);
9078	return skb;
9079}
9080
9081static struct sk_buff *
9082ath10k_wmi_10_4_gen_radar_found(struct ath10k *ar,
9083				const struct ath10k_radar_found_info *arg)
9084{
9085	struct wmi_radar_found_info *cmd;
9086	struct sk_buff *skb;
9087
9088	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
9089	if (!skb)
9090		return ERR_PTR(-ENOMEM);
9091
9092	cmd = (struct wmi_radar_found_info *)skb->data;
9093	cmd->pri_min   = __cpu_to_le32(arg->pri_min);
9094	cmd->pri_max   = __cpu_to_le32(arg->pri_max);
9095	cmd->width_min = __cpu_to_le32(arg->width_min);
9096	cmd->width_max = __cpu_to_le32(arg->width_max);
9097	cmd->sidx_min  = __cpu_to_le32(arg->sidx_min);
9098	cmd->sidx_max  = __cpu_to_le32(arg->sidx_max);
9099
9100	ath10k_dbg(ar, ATH10K_DBG_WMI,
9101		   "wmi radar found pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
9102		   arg->pri_min, arg->pri_max, arg->width_min,
9103		   arg->width_max, arg->sidx_min, arg->sidx_max);
9104	return skb;
9105}
9106
9107static struct sk_buff *
9108ath10k_wmi_10_4_gen_per_peer_per_tid_cfg(struct ath10k *ar,
9109					 const struct wmi_per_peer_per_tid_cfg_arg *arg)
9110{
9111	struct wmi_peer_per_tid_cfg_cmd *cmd;
9112	struct sk_buff *skb;
9113
9114	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
9115	if (!skb)
9116		return ERR_PTR(-ENOMEM);
9117
9118	memset(skb->data, 0, sizeof(*cmd));
9119
9120	cmd = (struct wmi_peer_per_tid_cfg_cmd *)skb->data;
9121	cmd->vdev_id = cpu_to_le32(arg->vdev_id);
9122	ether_addr_copy(cmd->peer_macaddr.addr, arg->peer_macaddr.addr);
9123	cmd->tid = cpu_to_le32(arg->tid);
9124	cmd->ack_policy = cpu_to_le32(arg->ack_policy);
9125	cmd->aggr_control = cpu_to_le32(arg->aggr_control);
9126	cmd->rate_control = cpu_to_le32(arg->rate_ctrl);
9127	cmd->retry_count = cpu_to_le32(arg->retry_count);
9128	cmd->rcode_flags = cpu_to_le32(arg->rcode_flags);
9129	cmd->ext_tid_cfg_bitmap = cpu_to_le32(arg->ext_tid_cfg_bitmap);
9130	cmd->rtscts_ctrl = cpu_to_le32(arg->rtscts_ctrl);
9131
9132	ath10k_dbg(ar, ATH10K_DBG_WMI,
9133		   "wmi noack tid %d vdev id %d ack_policy %d aggr %u rate_ctrl %u rcflag %u retry_count %d rtscts %d ext_tid_cfg_bitmap %d mac_addr %pM\n",
9134		   arg->tid, arg->vdev_id, arg->ack_policy, arg->aggr_control,
9135		   arg->rate_ctrl, arg->rcode_flags, arg->retry_count,
9136		   arg->rtscts_ctrl, arg->ext_tid_cfg_bitmap, arg->peer_macaddr.addr);
9137	return skb;
9138}
9139
9140static struct sk_buff *
9141ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
9142{
9143	struct wmi_echo_cmd *cmd;
9144	struct sk_buff *skb;
9145
9146	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
9147	if (!skb)
9148		return ERR_PTR(-ENOMEM);
9149
9150	cmd = (struct wmi_echo_cmd *)skb->data;
9151	cmd->value = cpu_to_le32(value);
9152
9153	ath10k_dbg(ar, ATH10K_DBG_WMI,
9154		   "wmi echo value 0x%08x\n", value);
9155	return skb;
9156}
9157
9158int
9159ath10k_wmi_barrier(struct ath10k *ar)
9160{
9161	int ret;
9162	int time_left;
9163
9164	spin_lock_bh(&ar->data_lock);
9165	reinit_completion(&ar->wmi.barrier);
9166	spin_unlock_bh(&ar->data_lock);
9167
9168	ret = ath10k_wmi_echo(ar, ATH10K_WMI_BARRIER_ECHO_ID);
9169	if (ret) {
9170		ath10k_warn(ar, "failed to submit wmi echo: %d\n", ret);
9171		return ret;
9172	}
9173
9174	time_left = wait_for_completion_timeout(&ar->wmi.barrier,
9175						ATH10K_WMI_BARRIER_TIMEOUT_HZ);
9176	if (!time_left)
9177		return -ETIMEDOUT;
9178
9179	return 0;
9180}
9181
9182static struct sk_buff *
9183ath10k_wmi_10_2_4_op_gen_bb_timing(struct ath10k *ar,
9184				   const struct wmi_bb_timing_cfg_arg *arg)
9185{
9186	struct wmi_pdev_bb_timing_cfg_cmd *cmd;
9187	struct sk_buff *skb;
9188
9189	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
9190	if (!skb)
9191		return ERR_PTR(-ENOMEM);
9192
9193	cmd = (struct wmi_pdev_bb_timing_cfg_cmd *)skb->data;
9194	cmd->bb_tx_timing = __cpu_to_le32(arg->bb_tx_timing);
9195	cmd->bb_xpa_timing = __cpu_to_le32(arg->bb_xpa_timing);
9196
9197	ath10k_dbg(ar, ATH10K_DBG_WMI,
9198		   "wmi pdev bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
9199		   arg->bb_tx_timing, arg->bb_xpa_timing);
9200	return skb;
9201}
9202
9203static const struct wmi_ops wmi_ops = {
9204	.rx = ath10k_wmi_op_rx,
9205	.map_svc = wmi_main_svc_map,
9206
9207	.pull_scan = ath10k_wmi_op_pull_scan_ev,
9208	.pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
9209	.pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
9210	.pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
9211	.pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
9212	.pull_swba = ath10k_wmi_op_pull_swba_ev,
9213	.pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr,
9214	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
9215	.pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
9216	.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
9217	.pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats,
9218	.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
9219	.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
9220
9221	.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
9222	.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
9223	.gen_pdev_set_rd = ath10k_wmi_op_gen_pdev_set_rd,
9224	.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
9225	.gen_init = ath10k_wmi_op_gen_init,
9226	.gen_start_scan = ath10k_wmi_op_gen_start_scan,
9227	.gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
9228	.gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
9229	.gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
9230	.gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
9231	.gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
9232	.gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
9233	.gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
9234	.gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
9235	.gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
9236	.gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
9237	.gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
9238	/* .gen_vdev_wmm_conf not implemented */
9239	.gen_peer_create = ath10k_wmi_op_gen_peer_create,
9240	.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
9241	.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
9242	.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
9243	.gen_peer_assoc = ath10k_wmi_op_gen_peer_assoc,
9244	.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
9245	.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
9246	.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
9247	.gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
9248	.gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
9249	.gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
9250	.gen_request_stats = ath10k_wmi_op_gen_request_stats,
9251	.gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
9252	.gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
9253	.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
9254	.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
9255	.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
9256	.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
9257	/* .gen_pdev_get_temperature not implemented */
9258	.gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
9259	.gen_addba_send = ath10k_wmi_op_gen_addba_send,
9260	.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
9261	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
9262	.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
9263	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
9264	.gen_echo = ath10k_wmi_op_gen_echo,
9265	/* .gen_bcn_tmpl not implemented */
9266	/* .gen_prb_tmpl not implemented */
9267	/* .gen_p2p_go_bcn_ie not implemented */
9268	/* .gen_adaptive_qcs not implemented */
9269	/* .gen_pdev_enable_adaptive_cca not implemented */
9270};
9271
9272static const struct wmi_ops wmi_10_1_ops = {
9273	.rx = ath10k_wmi_10_1_op_rx,
9274	.map_svc = wmi_10x_svc_map,
9275	.pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
9276	.pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
9277	.gen_init = ath10k_wmi_10_1_op_gen_init,
9278	.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
9279	.gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
9280	.gen_peer_assoc = ath10k_wmi_10_1_op_gen_peer_assoc,
9281	/* .gen_pdev_get_temperature not implemented */
9282
9283	/* shared with main branch */
9284	.pull_scan = ath10k_wmi_op_pull_scan_ev,
9285	.pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
9286	.pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
9287	.pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
9288	.pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
9289	.pull_swba = ath10k_wmi_op_pull_swba_ev,
9290	.pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr,
9291	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
9292	.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
9293	.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
9294	.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
9295
9296	.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
9297	.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
9298	.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
9299	.gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
9300	.gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
9301	.gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
9302	.gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
9303	.gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
9304	.gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
9305	.gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
9306	.gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
9307	.gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
9308	.gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
9309	.gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
9310	/* .gen_vdev_wmm_conf not implemented */
9311	.gen_peer_create = ath10k_wmi_op_gen_peer_create,
9312	.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
9313	.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
9314	.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
9315	.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
9316	.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
9317	.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
9318	.gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
9319	.gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
9320	.gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
9321	.gen_request_stats = ath10k_wmi_op_gen_request_stats,
9322	.gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
9323	.gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
9324	.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
9325	.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
9326	.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
9327	.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
9328	.gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
9329	.gen_addba_send = ath10k_wmi_op_gen_addba_send,
9330	.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
9331	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
9332	.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
9333	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
9334	.gen_echo = ath10k_wmi_op_gen_echo,
9335	/* .gen_bcn_tmpl not implemented */
9336	/* .gen_prb_tmpl not implemented */
9337	/* .gen_p2p_go_bcn_ie not implemented */
9338	/* .gen_adaptive_qcs not implemented */
9339	/* .gen_pdev_enable_adaptive_cca not implemented */
9340};
9341
9342static const struct wmi_ops wmi_10_2_ops = {
9343	.rx = ath10k_wmi_10_2_op_rx,
9344	.pull_fw_stats = ath10k_wmi_10_2_op_pull_fw_stats,
9345	.gen_init = ath10k_wmi_10_2_op_gen_init,
9346	.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
9347	/* .gen_pdev_get_temperature not implemented */
9348
9349	/* shared with 10.1 */
9350	.map_svc = wmi_10x_svc_map,
9351	.pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
9352	.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
9353	.gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
9354	.gen_echo = ath10k_wmi_op_gen_echo,
9355
9356	.pull_scan = ath10k_wmi_op_pull_scan_ev,
9357	.pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
9358	.pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
9359	.pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
9360	.pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
9361	.pull_swba = ath10k_wmi_op_pull_swba_ev,
9362	.pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr,
9363	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
9364	.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
9365	.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
9366	.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
9367
9368	.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
9369	.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
9370	.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
9371	.gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
9372	.gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
9373	.gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
9374	.gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
9375	.gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
9376	.gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
9377	.gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
9378	.gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
9379	.gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
9380	.gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
9381	.gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
9382	/* .gen_vdev_wmm_conf not implemented */
9383	.gen_peer_create = ath10k_wmi_op_gen_peer_create,
9384	.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
9385	.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
9386	.gen_pdev_set_base_macaddr = ath10k_wmi_op_gen_pdev_set_base_macaddr,
9387	.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
9388	.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
9389	.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
9390	.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
9391	.gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
9392	.gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
9393	.gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
9394	.gen_request_stats = ath10k_wmi_op_gen_request_stats,
9395	.gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
9396	.gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
9397	.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
9398	.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
9399	.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
9400	.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
9401	.gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
9402	.gen_addba_send = ath10k_wmi_op_gen_addba_send,
9403	.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
9404	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
9405	.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
9406	.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
9407	/* .gen_pdev_enable_adaptive_cca not implemented */
9408};
9409
9410static const struct wmi_ops wmi_10_2_4_ops = {
9411	.rx = ath10k_wmi_10_2_op_rx,
9412	.pull_fw_stats = ath10k_wmi_10_2_4_op_pull_fw_stats,
9413	.gen_init = ath10k_wmi_10_2_op_gen_init,
9414	.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
9415	.gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
9416	.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
9417
9418	/* shared with 10.1 */
9419	.map_svc = wmi_10x_svc_map,
9420	.pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
9421	.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
9422	.gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
9423	.gen_echo = ath10k_wmi_op_gen_echo,
9424
9425	.pull_scan = ath10k_wmi_op_pull_scan_ev,
9426	.pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
9427	.pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
9428	.pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
9429	.pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
9430	.pull_swba = ath10k_wmi_10_2_4_op_pull_swba_ev,
9431	.pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr,
9432	.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
9433	.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
9434	.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
9435	.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
9436
9437	.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
9438	.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
9439	.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
9440	.gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
9441	.gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
9442	.gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
9443	.gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
9444	.gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
9445	.gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
9446	.gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
9447	.gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
9448	.gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
9449	.gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
9450	.gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
9451	.gen_peer_create = ath10k_wmi_op_gen_peer_create,
9452	.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
9453	.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
9454	.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
9455	.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
9456	.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
9457	.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
9458	.gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
9459	.gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
9460	.gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
9461	.gen_request_stats = ath10k_wmi_op_gen_request_stats,
9462	.gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
9463	.gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
9464	.gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
9465	.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
9466	.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
9467	.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
9468	.gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
9469	.gen_addba_send = ath10k_wmi_op_gen_addba_send,
9470	.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
9471	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
9472	.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
9473	.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
9474	.gen_pdev_enable_adaptive_cca =
9475		ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
9476	.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
9477	.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
9478	/* .gen_bcn_tmpl not implemented */
9479	/* .gen_prb_tmpl not implemented */
9480	/* .gen_p2p_go_bcn_ie not implemented */
9481	/* .gen_adaptive_qcs not implemented */
9482};
9483
9484static const struct wmi_ops wmi_10_4_ops = {
9485	.rx = ath10k_wmi_10_4_op_rx,
9486	.map_svc = wmi_10_4_svc_map,
9487
9488	.pull_fw_stats = ath10k_wmi_10_4_op_pull_fw_stats,
9489	.pull_scan = ath10k_wmi_op_pull_scan_ev,
9490	.pull_mgmt_rx = ath10k_wmi_10_4_op_pull_mgmt_rx_ev,
9491	.pull_ch_info = ath10k_wmi_10_4_op_pull_ch_info_ev,
9492	.pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
9493	.pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
9494	.pull_swba = ath10k_wmi_10_4_op_pull_swba_ev,
9495	.pull_phyerr_hdr = ath10k_wmi_10_4_op_pull_phyerr_ev_hdr,
9496	.pull_phyerr = ath10k_wmi_10_4_op_pull_phyerr_ev,
9497	.pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
9498	.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
9499	.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
9500	.pull_dfs_status_ev = ath10k_wmi_10_4_op_pull_dfs_status_ev,
9501	.get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme,
9502
9503	.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
9504	.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
9505	.gen_pdev_set_base_macaddr = ath10k_wmi_op_gen_pdev_set_base_macaddr,
9506	.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
9507	.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
9508	.gen_init = ath10k_wmi_10_4_op_gen_init,
9509	.gen_start_scan = ath10k_wmi_op_gen_start_scan,
9510	.gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
9511	.gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
9512	.gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
9513	.gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
9514	.gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
9515	.gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
9516	.gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
9517	.gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
9518	.gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
9519	.gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
9520	.gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
9521	.gen_peer_create = ath10k_wmi_op_gen_peer_create,
9522	.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
9523	.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
9524	.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
9525	.gen_peer_assoc = ath10k_wmi_10_4_op_gen_peer_assoc,
9526	.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
9527	.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
9528	.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
9529	.gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
9530	.gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
9531	.gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
9532	.gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
9533	.gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
9534	.gen_dbglog_cfg = ath10k_wmi_10_4_op_gen_dbglog_cfg,
9535	.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
9536	.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
9537	.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
9538	.gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
9539	.gen_addba_send = ath10k_wmi_op_gen_addba_send,
9540	.gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
9541	.gen_delba_send = ath10k_wmi_op_gen_delba_send,
9542	.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
9543	.ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
9544	.gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state,
9545	.gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
9546	.gen_pdev_get_tpc_table_cmdid =
9547			ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
9548	.gen_radar_found = ath10k_wmi_10_4_gen_radar_found,
9549	.gen_per_peer_per_tid_cfg = ath10k_wmi_10_4_gen_per_peer_per_tid_cfg,
9550
9551	/* shared with 10.2 */
9552	.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
9553	.gen_request_stats = ath10k_wmi_op_gen_request_stats,
9554	.gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
9555	.get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype,
9556	.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
9557	.gen_echo = ath10k_wmi_op_gen_echo,
9558	.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
9559};
9560
9561int ath10k_wmi_attach(struct ath10k *ar)
9562{
9563	switch (ar->running_fw->fw_file.wmi_op_version) {
9564	case ATH10K_FW_WMI_OP_VERSION_10_4:
9565		ar->wmi.ops = &wmi_10_4_ops;
9566		ar->wmi.cmd = &wmi_10_4_cmd_map;
9567		ar->wmi.vdev_param = &wmi_10_4_vdev_param_map;
9568		ar->wmi.pdev_param = &wmi_10_4_pdev_param_map;
9569		ar->wmi.peer_param = &wmi_peer_param_map;
9570		ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
9571		ar->wmi_key_cipher = wmi_key_cipher_suites;
9572		break;
9573	case ATH10K_FW_WMI_OP_VERSION_10_2_4:
9574		ar->wmi.cmd = &wmi_10_2_4_cmd_map;
9575		ar->wmi.ops = &wmi_10_2_4_ops;
9576		ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map;
9577		ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map;
9578		ar->wmi.peer_param = &wmi_peer_param_map;
9579		ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
9580		ar->wmi_key_cipher = wmi_key_cipher_suites;
9581		break;
9582	case ATH10K_FW_WMI_OP_VERSION_10_2:
9583		ar->wmi.cmd = &wmi_10_2_cmd_map;
9584		ar->wmi.ops = &wmi_10_2_ops;
9585		ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
9586		ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
9587		ar->wmi.peer_param = &wmi_peer_param_map;
9588		ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
9589		ar->wmi_key_cipher = wmi_key_cipher_suites;
9590		break;
9591	case ATH10K_FW_WMI_OP_VERSION_10_1:
9592		ar->wmi.cmd = &wmi_10x_cmd_map;
9593		ar->wmi.ops = &wmi_10_1_ops;
9594		ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
9595		ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
9596		ar->wmi.peer_param = &wmi_peer_param_map;
9597		ar->wmi.peer_flags = &wmi_10x_peer_flags_map;
9598		ar->wmi_key_cipher = wmi_key_cipher_suites;
9599		break;
9600	case ATH10K_FW_WMI_OP_VERSION_MAIN:
9601		ar->wmi.cmd = &wmi_cmd_map;
9602		ar->wmi.ops = &wmi_ops;
9603		ar->wmi.vdev_param = &wmi_vdev_param_map;
9604		ar->wmi.pdev_param = &wmi_pdev_param_map;
9605		ar->wmi.peer_param = &wmi_peer_param_map;
9606		ar->wmi.peer_flags = &wmi_peer_flags_map;
9607		ar->wmi_key_cipher = wmi_key_cipher_suites;
9608		break;
9609	case ATH10K_FW_WMI_OP_VERSION_TLV:
9610		ath10k_wmi_tlv_attach(ar);
9611		ar->wmi_key_cipher = wmi_tlv_key_cipher_suites;
9612		break;
9613	case ATH10K_FW_WMI_OP_VERSION_UNSET:
9614	case ATH10K_FW_WMI_OP_VERSION_MAX:
9615		ath10k_err(ar, "unsupported WMI op version: %d\n",
9616			   ar->running_fw->fw_file.wmi_op_version);
9617		return -EINVAL;
9618	}
9619
9620	init_completion(&ar->wmi.service_ready);
9621	init_completion(&ar->wmi.unified_ready);
9622	init_completion(&ar->wmi.barrier);
9623	init_completion(&ar->wmi.radar_confirm);
9624
9625	INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work);
9626	INIT_WORK(&ar->radar_confirmation_work,
9627		  ath10k_radar_confirmation_work);
9628
9629	if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
9630		     ar->running_fw->fw_file.fw_features)) {
9631		idr_init(&ar->wmi.mgmt_pending_tx);
9632	}
9633
9634	return 0;
9635}
9636
9637void ath10k_wmi_free_host_mem(struct ath10k *ar)
9638{
9639	int i;
9640
9641	/* free the host memory chunks requested by firmware */
9642	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
9643		dma_free_coherent(ar->dev,
9644				  ar->wmi.mem_chunks[i].len,
9645				  ar->wmi.mem_chunks[i].vaddr,
9646				  ar->wmi.mem_chunks[i].paddr);
9647	}
9648
9649	ar->wmi.num_mem_chunks = 0;
9650}
9651
9652static int ath10k_wmi_mgmt_tx_clean_up_pending(int msdu_id, void *ptr,
9653					       void *ctx)
9654{
9655	struct ath10k_mgmt_tx_pkt_addr *pkt_addr = ptr;
9656	struct ath10k *ar = ctx;
9657	struct sk_buff *msdu;
9658
9659	ath10k_dbg(ar, ATH10K_DBG_WMI,
9660		   "force cleanup mgmt msdu_id %u\n", msdu_id);
9661
9662	msdu = pkt_addr->vaddr;
9663	dma_unmap_single(ar->dev, pkt_addr->paddr,
9664			 msdu->len, DMA_TO_DEVICE);
9665	ieee80211_free_txskb(ar->hw, msdu);
9666
9667	return 0;
9668}
9669
9670void ath10k_wmi_detach(struct ath10k *ar)
9671{
9672	if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
9673		     ar->running_fw->fw_file.fw_features)) {
9674		spin_lock_bh(&ar->data_lock);
9675		idr_for_each(&ar->wmi.mgmt_pending_tx,
9676			     ath10k_wmi_mgmt_tx_clean_up_pending, ar);
9677		idr_destroy(&ar->wmi.mgmt_pending_tx);
9678		spin_unlock_bh(&ar->data_lock);
9679	}
9680
9681	cancel_work_sync(&ar->svc_rdy_work);
9682	dev_kfree_skb(ar->svc_rdy_skb);
9683}
9684