1 /* 2 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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 23 /** 24 * extract_per_chain_rssi_stats_tlv() - api to extract rssi stats from event 25 * buffer 26 * @wmi_handle: wmi handle 27 * @evt_buf: pointer to event buffer 28 * @index: Index into vdev stats 29 * @rssi_stats: Pointer to hold rssi stats 30 * 31 * Return: QDF_STATUS_SUCCESS for success or error code 32 */ 33 static QDF_STATUS 34 extract_per_chain_rssi_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 35 uint32_t index, 36 struct wmi_host_per_chain_rssi_stats *rssi_stats) 37 { 38 uint8_t *data; 39 wmi_rssi_stats *fw_rssi_stats; 40 wmi_per_chain_rssi_stats *rssi_event; 41 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 42 43 if (!evt_buf) { 44 wmi_err("evt_buf is null"); 45 return QDF_STATUS_E_NULL_VALUE; 46 } 47 48 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; 49 rssi_event = param_buf->chain_stats; 50 51 if (index >= rssi_event->num_per_chain_rssi_stats) { 52 wmi_err("Invalid index: %u", index); 53 return QDF_STATUS_E_INVAL; 54 } 55 56 data = ((uint8_t *)(&rssi_event[1])) + WMI_TLV_HDR_SIZE; 57 fw_rssi_stats = &((wmi_rssi_stats *)data)[index]; 58 if (fw_rssi_stats->vdev_id >= WLAN_UMAC_PDEV_MAX_VDEVS) 59 return QDF_STATUS_E_INVAL; 60 61 rssi_stats->vdev_id = fw_rssi_stats->vdev_id; 62 qdf_mem_copy(rssi_stats->rssi_avg_beacon, 63 fw_rssi_stats->rssi_avg_beacon, 64 sizeof(fw_rssi_stats->rssi_avg_beacon)); 65 qdf_mem_copy(rssi_stats->rssi_avg_data, 66 fw_rssi_stats->rssi_avg_data, 67 sizeof(fw_rssi_stats->rssi_avg_data)); 68 qdf_mem_copy(&rssi_stats->peer_macaddr, 69 &fw_rssi_stats->peer_macaddr, 70 sizeof(fw_rssi_stats->peer_macaddr)); 71 72 return QDF_STATUS_SUCCESS; 73 } 74 75 /** 76 * extract_peer_adv_stats_tlv() - extract adv peer stats from event 77 * @wmi_handle: wmi handle 78 * @evt_buf: pointer to event buffer 79 * @peer_adv_stats: Pointer to hold adv peer stats 80 * 81 * Return: QDF_STATUS_SUCCESS for success or error code 82 */ 83 static QDF_STATUS extract_peer_adv_stats_tlv(wmi_unified_t wmi_handle, 84 void *evt_buf, 85 struct wmi_host_peer_adv_stats 86 *peer_adv_stats) 87 { 88 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 89 wmi_peer_extd2_stats *adv_stats; 90 int i; 91 92 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 93 94 adv_stats = param_buf->peer_extd2_stats; 95 if (!adv_stats) { 96 wmi_debug("no peer_adv stats in event buffer"); 97 return QDF_STATUS_E_INVAL; 98 } 99 100 for (i = 0; i < param_buf->num_peer_extd2_stats; i++) { 101 WMI_MAC_ADDR_TO_CHAR_ARRAY(&adv_stats[i].peer_macaddr, 102 peer_adv_stats[i].peer_macaddr); 103 peer_adv_stats[i].fcs_count = adv_stats[i].rx_fcs_err; 104 peer_adv_stats[i].rx_bytes = 105 (uint64_t)adv_stats[i].rx_bytes_u32 << 106 WMI_LOWER_BITS_SHIFT_32 | 107 adv_stats[i].rx_bytes_l32; 108 peer_adv_stats[i].rx_count = adv_stats[i].rx_mpdus; 109 } 110 111 return QDF_STATUS_SUCCESS; 112 } 113 114 #ifdef WLAN_FEATURE_MIB_STATS 115 /** 116 * extract_mib_stats_tlv() - extract mib stats from event 117 * @wmi_handle: wmi handle 118 * @evt_buf: pointer to event buffer 119 * @mib_stats: pointer to hold mib stats 120 * 121 * Return: QDF_STATUS_SUCCESS for success or error code 122 */ 123 static QDF_STATUS extract_mib_stats_tlv(wmi_unified_t wmi_handle, 124 void *evt_buf, 125 struct mib_stats_metrics 126 *mib_stats) 127 { 128 WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; 129 wmi_stats_event_fixed_param *ev_param; 130 uint8_t *data; 131 wmi_mib_stats *ev; 132 wmi_mib_extd_stats *ev_extd; 133 134 param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; 135 ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; 136 data = (uint8_t *)param_buf->data; 137 138 ev = (wmi_mib_stats *)(data + 139 ev_param->num_pdev_stats * sizeof(wmi_pdev_stats) + 140 ev_param->num_vdev_stats * sizeof(wmi_vdev_stats) + 141 ev_param->num_peer_stats * sizeof(wmi_peer_stats) + 142 ev_param->num_bcnflt_stats * 143 sizeof(wmi_bcnfilter_stats_t) + 144 ev_param->num_chan_stats * sizeof(wmi_chan_stats)); 145 146 qdf_mem_zero(mib_stats, sizeof(*mib_stats)); 147 148 mib_stats->mib_counters.tx_frags = 149 ev->tx_mpdu_grp_frag_cnt; 150 mib_stats->mib_counters.group_tx_frames = 151 ev->tx_msdu_grp_frm_cnt; 152 mib_stats->mib_counters.failed_cnt = ev->tx_msdu_fail_cnt; 153 mib_stats->mib_counters.rx_frags = ev->rx_mpdu_frag_cnt; 154 mib_stats->mib_counters.group_rx_frames = 155 ev->rx_msdu_grp_frm_cnt; 156 mib_stats->mib_counters.fcs_error_cnt = 157 ev->rx_mpdu_fcs_err; 158 mib_stats->mib_counters.tx_frames = 159 ev->tx_msdu_frm_cnt; 160 mib_stats->mib_mac_statistics.retry_cnt = 161 ev->tx_msdu_retry_cnt; 162 mib_stats->mib_mac_statistics.frame_dup_cnt = 163 ev->rx_frm_dup_cnt; 164 mib_stats->mib_mac_statistics.rts_success_cnt = 165 ev->tx_rts_success_cnt; 166 mib_stats->mib_mac_statistics.rts_fail_cnt = 167 ev->tx_rts_fail_cnt; 168 169 mib_stats->mib_qos_counters.qos_tx_frag_cnt = 170 ev->tx_Qos_mpdu_grp_frag_cnt; 171 mib_stats->mib_qos_counters.qos_retry_cnt = 172 ev->tx_Qos_msdu_retry_UP; 173 mib_stats->mib_qos_counters.qos_failed_cnt = 174 ev->tx_Qos_msdu_fail_UP; 175 mib_stats->mib_qos_counters.qos_frame_dup_cnt = 176 ev->rx_Qos_frm_dup_cnt_UP; 177 mib_stats->mib_qos_counters.qos_rts_success_cnt = 178 ev->tx_Qos_rts_success_cnt_UP; 179 mib_stats->mib_qos_counters.qos_rts_fail_cnt = 180 ev->tx_Qos_rts_fail_cnt_UP; 181 mib_stats->mib_qos_counters.qos_rx_frag_cnt = 182 ev->rx_Qos_mpdu_frag_cnt_UP; 183 mib_stats->mib_qos_counters.qos_tx_frame_cnt = 184 ev->tx_Qos_msdu_frm_cnt_UP; 185 mib_stats->mib_qos_counters.qos_discarded_frame_cnt = 186 ev->rx_Qos_msdu_discard_cnt_UP; 187 mib_stats->mib_qos_counters.qos_mpdu_rx_cnt = 188 ev->rx_Qos_mpdu_cnt; 189 mib_stats->mib_qos_counters.qos_retries_rx_cnt = 190 ev->rx_Qos_mpdu_retryBit_cnt; 191 192 mib_stats->mib_rsna_stats.tkip_icv_err = 193 ev->rsna_TKIP_icv_err_cnt; 194 mib_stats->mib_rsna_stats.tkip_replays = 195 ev->rsna_TKIP_replay_err_cnt; 196 mib_stats->mib_rsna_stats.ccmp_decrypt_err = 197 ev->rsna_CCMP_decrypt_err_cnt; 198 mib_stats->mib_rsna_stats.ccmp_replays = 199 ev->rsna_CCMP_replay_err_cnt; 200 201 mib_stats->mib_counters_group3.tx_ampdu_cnt = 202 ev->tx_ampdu_cnt; 203 mib_stats->mib_counters_group3.tx_mpdus_in_ampdu_cnt = 204 ev->tx_mpdu_cnt_in_ampdu; 205 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 206 ev->tx_octets_in_ampdu.upload.high; 207 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt = 208 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt << 32; 209 mib_stats->mib_counters_group3.tx_octets_in_ampdu_cnt += 210 ev->tx_octets_in_ampdu.upload.low; 211 212 mib_stats->mib_counters_group3.ampdu_rx_cnt = 213 ev->rx_ampdu_cnt; 214 mib_stats->mib_counters_group3.mpdu_in_rx_ampdu_cnt = 215 ev->rx_mpdu_cnt_in_ampdu; 216 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 217 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_high; 218 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt = 219 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt << 32; 220 mib_stats->mib_counters_group3.rx_octets_in_ampdu_cnt += 221 ev->rx_octets_in_ampdu.upload.rx_octets_in_ampdu_low; 222 223 if (ev_param->num_mib_extd_stats) { 224 ev_extd = (wmi_mib_extd_stats *)((uint8_t *)ev + 225 ev_param->num_mib_stats * sizeof(wmi_mib_stats) + 226 ev_param->num_bcn_stats * sizeof(wmi_bcn_stats) + 227 ev_param->num_peer_extd_stats * 228 sizeof(wmi_peer_extd_stats)); 229 mib_stats->mib_mac_statistics.multi_retry_cnt = 230 ev_extd->tx_msdu_multi_retry_cnt; 231 mib_stats->mib_mac_statistics.tx_ack_fail_cnt = 232 ev_extd->tx_ack_fail_cnt; 233 234 mib_stats->mib_qos_counters.qos_multi_retry_cnt = 235 ev_extd->tx_qos_msdu_multi_retry_up; 236 mib_stats->mib_qos_counters.tx_qos_ack_fail_cnt_up = 237 ev_extd->tx_qos_ack_fail_cnt_up; 238 239 mib_stats->mib_rsna_stats.cmac_icv_err = 240 ev_extd->rsna_cmac_icv_err_cnt; 241 mib_stats->mib_rsna_stats.cmac_replays = 242 ev_extd->rsna_cmac_replay_err_cnt; 243 244 mib_stats->mib_counters_group3.rx_ampdu_deli_crc_err_cnt = 245 ev_extd->rx_ampdu_deli_crc_err_cnt; 246 } 247 248 return QDF_STATUS_SUCCESS; 249 } 250 251 static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops) 252 { 253 ops->extract_mib_stats = extract_mib_stats_tlv; 254 } 255 #else 256 static void wmi_cp_stats_attach_mib_stats_tlv(struct wmi_ops *ops) 257 { 258 } 259 #endif /* WLAN_FEATURE_MIB_STATS */ 260 261 /** 262 * send_request_peer_stats_info_cmd_tlv() - WMI request peer stats function 263 * @wmi_handle: handle to WMI. 264 * @param: pointer to hold peer stats request parameter 265 * 266 * Return: QDF_STATUS 267 */ 268 static QDF_STATUS 269 send_request_peer_stats_info_cmd_tlv(wmi_unified_t wmi_handle, 270 struct peer_stats_request_params *param) 271 { 272 int32_t ret; 273 wmi_request_peer_stats_info_cmd_fixed_param *cmd; 274 wmi_buf_t buf; 275 uint16_t len = sizeof(wmi_request_peer_stats_info_cmd_fixed_param); 276 277 buf = wmi_buf_alloc(wmi_handle, len); 278 if (!buf) 279 return QDF_STATUS_E_NOMEM; 280 281 cmd = (wmi_request_peer_stats_info_cmd_fixed_param *)wmi_buf_data(buf); 282 WMITLV_SET_HDR(&cmd->tlv_header, 283 WMITLV_TAG_STRUC_wmi_request_peer_stats_info_cmd_fixed_param, 284 WMITLV_GET_STRUCT_TLVLEN( 285 wmi_request_peer_stats_info_cmd_fixed_param)); 286 cmd->request_type = param->request_type; 287 cmd->vdev_id = param->vdev_id; 288 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_mac_addr, &cmd->peer_macaddr); 289 cmd->reset_after_request = param->reset_after_request; 290 291 wmi_debug("PEER STATS REQ VDEV_ID:%d PEER:"QDF_MAC_ADDR_FMT" TYPE:%d RESET:%d", 292 cmd->vdev_id, QDF_MAC_ADDR_REF(param->peer_mac_addr), 293 cmd->request_type, 294 cmd->reset_after_request); 295 296 wmi_mtrace(WMI_REQUEST_PEER_STATS_INFO_CMDID, cmd->vdev_id, 0); 297 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 298 WMI_REQUEST_PEER_STATS_INFO_CMDID); 299 if (ret) { 300 wmi_err("Failed to send peer stats request to fw =%d", ret); 301 wmi_buf_free(buf); 302 } 303 304 return qdf_status_from_os_return(ret); 305 } 306 307 /** 308 * extract_peer_stats_count_tlv() - extract peer stats count from event 309 * @wmi_handle: wmi handle 310 * @evt_buf: pointer to event buffer 311 * @stats_param: Pointer to hold stats count 312 * 313 * Return: QDF_STATUS_SUCCESS for success or error code 314 */ 315 static QDF_STATUS 316 extract_peer_stats_count_tlv(wmi_unified_t wmi_handle, void *evt_buf, 317 wmi_host_stats_event *stats_param) 318 { 319 WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf; 320 wmi_peer_stats_info_event_fixed_param *ev_param; 321 322 param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf; 323 if (!param_buf) 324 return QDF_STATUS_E_FAILURE; 325 326 ev_param = param_buf->fixed_param; 327 if (!ev_param) 328 return QDF_STATUS_E_FAILURE; 329 330 if (!param_buf->num_peer_stats_info || 331 param_buf->num_peer_stats_info < ev_param->num_peers) { 332 wmi_err_rl("actual num of peers stats info: %d is less than provided peers: %d", 333 param_buf->num_peer_stats_info, ev_param->num_peers); 334 return QDF_STATUS_E_FAULT; 335 } 336 337 if (!stats_param) 338 return QDF_STATUS_E_FAILURE; 339 340 stats_param->num_peer_stats_info_ext = ev_param->num_peers; 341 342 return QDF_STATUS_SUCCESS; 343 } 344 345 static void dump_peer_stats_info(wmi_peer_stats_info *stats) 346 { 347 u_int8_t mac[6]; 348 int i; 349 350 WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac); 351 wmi_debug("mac "QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac)); 352 wmi_debug("tx_bytes %d %d tx_packets %d %d tx_retries %d tx_failed %d", 353 stats->tx_bytes.low_32, 354 stats->tx_bytes.high_32, 355 stats->tx_packets.low_32, 356 stats->tx_packets.high_32, 357 stats->tx_retries, stats->tx_failed); 358 wmi_debug("rx_bytes %d %d rx_packets %d %d", 359 stats->rx_bytes.low_32, 360 stats->rx_bytes.high_32, 361 stats->rx_packets.low_32, 362 stats->rx_packets.high_32); 363 wmi_debug("tx_rate_code %x rx_rate_code %x tx_rate %x rx_rate %x peer_rssi %d tx_succeed %d", 364 stats->last_tx_rate_code, 365 stats->last_rx_rate_code, 366 stats->last_tx_bitrate_kbps, 367 stats->last_rx_bitrate_kbps, 368 stats->peer_rssi, stats->tx_succeed); 369 for (i = 0; i < WMI_MAX_CHAINS; i++) 370 wmi_debug("chain%d_rssi %d", i, stats->peer_rssi_per_chain[i]); 371 } 372 373 /** 374 * extract_peer_tx_pkt_per_mcs_tlv() - extract peer tx packets per MCS 375 * from event 376 * @wmi_handle: wmi handle 377 * @evt_buf: pointer to event buffer 378 * @index: Index into vdev stats 379 * @peer_stats_info: Pointer to hold peer stats info 380 * 381 * Return: QDF_STATUS_SUCCESS for success or error code 382 */ 383 static QDF_STATUS 384 extract_peer_tx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle, void *evt_buf, 385 uint32_t index, 386 wmi_host_peer_stats_info *peer_stats_info) 387 { 388 WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf; 389 int i, j; 390 391 param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf; 392 393 if (index + peer_stats_info->num_tx_rate_counts <= 394 param_buf->num_tx_rate_counts) { 395 peer_stats_info->tx_pkt_per_mcs = 396 qdf_mem_malloc( 397 peer_stats_info->num_tx_rate_counts * sizeof(uint32_t)); 398 399 if (!peer_stats_info->tx_pkt_per_mcs) 400 return QDF_STATUS_E_NOMEM; 401 wmi_debug("Tx rate counts"); 402 for (j = 0, i = index; j < peer_stats_info->num_tx_rate_counts; 403 j++, i++) { 404 peer_stats_info->tx_pkt_per_mcs[j] = 405 param_buf->tx_rate_counts[i]; 406 wmi_nofl_debug("MCS [%d] %d", j, 407 peer_stats_info->tx_pkt_per_mcs[j]); 408 } 409 } else { 410 wmi_err("invalid idx %d curr peer tx_rate_counts %d total tx_rate_count %d", 411 index, peer_stats_info->num_tx_rate_counts, 412 param_buf->num_tx_rate_counts); 413 } 414 return QDF_STATUS_SUCCESS; 415 } 416 417 /** 418 * extract_peer_rx_pkt_per_mcs_tlv() - extract peer rx rpackets per MCS 419 * from event 420 * @wmi_handle: wmi handle 421 * @evt_buf: pointer to event buffer 422 * @index: Index into vdev stats 423 * @peer_stats_info: Pointer to hold peer stats info 424 * 425 * Return: QDF_STATUS_SUCCESS for success or error code 426 */ 427 static QDF_STATUS 428 extract_peer_rx_pkt_per_mcs_tlv(wmi_unified_t wmi_handle, void *evt_buf, 429 uint32_t index, 430 wmi_host_peer_stats_info *peer_stats_info) 431 { 432 WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf; 433 int i, j; 434 435 param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf; 436 437 if (index + peer_stats_info->num_rx_rate_counts <= 438 param_buf->num_rx_rate_counts) { 439 peer_stats_info->rx_pkt_per_mcs = 440 qdf_mem_malloc( 441 peer_stats_info->num_rx_rate_counts * sizeof(uint32_t)); 442 443 if (!peer_stats_info->rx_pkt_per_mcs) 444 return QDF_STATUS_E_NOMEM; 445 wmi_debug("Rx rate counts"); 446 for (j = 0, i = index; j < peer_stats_info->num_rx_rate_counts; 447 j++, i++) { 448 peer_stats_info->rx_pkt_per_mcs[j] = 449 param_buf->rx_rate_counts[i]; 450 wmi_nofl_debug("MCS [%d] %d", j, 451 peer_stats_info->rx_pkt_per_mcs[j]); 452 } 453 } else { 454 wmi_err("invalid idx %d curr peer rx_rate_counts %d total rx_rate_count %d", 455 index, peer_stats_info->num_rx_rate_counts, 456 param_buf->num_rx_rate_counts); 457 } 458 return QDF_STATUS_SUCCESS; 459 } 460 461 /** 462 * extract_peer_stats_info_tlv() - extract peer stats info from event 463 * @wmi_handle: wmi handle 464 * @evt_buf: pointer to event buffer 465 * @index: Index into vdev stats 466 * @peer_stats_info: Pointer to hold peer stats info 467 * 468 * Return: QDF_STATUS_SUCCESS for success or error code 469 */ 470 static QDF_STATUS 471 extract_peer_stats_info_tlv(wmi_unified_t wmi_handle, void *evt_buf, 472 uint32_t index, 473 wmi_host_peer_stats_info *peer_stats_info) 474 { 475 WMI_PEER_STATS_INFO_EVENTID_param_tlvs *param_buf; 476 wmi_peer_stats_info_event_fixed_param *ev_param; 477 478 param_buf = (WMI_PEER_STATS_INFO_EVENTID_param_tlvs *)evt_buf; 479 ev_param = param_buf->fixed_param; 480 481 if (index < ev_param->num_peers) { 482 wmi_peer_stats_info *ev = ¶m_buf->peer_stats_info[index]; 483 int i; 484 485 dump_peer_stats_info(ev); 486 487 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_macaddr, 488 peer_stats_info->peer_macaddr.bytes); 489 peer_stats_info->tx_packets = ev->tx_packets.low_32; 490 peer_stats_info->tx_bytes = ev->tx_bytes.high_32; 491 peer_stats_info->tx_bytes <<= 32; 492 peer_stats_info->tx_bytes += ev->tx_bytes.low_32; 493 peer_stats_info->rx_packets = ev->rx_packets.low_32; 494 peer_stats_info->rx_bytes = ev->rx_bytes.high_32; 495 peer_stats_info->rx_bytes <<= 32; 496 peer_stats_info->rx_bytes += ev->rx_bytes.low_32; 497 peer_stats_info->tx_retries = ev->tx_retries; 498 peer_stats_info->tx_failed = ev->tx_failed; 499 peer_stats_info->tx_succeed = ev->tx_succeed; 500 peer_stats_info->peer_rssi = ev->peer_rssi; 501 peer_stats_info->last_tx_bitrate_kbps = 502 ev->last_tx_bitrate_kbps; 503 peer_stats_info->last_tx_rate_code = ev->last_tx_rate_code; 504 peer_stats_info->last_rx_bitrate_kbps = 505 ev->last_rx_bitrate_kbps; 506 peer_stats_info->last_rx_rate_code = ev->last_rx_rate_code; 507 for (i = 0; i < WMI_MAX_CHAINS; i++) 508 peer_stats_info->peer_rssi_per_chain[i] = 509 ev->peer_rssi_per_chain[i]; 510 peer_stats_info->num_tx_rate_counts = ev->num_tx_rate_counts; 511 peer_stats_info->num_rx_rate_counts = ev->num_rx_rate_counts; 512 } 513 514 return QDF_STATUS_SUCCESS; 515 } 516 517 #ifdef WLAN_FEATURE_BIG_DATA_STATS 518 /** 519 * extract_big_data_stats_tlv() - extract big data from event 520 * @wmi_handle: wmi handle 521 * @evt_buf: pointer to event buffer 522 * @stats: Pointer to hold big data stats 523 * 524 * Return: QDF_STATUS_SUCCESS for success or error code 525 */ 526 static QDF_STATUS 527 extract_big_data_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, 528 struct big_data_stats_event *stats) 529 { 530 WMI_VDEV_SEND_BIG_DATA_P2_EVENTID_param_tlvs *param_buf; 531 wmi_vdev_send_big_data_p2_event_fixed_param *event; 532 wmi_big_data_dp_stats_tlv_param *dp_stats_param_buf; 533 534 param_buf = (WMI_VDEV_SEND_BIG_DATA_P2_EVENTID_param_tlvs *)evt_buf; 535 if (!param_buf) { 536 wmi_err("invalid buffer"); 537 return QDF_STATUS_E_FAILURE; 538 } 539 540 event = param_buf->fixed_param; 541 if (!event) { 542 wmi_err("invalid fixed param"); 543 return QDF_STATUS_E_FAILURE; 544 } 545 546 dp_stats_param_buf = param_buf->big_data_dp_stats; 547 if (!dp_stats_param_buf) { 548 wmi_err("invalid dp stats param"); 549 return QDF_STATUS_E_FAILURE; 550 } 551 552 stats->vdev_id = event->vdev_id; 553 stats->ani_level = event->ani_level; 554 stats->tsf_out_of_sync = event->tsf_out_of_sync; 555 556 stats->last_data_tx_pwr = dp_stats_param_buf->last_data_tx_pwr; 557 stats->target_power_dsss = dp_stats_param_buf->target_power_dsss; 558 stats->target_power_ofdm = dp_stats_param_buf->target_power_ofdm; 559 stats->last_tx_data_rix = dp_stats_param_buf->last_tx_data_rix; 560 stats->last_tx_data_rate_kbps = 561 dp_stats_param_buf->last_tx_data_rate_kbps; 562 563 return QDF_STATUS_SUCCESS; 564 } 565 #endif 566 567 #ifdef WLAN_FEATURE_BIG_DATA_STATS 568 static void 569 wmi_attach_big_data_stats_handler(struct wmi_ops *ops) 570 { 571 ops->extract_big_data_stats = extract_big_data_stats_tlv; 572 } 573 #else 574 static void 575 wmi_attach_big_data_stats_handler(struct wmi_ops *ops) 576 {} 577 #endif 578 579 void wmi_mc_cp_stats_attach_tlv(wmi_unified_t wmi_handle) 580 { 581 struct wmi_ops *ops = wmi_handle->ops; 582 583 ops->extract_per_chain_rssi_stats = extract_per_chain_rssi_stats_tlv; 584 ops->extract_peer_adv_stats = extract_peer_adv_stats_tlv; 585 wmi_cp_stats_attach_mib_stats_tlv(ops); 586 ops->send_request_peer_stats_info_cmd = 587 send_request_peer_stats_info_cmd_tlv; 588 ops->extract_peer_stats_count = extract_peer_stats_count_tlv; 589 ops->extract_peer_stats_info = extract_peer_stats_info_tlv; 590 wmi_handle->ops->extract_peer_tx_pkt_per_mcs = 591 extract_peer_tx_pkt_per_mcs_tlv; 592 wmi_handle->ops->extract_peer_rx_pkt_per_mcs = 593 extract_peer_rx_pkt_per_mcs_tlv; 594 wmi_attach_big_data_stats_handler(ops); 595 } 596