xref: /wlan-dirver/qca-wifi-host-cmn/wmi/src/wmi_unified_cp_stats_tlv.c (revision f49b3a17535861c81c96f561e6e9be8a33a99f15)
1 /*
2  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "osdep.h"
19 #include "wmi.h"
20 #include "wmi_unified_priv.h"
21 #include "wmi_unified_param.h"
22 #include "target_if_cp_stats.h"
23 #include <wlan_cp_stats_public_structs.h>
24 
25 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
26 #ifdef WLAN_SUPPORT_TWT
27 static uint32_t
28 get_stats_req_twt_dialog_id(struct infra_cp_stats_cmd_info *req)
29 {
30 	return req->dialog_id;
31 }
32 
33 static enum WMI_HOST_GET_STATS_TWT_STATUS
34 wmi_get_converted_twt_get_stats_status(WMI_GET_STATS_TWT_STATUS_T tgt_status)
35 {
36 	switch (tgt_status) {
37 	case WMI_GET_STATS_TWT_STATUS_OK:
38 		return WMI_HOST_GET_STATS_TWT_STATUS_OK;
39 	case WMI_GET_STATS_TWT_STATUS_DIALOG_ID_NOT_EXIST:
40 		return WMI_HOST_GET_STATS_TWT_STATUS_DIALOG_ID_NOT_EXIST;
41 	case WMI_GET_STATS_TWT_STATUS_INVALID_PARAM:
42 		return WMI_HOST_GET_STATS_TWT_STATUS_INVALID_PARAM;
43 	default:
44 		return WMI_HOST_GET_STATS_TWT_STATUS_UNKNOWN_ERROR;
45 	}
46 }
47 
48 static inline
49 void wmi_extract_ctrl_path_twt_stats_tlv(void *tag_buf,
50 					 struct twt_infra_cp_stats_event *param)
51 {
52 	wmi_ctrl_path_twt_stats_struct *wmi_stats_buf =
53 			(wmi_ctrl_path_twt_stats_struct *)tag_buf;
54 
55 	param->dialog_id = wmi_stats_buf->dialog_id;
56 	param->status = wmi_get_converted_twt_get_stats_status(wmi_stats_buf->status);
57 	param->num_sp_cycles = wmi_stats_buf->num_sp_cycles;
58 	param->avg_sp_dur_us = wmi_stats_buf->avg_sp_dur_us;
59 	param->min_sp_dur_us = wmi_stats_buf->min_sp_dur_us;
60 	param->max_sp_dur_us = wmi_stats_buf->max_sp_dur_us;
61 	param->tx_mpdu_per_sp = wmi_stats_buf->tx_mpdu_per_sp;
62 	param->rx_mpdu_per_sp = wmi_stats_buf->rx_mpdu_per_sp;
63 	param->tx_bytes_per_sp = wmi_stats_buf->tx_bytes_per_sp;
64 	param->rx_bytes_per_sp = wmi_stats_buf->rx_bytes_per_sp;
65 
66 	wmi_debug("dialog_id = %u status = %u", wmi_stats_buf->dialog_id,
67 		  wmi_stats_buf->status);
68 	wmi_debug("num_sp_cycles = %u avg_sp_dur_us = 0x%x, \
69 		  min_sp_dur_us = 0x%x, max_sp_dur_us = 0x%x",
70 		  wmi_stats_buf->num_sp_cycles, wmi_stats_buf->avg_sp_dur_us,
71 		  wmi_stats_buf->min_sp_dur_us, wmi_stats_buf->max_sp_dur_us);
72 	wmi_debug("tx_mpdu_per_sp 0x%x, rx_mpdu_per_sp = 0x%x, \
73 		  tx_bytes_per_sp = 0x%x, rx_bytes_per_sp = 0x%x",
74 		  wmi_stats_buf->tx_mpdu_per_sp, wmi_stats_buf->rx_mpdu_per_sp,
75 		  wmi_stats_buf->tx_bytes_per_sp,
76 		  wmi_stats_buf->rx_bytes_per_sp);
77 }
78 
79 static void wmi_twt_extract_stats_struct(void *tag_buf,
80 					 struct infra_cp_stats_event *params)
81 {
82 	struct twt_infra_cp_stats_event *twt_params;
83 
84 	twt_params = params->twt_infra_cp_stats +
85 		     params->num_twt_infra_cp_stats;
86 
87 	wmi_debug("TWT stats struct found - num_twt_cp_stats %d",
88 		  params->num_twt_infra_cp_stats);
89 
90 	params->num_twt_infra_cp_stats++;
91 	wmi_extract_ctrl_path_twt_stats_tlv(tag_buf, twt_params);
92 }
93 #else
94 static inline
95 uint32_t get_stats_req_twt_dialog_id(struct infra_cp_stats_cmd_info *req)
96 {
97 	return 0;
98 }
99 
100 static void wmi_twt_extract_stats_struct(void *tag_buf,
101 					 struct infra_cp_stats_event *params)
102 {
103 }
104 #endif /* WLAN_SUPPORT_TWT */
105 
106 /*
107  * wmi_stats_extract_tag_struct: function to extract tag structs
108  * @tag_type: tag type that is to be printed
109  * @tag_buf: pointer to the tag structure
110  * @params: buffer to hold parameters extracted from response event
111  *
112  * Return: None
113  */
114 static void wmi_stats_extract_tag_struct(uint32_t tag_type, void *tag_buf,
115 					 struct infra_cp_stats_event *params)
116 {
117 	wmi_debug("tag_type %d", tag_type);
118 
119 	switch (tag_type) {
120 	case WMITLV_TAG_STRUC_wmi_ctrl_path_pdev_stats_struct:
121 		break;
122 
123 	case WMITLV_TAG_STRUC_wmi_ctrl_path_mem_stats_struct:
124 		break;
125 
126 	case WMITLV_TAG_STRUC_wmi_ctrl_path_twt_stats_struct:
127 		wmi_twt_extract_stats_struct(tag_buf, params);
128 		break;
129 
130 	default:
131 		break;
132 	}
133 }
134 
135 /*
136  * wmi_stats_handler: parse the wmi event and fill the stats values
137  * @buff: Buffer containing wmi event
138  * @len: length of event buffer
139  * @params: buffer to hold parameters extracted from response event
140  *
141  * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
142  */
143 QDF_STATUS wmi_stats_handler(void *buff, int32_t len,
144 			     struct infra_cp_stats_event *params)
145 {
146 	WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf;
147 	wmi_ctrl_path_stats_event_fixed_param *ev;
148 	uint8_t *buf_ptr = (uint8_t *)buff;
149 	uint32_t curr_tlv_tag;
150 	uint32_t curr_tlv_len;
151 	uint8_t *tag_start_ptr;
152 
153 	param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)buff;
154 	if (!param_buf) {
155 		wmi_err_rl("param_buf is NULL");
156 		return QDF_STATUS_E_FAILURE;
157 	}
158 	ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param;
159 
160 	curr_tlv_tag = WMITLV_GET_TLVTAG(ev->tlv_header);
161 	curr_tlv_len = WMITLV_GET_TLVLEN(ev->tlv_header);
162 	buf_ptr = (uint8_t *)param_buf->fixed_param;
163 	wmi_debug("Fixed param more %d req_id %d status %d", ev->more,
164 		  ev->request_id, ev->status);
165 	params->request_id = ev->request_id;
166 	params->status = ev->status;
167 
168 	/* buffer should point to next TLV in event */
169 	buf_ptr += (curr_tlv_len + WMI_TLV_HDR_SIZE);
170 	len -= (curr_tlv_len + WMI_TLV_HDR_SIZE);
171 
172 	curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr));
173 	curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr));
174 
175 	wmi_debug("curr_tlv_len %d curr_tlv_tag %d rem_len %d", len,
176 		  curr_tlv_len, curr_tlv_tag);
177 
178 	while ((len >= curr_tlv_len) &&
179 	       (curr_tlv_tag >= WMITLV_TAG_FIRST_ARRAY_ENUM)) {
180 		if (curr_tlv_tag == WMITLV_TAG_ARRAY_STRUC) {
181 			/* Move to next WMITLV_TAG_ARRAY_STRUC */
182 			buf_ptr += WMI_TLV_HDR_SIZE;
183 			len -= WMI_TLV_HDR_SIZE;
184 			if (len <= 0)
185 				break;
186 		}
187 		curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr));
188 		curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr));
189 
190 		wmi_debug("curr_tlv_len %d curr_tlv_tag %d rem_len %d",
191 			  len, curr_tlv_len, curr_tlv_tag);
192 		if (curr_tlv_len) {
193 			/* point to the tag inside WMITLV_TAG_ARRAY_STRUC */
194 			tag_start_ptr = buf_ptr + WMI_TLV_HDR_SIZE;
195 			curr_tlv_tag = WMITLV_GET_TLVTAG(
196 						WMITLV_GET_HDR(tag_start_ptr));
197 			wmi_stats_extract_tag_struct(curr_tlv_tag,
198 						     (void *)tag_start_ptr,
199 						     params);
200 		}
201 		/* Move to next tag */
202 		buf_ptr += curr_tlv_len + WMI_TLV_HDR_SIZE;
203 		len -= (curr_tlv_len + WMI_TLV_HDR_SIZE);
204 
205 		if (len <= 0)
206 			break;
207 	}
208 
209 	return QDF_STATUS_SUCCESS;
210 }
211 
212 /**
213  * extract_infra_cp_stats_tlv - api to extract stats information from
214  * event buffer
215  * @wmi_handle:  wmi handle
216  * @evt_buf:     event buffer
217  * @evt_buf_len: length of the event buffer
218  * @params:      buffer to populate more flag
219  *
220  * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
221  */
222 QDF_STATUS
223 extract_infra_cp_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
224 			   uint32_t evt_buf_len,
225 			   struct infra_cp_stats_event *params)
226 {
227 	wmi_stats_handler(evt_buf, evt_buf_len, params);
228 	return QDF_STATUS_SUCCESS;
229 }
230 
231 /**
232  * prepare_infra_cp_stats_buf() - Allocate and prepate wmi cmd request buffer
233  * @wmi_handle: wmi handle
234  * @stats_req: Request parameters to be filled in wmi cmd request buffer
235  * @req_buf_len: length of the output wmi cmd buffer allocated
236  *
237  * Return: Valid wmi buffer pointer on success and NULL pointer for failure
238  */
239 static wmi_buf_t
240 prepare_infra_cp_stats_buf(wmi_unified_t wmi_handle,
241 			   struct infra_cp_stats_cmd_info *stats_req,
242 			   uint32_t *req_buf_len)
243 {
244 	wmi_request_ctrl_path_stats_cmd_fixed_param *cmd_fixed_param;
245 	uint32_t index;
246 	wmi_buf_t req_buf;
247 	uint8_t *buf_ptr;
248 	uint32_t *pdev_id_array;
249 	uint32_t *vdev_id_array;
250 	uint8_t *mac_addr_array;
251 	uint32_t *dialog_id_array;
252 	uint32_t num_pdev_ids = stats_req->num_pdev_ids;
253 	uint32_t num_vdev_ids = stats_req->num_vdev_ids;
254 	uint32_t num_mac_addr_list = stats_req->num_mac_addr_list;
255 	uint32_t num_dialog_ids = INFRA_CP_STATS_MAX_REQ_TWT_DIALOG_ID;
256 
257 	/* Calculate total buffer length */
258 	*req_buf_len = (sizeof(wmi_request_ctrl_path_stats_cmd_fixed_param) +
259 		       WMI_TLV_HDR_SIZE + (sizeof(A_UINT32) * (num_pdev_ids)) +
260 		       WMI_TLV_HDR_SIZE + sizeof(A_UINT32) * (num_vdev_ids) +
261 		       WMI_TLV_HDR_SIZE +
262 		       sizeof(wmi_mac_addr) * (num_mac_addr_list) +
263 		       WMI_TLV_HDR_SIZE +
264 		       (sizeof(A_UINT32) * (num_dialog_ids)));
265 	req_buf = wmi_buf_alloc(wmi_handle, *req_buf_len);
266 	if (!req_buf)
267 		return NULL;
268 
269 	cmd_fixed_param = (wmi_request_ctrl_path_stats_cmd_fixed_param *)
270 				wmi_buf_data(req_buf);
271 
272 	/*Set TLV header*/
273 	WMITLV_SET_HDR(&cmd_fixed_param->tlv_header,
274 		WMITLV_TAG_STRUC_wmi_request_ctrl_path_stats_cmd_fixed_param,
275 		WMITLV_GET_STRUCT_TLVLEN(
276 				wmi_request_ctrl_path_stats_cmd_fixed_param));
277 
278 	index = get_infra_cp_stats_id(stats_req->stats_id);
279 	cmd_fixed_param->stats_id_mask = (1 << index);
280 
281 	cmd_fixed_param->request_id = stats_req->action;
282 	cmd_fixed_param->action = get_infra_cp_stats_action(stats_req->action);
283 
284 	buf_ptr = (uint8_t *)cmd_fixed_param;
285 	/* Setting tlv header for pdev id arrays*/
286 	buf_ptr = buf_ptr + sizeof(*cmd_fixed_param);
287 	pdev_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
288 	WMITLV_SET_HDR(buf_ptr,  WMITLV_TAG_ARRAY_UINT32,
289 		       sizeof(A_UINT32) * num_pdev_ids);
290 
291 	/* Setting tlv header for vdev id arrays*/
292 	buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE +
293 		  (sizeof(A_UINT32) * num_pdev_ids);
294 	vdev_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
295 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
296 		       sizeof(A_UINT32) * num_vdev_ids);
297 
298 	/* Setting tlv header for mac addr arrays*/
299 	buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE +
300 		  (sizeof(A_UINT32) * num_vdev_ids);
301 	mac_addr_array = buf_ptr + WMI_TLV_HDR_SIZE;
302 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC,
303 		       sizeof(wmi_mac_addr) * num_mac_addr_list);
304 
305 	/* Setting tlv header for dialog id arrays*/
306 	buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE +
307 		  sizeof(wmi_mac_addr) * num_mac_addr_list;
308 	dialog_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE);
309 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
310 		       sizeof(A_UINT32) * num_dialog_ids);
311 
312 	for (index = 0; index < num_pdev_ids; index++)
313 		pdev_id_array[index] = stats_req->pdev_id[index];
314 
315 	for (index = 0; index < num_vdev_ids; index++)
316 		vdev_id_array[index] = stats_req->vdev_id[index];
317 
318 	for (index = 0; index < num_mac_addr_list; index++) {
319 		qdf_mem_copy(mac_addr_array, stats_req->peer_mac_addr[index],
320 			     QDF_MAC_ADDR_SIZE);
321 		mac_addr_array += QDF_MAC_ADDR_SIZE;
322 	}
323 
324 	dialog_id_array[0] = get_stats_req_twt_dialog_id(stats_req);
325 
326 	wmi_debug("stats_id_mask 0x%x action 0x%x dialog_id %d",
327 		  cmd_fixed_param->stats_id_mask, cmd_fixed_param->action,
328 		  dialog_id_array[0]);
329 	wmi_debug("num_pdev_ids %d num_vdev_ids %d num_dialog_ids %d \
330 		   num_mac_addr %d", num_pdev_ids, num_vdev_ids,
331 		   num_dialog_ids, num_mac_addr_list);
332 
333 	return req_buf;
334 }
335 
336 /**
337  * send_infra_cp_stats_request_cmd_tlv() - Prepare and send infra_cp_stats
338  * wmi cmd to firmware
339  * @wmi_handle: wmi handle
340  * @param: Pointer to request structure
341  *
342  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
343  * on failure
344  */
345 static QDF_STATUS
346 send_infra_cp_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
347 				    struct infra_cp_stats_cmd_info *param)
348 {
349 	uint32_t len;
350 	wmi_buf_t buf;
351 	QDF_STATUS status;
352 
353 	buf = prepare_infra_cp_stats_buf(wmi_handle, param, &len);
354 	if (!buf)
355 		return QDF_STATUS_E_NOMEM;
356 
357 	wmi_debug("buf_len %d", len);
358 
359 	wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0);
360 	status = wmi_unified_cmd_send(wmi_handle, buf,
361 				      len, WMI_REQUEST_CTRL_PATH_STATS_CMDID);
362 
363 	if (QDF_IS_STATUS_ERROR(status)) {
364 		wmi_buf_free(buf);
365 		return QDF_STATUS_E_FAILURE;
366 	}
367 
368 	return QDF_STATUS_SUCCESS;
369 }
370 #else
371 static inline QDF_STATUS
372 send_infra_cp_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
373 				    struct infra_cp_stats_cmd_info *param)
374 {
375 	return QDF_STATUS_SUCCESS;
376 }
377 #endif
378 
379 #ifdef QCA_WIFI_EMULATION
380 static QDF_STATUS
381 send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
382 			   uint8_t macaddr[QDF_MAC_ADDR_SIZE],
383 			   struct stats_request_params *param)
384 {
385 	return QDF_STATUS_SUCCESS;
386 }
387 #else
388 /**
389  * send_stats_request_cmd_tlv() - WMI request stats function
390  * @param wmi_handle: handle to WMI.
391  * @param macaddr: MAC address
392  * @param param: pointer to hold stats request parameter
393  *
394  * Return: 0  on success and -ve on failure.
395  */
396 static QDF_STATUS
397 send_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
398 			   uint8_t macaddr[QDF_MAC_ADDR_SIZE],
399 			   struct stats_request_params *param)
400 {
401 	int32_t ret;
402 	wmi_request_stats_cmd_fixed_param *cmd;
403 	wmi_buf_t buf;
404 	uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param);
405 	bool is_qmi_send_support;
406 
407 	buf = wmi_buf_alloc(wmi_handle, len);
408 	if (!buf)
409 		return QDF_STATUS_E_NOMEM;
410 
411 	cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf);
412 	WMITLV_SET_HDR(&cmd->tlv_header,
413 		       WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
414 		       WMITLV_GET_STRUCT_TLVLEN
415 			       (wmi_request_stats_cmd_fixed_param));
416 	cmd->stats_id = param->stats_id;
417 	cmd->vdev_id = param->vdev_id;
418 	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
419 							wmi_handle,
420 							param->pdev_id);
421 	is_qmi_send_support = param->is_qmi_send_support;
422 
423 	WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr);
424 
425 	wmi_debug("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d, is_qmi_send_support %d",
426 		  cmd->stats_id, cmd->vdev_id, cmd->pdev_id,
427 		  is_qmi_send_support);
428 
429 	wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0);
430 	ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len,
431 					  WMI_REQUEST_STATS_CMDID,
432 					  is_qmi_send_support);
433 
434 	if (ret) {
435 		wmi_err("Failed to send stats request to fw =%d", ret);
436 		wmi_buf_free(buf);
437 	}
438 
439 	return qdf_status_from_os_return(ret);
440 }
441 #endif
442 
443 #ifdef WLAN_FEATURE_BIG_DATA_STATS
444 /**
445  * send_big_data_stats_request_cmd_tlv () - send big data stats cmd
446  * @wmi_handle: wmi handle
447  * @param : pointer to command request param
448  *
449  * Return: QDF_STATUS_SUCCESS for success or error code
450  */
451 static QDF_STATUS
452 send_big_data_stats_request_cmd_tlv(wmi_unified_t wmi_handle,
453 				    struct stats_request_params *param)
454 {
455 	int32_t ret = 0;
456 	wmi_vdev_get_big_data_p2_cmd_fixed_param *cmd;
457 	wmi_buf_t buf;
458 	uint16_t len = sizeof(wmi_vdev_get_big_data_p2_cmd_fixed_param);
459 
460 	buf = wmi_buf_alloc(wmi_handle, len);
461 	if (!buf)
462 		return QDF_STATUS_E_NOMEM;
463 
464 	cmd = (wmi_vdev_get_big_data_p2_cmd_fixed_param *)wmi_buf_data(buf);
465 	WMITLV_SET_HDR(
466 		&cmd->tlv_header,
467 		WMITLV_TAG_STRUC_wmi_vdev_get_big_data_p2_cmd_fixed_param,
468 		WMITLV_GET_STRUCT_TLVLEN
469 		(wmi_vdev_get_big_data_p2_cmd_fixed_param));
470 
471 	cmd->vdev_id = param->vdev_id;
472 
473 	wmi_debug("STATS VDEV_ID:%d -->", cmd->vdev_id);
474 
475 	wmi_mtrace(WMI_VDEV_GET_BIG_DATA_P2_CMDID, cmd->vdev_id, 0);
476 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
477 				   WMI_VDEV_GET_BIG_DATA_P2_CMDID);
478 
479 	if (ret) {
480 		wmi_err("Failed to send big data stats request to fw =%d", ret);
481 		wmi_buf_free(buf);
482 	}
483 
484 	return qdf_status_from_os_return(ret);
485 }
486 #endif
487 
488 /**
489  * extract_all_stats_counts_tlv() - extract all stats count from event
490  * @param wmi_handle: wmi handle
491  * @param evt_buf: pointer to event buffer
492  * @param stats_param: Pointer to hold stats count
493  *
494  * Return: QDF_STATUS_SUCCESS for success or error code
495  */
496 static QDF_STATUS
497 extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, void *evt_buf,
498 			     wmi_host_stats_event *stats_param)
499 {
500 	wmi_stats_event_fixed_param *ev;
501 	wmi_per_chain_rssi_stats *rssi_event;
502 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
503 	uint64_t min_data_len;
504 	uint32_t i;
505 
506 	qdf_mem_zero(stats_param, sizeof(*stats_param));
507 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
508 	ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
509 	rssi_event = param_buf->chain_stats;
510 	if (!ev) {
511 		wmi_err("event fixed param NULL");
512 		return QDF_STATUS_E_FAILURE;
513 	}
514 
515 	if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) {
516 		wmi_err("num_data : %u is invalid", param_buf->num_data);
517 		return QDF_STATUS_E_FAULT;
518 	}
519 
520 	for (i = 1; i <= WMI_REQUEST_VDEV_EXTD_STAT; i = i << 1) {
521 		switch (ev->stats_id & i) {
522 		case WMI_REQUEST_PEER_STAT:
523 			stats_param->stats_id |= WMI_HOST_REQUEST_PEER_STAT;
524 			break;
525 
526 		case WMI_REQUEST_AP_STAT:
527 			stats_param->stats_id |= WMI_HOST_REQUEST_AP_STAT;
528 			break;
529 
530 		case WMI_REQUEST_PDEV_STAT:
531 			stats_param->stats_id |= WMI_HOST_REQUEST_PDEV_STAT;
532 			break;
533 
534 		case WMI_REQUEST_VDEV_STAT:
535 			stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_STAT;
536 			break;
537 
538 		case WMI_REQUEST_BCNFLT_STAT:
539 			stats_param->stats_id |= WMI_HOST_REQUEST_BCNFLT_STAT;
540 			break;
541 
542 		case WMI_REQUEST_VDEV_RATE_STAT:
543 			stats_param->stats_id |=
544 				WMI_HOST_REQUEST_VDEV_RATE_STAT;
545 			break;
546 
547 		case WMI_REQUEST_BCN_STAT:
548 			stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
549 			break;
550 		case WMI_REQUEST_PEER_EXTD_STAT:
551 			stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT;
552 			break;
553 
554 		case WMI_REQUEST_PEER_EXTD2_STAT:
555 			stats_param->stats_id |=
556 				WMI_HOST_REQUEST_PEER_ADV_STATS;
557 			break;
558 
559 		case WMI_REQUEST_PMF_BCN_PROTECT_STAT:
560 			stats_param->stats_id |=
561 				WMI_HOST_REQUEST_PMF_BCN_PROTECT_STAT;
562 			break;
563 
564 		case WMI_REQUEST_VDEV_EXTD_STAT:
565 			stats_param->stats_id |=
566 				WMI_HOST_REQUEST_VDEV_PRB_FILS_STAT;
567 			break;
568 		}
569 	}
570 
571 	/* ev->num_*_stats may cause uint32_t overflow, so use uint64_t
572 	 * to save total length calculated
573 	 */
574 	min_data_len =
575 		(((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
576 		(((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
577 		(((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) +
578 		(((uint64_t)ev->num_bcnflt_stats) *
579 		 sizeof(wmi_bcnfilter_stats_t)) +
580 		(((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) +
581 		(((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) +
582 		(((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) +
583 		(((uint64_t)ev->num_peer_extd_stats) *
584 		 sizeof(wmi_peer_extd_stats)) +
585 		(((uint64_t)ev->num_mib_extd_stats) *
586 		 sizeof(wmi_mib_extd_stats));
587 	if (param_buf->num_data != min_data_len) {
588 		wmi_err("data len: %u isn't same as calculated: %llu",
589 			 param_buf->num_data, min_data_len);
590 		return QDF_STATUS_E_FAULT;
591 	}
592 
593 	stats_param->last_event = ev->last_event;
594 	stats_param->num_pdev_stats = ev->num_pdev_stats;
595 	stats_param->num_pdev_ext_stats = 0;
596 	stats_param->num_vdev_stats = ev->num_vdev_stats;
597 	stats_param->num_peer_stats = ev->num_peer_stats;
598 	stats_param->num_peer_extd_stats = ev->num_peer_extd_stats;
599 	stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
600 	stats_param->num_chan_stats = ev->num_chan_stats;
601 	stats_param->num_mib_stats = ev->num_mib_stats;
602 	stats_param->num_mib_extd_stats = ev->num_mib_extd_stats;
603 	stats_param->num_bcn_stats = ev->num_bcn_stats;
604 	stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
605 							wmi_handle,
606 							ev->pdev_id);
607 
608 	/* if chain_stats is not populated */
609 	if (!param_buf->chain_stats || !param_buf->num_chain_stats)
610 		return QDF_STATUS_SUCCESS;
611 
612 	if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
613 	    WMITLV_GET_TLVTAG(rssi_event->tlv_header))
614 		return QDF_STATUS_SUCCESS;
615 
616 	if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
617 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header))
618 		return QDF_STATUS_SUCCESS;
619 
620 	if (rssi_event->num_per_chain_rssi_stats >=
621 	    WMITLV_GET_TLVLEN(rssi_event->tlv_header)) {
622 		wmi_err("num_per_chain_rssi_stats:%u is out of bounds",
623 			 rssi_event->num_per_chain_rssi_stats);
624 		return QDF_STATUS_E_INVAL;
625 	}
626 	stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
627 
628 	if (param_buf->vdev_extd_stats)
629 		stats_param->num_vdev_extd_stats =
630 			param_buf->num_vdev_extd_stats;
631 
632 	/* if peer_adv_stats is not populated */
633 	if (param_buf->num_peer_extd2_stats)
634 		stats_param->num_peer_adv_stats =
635 			param_buf->num_peer_extd2_stats;
636 
637 	return QDF_STATUS_SUCCESS;
638 }
639 
640 /**
641  * extract_pdev_tx_stats() - extract pdev tx stats from event
642  */
643 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx,
644 				  struct wlan_dbg_tx_stats *tx_stats)
645 {
646 	/* Tx Stats */
647 	tx->comp_queued = tx_stats->comp_queued;
648 	tx->comp_delivered = tx_stats->comp_delivered;
649 	tx->msdu_enqued = tx_stats->msdu_enqued;
650 	tx->mpdu_enqued = tx_stats->mpdu_enqued;
651 	tx->wmm_drop = tx_stats->wmm_drop;
652 	tx->local_enqued = tx_stats->local_enqued;
653 	tx->local_freed = tx_stats->local_freed;
654 	tx->hw_queued = tx_stats->hw_queued;
655 	tx->hw_reaped = tx_stats->hw_reaped;
656 	tx->underrun = tx_stats->underrun;
657 	tx->tx_abort = tx_stats->tx_abort;
658 	tx->mpdus_requed = tx_stats->mpdus_requed;
659 	tx->data_rc = tx_stats->data_rc;
660 	tx->self_triggers = tx_stats->self_triggers;
661 	tx->sw_retry_failure = tx_stats->sw_retry_failure;
662 	tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err;
663 	tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry;
664 	tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout;
665 	tx->pdev_resets = tx_stats->pdev_resets;
666 	tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure;
667 	tx->phy_underrun = tx_stats->phy_underrun;
668 	tx->txop_ovf = tx_stats->txop_ovf;
669 
670 	return;
671 }
672 
673 
674 /**
675  * extract_pdev_rx_stats() - extract pdev rx stats from event
676  */
677 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx,
678 				  struct wlan_dbg_rx_stats *rx_stats)
679 {
680 	/* Rx Stats */
681 	rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change;
682 	rx->status_rcvd = rx_stats->status_rcvd;
683 	rx->r0_frags = rx_stats->r0_frags;
684 	rx->r1_frags = rx_stats->r1_frags;
685 	rx->r2_frags = rx_stats->r2_frags;
686 	/* Only TLV */
687 	rx->r3_frags = 0;
688 	rx->htt_msdus = rx_stats->htt_msdus;
689 	rx->htt_mpdus = rx_stats->htt_mpdus;
690 	rx->loc_msdus = rx_stats->loc_msdus;
691 	rx->loc_mpdus = rx_stats->loc_mpdus;
692 	rx->oversize_amsdu = rx_stats->oversize_amsdu;
693 	rx->phy_errs = rx_stats->phy_errs;
694 	rx->phy_err_drop = rx_stats->phy_err_drop;
695 	rx->mpdu_errs = rx_stats->mpdu_errs;
696 
697 	return;
698 }
699 
700 /**
701  * extract_pdev_stats_tlv() - extract pdev stats from event
702  * @param wmi_handle: wmi handle
703  * @param evt_buf: pointer to event buffer
704  * @param index: Index into pdev stats
705  * @param pdev_stats: Pointer to hold pdev stats
706  *
707  * Return: QDF_STATUS_SUCCESS for success or error code
708  */
709 static QDF_STATUS
710 extract_pdev_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t index,
711 		       wmi_host_pdev_stats *pdev_stats)
712 {
713 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
714 	wmi_stats_event_fixed_param *ev_param;
715 	uint8_t *data;
716 
717 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
718 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
719 	pdev_stats->pdev_id =
720 	     wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle,
721 							     ev_param->pdev_id);
722 
723 	data = param_buf->data;
724 
725 	if (index < ev_param->num_pdev_stats) {
726 		wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) +
727 				(index * sizeof(wmi_pdev_stats)));
728 
729 		pdev_stats->chan_nf = ev->chan_nf;
730 		pdev_stats->tx_frame_count = ev->tx_frame_count;
731 		pdev_stats->rx_frame_count = ev->rx_frame_count;
732 		pdev_stats->rx_clear_count = ev->rx_clear_count;
733 		pdev_stats->cycle_count = ev->cycle_count;
734 		pdev_stats->phy_err_count = ev->phy_err_count;
735 		pdev_stats->chan_tx_pwr = ev->chan_tx_pwr;
736 
737 		extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx),
738 			&(ev->pdev_stats.tx));
739 		extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx),
740 			&(ev->pdev_stats.rx));
741 	}
742 
743 	return QDF_STATUS_SUCCESS;
744 }
745 
746 /**
747  * extract_vdev_stats_tlv() - extract vdev stats from event
748  * @param wmi_handle: wmi handle
749  * @param evt_buf: pointer to event buffer
750  * @param index: Index into vdev stats
751  * @param vdev_stats: Pointer to hold vdev stats
752  *
753  * Return: QDF_STATUS_SUCCESS for success or error code
754  */
755 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle,
756 	void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats)
757 {
758 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
759 	wmi_stats_event_fixed_param *ev_param;
760 	uint8_t *data;
761 
762 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
763 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
764 	data = (uint8_t *) param_buf->data;
765 
766 	if (index < ev_param->num_vdev_stats) {
767 		wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) +
768 				((ev_param->num_pdev_stats) *
769 				sizeof(wmi_pdev_stats)) +
770 				(index * sizeof(wmi_vdev_stats)));
771 
772 		vdev_stats->vdev_id = ev->vdev_id;
773 		vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr;
774 		vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr;
775 
776 		OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt,
777 			sizeof(ev->tx_frm_cnt));
778 		vdev_stats->rx_frm_cnt = ev->rx_frm_cnt;
779 		OS_MEMCPY(vdev_stats->multiple_retry_cnt,
780 				ev->multiple_retry_cnt,
781 				sizeof(ev->multiple_retry_cnt));
782 		OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt,
783 				sizeof(ev->fail_cnt));
784 		vdev_stats->rts_fail_cnt = ev->rts_fail_cnt;
785 		vdev_stats->rts_succ_cnt = ev->rts_succ_cnt;
786 		vdev_stats->rx_err_cnt = ev->rx_err_cnt;
787 		vdev_stats->rx_discard_cnt = ev->rx_discard_cnt;
788 		vdev_stats->ack_fail_cnt = ev->ack_fail_cnt;
789 		OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history,
790 			sizeof(ev->tx_rate_history));
791 		OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history,
792 			sizeof(ev->bcn_rssi_history));
793 
794 	}
795 
796 	return QDF_STATUS_SUCCESS;
797 }
798 
799 /**
800  * extract_peer_stats_tlv() - extract peer stats from event
801  * @param wmi_handle: wmi handle
802  * @param evt_buf: pointer to event buffer
803  * @param index: Index into peer stats
804  * @param peer_stats: Pointer to hold peer stats
805  *
806  * Return: QDF_STATUS_SUCCESS for success or error code
807  */
808 static QDF_STATUS
809 extract_peer_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t index,
810 		       wmi_host_peer_stats *peer_stats)
811 {
812 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
813 	wmi_stats_event_fixed_param *ev_param;
814 	uint8_t *data;
815 
816 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
817 	ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
818 	data = (uint8_t *) param_buf->data;
819 
820 	if (index < ev_param->num_peer_stats) {
821 		wmi_peer_stats *ev = (wmi_peer_stats *) ((data) +
822 			((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) +
823 			((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) +
824 			(index * sizeof(wmi_peer_stats)));
825 
826 		OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats));
827 
828 		OS_MEMCPY(&(peer_stats->peer_macaddr),
829 			&(ev->peer_macaddr), sizeof(wmi_mac_addr));
830 
831 		peer_stats->peer_rssi = ev->peer_rssi;
832 		peer_stats->peer_tx_rate = ev->peer_tx_rate;
833 		peer_stats->peer_rx_rate = ev->peer_rx_rate;
834 	}
835 
836 	return QDF_STATUS_SUCCESS;
837 }
838 
839 /**
840  * extract_peer_extd_stats_tlv() - extract extended peer stats from event
841  * @param wmi_handle: wmi handle
842  * @param evt_buf: pointer to event buffer
843  * @param index: Index into extended peer stats
844  * @param peer_extd_stats: Pointer to hold extended peer stats
845  *
846  * Return: QDF_STATUS_SUCCESS for success or error code
847  */
848 static QDF_STATUS
849 extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
850 			    void *evt_buf, uint32_t index,
851 			    wmi_host_peer_extd_stats *peer_extd_stats)
852 {
853 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
854 	wmi_stats_event_fixed_param *ev_param;
855 	uint8_t *data;
856 
857 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
858 	ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
859 	data = (uint8_t *)param_buf->data;
860 	if (!data)
861 		return QDF_STATUS_E_FAILURE;
862 
863 	if (index < ev_param->num_peer_extd_stats) {
864 		wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data +
865 			(ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) +
866 			(ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) +
867 			(ev_param->num_peer_stats * sizeof(wmi_peer_stats)) +
868 			(ev_param->num_bcnflt_stats *
869 			sizeof(wmi_bcnfilter_stats_t)) +
870 			(ev_param->num_chan_stats * sizeof(wmi_chan_stats)) +
871 			(ev_param->num_mib_stats * sizeof(wmi_mib_stats)) +
872 			(ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) +
873 			(index * sizeof(wmi_peer_extd_stats)));
874 
875 		qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats));
876 		qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr,
877 			     sizeof(wmi_mac_addr));
878 
879 		peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt;
880 	}
881 
882 	return QDF_STATUS_SUCCESS;
883 
884 }
885 
886 /**
887  * extract_pmf_bcn_protect_stats_tlv() - extract pmf bcn stats from event
888  * @wmi_handle: wmi handle
889  * @evt_buf: pointer to event buffer
890  * @pmf_bcn_stats: Pointer to hold pmf bcn protect stats
891  *
892  * Return: QDF_STATUS_SUCCESS for success or error code
893  */
894 
895 static QDF_STATUS
896 extract_pmf_bcn_protect_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
897 				  wmi_host_pmf_bcn_protect_stats *pmf_bcn_stats)
898 {
899 	WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
900 	wmi_stats_event_fixed_param *ev_param;
901 
902 	param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
903 	if (!param_buf)
904 		return QDF_STATUS_E_FAILURE;
905 
906 	ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
907 
908 	if ((ev_param->stats_id & WMI_REQUEST_PMF_BCN_PROTECT_STAT) &&
909 	    param_buf->pmf_bcn_protect_stats) {
910 		pmf_bcn_stats->igtk_mic_fail_cnt =
911 			param_buf->pmf_bcn_protect_stats->igtk_mic_fail_cnt;
912 		pmf_bcn_stats->igtk_replay_cnt =
913 			param_buf->pmf_bcn_protect_stats->igtk_replay_cnt;
914 		pmf_bcn_stats->bcn_mic_fail_cnt =
915 			param_buf->pmf_bcn_protect_stats->bcn_mic_fail_cnt;
916 		pmf_bcn_stats->bcn_replay_cnt =
917 			param_buf->pmf_bcn_protect_stats->bcn_replay_cnt;
918 	}
919 
920 	return QDF_STATUS_SUCCESS;
921 }
922 
923 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
924 static void wmi_infra_cp_stats_ops_attach_tlv(struct wmi_ops *ops)
925 {
926 	ops->send_infra_cp_stats_request_cmd =
927 					send_infra_cp_stats_request_cmd_tlv;
928 }
929 #else
930 static void wmi_infra_cp_stats_ops_attach_tlv(struct wmi_ops *ops)
931 {
932 }
933 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
934 
935 #ifdef WLAN_FEATURE_SON
936 /**
937  * extract_inst_rssi_stats_resp_tlv() - extract inst rssi stats from event
938  * @wmi_handle: wmi handle
939  * @evt_buf: pointer to event buffer
940  * @inst_rssi_resp: Pointer to hold inst rssi response
941  *
942  * @Return: QDF_STATUS_SUCCESS for success or error code
943  */
944 static QDF_STATUS
945 extract_inst_rssi_stats_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf,
946 			struct wmi_host_inst_rssi_stats_resp *inst_rssi_resp)
947 {
948 	WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf;
949 	wmi_inst_rssi_stats_resp_fixed_param *event;
950 
951 	param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf;
952 	event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param;
953 
954 	inst_rssi_resp->inst_rssi = event->iRSSI;
955 	WMI_CHAR_ARRAY_TO_MAC_ADDR(inst_rssi_resp->peer_macaddr.bytes,
956 				   &event->peer_macaddr);
957 	inst_rssi_resp->vdev_id = event->vdev_id;
958 
959 	return QDF_STATUS_SUCCESS;
960 }
961 
962 static void
963 wmi_inst_rssi_stats_ops_attach_tlv(struct wmi_ops *ops)
964 {
965 	ops->extract_inst_rssi_stats_resp = extract_inst_rssi_stats_resp_tlv;
966 }
967 #else
968 static void
969 wmi_inst_rssi_stats_ops_attach_tlv(struct wmi_ops *ops)
970 {
971 }
972 #endif
973 
974 void wmi_cp_stats_attach_tlv(wmi_unified_t wmi_handle)
975 {
976 	struct wmi_ops *ops = wmi_handle->ops;
977 
978 	ops->send_stats_request_cmd = send_stats_request_cmd_tlv;
979 #ifdef WLAN_FEATURE_BIG_DATA_STATS
980 	ops->send_big_data_stats_request_cmd =
981 				send_big_data_stats_request_cmd_tlv;
982 #endif
983 	ops->extract_all_stats_count = extract_all_stats_counts_tlv;
984 	ops->extract_pdev_stats = extract_pdev_stats_tlv;
985 	ops->extract_vdev_stats = extract_vdev_stats_tlv;
986 	ops->extract_peer_stats = extract_peer_stats_tlv;
987 	ops->extract_peer_extd_stats = extract_peer_extd_stats_tlv;
988 	wmi_infra_cp_stats_ops_attach_tlv(ops);
989 	ops->extract_pmf_bcn_protect_stats = extract_pmf_bcn_protect_stats_tlv,
990 	wmi_inst_rssi_stats_ops_attach_tlv(ops);
991 
992 	wmi_mc_cp_stats_attach_tlv(wmi_handle);
993 }
994