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 #ifdef CONFIG_WLAN_BMISS 107 static void 108 wmi_extract_ctrl_path_bmiss_stats_tlv(void *tag_buf, 109 struct bmiss_infra_cp_stats_event *param) 110 { 111 int idx = 0; 112 113 wmi_ctrl_path_bmiss_stats_struct *wmi_stats_buf = 114 (wmi_ctrl_path_bmiss_stats_struct *)tag_buf; 115 param->num_pre_bmiss = wmi_stats_buf->num_pre_bmiss; 116 for (idx = 0; idx < BMISS_STATS_RSSI_SAMPLES_MAX; idx++) { 117 param->rssi_samples[idx].rssi = 118 wmi_stats_buf->rssi_samples[idx].rssi; 119 param->rssi_samples[idx].sample_time = 120 wmi_stats_buf->rssi_samples[idx].sample_time; 121 } 122 param->rssi_sample_curr_index = wmi_stats_buf->rssi_sample_curr_index; 123 param->num_first_bmiss = wmi_stats_buf->num_first_bmiss; 124 param->num_final_bmiss = wmi_stats_buf->num_final_bmiss; 125 param->num_null_sent_in_first_bmiss = 126 wmi_stats_buf->num_null_sent_in_first_bmiss; 127 param->num_null_failed_in_first_bmiss = 128 wmi_stats_buf->num_null_failed_in_first_bmiss; 129 param->num_null_failed_in_final_bmiss = 130 wmi_stats_buf->num_null_failed_in_final_bmiss; 131 param->cons_bmiss_stats.num_of_bmiss_sequences = 132 wmi_stats_buf->cons_bmiss_stats.num_of_bmiss_sequences; 133 param->cons_bmiss_stats.num_bitmask_wraparound = 134 wmi_stats_buf->cons_bmiss_stats.num_bitmask_wraparound; 135 param->cons_bmiss_stats.num_bcn_hist_lost = 136 wmi_stats_buf->cons_bmiss_stats.num_bcn_hist_lost; 137 wmi_debug("num_pre_bmiss = %u", wmi_stats_buf->num_pre_bmiss); 138 wmi_debug("num_first_bmiss = %u num_final_bmiss = %u, num_null_sent_in_first_bmiss = %u, num_null_failed_in_first_bmiss = %u", 139 wmi_stats_buf->num_first_bmiss, 140 wmi_stats_buf->num_final_bmiss, 141 wmi_stats_buf->num_null_sent_in_first_bmiss, 142 wmi_stats_buf->num_null_failed_in_first_bmiss); 143 wmi_debug("num_null_sent_in_final_bmiss %u null_fail_cnt_final_bmiss = %u rssi_sample_curr_index = %u", 144 wmi_stats_buf->num_null_sent_in_final_bmiss, 145 wmi_stats_buf->num_null_failed_in_final_bmiss, 146 wmi_stats_buf->rssi_sample_curr_index); 147 for (idx = 0; idx < BMISS_STATS_RSSI_SAMPLES_MAX; idx++) { 148 wmi_debug("rssi_sample-%u: rssi=%u", idx, 149 wmi_stats_buf->rssi_samples[idx].rssi); 150 wmi_debug("rssi_sample-%u: sampletime=%u", idx, 151 wmi_stats_buf->rssi_samples[idx].sample_time); 152 } 153 wmi_debug("num_of_bmiss_sequences %u num_bitmask_wraparound = %u num_bcn_hist_lost = %u", 154 wmi_stats_buf->cons_bmiss_stats.num_of_bmiss_sequences, 155 wmi_stats_buf->cons_bmiss_stats.num_bitmask_wraparound, 156 wmi_stats_buf->cons_bmiss_stats.num_bcn_hist_lost); 157 } 158 159 static void wmi_bmiss_extract_stats_struct(void *tag_buf, 160 struct infra_cp_stats_event *params) 161 { 162 struct bmiss_infra_cp_stats_event *bmiss_params; 163 164 bmiss_params = params->bmiss_infra_cp_stats; 165 wmi_debug("BMISS stats struct found"); 166 wmi_extract_ctrl_path_bmiss_stats_tlv(tag_buf, bmiss_params); 167 } 168 169 #else /* CONFIG_WLAN_BMISS */ 170 static inline 171 void wmi_bmiss_extract_stats_struct(void *tag_buf, 172 struct infra_cp_stats_event *params) 173 174 { 175 } 176 177 #endif/* CONFIG_WLAN_BMISS */ 178 179 /* 180 * wmi_stats_extract_tag_struct: function to extract tag structs 181 * @tag_type: tag type that is to be printed 182 * @tag_buf: pointer to the tag structure 183 * @params: buffer to hold parameters extracted from response event 184 * 185 * Return: None 186 */ 187 static void wmi_stats_extract_tag_struct(uint32_t tag_type, void *tag_buf, 188 struct infra_cp_stats_event *params) 189 { 190 wmi_debug("tag_type %d", tag_type); 191 192 switch (tag_type) { 193 case WMITLV_TAG_STRUC_wmi_ctrl_path_pdev_stats_struct: 194 break; 195 196 case WMITLV_TAG_STRUC_wmi_ctrl_path_mem_stats_struct: 197 break; 198 199 case WMITLV_TAG_STRUC_wmi_ctrl_path_twt_stats_struct: 200 wmi_twt_extract_stats_struct(tag_buf, params); 201 break; 202 203 case WMITLV_TAG_STRUC_wmi_ctrl_path_bmiss_stats_struct: 204 wmi_bmiss_extract_stats_struct(tag_buf, params); 205 break; 206 207 default: 208 break; 209 } 210 } 211 212 /* 213 * wmi_stats_handler: parse the wmi event and fill the stats values 214 * @buff: Buffer containing wmi event 215 * @len: length of event buffer 216 * @params: buffer to hold parameters extracted from response event 217 * 218 * Return: QDF_STATUS_SUCCESS on success, else other qdf error values 219 */ 220 QDF_STATUS wmi_stats_handler(void *buff, int32_t len, 221 struct infra_cp_stats_event *params) 222 { 223 WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *param_buf; 224 wmi_ctrl_path_stats_event_fixed_param *ev; 225 uint8_t *buf_ptr = (uint8_t *)buff; 226 uint32_t curr_tlv_tag; 227 uint32_t curr_tlv_len; 228 uint8_t *tag_start_ptr; 229 230 param_buf = (WMI_CTRL_PATH_STATS_EVENTID_param_tlvs *)buff; 231 if (!param_buf) { 232 wmi_err_rl("param_buf is NULL"); 233 return QDF_STATUS_E_FAILURE; 234 } 235 ev = (wmi_ctrl_path_stats_event_fixed_param *)param_buf->fixed_param; 236 237 curr_tlv_tag = WMITLV_GET_TLVTAG(ev->tlv_header); 238 curr_tlv_len = WMITLV_GET_TLVLEN(ev->tlv_header); 239 buf_ptr = (uint8_t *)param_buf->fixed_param; 240 wmi_debug("Fixed param more %d req_id %d status %d", ev->more, 241 ev->request_id, ev->status); 242 params->request_id = ev->request_id; 243 params->status = ev->status; 244 245 /* buffer should point to next TLV in event */ 246 buf_ptr += (curr_tlv_len + WMI_TLV_HDR_SIZE); 247 len -= (curr_tlv_len + WMI_TLV_HDR_SIZE); 248 249 curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr)); 250 curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); 251 252 wmi_debug("curr_tlv_len %d curr_tlv_tag %d rem_len %d", len, 253 curr_tlv_len, curr_tlv_tag); 254 255 while ((len >= curr_tlv_len) && 256 (curr_tlv_tag >= WMITLV_TAG_FIRST_ARRAY_ENUM)) { 257 if (curr_tlv_tag == WMITLV_TAG_ARRAY_STRUC) { 258 /* Move to next WMITLV_TAG_ARRAY_STRUC */ 259 buf_ptr += WMI_TLV_HDR_SIZE; 260 len -= WMI_TLV_HDR_SIZE; 261 if (len <= 0) 262 break; 263 } 264 curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr)); 265 curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); 266 267 wmi_debug("curr_tlv_len %d curr_tlv_tag %d rem_len %d", 268 len, curr_tlv_len, curr_tlv_tag); 269 if (curr_tlv_len) { 270 /* point to the tag inside WMITLV_TAG_ARRAY_STRUC */ 271 tag_start_ptr = buf_ptr + WMI_TLV_HDR_SIZE; 272 curr_tlv_tag = WMITLV_GET_TLVTAG( 273 WMITLV_GET_HDR(tag_start_ptr)); 274 wmi_stats_extract_tag_struct(curr_tlv_tag, 275 (void *)tag_start_ptr, 276 params); 277 /* Move to next tag */ 278 buf_ptr += curr_tlv_len + WMI_TLV_HDR_SIZE; 279 len -= (curr_tlv_len + WMI_TLV_HDR_SIZE); 280 } 281 if (len <= 0) 282 break; 283 } 284 285 return QDF_STATUS_SUCCESS; 286 } 287 288 /** 289 * extract_infra_cp_stats_tlv - api to extract stats information from 290 * event buffer 291 * @wmi_handle: wmi handle 292 * @evt_buf: event buffer 293 * @evt_buf_len: length of the event buffer 294 * @params: buffer to populate more flag 295 * 296 * Return: QDF_STATUS_SUCCESS on success, else other qdf error values 297 */ 298 QDF_STATUS 299 extract_infra_cp_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 300 uint32_t evt_buf_len, 301 struct infra_cp_stats_event *params) 302 { 303 wmi_stats_handler(evt_buf, evt_buf_len, params); 304 return QDF_STATUS_SUCCESS; 305 } 306 307 /** 308 * prepare_infra_cp_stats_buf() - Allocate and prepate wmi cmd request buffer 309 * @wmi_handle: wmi handle 310 * @stats_req: Request parameters to be filled in wmi cmd request buffer 311 * @req_buf_len: length of the output wmi cmd buffer allocated 312 * 313 * Return: Valid wmi buffer pointer on success and NULL pointer for failure 314 */ 315 static wmi_buf_t 316 prepare_infra_cp_stats_buf(wmi_unified_t wmi_handle, 317 struct infra_cp_stats_cmd_info *stats_req, 318 uint32_t *req_buf_len) 319 { 320 wmi_request_ctrl_path_stats_cmd_fixed_param *cmd_fixed_param; 321 uint32_t index; 322 wmi_buf_t req_buf; 323 uint8_t *buf_ptr; 324 uint32_t *pdev_id_array; 325 uint32_t *vdev_id_array; 326 uint8_t *mac_addr_array; 327 uint32_t *dialog_id_array; 328 uint32_t num_pdev_ids = stats_req->num_pdev_ids; 329 uint32_t num_vdev_ids = stats_req->num_vdev_ids; 330 uint32_t num_mac_addr_list = stats_req->num_mac_addr_list; 331 uint32_t num_dialog_ids = INFRA_CP_STATS_MAX_REQ_TWT_DIALOG_ID; 332 333 /* Calculate total buffer length */ 334 *req_buf_len = (sizeof(wmi_request_ctrl_path_stats_cmd_fixed_param) + 335 WMI_TLV_HDR_SIZE + (sizeof(A_UINT32) * (num_pdev_ids)) + 336 WMI_TLV_HDR_SIZE + sizeof(A_UINT32) * (num_vdev_ids) + 337 WMI_TLV_HDR_SIZE + 338 sizeof(wmi_mac_addr) * (num_mac_addr_list) + 339 WMI_TLV_HDR_SIZE + 340 (sizeof(A_UINT32) * (num_dialog_ids))); 341 req_buf = wmi_buf_alloc(wmi_handle, *req_buf_len); 342 if (!req_buf) 343 return NULL; 344 345 cmd_fixed_param = (wmi_request_ctrl_path_stats_cmd_fixed_param *) 346 wmi_buf_data(req_buf); 347 348 /*Set TLV header*/ 349 WMITLV_SET_HDR(&cmd_fixed_param->tlv_header, 350 WMITLV_TAG_STRUC_wmi_request_ctrl_path_stats_cmd_fixed_param, 351 WMITLV_GET_STRUCT_TLVLEN( 352 wmi_request_ctrl_path_stats_cmd_fixed_param)); 353 354 index = get_infra_cp_stats_id(stats_req->stats_id); 355 cmd_fixed_param->stats_id_mask = (1 << index); 356 357 cmd_fixed_param->request_id = stats_req->action; 358 cmd_fixed_param->action = get_infra_cp_stats_action(stats_req->action); 359 360 buf_ptr = (uint8_t *)cmd_fixed_param; 361 /* Setting tlv header for pdev id arrays*/ 362 buf_ptr = buf_ptr + sizeof(*cmd_fixed_param); 363 pdev_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 364 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 365 sizeof(A_UINT32) * num_pdev_ids); 366 367 /* Setting tlv header for vdev id arrays*/ 368 buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE + 369 (sizeof(A_UINT32) * num_pdev_ids); 370 vdev_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 371 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 372 sizeof(A_UINT32) * num_vdev_ids); 373 374 /* Setting tlv header for mac addr arrays*/ 375 buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE + 376 (sizeof(A_UINT32) * num_vdev_ids); 377 mac_addr_array = buf_ptr + WMI_TLV_HDR_SIZE; 378 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, 379 sizeof(wmi_mac_addr) * num_mac_addr_list); 380 381 /* Setting tlv header for dialog id arrays*/ 382 buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE + 383 sizeof(wmi_mac_addr) * num_mac_addr_list; 384 dialog_id_array = (uint32_t *)(buf_ptr + WMI_TLV_HDR_SIZE); 385 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 386 sizeof(A_UINT32) * num_dialog_ids); 387 388 for (index = 0; index < num_pdev_ids; index++) 389 pdev_id_array[index] = stats_req->pdev_id[index]; 390 391 for (index = 0; index < num_vdev_ids; index++) 392 vdev_id_array[index] = stats_req->vdev_id[index]; 393 394 for (index = 0; index < num_mac_addr_list; index++) { 395 qdf_mem_copy(mac_addr_array, stats_req->peer_mac_addr[index], 396 QDF_MAC_ADDR_SIZE); 397 mac_addr_array += QDF_MAC_ADDR_SIZE; 398 } 399 400 dialog_id_array[0] = get_stats_req_twt_dialog_id(stats_req); 401 402 wmi_debug("stats_id_mask 0x%x action 0x%x dialog_id %d", 403 cmd_fixed_param->stats_id_mask, cmd_fixed_param->action, 404 dialog_id_array[0]); 405 wmi_debug("num_pdev_ids %d num_vdev_ids %d num_dialog_ids %d \ 406 num_mac_addr %d", num_pdev_ids, num_vdev_ids, 407 num_dialog_ids, num_mac_addr_list); 408 409 return req_buf; 410 } 411 412 /** 413 * send_infra_cp_stats_request_cmd_tlv() - Prepare and send infra_cp_stats 414 * wmi cmd to firmware 415 * @wmi_handle: wmi handle 416 * @param: Pointer to request structure 417 * 418 * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes 419 * on failure 420 */ 421 static QDF_STATUS 422 send_infra_cp_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 423 struct infra_cp_stats_cmd_info *param) 424 { 425 uint32_t len; 426 wmi_buf_t buf; 427 QDF_STATUS status; 428 429 buf = prepare_infra_cp_stats_buf(wmi_handle, param, &len); 430 if (!buf) 431 return QDF_STATUS_E_NOMEM; 432 433 wmi_debug("buf_len %d", len); 434 435 wmi_mtrace(WMI_REQUEST_CTRL_PATH_STATS_CMDID, NO_SESSION, 0); 436 status = wmi_unified_cmd_send(wmi_handle, buf, 437 len, WMI_REQUEST_CTRL_PATH_STATS_CMDID); 438 439 if (QDF_IS_STATUS_ERROR(status)) { 440 wmi_buf_free(buf); 441 return QDF_STATUS_E_FAILURE; 442 } 443 444 return QDF_STATUS_SUCCESS; 445 } 446 #else 447 static inline QDF_STATUS 448 send_infra_cp_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 449 struct infra_cp_stats_cmd_info *param) 450 { 451 return QDF_STATUS_SUCCESS; 452 } 453 #endif 454 455 #ifdef QCA_WIFI_EMULATION 456 static QDF_STATUS 457 send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 458 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 459 struct stats_request_params *param) 460 { 461 return QDF_STATUS_SUCCESS; 462 } 463 #else 464 /** 465 * send_stats_request_cmd_tlv() - WMI request stats function 466 * @param wmi_handle: handle to WMI. 467 * @param macaddr: MAC address 468 * @param param: pointer to hold stats request parameter 469 * 470 * Return: 0 on success and -ve on failure. 471 */ 472 static QDF_STATUS 473 send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 474 uint8_t macaddr[QDF_MAC_ADDR_SIZE], 475 struct stats_request_params *param) 476 { 477 int32_t ret; 478 wmi_request_stats_cmd_fixed_param *cmd; 479 wmi_buf_t buf; 480 uint16_t len = sizeof(wmi_request_stats_cmd_fixed_param); 481 bool is_qmi_send_support; 482 483 buf = wmi_buf_alloc(wmi_handle, len); 484 if (!buf) 485 return QDF_STATUS_E_NOMEM; 486 487 cmd = (wmi_request_stats_cmd_fixed_param *) wmi_buf_data(buf); 488 WMITLV_SET_HDR(&cmd->tlv_header, 489 WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, 490 WMITLV_GET_STRUCT_TLVLEN 491 (wmi_request_stats_cmd_fixed_param)); 492 cmd->stats_id = param->stats_id; 493 cmd->vdev_id = param->vdev_id; 494 cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target( 495 wmi_handle, 496 param->pdev_id); 497 is_qmi_send_support = param->is_qmi_send_support; 498 499 WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->peer_macaddr); 500 501 wmi_debug("STATS REQ STATS_ID:%d VDEV_ID:%d PDEV_ID:%d, is_qmi_send_support %d", 502 cmd->stats_id, cmd->vdev_id, cmd->pdev_id, 503 is_qmi_send_support); 504 505 wmi_mtrace(WMI_REQUEST_STATS_CMDID, cmd->vdev_id, 0); 506 ret = wmi_unified_cmd_send_pm_chk(wmi_handle, buf, len, 507 WMI_REQUEST_STATS_CMDID, 508 is_qmi_send_support); 509 510 if (ret) { 511 wmi_err("Failed to send stats request to fw =%d", ret); 512 wmi_buf_free(buf); 513 } 514 515 return qdf_status_from_os_return(ret); 516 } 517 #endif 518 519 #ifdef WLAN_FEATURE_BIG_DATA_STATS 520 /** 521 * send_big_data_stats_request_cmd_tlv () - send big data stats cmd 522 * @wmi_handle: wmi handle 523 * @param : pointer to command request param 524 * 525 * Return: QDF_STATUS_SUCCESS for success or error code 526 */ 527 static QDF_STATUS 528 send_big_data_stats_request_cmd_tlv(wmi_unified_t wmi_handle, 529 struct stats_request_params *param) 530 { 531 int32_t ret = 0; 532 wmi_vdev_get_big_data_p2_cmd_fixed_param *cmd; 533 wmi_buf_t buf; 534 uint16_t len = sizeof(wmi_vdev_get_big_data_p2_cmd_fixed_param); 535 536 buf = wmi_buf_alloc(wmi_handle, len); 537 if (!buf) 538 return QDF_STATUS_E_NOMEM; 539 540 cmd = (wmi_vdev_get_big_data_p2_cmd_fixed_param *)wmi_buf_data(buf); 541 WMITLV_SET_HDR( 542 &cmd->tlv_header, 543 WMITLV_TAG_STRUC_wmi_vdev_get_big_data_p2_cmd_fixed_param, 544 WMITLV_GET_STRUCT_TLVLEN 545 (wmi_vdev_get_big_data_p2_cmd_fixed_param)); 546 547 cmd->vdev_id = param->vdev_id; 548 549 wmi_debug("STATS VDEV_ID:%d -->", cmd->vdev_id); 550 551 wmi_mtrace(WMI_VDEV_GET_BIG_DATA_P2_CMDID, cmd->vdev_id, 0); 552 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 553 WMI_VDEV_GET_BIG_DATA_P2_CMDID); 554 555 if (ret) { 556 wmi_err("Failed to send big data stats request to fw =%d", ret); 557 wmi_buf_free(buf); 558 } 559 560 return qdf_status_from_os_return(ret); 561 } 562 #endif 563 564 /** 565 * extract_all_stats_counts_tlv() - extract all stats count from event 566 * @param wmi_handle: wmi handle 567 * @param evt_buf: pointer to event buffer 568 * @param stats_param: Pointer to hold stats count 569 * 570 * Return: QDF_STATUS_SUCCESS for success or error code 571 */ 572 static QDF_STATUS 573 extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, void *evt_buf, 574 wmi_host_stats_event *stats_param) 575 { 576 wmi_stats_event_fixed_param *ev; 577 wmi_per_chain_rssi_stats *rssi_event; 578 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 579 uint64_t min_data_len; 580 uint32_t i; 581 582 qdf_mem_zero(stats_param, sizeof(*stats_param)); 583 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 584 ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 585 rssi_event = param_buf->chain_stats; 586 if (!ev) { 587 wmi_err("event fixed param NULL"); 588 return QDF_STATUS_E_FAILURE; 589 } 590 591 if (param_buf->num_data > WMI_SVC_MSG_MAX_SIZE - sizeof(*ev)) { 592 wmi_err("num_data : %u is invalid", param_buf->num_data); 593 return QDF_STATUS_E_FAULT; 594 } 595 596 for (i = 1; i <= WMI_REQUEST_VDEV_EXTD_STAT; i = i << 1) { 597 switch (ev->stats_id & i) { 598 case WMI_REQUEST_PEER_STAT: 599 stats_param->stats_id |= WMI_HOST_REQUEST_PEER_STAT; 600 break; 601 602 case WMI_REQUEST_AP_STAT: 603 stats_param->stats_id |= WMI_HOST_REQUEST_AP_STAT; 604 break; 605 606 case WMI_REQUEST_PDEV_STAT: 607 stats_param->stats_id |= WMI_HOST_REQUEST_PDEV_STAT; 608 break; 609 610 case WMI_REQUEST_VDEV_STAT: 611 stats_param->stats_id |= WMI_HOST_REQUEST_VDEV_STAT; 612 break; 613 614 case WMI_REQUEST_BCNFLT_STAT: 615 stats_param->stats_id |= WMI_HOST_REQUEST_BCNFLT_STAT; 616 break; 617 618 case WMI_REQUEST_VDEV_RATE_STAT: 619 stats_param->stats_id |= 620 WMI_HOST_REQUEST_VDEV_RATE_STAT; 621 break; 622 623 case WMI_REQUEST_BCN_STAT: 624 stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; 625 break; 626 case WMI_REQUEST_PEER_EXTD_STAT: 627 stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT; 628 break; 629 630 case WMI_REQUEST_PEER_EXTD2_STAT: 631 stats_param->stats_id |= 632 WMI_HOST_REQUEST_PEER_ADV_STATS; 633 break; 634 635 case WMI_REQUEST_PMF_BCN_PROTECT_STAT: 636 stats_param->stats_id |= 637 WMI_HOST_REQUEST_PMF_BCN_PROTECT_STAT; 638 break; 639 640 case WMI_REQUEST_VDEV_EXTD_STAT: 641 stats_param->stats_id |= 642 WMI_HOST_REQUEST_VDEV_PRB_FILS_STAT; 643 break; 644 } 645 } 646 647 /* ev->num_*_stats may cause uint32_t overflow, so use uint64_t 648 * to save total length calculated 649 */ 650 min_data_len = 651 (((uint64_t)ev->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 652 (((uint64_t)ev->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 653 (((uint64_t)ev->num_peer_stats) * sizeof(wmi_peer_stats)) + 654 (((uint64_t)ev->num_bcnflt_stats) * 655 sizeof(wmi_bcnfilter_stats_t)) + 656 (((uint64_t)ev->num_chan_stats) * sizeof(wmi_chan_stats)) + 657 (((uint64_t)ev->num_mib_stats) * sizeof(wmi_mib_stats)) + 658 (((uint64_t)ev->num_bcn_stats) * sizeof(wmi_bcn_stats)) + 659 (((uint64_t)ev->num_peer_extd_stats) * 660 sizeof(wmi_peer_extd_stats)) + 661 (((uint64_t)ev->num_mib_extd_stats) * 662 sizeof(wmi_mib_extd_stats)); 663 if (param_buf->num_data != min_data_len) { 664 wmi_err("data len: %u isn't same as calculated: %llu", 665 param_buf->num_data, min_data_len); 666 return QDF_STATUS_E_FAULT; 667 } 668 669 stats_param->last_event = ev->last_event; 670 stats_param->num_pdev_stats = ev->num_pdev_stats; 671 stats_param->num_pdev_ext_stats = 0; 672 stats_param->num_vdev_stats = ev->num_vdev_stats; 673 stats_param->num_peer_stats = ev->num_peer_stats; 674 stats_param->num_peer_extd_stats = ev->num_peer_extd_stats; 675 stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; 676 stats_param->num_chan_stats = ev->num_chan_stats; 677 stats_param->num_mib_stats = ev->num_mib_stats; 678 stats_param->num_mib_extd_stats = ev->num_mib_extd_stats; 679 stats_param->num_bcn_stats = ev->num_bcn_stats; 680 stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( 681 wmi_handle, 682 ev->pdev_id); 683 684 /* if chain_stats is not populated */ 685 if (!param_buf->chain_stats || !param_buf->num_chain_stats) 686 return QDF_STATUS_SUCCESS; 687 688 if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats != 689 WMITLV_GET_TLVTAG(rssi_event->tlv_header)) 690 return QDF_STATUS_SUCCESS; 691 692 if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) != 693 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) 694 return QDF_STATUS_SUCCESS; 695 696 if (rssi_event->num_per_chain_rssi_stats >= 697 WMITLV_GET_TLVLEN(rssi_event->tlv_header)) { 698 wmi_err("num_per_chain_rssi_stats:%u is out of bounds", 699 rssi_event->num_per_chain_rssi_stats); 700 return QDF_STATUS_E_INVAL; 701 } 702 stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats; 703 704 if (param_buf->vdev_extd_stats) 705 stats_param->num_vdev_extd_stats = 706 param_buf->num_vdev_extd_stats; 707 708 /* if peer_adv_stats is not populated */ 709 if (param_buf->num_peer_extd2_stats) 710 stats_param->num_peer_adv_stats = 711 param_buf->num_peer_extd2_stats; 712 713 return QDF_STATUS_SUCCESS; 714 } 715 716 /** 717 * extract_pdev_tx_stats() - extract pdev tx stats from event 718 */ 719 static void extract_pdev_tx_stats(wmi_host_dbg_tx_stats *tx, 720 struct wlan_dbg_tx_stats *tx_stats) 721 { 722 /* Tx Stats */ 723 tx->comp_queued = tx_stats->comp_queued; 724 tx->comp_delivered = tx_stats->comp_delivered; 725 tx->msdu_enqued = tx_stats->msdu_enqued; 726 tx->mpdu_enqued = tx_stats->mpdu_enqued; 727 tx->wmm_drop = tx_stats->wmm_drop; 728 tx->local_enqued = tx_stats->local_enqued; 729 tx->local_freed = tx_stats->local_freed; 730 tx->hw_queued = tx_stats->hw_queued; 731 tx->hw_reaped = tx_stats->hw_reaped; 732 tx->underrun = tx_stats->underrun; 733 tx->tx_abort = tx_stats->tx_abort; 734 tx->mpdus_requed = tx_stats->mpdus_requed; 735 tx->data_rc = tx_stats->data_rc; 736 tx->self_triggers = tx_stats->self_triggers; 737 tx->sw_retry_failure = tx_stats->sw_retry_failure; 738 tx->illgl_rate_phy_err = tx_stats->illgl_rate_phy_err; 739 tx->pdev_cont_xretry = tx_stats->pdev_cont_xretry; 740 tx->pdev_tx_timeout = tx_stats->pdev_tx_timeout; 741 tx->pdev_resets = tx_stats->pdev_resets; 742 tx->stateless_tid_alloc_failure = tx_stats->stateless_tid_alloc_failure; 743 tx->phy_underrun = tx_stats->phy_underrun; 744 tx->txop_ovf = tx_stats->txop_ovf; 745 746 return; 747 } 748 749 750 /** 751 * extract_pdev_rx_stats() - extract pdev rx stats from event 752 */ 753 static void extract_pdev_rx_stats(wmi_host_dbg_rx_stats *rx, 754 struct wlan_dbg_rx_stats *rx_stats) 755 { 756 /* Rx Stats */ 757 rx->mid_ppdu_route_change = rx_stats->mid_ppdu_route_change; 758 rx->status_rcvd = rx_stats->status_rcvd; 759 rx->r0_frags = rx_stats->r0_frags; 760 rx->r1_frags = rx_stats->r1_frags; 761 rx->r2_frags = rx_stats->r2_frags; 762 /* Only TLV */ 763 rx->r3_frags = 0; 764 rx->htt_msdus = rx_stats->htt_msdus; 765 rx->htt_mpdus = rx_stats->htt_mpdus; 766 rx->loc_msdus = rx_stats->loc_msdus; 767 rx->loc_mpdus = rx_stats->loc_mpdus; 768 rx->oversize_amsdu = rx_stats->oversize_amsdu; 769 rx->phy_errs = rx_stats->phy_errs; 770 rx->phy_err_drop = rx_stats->phy_err_drop; 771 rx->mpdu_errs = rx_stats->mpdu_errs; 772 773 return; 774 } 775 776 /** 777 * extract_pdev_stats_tlv() - extract pdev stats from event 778 * @param wmi_handle: wmi handle 779 * @param evt_buf: pointer to event buffer 780 * @param index: Index into pdev stats 781 * @param pdev_stats: Pointer to hold pdev stats 782 * 783 * Return: QDF_STATUS_SUCCESS for success or error code 784 */ 785 static QDF_STATUS 786 extract_pdev_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t index, 787 wmi_host_pdev_stats *pdev_stats) 788 { 789 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 790 wmi_stats_event_fixed_param *ev_param; 791 uint8_t *data; 792 793 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 794 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 795 pdev_stats->pdev_id = 796 wmi_handle->ops->convert_pdev_id_target_to_host(wmi_handle, 797 ev_param->pdev_id); 798 799 data = param_buf->data; 800 801 if (index < ev_param->num_pdev_stats) { 802 wmi_pdev_stats *ev = (wmi_pdev_stats *) ((data) + 803 (index * sizeof(wmi_pdev_stats))); 804 805 pdev_stats->chan_nf = ev->chan_nf; 806 pdev_stats->tx_frame_count = ev->tx_frame_count; 807 pdev_stats->rx_frame_count = ev->rx_frame_count; 808 pdev_stats->rx_clear_count = ev->rx_clear_count; 809 pdev_stats->cycle_count = ev->cycle_count; 810 pdev_stats->phy_err_count = ev->phy_err_count; 811 pdev_stats->chan_tx_pwr = ev->chan_tx_pwr; 812 813 extract_pdev_tx_stats(&(pdev_stats->pdev_stats.tx), 814 &(ev->pdev_stats.tx)); 815 extract_pdev_rx_stats(&(pdev_stats->pdev_stats.rx), 816 &(ev->pdev_stats.rx)); 817 } 818 819 return QDF_STATUS_SUCCESS; 820 } 821 822 /** 823 * extract_vdev_stats_tlv() - extract vdev stats from event 824 * @param wmi_handle: wmi handle 825 * @param evt_buf: pointer to event buffer 826 * @param index: Index into vdev stats 827 * @param vdev_stats: Pointer to hold vdev stats 828 * 829 * Return: QDF_STATUS_SUCCESS for success or error code 830 */ 831 static QDF_STATUS extract_vdev_stats_tlv(wmi_unified_t wmi_handle, 832 void *evt_buf, uint32_t index, wmi_host_vdev_stats *vdev_stats) 833 { 834 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 835 wmi_stats_event_fixed_param *ev_param; 836 uint8_t *data; 837 838 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 839 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 840 data = (uint8_t *) param_buf->data; 841 842 if (index < ev_param->num_vdev_stats) { 843 wmi_vdev_stats *ev = (wmi_vdev_stats *) ((data) + 844 ((ev_param->num_pdev_stats) * 845 sizeof(wmi_pdev_stats)) + 846 (index * sizeof(wmi_vdev_stats))); 847 848 vdev_stats->vdev_id = ev->vdev_id; 849 vdev_stats->vdev_snr.bcn_snr = ev->vdev_snr.bcn_snr; 850 vdev_stats->vdev_snr.dat_snr = ev->vdev_snr.dat_snr; 851 852 OS_MEMCPY(vdev_stats->tx_frm_cnt, ev->tx_frm_cnt, 853 sizeof(ev->tx_frm_cnt)); 854 vdev_stats->rx_frm_cnt = ev->rx_frm_cnt; 855 OS_MEMCPY(vdev_stats->multiple_retry_cnt, 856 ev->multiple_retry_cnt, 857 sizeof(ev->multiple_retry_cnt)); 858 OS_MEMCPY(vdev_stats->fail_cnt, ev->fail_cnt, 859 sizeof(ev->fail_cnt)); 860 vdev_stats->rts_fail_cnt = ev->rts_fail_cnt; 861 vdev_stats->rts_succ_cnt = ev->rts_succ_cnt; 862 vdev_stats->rx_err_cnt = ev->rx_err_cnt; 863 vdev_stats->rx_discard_cnt = ev->rx_discard_cnt; 864 vdev_stats->ack_fail_cnt = ev->ack_fail_cnt; 865 OS_MEMCPY(vdev_stats->tx_rate_history, ev->tx_rate_history, 866 sizeof(ev->tx_rate_history)); 867 OS_MEMCPY(vdev_stats->bcn_rssi_history, ev->bcn_rssi_history, 868 sizeof(ev->bcn_rssi_history)); 869 870 } 871 872 return QDF_STATUS_SUCCESS; 873 } 874 875 /** 876 * extract_peer_stats_tlv() - extract peer stats from event 877 * @param wmi_handle: wmi handle 878 * @param evt_buf: pointer to event buffer 879 * @param index: Index into peer stats 880 * @param peer_stats: Pointer to hold peer stats 881 * 882 * Return: QDF_STATUS_SUCCESS for success or error code 883 */ 884 static QDF_STATUS 885 extract_peer_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t index, 886 wmi_host_peer_stats *peer_stats) 887 { 888 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 889 wmi_stats_event_fixed_param *ev_param; 890 uint8_t *data; 891 892 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 893 ev_param = (wmi_stats_event_fixed_param *) param_buf->fixed_param; 894 data = (uint8_t *) param_buf->data; 895 896 if (index < ev_param->num_peer_stats) { 897 wmi_peer_stats *ev = (wmi_peer_stats *) ((data) + 898 ((ev_param->num_pdev_stats) * sizeof(wmi_pdev_stats)) + 899 ((ev_param->num_vdev_stats) * sizeof(wmi_vdev_stats)) + 900 (index * sizeof(wmi_peer_stats))); 901 902 OS_MEMSET(peer_stats, 0, sizeof(wmi_host_peer_stats)); 903 904 OS_MEMCPY(&(peer_stats->peer_macaddr), 905 &(ev->peer_macaddr), sizeof(wmi_mac_addr)); 906 907 peer_stats->peer_rssi = ev->peer_rssi; 908 peer_stats->peer_tx_rate = ev->peer_tx_rate; 909 peer_stats->peer_rx_rate = ev->peer_rx_rate; 910 } 911 912 return QDF_STATUS_SUCCESS; 913 } 914 915 /** 916 * extract_peer_extd_stats_tlv() - extract extended peer stats from event 917 * @param wmi_handle: wmi handle 918 * @param evt_buf: pointer to event buffer 919 * @param index: Index into extended peer stats 920 * @param peer_extd_stats: Pointer to hold extended peer stats 921 * 922 * Return: QDF_STATUS_SUCCESS for success or error code 923 */ 924 static QDF_STATUS 925 extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, 926 void *evt_buf, uint32_t index, 927 wmi_host_peer_extd_stats *peer_extd_stats) 928 { 929 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 930 wmi_stats_event_fixed_param *ev_param; 931 uint8_t *data; 932 933 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 934 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 935 data = (uint8_t *)param_buf->data; 936 if (!data) 937 return QDF_STATUS_E_FAILURE; 938 939 if (index < ev_param->num_peer_extd_stats) { 940 wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data + 941 (ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) + 942 (ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) + 943 (ev_param->num_peer_stats * sizeof(wmi_peer_stats)) + 944 (ev_param->num_bcnflt_stats * 945 sizeof(wmi_bcnfilter_stats_t)) + 946 (ev_param->num_chan_stats * sizeof(wmi_chan_stats)) + 947 (ev_param->num_mib_stats * sizeof(wmi_mib_stats)) + 948 (ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) + 949 (index * sizeof(wmi_peer_extd_stats))); 950 951 qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats)); 952 qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr, 953 sizeof(wmi_mac_addr)); 954 955 peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt; 956 } 957 958 return QDF_STATUS_SUCCESS; 959 960 } 961 962 /** 963 * extract_pmf_bcn_protect_stats_tlv() - extract pmf bcn stats from event 964 * @wmi_handle: wmi handle 965 * @evt_buf: pointer to event buffer 966 * @pmf_bcn_stats: Pointer to hold pmf bcn protect stats 967 * 968 * Return: QDF_STATUS_SUCCESS for success or error code 969 */ 970 971 static QDF_STATUS 972 extract_pmf_bcn_protect_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 973 wmi_host_pmf_bcn_protect_stats *pmf_bcn_stats) 974 { 975 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 976 wmi_stats_event_fixed_param *ev_param; 977 978 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 979 if (!param_buf) 980 return QDF_STATUS_E_FAILURE; 981 982 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 983 984 if ((ev_param->stats_id & WMI_REQUEST_PMF_BCN_PROTECT_STAT) && 985 param_buf->pmf_bcn_protect_stats) { 986 pmf_bcn_stats->igtk_mic_fail_cnt = 987 param_buf->pmf_bcn_protect_stats->igtk_mic_fail_cnt; 988 pmf_bcn_stats->igtk_replay_cnt = 989 param_buf->pmf_bcn_protect_stats->igtk_replay_cnt; 990 pmf_bcn_stats->bcn_mic_fail_cnt = 991 param_buf->pmf_bcn_protect_stats->bcn_mic_fail_cnt; 992 pmf_bcn_stats->bcn_replay_cnt = 993 param_buf->pmf_bcn_protect_stats->bcn_replay_cnt; 994 } 995 996 return QDF_STATUS_SUCCESS; 997 } 998 999 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS 1000 static void wmi_infra_cp_stats_ops_attach_tlv(struct wmi_ops *ops) 1001 { 1002 ops->send_infra_cp_stats_request_cmd = 1003 send_infra_cp_stats_request_cmd_tlv; 1004 } 1005 #else 1006 static void wmi_infra_cp_stats_ops_attach_tlv(struct wmi_ops *ops) 1007 { 1008 } 1009 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */ 1010 1011 #ifdef WLAN_FEATURE_SON 1012 /** 1013 * extract_inst_rssi_stats_resp_tlv() - extract inst rssi stats from event 1014 * @wmi_handle: wmi handle 1015 * @evt_buf: pointer to event buffer 1016 * @inst_rssi_resp: Pointer to hold inst rssi response 1017 * 1018 * @Return: QDF_STATUS_SUCCESS for success or error code 1019 */ 1020 static QDF_STATUS 1021 extract_inst_rssi_stats_resp_tlv(wmi_unified_t wmi_handle, void *evt_buf, 1022 struct wmi_host_inst_rssi_stats_resp *inst_rssi_resp) 1023 { 1024 WMI_INST_RSSI_STATS_EVENTID_param_tlvs *param_buf; 1025 wmi_inst_rssi_stats_resp_fixed_param *event; 1026 1027 param_buf = (WMI_INST_RSSI_STATS_EVENTID_param_tlvs *)evt_buf; 1028 event = (wmi_inst_rssi_stats_resp_fixed_param *)param_buf->fixed_param; 1029 1030 inst_rssi_resp->inst_rssi = event->iRSSI; 1031 WMI_CHAR_ARRAY_TO_MAC_ADDR(inst_rssi_resp->peer_macaddr.bytes, 1032 &event->peer_macaddr); 1033 inst_rssi_resp->vdev_id = event->vdev_id; 1034 1035 return QDF_STATUS_SUCCESS; 1036 } 1037 1038 static void 1039 wmi_inst_rssi_stats_ops_attach_tlv(struct wmi_ops *ops) 1040 { 1041 ops->extract_inst_rssi_stats_resp = extract_inst_rssi_stats_resp_tlv; 1042 } 1043 #else 1044 static void 1045 wmi_inst_rssi_stats_ops_attach_tlv(struct wmi_ops *ops) 1046 { 1047 } 1048 #endif 1049 1050 void wmi_cp_stats_attach_tlv(wmi_unified_t wmi_handle) 1051 { 1052 struct wmi_ops *ops = wmi_handle->ops; 1053 1054 ops->send_stats_request_cmd = send_stats_request_cmd_tlv; 1055 #ifdef WLAN_FEATURE_BIG_DATA_STATS 1056 ops->send_big_data_stats_request_cmd = 1057 send_big_data_stats_request_cmd_tlv; 1058 #endif 1059 ops->extract_all_stats_count = extract_all_stats_counts_tlv; 1060 ops->extract_pdev_stats = extract_pdev_stats_tlv; 1061 ops->extract_vdev_stats = extract_vdev_stats_tlv; 1062 ops->extract_peer_stats = extract_peer_stats_tlv; 1063 ops->extract_peer_extd_stats = extract_peer_extd_stats_tlv; 1064 wmi_infra_cp_stats_ops_attach_tlv(ops); 1065 ops->extract_pmf_bcn_protect_stats = extract_pmf_bcn_protect_stats_tlv, 1066 wmi_inst_rssi_stats_ops_attach_tlv(ops); 1067 1068 wmi_mc_cp_stats_attach_tlv(wmi_handle); 1069 } 1070