1 /* 2 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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 #include <dp_types.h> 18 #include "dp_rx.h" 19 #include "dp_tx.h" 20 #include "dp_peer.h" 21 #include <dp_htt.h> 22 #include <dp_mon_filter.h> 23 #include <dp_htt.h> 24 #include <dp_mon.h> 25 #include <dp_rx_mon.h> 26 #include <dp_internal.h> 27 #include "htt_ppdu_stats.h" 28 #include "dp_cal_client_api.h" 29 #if defined(DP_CON_MON) 30 #ifndef REMOVE_PKT_LOG 31 #include <pktlog_ac_api.h> 32 #include <pktlog_ac.h> 33 #endif 34 #endif 35 #ifdef FEATURE_PERPKT_INFO 36 #include "dp_ratetable.h" 37 #endif 38 #ifdef QCA_SUPPORT_LITE_MONITOR 39 #include "dp_lite_mon.h" 40 #endif 41 #include "dp_mon_1.0.h" 42 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 43 #include "dp_mon_2.0.h" 44 #include "dp_mon_filter_2.0.h" 45 #endif 46 47 #define DP_INTR_POLL_TIMER_MS 5 48 #define INVALID_FREE_BUFF 0xffffffff 49 50 #ifdef WLAN_RX_PKT_CAPTURE_ENH 51 #include "dp_rx_mon_feature.h" 52 #endif /* WLAN_RX_PKT_CAPTURE_ENH */ 53 54 #ifdef QCA_UNDECODED_METADATA_SUPPORT 55 #define MAX_STRING_LEN_PER_FIELD 6 56 #define DP_UNDECODED_ERR_LENGTH (MAX_STRING_LEN_PER_FIELD * CDP_PHYRX_ERR_MAX) 57 #endif 58 59 #ifdef QCA_MCOPY_SUPPORT 60 static inline void dp_pdev_disable_mcopy_code(struct dp_pdev * pdev)61 dp_pdev_disable_mcopy_code(struct dp_pdev *pdev) 62 { 63 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 64 65 mon_pdev->mcopy_mode = M_COPY_DISABLED; 66 mon_pdev->mvdev = NULL; 67 } 68 69 static inline void dp_reset_mcopy_mode(struct dp_pdev * pdev)70 dp_reset_mcopy_mode(struct dp_pdev *pdev) 71 { 72 QDF_STATUS status = QDF_STATUS_SUCCESS; 73 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 74 struct cdp_mon_ops *cdp_ops; 75 76 if (mon_pdev->mcopy_mode) { 77 cdp_ops = dp_mon_cdp_ops_get(pdev->soc); 78 if (cdp_ops && cdp_ops->config_full_mon_mode) 79 cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev, 80 DP_FULL_MON_ENABLE); 81 dp_pdev_disable_mcopy_code(pdev); 82 dp_mon_filter_reset_mcopy_mode(pdev); 83 status = dp_mon_filter_update(pdev); 84 if (status != QDF_STATUS_SUCCESS) { 85 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 86 FL("Failed to reset AM copy mode filters")); 87 } 88 mon_pdev->monitor_configured = false; 89 } 90 } 91 92 static QDF_STATUS dp_config_mcopy_mode(struct dp_pdev * pdev,int val)93 dp_config_mcopy_mode(struct dp_pdev *pdev, int val) 94 { 95 QDF_STATUS status = QDF_STATUS_SUCCESS; 96 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 97 struct dp_mon_ops *mon_ops; 98 struct cdp_mon_ops *cdp_ops; 99 100 if (mon_pdev->mvdev) 101 return QDF_STATUS_E_RESOURCES; 102 103 mon_pdev->mcopy_mode = val; 104 mon_pdev->tx_sniffer_enable = 0; 105 mon_pdev->monitor_configured = true; 106 107 mon_ops = dp_mon_ops_get(pdev->soc); 108 if (!wlan_cfg_is_delay_mon_replenish(pdev->soc->wlan_cfg_ctx)) { 109 if (mon_ops && mon_ops->mon_vdev_set_monitor_mode_rings) 110 mon_ops->mon_vdev_set_monitor_mode_rings(pdev, true); 111 } 112 113 /* 114 * Setup the M copy mode filter. 115 */ 116 cdp_ops = dp_mon_cdp_ops_get(pdev->soc); 117 if (cdp_ops && cdp_ops->config_full_mon_mode) 118 cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev, 119 DP_FULL_MON_ENABLE); 120 dp_mon_filter_setup_mcopy_mode(pdev); 121 status = dp_mon_filter_update(pdev); 122 if (status != QDF_STATUS_SUCCESS) { 123 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 124 FL("Failed to set M_copy mode filters")); 125 dp_mon_filter_reset_mcopy_mode(pdev); 126 dp_pdev_disable_mcopy_code(pdev); 127 return status; 128 } 129 130 if (!mon_pdev->pktlog_ppdu_stats) 131 dp_h2t_cfg_stats_msg_send(pdev, 132 DP_PPDU_STATS_CFG_SNIFFER, 133 pdev->pdev_id); 134 135 return status; 136 } 137 #else 138 static inline void dp_reset_mcopy_mode(struct dp_pdev * pdev)139 dp_reset_mcopy_mode(struct dp_pdev *pdev) 140 { 141 } 142 143 static inline QDF_STATUS dp_config_mcopy_mode(struct dp_pdev * pdev,int val)144 dp_config_mcopy_mode(struct dp_pdev *pdev, int val) 145 { 146 return QDF_STATUS_E_INVAL; 147 } 148 #endif /* QCA_MCOPY_SUPPORT */ 149 150 #ifdef QCA_UNDECODED_METADATA_SUPPORT 151 static QDF_STATUS dp_reset_undecoded_metadata_capture(struct dp_pdev * pdev)152 dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev) 153 { 154 QDF_STATUS status = QDF_STATUS_SUCCESS; 155 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 156 157 if (mon_pdev->undecoded_metadata_capture) { 158 dp_mon_filter_reset_undecoded_metadata_mode(pdev); 159 status = dp_mon_filter_update(pdev); 160 if (status != QDF_STATUS_SUCCESS) { 161 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 162 FL("Undecoded capture filter reset failed")); 163 } 164 } 165 mon_pdev->undecoded_metadata_capture = 0; 166 return status; 167 } 168 169 static QDF_STATUS dp_enable_undecoded_metadata_capture(struct dp_pdev * pdev,int val)170 dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val) 171 { 172 QDF_STATUS status = QDF_STATUS_SUCCESS; 173 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 174 175 if (!mon_pdev->mvdev) { 176 qdf_err("monitor_pdev is NULL"); 177 return QDF_STATUS_E_RESOURCES; 178 } 179 180 mon_pdev->undecoded_metadata_capture = val; 181 mon_pdev->monitor_configured = true; 182 183 184 /* Setup the undecoded metadata capture mode filter. */ 185 dp_mon_filter_setup_undecoded_metadata_mode(pdev); 186 status = dp_mon_filter_update(pdev); 187 if (status != QDF_STATUS_SUCCESS) { 188 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 189 FL("Failed to set Undecoded capture filters")); 190 dp_mon_filter_reset_undecoded_metadata_mode(pdev); 191 return status; 192 } 193 194 return status; 195 } 196 #else 197 static inline QDF_STATUS dp_reset_undecoded_metadata_capture(struct dp_pdev * pdev)198 dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev) 199 { 200 return QDF_STATUS_E_INVAL; 201 } 202 203 static inline QDF_STATUS dp_enable_undecoded_metadata_capture(struct dp_pdev * pdev,int val)204 dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val) 205 { 206 return QDF_STATUS_E_INVAL; 207 } 208 #endif /* QCA_UNDECODED_METADATA_SUPPORT */ 209 dp_reset_monitor_mode(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t special_monitor)210 QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, 211 uint8_t pdev_id, 212 uint8_t special_monitor) 213 { 214 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 215 struct dp_pdev *pdev = 216 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 217 pdev_id); 218 QDF_STATUS status = QDF_STATUS_SUCCESS; 219 struct dp_mon_pdev *mon_pdev; 220 221 if (!pdev) 222 return QDF_STATUS_E_FAILURE; 223 224 mon_pdev = pdev->monitor_pdev; 225 qdf_spin_lock_bh(&mon_pdev->mon_lock); 226 status = dp_reset_monitor_mode_unlock(soc_hdl, pdev_id, 227 special_monitor); 228 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 229 230 return status; 231 } 232 dp_reset_monitor_mode_unlock(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t special_monitor)233 QDF_STATUS dp_reset_monitor_mode_unlock(struct cdp_soc_t *soc_hdl, 234 uint8_t pdev_id, 235 uint8_t special_monitor) 236 { 237 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 238 struct dp_pdev *pdev = 239 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 240 pdev_id); 241 QDF_STATUS status = QDF_STATUS_SUCCESS; 242 struct dp_mon_pdev *mon_pdev; 243 struct cdp_mon_ops *cdp_ops; 244 245 if (!pdev) 246 return QDF_STATUS_E_FAILURE; 247 248 mon_pdev = pdev->monitor_pdev; 249 250 cdp_ops = dp_mon_cdp_ops_get(soc); 251 if (cdp_ops && cdp_ops->soc_config_full_mon_mode) { 252 cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev, 253 DP_FULL_MON_DISABLE); 254 mon_pdev->hold_mon_dest_ring = false; 255 mon_pdev->is_bkpressure = false; 256 mon_pdev->set_reset_mon = false; 257 #if defined(QCA_SUPPORT_FULL_MON) 258 if (mon_pdev->mon_desc) 259 qdf_mem_zero(mon_pdev->mon_desc, 260 sizeof(struct hal_rx_mon_desc_info)); 261 #endif 262 } 263 264 /* 265 * Lite monitor mode, smart monitor mode and monitor 266 * mode uses this APIs to filter reset and mode disable 267 */ 268 if (mon_pdev->mcopy_mode) { 269 #if defined(QCA_MCOPY_SUPPORT) 270 dp_pdev_disable_mcopy_code(pdev); 271 dp_mon_filter_reset_mcopy_mode(pdev); 272 #endif /* QCA_MCOPY_SUPPORT */ 273 } else if (special_monitor) { 274 #if defined(ATH_SUPPORT_NAC) 275 dp_mon_filter_reset_smart_monitor(pdev); 276 #endif /* ATH_SUPPORT_NAC */ 277 /* for mon 2.0 we make use of lite mon to 278 * set filters for smart monitor use case. 279 */ 280 dp_monitor_lite_mon_disable_rx(pdev); 281 } else if (mon_pdev->undecoded_metadata_capture) { 282 #ifdef QCA_UNDECODED_METADATA_SUPPORT 283 dp_reset_undecoded_metadata_capture(pdev); 284 #endif 285 } else { 286 dp_mon_filter_reset_mon_mode(pdev); 287 } 288 status = dp_mon_filter_update(pdev); 289 if (status != QDF_STATUS_SUCCESS) { 290 dp_rx_mon_dest_err("%pK: Failed to reset monitor filters", 291 soc); 292 } 293 294 mon_pdev->mvdev = NULL; 295 mon_pdev->monitor_configured = false; 296 297 return QDF_STATUS_SUCCESS; 298 } 299 300 #ifdef QCA_ADVANCE_MON_FILTER_SUPPORT 301 QDF_STATUS dp_pdev_set_advance_monitor_filter(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_monitor_filter * filter_val)302 dp_pdev_set_advance_monitor_filter(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 303 struct cdp_monitor_filter *filter_val) 304 { 305 /* Many monitor VAPs can exists in a system but only one can be up at 306 * anytime 307 */ 308 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 309 struct dp_vdev *vdev; 310 struct dp_pdev *pdev = 311 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 312 pdev_id); 313 QDF_STATUS status = QDF_STATUS_SUCCESS; 314 struct dp_mon_pdev *mon_pdev; 315 316 if (!pdev || !pdev->monitor_pdev) 317 return QDF_STATUS_E_FAILURE; 318 319 mon_pdev = pdev->monitor_pdev; 320 vdev = mon_pdev->mvdev; 321 322 if (!vdev) 323 return QDF_STATUS_E_FAILURE; 324 325 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN, 326 "pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK", 327 pdev, pdev_id, soc, vdev); 328 329 /*Check if current pdev's monitor_vdev exists */ 330 if (!mon_pdev->mvdev) { 331 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 332 "vdev=%pK", vdev); 333 qdf_assert(vdev); 334 } 335 336 /* update filter mode, type in pdev structure */ 337 mon_pdev->mon_filter_mode = filter_val->mode; 338 mon_pdev->fp_mgmt_filter = filter_val->fp_mgmt; 339 mon_pdev->fp_ctrl_filter = filter_val->fp_ctrl; 340 mon_pdev->fp_data_filter = filter_val->fp_data; 341 mon_pdev->mo_mgmt_filter = filter_val->mo_mgmt; 342 mon_pdev->mo_ctrl_filter = filter_val->mo_ctrl; 343 mon_pdev->mo_data_filter = filter_val->mo_data; 344 345 dp_mon_filter_setup_mon_mode(pdev); 346 status = dp_mon_filter_update(pdev); 347 if (status != QDF_STATUS_SUCCESS) { 348 dp_rx_mon_dest_err("%pK: Failed to set filter for adv mon mode", 349 soc); 350 dp_mon_filter_reset_mon_mode(pdev); 351 } 352 353 return status; 354 } 355 #endif 356 357 QDF_STATUS dp_deliver_tx_mgmt(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,qdf_nbuf_t nbuf)358 dp_deliver_tx_mgmt(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf) 359 { 360 struct dp_pdev *pdev = 361 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, 362 pdev_id); 363 364 if (!pdev) 365 return QDF_STATUS_E_FAILURE; 366 367 dp_deliver_mgmt_frm(pdev, nbuf); 368 369 return QDF_STATUS_SUCCESS; 370 } 371 372 #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS 373 /** 374 * dp_scan_spcl_vap_stats_attach() - alloc spcl vap stats struct 375 * @mon_vdev: Datapath mon VDEV handle 376 * 377 * Return: 0 on success, not 0 on failure 378 */ 379 static inline QDF_STATUS dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev * mon_vdev)380 dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev *mon_vdev) 381 { 382 mon_vdev->scan_spcl_vap_stats = 383 qdf_mem_malloc(sizeof(struct cdp_scan_spcl_vap_stats)); 384 385 if (!mon_vdev->scan_spcl_vap_stats) { 386 dp_mon_err("scan spcl vap stats attach fail"); 387 return QDF_STATUS_E_NOMEM; 388 } 389 390 return QDF_STATUS_SUCCESS; 391 } 392 393 /** 394 * dp_scan_spcl_vap_stats_detach() - free spcl vap stats struct 395 * @mon_vdev: Datapath mon VDEV handle 396 * 397 * Return: void 398 */ 399 static inline void dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev * mon_vdev)400 dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev *mon_vdev) 401 { 402 if (mon_vdev->scan_spcl_vap_stats) { 403 qdf_mem_free(mon_vdev->scan_spcl_vap_stats); 404 mon_vdev->scan_spcl_vap_stats = NULL; 405 } 406 } 407 408 /** 409 * dp_reset_scan_spcl_vap_stats() - reset spcl vap rx stats 410 * @vdev: Datapath VDEV handle 411 * 412 * Return: void 413 */ 414 static inline void dp_reset_scan_spcl_vap_stats(struct dp_vdev * vdev)415 dp_reset_scan_spcl_vap_stats(struct dp_vdev *vdev) 416 { 417 struct dp_mon_vdev *mon_vdev; 418 struct dp_mon_pdev *mon_pdev; 419 420 mon_pdev = vdev->pdev->monitor_pdev; 421 if (!mon_pdev || !mon_pdev->reset_scan_spcl_vap_stats_enable) 422 return; 423 424 mon_vdev = vdev->monitor_vdev; 425 if (!mon_vdev || !mon_vdev->scan_spcl_vap_stats) 426 return; 427 428 qdf_mem_zero(mon_vdev->scan_spcl_vap_stats, 429 sizeof(struct cdp_scan_spcl_vap_stats)); 430 } 431 432 /** 433 * dp_get_scan_spcl_vap_stats() - get spcl vap rx stats 434 * @soc_hdl: Datapath soc handle 435 * @vdev_id: vdev id 436 * @stats: structure to hold spcl vap stats 437 * 438 * Return: 0 on success, not 0 on failure 439 */ 440 static QDF_STATUS dp_get_scan_spcl_vap_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,struct cdp_scan_spcl_vap_stats * stats)441 dp_get_scan_spcl_vap_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 442 struct cdp_scan_spcl_vap_stats *stats) 443 { 444 struct dp_mon_vdev *mon_vdev = NULL; 445 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 446 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 447 DP_MOD_ID_CDP); 448 449 if (!vdev || !stats) { 450 if (vdev) 451 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 452 return QDF_STATUS_E_INVAL; 453 } 454 455 mon_vdev = vdev->monitor_vdev; 456 if (!mon_vdev || !mon_vdev->scan_spcl_vap_stats) { 457 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 458 return QDF_STATUS_E_INVAL; 459 } 460 461 qdf_mem_copy(stats, mon_vdev->scan_spcl_vap_stats, 462 sizeof(struct cdp_scan_spcl_vap_stats)); 463 464 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 465 return QDF_STATUS_SUCCESS; 466 } 467 #else 468 static inline void dp_reset_scan_spcl_vap_stats(struct dp_vdev * vdev)469 dp_reset_scan_spcl_vap_stats(struct dp_vdev *vdev) 470 { 471 } 472 473 static inline QDF_STATUS dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev * mon_vdev)474 dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev *mon_vdev) 475 { 476 return QDF_STATUS_SUCCESS; 477 } 478 479 static inline void dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev * mon_vdev)480 dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev *mon_vdev) 481 { 482 } 483 #endif 484 485 /** 486 * dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode 487 * @dp_soc: DP soc context 488 * @vdev_id: vdev ID 489 * @special_monitor: Flag to denote if its smart monitor mode 490 * 491 * Return: 0 on success, not 0 on failure 492 */ dp_vdev_set_monitor_mode(struct cdp_soc_t * dp_soc,uint8_t vdev_id,uint8_t special_monitor)493 QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc, 494 uint8_t vdev_id, 495 uint8_t special_monitor) 496 { 497 struct dp_soc *soc = (struct dp_soc *)dp_soc; 498 struct dp_pdev *pdev; 499 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 500 DP_MOD_ID_CDP); 501 QDF_STATUS status = QDF_STATUS_SUCCESS; 502 struct dp_mon_pdev *mon_pdev; 503 struct cdp_mon_ops *cdp_ops; 504 505 if (!vdev) 506 return QDF_STATUS_E_FAILURE; 507 508 pdev = vdev->pdev; 509 510 if (!pdev || !pdev->monitor_pdev) { 511 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 512 return QDF_STATUS_E_FAILURE; 513 } 514 515 mon_pdev = pdev->monitor_pdev; 516 517 mon_pdev->mvdev = vdev; 518 519 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN, 520 "pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK\n", 521 pdev, pdev->pdev_id, pdev->soc, vdev); 522 523 /* 524 * do not configure monitor buf ring and filter for smart and 525 * lite monitor 526 * for smart monitor filters are added along with first NAC 527 * for lite monitor required configuration done through 528 * dp_set_pdev_param 529 */ 530 531 if (special_monitor) { 532 status = QDF_STATUS_SUCCESS; 533 goto fail; 534 } 535 536 if (mon_pdev->scan_spcl_vap_configured) 537 dp_reset_scan_spcl_vap_stats(vdev); 538 539 /*Check if current pdev's monitor_vdev exists */ 540 if (mon_pdev->monitor_configured) { 541 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 542 "monitor vap already created vdev=%pK\n", vdev); 543 status = QDF_STATUS_E_RESOURCES; 544 goto fail; 545 } 546 547 mon_pdev->monitor_configured = true; 548 mon_pdev->phy_ppdu_id_size = hal_rx_get_phy_ppdu_id_size(soc->hal_soc); 549 550 /* If advance monitor filter is applied using lite_mon 551 * via vap configuration, required filters are already applied 552 * hence returning SUCCESS from here. 553 */ 554 if (dp_monitor_lite_mon_is_rx_adv_filter_enable(pdev)) { 555 status = QDF_STATUS_SUCCESS; 556 goto fail; 557 } 558 /* disable lite mon if configured, monitor vap takes 559 * priority over lite mon when its created. Lite mon 560 * can be configured later again. 561 */ 562 dp_monitor_lite_mon_disable_rx(pdev); 563 564 cdp_ops = dp_mon_cdp_ops_get(soc); 565 if (cdp_ops && cdp_ops->soc_config_full_mon_mode) 566 cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev, 567 DP_FULL_MON_ENABLE); 568 dp_mon_filter_setup_mon_mode(pdev); 569 status = dp_mon_filter_update(pdev); 570 if (status != QDF_STATUS_SUCCESS) { 571 dp_cdp_err("%pK: Failed to reset monitor filters", soc); 572 dp_mon_filter_reset_mon_mode(pdev); 573 mon_pdev->monitor_configured = false; 574 mon_pdev->mvdev = NULL; 575 } 576 577 fail: 578 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 579 return status; 580 } 581 582 #ifdef QCA_TX_CAPTURE_SUPPORT 583 static QDF_STATUS dp_config_tx_capture_mode(struct dp_pdev * pdev)584 dp_config_tx_capture_mode(struct dp_pdev *pdev) 585 { 586 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 587 588 mon_pdev->tx_sniffer_enable = 1; 589 mon_pdev->monitor_configured = false; 590 591 if (!mon_pdev->pktlog_ppdu_stats) 592 dp_h2t_cfg_stats_msg_send(pdev, 593 DP_PPDU_STATS_CFG_SNIFFER, 594 pdev->pdev_id); 595 596 return QDF_STATUS_SUCCESS; 597 } 598 #else 599 #ifdef QCA_MCOPY_SUPPORT 600 static QDF_STATUS dp_config_tx_capture_mode(struct dp_pdev * pdev)601 dp_config_tx_capture_mode(struct dp_pdev *pdev) 602 { 603 return QDF_STATUS_E_INVAL; 604 } 605 #endif 606 #endif 607 608 #if defined(QCA_MCOPY_SUPPORT) || defined(QCA_TX_CAPTURE_SUPPORT) 609 QDF_STATUS dp_config_debug_sniffer(struct dp_pdev * pdev,int val)610 dp_config_debug_sniffer(struct dp_pdev *pdev, int val) 611 { 612 QDF_STATUS status = QDF_STATUS_SUCCESS; 613 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 614 615 /* 616 * Note: The mirror copy mode cannot co-exist with any other 617 * monitor modes. Hence disabling the filter for this mode will 618 * reset the monitor destination ring filters. 619 */ 620 dp_reset_mcopy_mode(pdev); 621 switch (val) { 622 case 0: 623 mon_pdev->tx_sniffer_enable = 0; 624 mon_pdev->monitor_configured = false; 625 626 /* 627 * We don't need to reset the Rx monitor status ring or call 628 * the API dp_ppdu_ring_reset() if all debug sniffer mode is 629 * disabled. The Rx monitor status ring will be disabled when 630 * the last mode using the monitor status ring get disabled. 631 */ 632 if (!mon_pdev->pktlog_ppdu_stats && 633 !mon_pdev->enhanced_stats_en && 634 !mon_pdev->bpr_enable) { 635 dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id); 636 } else if (mon_pdev->enhanced_stats_en && 637 !mon_pdev->bpr_enable) { 638 dp_h2t_cfg_stats_msg_send(pdev, 639 DP_PPDU_STATS_CFG_ENH_STATS, 640 pdev->pdev_id); 641 } else if (!mon_pdev->enhanced_stats_en && 642 mon_pdev->bpr_enable) { 643 dp_h2t_cfg_stats_msg_send(pdev, 644 DP_PPDU_STATS_CFG_BPR_ENH, 645 pdev->pdev_id); 646 } else { 647 dp_h2t_cfg_stats_msg_send(pdev, 648 DP_PPDU_STATS_CFG_BPR, 649 pdev->pdev_id); 650 } 651 break; 652 653 case 1: 654 status = dp_config_tx_capture_mode(pdev); 655 break; 656 case 2: 657 case 4: 658 status = dp_config_mcopy_mode(pdev, val); 659 break; 660 661 default: 662 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 663 "Invalid value, mode: %d not supported", val); 664 status = QDF_STATUS_E_INVAL; 665 break; 666 } 667 return status; 668 } 669 #endif 670 671 #ifdef QCA_UNDECODED_METADATA_SUPPORT 672 QDF_STATUS dp_mon_config_undecoded_metadata_capture(struct dp_pdev * pdev,int val)673 dp_mon_config_undecoded_metadata_capture(struct dp_pdev *pdev, int val) 674 { 675 QDF_STATUS status = QDF_STATUS_SUCCESS; 676 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 677 678 if (!mon_pdev->mvdev && !mon_pdev->scan_spcl_vap_configured) { 679 qdf_err("No monitor or Special vap, undecoded capture not supported"); 680 return QDF_STATUS_E_RESOURCES; 681 } 682 683 if (val) 684 status = dp_enable_undecoded_metadata_capture(pdev, val); 685 else 686 status = dp_reset_undecoded_metadata_capture(pdev); 687 688 return status; 689 } 690 #endif 691 692 /** 693 * dp_monitor_mode_ring_config() - Send the tlv config to fw for monitor buffer 694 * ring based on target 695 * @soc: soc handle 696 * @mac_for_pdev: WIN- pdev_id, MCL- mac id 697 * @pdev: physical device handle 698 * @ring_num: mac id 699 * @htt_tlv_filter: tlv filter 700 * 701 * Return: zero on success, non-zero on failure 702 */ 703 static inline QDF_STATUS dp_monitor_mode_ring_config(struct dp_soc * soc,uint8_t mac_for_pdev,struct dp_pdev * pdev,uint8_t ring_num,struct htt_rx_ring_tlv_filter htt_tlv_filter)704 dp_monitor_mode_ring_config(struct dp_soc *soc, uint8_t mac_for_pdev, 705 struct dp_pdev *pdev, uint8_t ring_num, 706 struct htt_rx_ring_tlv_filter htt_tlv_filter) 707 { 708 QDF_STATUS status; 709 710 if (soc->wlan_cfg_ctx->rxdma1_enable) 711 status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 712 soc->rxdma_mon_buf_ring[ring_num] 713 .hal_srng, 714 RXDMA_MONITOR_BUF, 715 RX_MONITOR_BUFFER_SIZE, 716 &htt_tlv_filter); 717 else 718 status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 719 pdev->rx_mac_buf_ring[ring_num] 720 .hal_srng, 721 RXDMA_BUF, RX_DATA_BUFFER_SIZE, 722 &htt_tlv_filter); 723 724 return status; 725 } 726 727 /** 728 * dp_get_mon_vdev_from_pdev_wifi3() - Get vdev id of monitor mode 729 * @soc_hdl: datapath soc handle 730 * @pdev_id: physical device instance id 731 * 732 * Return: virtual interface id 733 */ dp_get_mon_vdev_from_pdev_wifi3(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)734 static uint8_t dp_get_mon_vdev_from_pdev_wifi3(struct cdp_soc_t *soc_hdl, 735 uint8_t pdev_id) 736 { 737 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 738 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 739 740 if (qdf_unlikely(!pdev || !pdev->monitor_pdev || 741 !pdev->monitor_pdev->mvdev)) 742 return -EINVAL; 743 744 return pdev->monitor_pdev->mvdev->vdev_id; 745 } 746 747 #if defined(QCA_TX_CAPTURE_SUPPORT) || defined(QCA_ENHANCED_STATS_SUPPORT) 748 #ifndef WLAN_TX_PKT_CAPTURE_ENH dp_deliver_mgmt_frm(struct dp_pdev * pdev,qdf_nbuf_t nbuf)749 void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf) 750 { 751 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 752 753 if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode) { 754 dp_wdi_event_handler(WDI_EVENT_TX_MGMT_CTRL, pdev->soc, 755 nbuf, HTT_INVALID_PEER, 756 WDI_NO_VAL, pdev->pdev_id); 757 } else { 758 if (!mon_pdev->bpr_enable) 759 qdf_nbuf_free(nbuf); 760 } 761 } 762 #endif 763 #endif 764 dp_htt_ppdu_stats_attach(struct dp_pdev * pdev)765 QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev) 766 { 767 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 768 769 mon_pdev->ppdu_tlv_buf = qdf_mem_malloc(HTT_T2H_MAX_MSG_SIZE); 770 771 if (!mon_pdev->ppdu_tlv_buf) { 772 QDF_TRACE_ERROR(QDF_MODULE_ID_DP, "ppdu_tlv_buf alloc fail"); 773 return QDF_STATUS_E_NOMEM; 774 } 775 776 return QDF_STATUS_SUCCESS; 777 } 778 dp_htt_ppdu_stats_detach(struct dp_pdev * pdev)779 void dp_htt_ppdu_stats_detach(struct dp_pdev *pdev) 780 { 781 struct ppdu_info *ppdu_info, *ppdu_info_next; 782 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 783 784 785 TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->ppdu_info_list, 786 ppdu_info_list_elem, ppdu_info_next) { 787 if (!ppdu_info) 788 break; 789 TAILQ_REMOVE(&mon_pdev->ppdu_info_list, 790 ppdu_info, ppdu_info_list_elem); 791 mon_pdev->list_depth--; 792 qdf_assert_always(ppdu_info->nbuf); 793 qdf_nbuf_free(ppdu_info->nbuf); 794 qdf_mem_free(ppdu_info); 795 } 796 797 TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->sched_comp_ppdu_list, 798 ppdu_info_list_elem, ppdu_info_next) { 799 if (!ppdu_info) 800 break; 801 TAILQ_REMOVE(&mon_pdev->sched_comp_ppdu_list, 802 ppdu_info, ppdu_info_list_elem); 803 mon_pdev->sched_comp_list_depth--; 804 qdf_assert_always(ppdu_info->nbuf); 805 qdf_nbuf_free(ppdu_info->nbuf); 806 qdf_mem_free(ppdu_info); 807 } 808 809 if (mon_pdev->ppdu_tlv_buf) 810 qdf_mem_free(mon_pdev->ppdu_tlv_buf); 811 } 812 dp_pdev_get_rx_mon_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_pdev_mon_stats * stats)813 QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 814 struct cdp_pdev_mon_stats *stats) 815 { 816 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 817 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 818 struct dp_mon_pdev *mon_pdev; 819 820 if (!pdev) 821 return QDF_STATUS_E_FAILURE; 822 823 mon_pdev = pdev->monitor_pdev; 824 if (!mon_pdev) 825 return QDF_STATUS_E_FAILURE; 826 827 qdf_mem_copy(stats, &mon_pdev->rx_mon_stats, 828 sizeof(struct cdp_pdev_mon_stats)); 829 830 return QDF_STATUS_SUCCESS; 831 } 832 833 #ifdef QCA_UNDECODED_METADATA_SUPPORT 834 /** 835 * dp_pdev_get_undecoded_capture_stats() - Get undecoded metadata captured 836 * monitor pdev stats 837 * @mon_pdev: Monitor PDEV handle 838 * @rx_mon_stats: Monitor pdev status/destination ring stats 839 * 840 * Return: None 841 */ 842 static inline void dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev * mon_pdev,struct cdp_pdev_mon_stats * rx_mon_stats)843 dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev *mon_pdev, 844 struct cdp_pdev_mon_stats *rx_mon_stats) 845 { 846 char undecoded_error[DP_UNDECODED_ERR_LENGTH]; 847 uint8_t index = 0, i; 848 849 DP_PRINT_STATS("Rx Undecoded Frame count:%d", 850 rx_mon_stats->rx_undecoded_count); 851 index = 0; 852 for (i = 0; i < (CDP_PHYRX_ERR_MAX); i++) { 853 index += qdf_snprint(&undecoded_error[index], 854 DP_UNDECODED_ERR_LENGTH - index, 855 " %d", rx_mon_stats->rx_undecoded_error[i]); 856 } 857 DP_PRINT_STATS("Undecoded Error (0-63):%s", undecoded_error); 858 } 859 #else 860 static inline void dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev * mon_pdev,struct cdp_pdev_mon_stats * rx_mon_stats)861 dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev *mon_pdev, 862 struct cdp_pdev_mon_stats *rx_mon_stats) 863 { 864 } 865 #endif 866 867 static const char * 868 dp_preamble_type_str[] = { 869 "preamble OFDMA ", 870 "preamble CCK ", 871 "preamble HT ", 872 "preamble VHT ", 873 "preamble HE ", 874 "preamble EHT ", 875 "preamble NO SUPPORT", 876 }; 877 878 static const char * 879 dp_reception_type_str[] = { 880 "reception su ", 881 "reception mu_mimo ", 882 "reception ofdma ", 883 "reception ofdma mimo", 884 }; 885 886 static const char * 887 dp_mu_dl_ul_str[] = { 888 "MU DL", 889 "MU UL", 890 }; 891 892 static inline void dp_print_pdev_mpdu_fcs_ok_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)893 dp_print_pdev_mpdu_fcs_ok_cnt(struct cdp_pdev_mon_stats *rx_mon_sts, 894 uint32_t pkt_t, uint32_t rx_t, 895 uint32_t dl_ul, uint32_t user) 896 { 897 DP_PRINT_STATS("%s, %s, %s, user=%d, mpdu_fcs_ok=%d", 898 dp_preamble_type_str[pkt_t], 899 dp_reception_type_str[rx_t], 900 dp_mu_dl_ul_str[dl_ul], 901 user, 902 rx_mon_sts->mpdu_cnt_fcs_ok[pkt_t][rx_t][dl_ul][user]); 903 } 904 905 static inline void dp_print_pdev_mpdu_fcs_err_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)906 dp_print_pdev_mpdu_fcs_err_cnt(struct cdp_pdev_mon_stats *rx_mon_sts, 907 uint32_t pkt_t, uint32_t rx_t, 908 uint32_t dl_ul, uint32_t user) 909 { 910 DP_PRINT_STATS("%s, %s, %s, user=%d, mpdu_fcs_err=%d", 911 dp_preamble_type_str[pkt_t], 912 dp_reception_type_str[rx_t], 913 dp_mu_dl_ul_str[dl_ul], 914 user, 915 rx_mon_sts->mpdu_cnt_fcs_err[pkt_t][rx_t][dl_ul][user]); 916 } 917 918 static inline void dp_print_pdev_mpdu_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)919 dp_print_pdev_mpdu_cnt(struct cdp_pdev_mon_stats *rx_mon_sts, 920 uint32_t pkt_t, uint32_t rx_t, 921 uint32_t dl_ul, uint32_t user) 922 { 923 if (rx_mon_sts->mpdu_cnt_fcs_ok[pkt_t][rx_t][dl_ul][user]) 924 dp_print_pdev_mpdu_fcs_ok_cnt(rx_mon_sts, pkt_t, rx_t, 925 dl_ul, user); 926 927 if (rx_mon_sts->mpdu_cnt_fcs_err[pkt_t][rx_t][dl_ul][user]) 928 dp_print_pdev_mpdu_fcs_err_cnt(rx_mon_sts, pkt_t, rx_t, 929 dl_ul, user); 930 } 931 932 static inline void dp_print_pdev_mpdu_user(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul)933 dp_print_pdev_mpdu_user(struct cdp_pdev_mon_stats *rx_mon_sts, 934 uint32_t pkt_t, uint32_t rx_t, 935 uint32_t dl_ul) 936 { 937 uint32_t user; 938 939 for (user = 0; user < CDP_MU_SNIF_USER_MAX; user++) 940 dp_print_pdev_mpdu_cnt(rx_mon_sts, pkt_t, rx_t, 941 dl_ul, user); 942 } 943 944 static inline void dp_print_pdev_mpdu_dl_ul(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t)945 dp_print_pdev_mpdu_dl_ul(struct cdp_pdev_mon_stats *rx_mon_sts, 946 uint32_t pkt_t, uint32_t rx_t) 947 { 948 uint32_t dl_ul; 949 950 for (dl_ul = CDP_MU_TYPE_DL; dl_ul < CDP_MU_TYPE_MAX; dl_ul++) 951 dp_print_pdev_mpdu_user(rx_mon_sts, pkt_t, rx_t, 952 dl_ul); 953 } 954 955 static inline void dp_print_pdev_mpdu_rx_type(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t)956 dp_print_pdev_mpdu_rx_type(struct cdp_pdev_mon_stats *rx_mon_sts, 957 uint32_t pkt_t) 958 { 959 uint32_t rx_t; 960 961 for (rx_t = CDP_RX_TYPE_SU; rx_t < CDP_RX_TYPE_MAX; rx_t++) 962 dp_print_pdev_mpdu_dl_ul(rx_mon_sts, pkt_t, rx_t); 963 } 964 965 static inline void dp_print_pdev_mpdu_pkt_type(struct cdp_pdev_mon_stats * rx_mon_sts)966 dp_print_pdev_mpdu_pkt_type(struct cdp_pdev_mon_stats *rx_mon_sts) 967 { 968 uint32_t pkt_t; 969 970 for (pkt_t = CDP_PKT_TYPE_OFDM; pkt_t < CDP_PKT_TYPE_MAX; pkt_t++) 971 dp_print_pdev_mpdu_rx_type(rx_mon_sts, pkt_t); 972 } 973 974 static inline void print_ppdu_eht_type_mode(struct cdp_pdev_mon_stats * rx_mon_stats,uint32_t ppdu_type_mode,uint32_t dl_ul)975 print_ppdu_eht_type_mode( 976 struct cdp_pdev_mon_stats *rx_mon_stats, 977 uint32_t ppdu_type_mode, 978 uint32_t dl_ul) 979 { 980 DP_PRINT_STATS("type_mode=%d, dl_ul=%d, cnt=%d", 981 ppdu_type_mode, 982 dl_ul, 983 rx_mon_stats->ppdu_eht_type_mode[ppdu_type_mode][dl_ul]); 984 } 985 986 static inline void print_ppdu_eth_type_mode_dl_ul(struct cdp_pdev_mon_stats * rx_mon_stats,uint32_t ppdu_type_mode)987 print_ppdu_eth_type_mode_dl_ul( 988 struct cdp_pdev_mon_stats *rx_mon_stats, 989 uint32_t ppdu_type_mode 990 ) 991 { 992 uint32_t dl_ul; 993 994 for (dl_ul = 0; dl_ul < CDP_MU_TYPE_MAX; dl_ul++) { 995 if (rx_mon_stats->ppdu_eht_type_mode[ppdu_type_mode][dl_ul]) 996 print_ppdu_eht_type_mode(rx_mon_stats, 997 ppdu_type_mode, dl_ul); 998 } 999 } 1000 1001 static inline void dp_print_pdev_eht_ppdu_cnt(struct dp_pdev * pdev)1002 dp_print_pdev_eht_ppdu_cnt(struct dp_pdev *pdev) 1003 { 1004 struct cdp_pdev_mon_stats *rx_mon_stats; 1005 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1006 uint32_t ppdu_type_mode; 1007 1008 rx_mon_stats = &mon_pdev->rx_mon_stats; 1009 DP_PRINT_STATS("Monitor EHT PPDU Count"); 1010 for (ppdu_type_mode = 0; ppdu_type_mode < CDP_EHT_TYPE_MODE_MAX; 1011 ppdu_type_mode++) { 1012 print_ppdu_eth_type_mode_dl_ul(rx_mon_stats, 1013 ppdu_type_mode); 1014 } 1015 } 1016 1017 static inline void dp_print_pdev_mpdu_stats(struct dp_pdev * pdev)1018 dp_print_pdev_mpdu_stats(struct dp_pdev *pdev) 1019 { 1020 struct cdp_pdev_mon_stats *rx_mon_stats; 1021 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1022 1023 rx_mon_stats = &mon_pdev->rx_mon_stats; 1024 DP_PRINT_STATS("Monitor MPDU Count"); 1025 dp_print_pdev_mpdu_pkt_type(rx_mon_stats); 1026 } 1027 1028 void dp_print_pdev_rx_mon_stats(struct dp_pdev * pdev)1029 dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev) 1030 { 1031 struct cdp_pdev_mon_stats *rx_mon_stats; 1032 uint32_t *stat_ring_ppdu_ids; 1033 uint32_t *dest_ring_ppdu_ids; 1034 int i, idx; 1035 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1036 1037 rx_mon_stats = &mon_pdev->rx_mon_stats; 1038 1039 DP_PRINT_STATS("PDEV Rx Monitor Stats:\n"); 1040 1041 DP_PRINT_STATS("status_ppdu_compl_cnt = %d", 1042 rx_mon_stats->status_ppdu_compl); 1043 DP_PRINT_STATS("status_ppdu_start_cnt = %d", 1044 rx_mon_stats->status_ppdu_start); 1045 DP_PRINT_STATS("status_ppdu_end_cnt = %d", 1046 rx_mon_stats->status_ppdu_end); 1047 DP_PRINT_STATS("status_ppdu_start_mis_cnt = %d", 1048 rx_mon_stats->status_ppdu_start_mis); 1049 DP_PRINT_STATS("status_ppdu_end_mis_cnt = %d", 1050 rx_mon_stats->status_ppdu_end_mis); 1051 1052 DP_PRINT_STATS("start_user_info_cnt = %d", 1053 rx_mon_stats->start_user_info_cnt); 1054 DP_PRINT_STATS("end_user_stats_cnt = %d", 1055 rx_mon_stats->end_user_stats_cnt); 1056 1057 DP_PRINT_STATS("status_ppdu_done_cnt = %d", 1058 rx_mon_stats->status_ppdu_done); 1059 DP_PRINT_STATS("dest_ppdu_done_cnt = %d", 1060 rx_mon_stats->dest_ppdu_done); 1061 DP_PRINT_STATS("dest_mpdu_done_cnt = %d", 1062 rx_mon_stats->dest_mpdu_done); 1063 DP_PRINT_STATS("tlv_tag_status_err_cnt = %u", 1064 rx_mon_stats->tlv_tag_status_err); 1065 DP_PRINT_STATS("mon status DMA not done WAR count= %u", 1066 rx_mon_stats->status_buf_done_war); 1067 DP_PRINT_STATS("dest_mpdu_drop_cnt = %d", 1068 rx_mon_stats->dest_mpdu_drop); 1069 DP_PRINT_STATS("dup_mon_linkdesc_cnt = %d", 1070 rx_mon_stats->dup_mon_linkdesc_cnt); 1071 DP_PRINT_STATS("dup_mon_buf_cnt = %d", 1072 rx_mon_stats->dup_mon_buf_cnt); 1073 DP_PRINT_STATS("mon_rx_buf_reaped = %u", 1074 rx_mon_stats->mon_rx_bufs_reaped_dest); 1075 DP_PRINT_STATS("mon_rx_buf_replenished = %u", 1076 rx_mon_stats->mon_rx_bufs_replenished_dest); 1077 DP_PRINT_STATS("ppdu_id_mismatch = %u", 1078 rx_mon_stats->ppdu_id_mismatch); 1079 DP_PRINT_STATS("mpdu_ppdu_id_match_cnt = %d", 1080 rx_mon_stats->ppdu_id_match); 1081 DP_PRINT_STATS("ppdus dropped frm status ring = %d", 1082 rx_mon_stats->status_ppdu_drop); 1083 DP_PRINT_STATS("ppdus dropped frm dest ring = %d", 1084 rx_mon_stats->dest_ppdu_drop); 1085 DP_PRINT_STATS("mpdu_ppdu_id_mismatch_drop = %u", 1086 rx_mon_stats->mpdu_ppdu_id_mismatch_drop); 1087 DP_PRINT_STATS("mpdu_decap_type_invalid = %u", 1088 rx_mon_stats->mpdu_decap_type_invalid); 1089 DP_PRINT_STATS("pending_desc_count = %u", 1090 rx_mon_stats->pending_desc_count); 1091 stat_ring_ppdu_ids = 1092 (uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST); 1093 dest_ring_ppdu_ids = 1094 (uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST); 1095 1096 if (!stat_ring_ppdu_ids || !dest_ring_ppdu_ids) 1097 DP_PRINT_STATS("Unable to allocate ppdu id hist mem\n"); 1098 1099 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1100 idx = rx_mon_stats->ppdu_id_hist_idx; 1101 qdf_mem_copy(stat_ring_ppdu_ids, 1102 rx_mon_stats->stat_ring_ppdu_id_hist, 1103 sizeof(uint32_t) * MAX_PPDU_ID_HIST); 1104 qdf_mem_copy(dest_ring_ppdu_ids, 1105 rx_mon_stats->dest_ring_ppdu_id_hist, 1106 sizeof(uint32_t) * MAX_PPDU_ID_HIST); 1107 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1108 1109 DP_PRINT_STATS("PPDU Id history:"); 1110 DP_PRINT_STATS("stat_ring_ppdu_ids\t dest_ring_ppdu_ids"); 1111 for (i = 0; i < MAX_PPDU_ID_HIST; i++) { 1112 idx = (idx + 1) & (MAX_PPDU_ID_HIST - 1); 1113 DP_PRINT_STATS("%*u\t%*u", 16, 1114 rx_mon_stats->stat_ring_ppdu_id_hist[idx], 16, 1115 rx_mon_stats->dest_ring_ppdu_id_hist[idx]); 1116 } 1117 qdf_mem_free(stat_ring_ppdu_ids); 1118 qdf_mem_free(dest_ring_ppdu_ids); 1119 DP_PRINT_STATS("mon_rx_dest_stuck = %d", 1120 rx_mon_stats->mon_rx_dest_stuck); 1121 1122 dp_pdev_get_undecoded_capture_stats(mon_pdev, rx_mon_stats); 1123 dp_mon_rx_print_advanced_stats(pdev->soc, pdev); 1124 1125 dp_print_pdev_mpdu_stats(pdev); 1126 dp_print_pdev_eht_ppdu_cnt(pdev); 1127 1128 } 1129 1130 #ifdef QCA_SUPPORT_BPR 1131 QDF_STATUS dp_set_bpr_enable(struct dp_pdev * pdev,int val)1132 dp_set_bpr_enable(struct dp_pdev *pdev, int val) 1133 { 1134 struct dp_mon_ops *mon_ops; 1135 1136 mon_ops = dp_mon_ops_get(pdev->soc); 1137 if (mon_ops && mon_ops->mon_set_bpr_enable) 1138 return mon_ops->mon_set_bpr_enable(pdev, val); 1139 1140 return QDF_STATUS_E_FAILURE; 1141 } 1142 #endif 1143 1144 #ifdef WDI_EVENT_ENABLE 1145 #ifdef BE_PKTLOG_SUPPORT 1146 static bool dp_set_hybrid_pktlog_enable(struct dp_pdev * pdev,struct dp_mon_pdev * mon_pdev,struct dp_soc * soc)1147 dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev, 1148 struct dp_mon_pdev *mon_pdev, 1149 struct dp_soc *soc) 1150 { 1151 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1152 struct dp_mon_ops *mon_ops = NULL; 1153 uint16_t num_buffers; 1154 1155 /* Nothing needs to be done if monitor mode is 1156 * enabled 1157 */ 1158 if (mon_pdev->mvdev) 1159 return false; 1160 1161 mon_ops = dp_mon_ops_get(pdev->soc); 1162 if (!mon_ops) { 1163 dp_mon_filter_err("Mon ops uninitialized"); 1164 return QDF_STATUS_E_FAILURE; 1165 } 1166 1167 if (!mon_pdev->pktlog_hybrid_mode) { 1168 mon_pdev->pktlog_hybrid_mode = true; 1169 soc_cfg_ctx = soc->wlan_cfg_ctx; 1170 num_buffers = 1171 wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx); 1172 1173 if (mon_ops && mon_ops->set_mon_mode_buf_rings_tx) 1174 mon_ops->set_mon_mode_buf_rings_tx(pdev, num_buffers); 1175 1176 dp_mon_filter_setup_pktlog_hybrid(pdev); 1177 if (dp_tx_mon_filter_update(pdev) != 1178 QDF_STATUS_SUCCESS) { 1179 dp_cdp_err("Set hybrid filters failed"); 1180 dp_mon_filter_reset_pktlog_hybrid(pdev); 1181 mon_pdev->rx_pktlog_mode = 1182 DP_RX_PKTLOG_DISABLED; 1183 return false; 1184 } 1185 1186 dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_PKTLOG); 1187 } 1188 1189 return true; 1190 } 1191 1192 static void dp_set_hybrid_pktlog_disable(struct dp_mon_pdev * mon_pdev)1193 dp_set_hybrid_pktlog_disable(struct dp_mon_pdev *mon_pdev) 1194 { 1195 mon_pdev->pktlog_hybrid_mode = false; 1196 } 1197 #else 1198 static void dp_set_hybrid_pktlog_disable(struct dp_mon_pdev * mon_pdev)1199 dp_set_hybrid_pktlog_disable(struct dp_mon_pdev *mon_pdev) 1200 { 1201 } 1202 1203 static bool dp_set_hybrid_pktlog_enable(struct dp_pdev * pdev,struct dp_mon_pdev * mon_pdev,struct dp_soc * soc)1204 dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev, 1205 struct dp_mon_pdev *mon_pdev, 1206 struct dp_soc *soc) 1207 { 1208 dp_cdp_err("Hybrid mode is supported only on beryllium"); 1209 return true; 1210 } 1211 #endif dp_set_pktlog_wifi3(struct dp_pdev * pdev,uint32_t event,bool enable)1212 int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, 1213 bool enable) 1214 { 1215 struct dp_soc *soc = NULL; 1216 int max_mac_rings = wlan_cfg_get_num_mac_rings 1217 (pdev->wlan_cfg_ctx); 1218 uint8_t mac_id = 0; 1219 struct dp_mon_ops *mon_ops; 1220 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1221 1222 soc = pdev->soc; 1223 mon_ops = dp_mon_ops_get(soc); 1224 1225 if (!mon_ops) 1226 return 0; 1227 1228 dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings); 1229 1230 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 1231 FL("Max_mac_rings %d "), 1232 max_mac_rings); 1233 1234 if (enable) { 1235 switch (event) { 1236 case WDI_EVENT_RX_DESC: 1237 /* Nothing needs to be done if monitor mode is 1238 * enabled 1239 */ 1240 if (mon_pdev->mvdev) 1241 return 0; 1242 1243 if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_FULL) 1244 break; 1245 1246 mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL; 1247 dp_mon_filter_setup_rx_pkt_log_full(pdev); 1248 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1249 dp_cdp_err("%pK: Pktlog full filters set failed", 1250 soc); 1251 dp_mon_filter_reset_rx_pkt_log_full(pdev); 1252 mon_pdev->rx_pktlog_mode = 1253 DP_RX_PKTLOG_DISABLED; 1254 return 0; 1255 } 1256 1257 dp_monitor_reap_timer_start(soc, 1258 CDP_MON_REAP_SOURCE_PKTLOG); 1259 break; 1260 1261 case WDI_EVENT_LITE_RX: 1262 /* Nothing needs to be done if monitor mode is 1263 * enabled 1264 */ 1265 if (mon_pdev->mvdev) 1266 return 0; 1267 1268 if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_LITE) 1269 break; 1270 1271 mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE; 1272 1273 /* 1274 * Set the packet log lite mode filter. 1275 */ 1276 dp_mon_filter_setup_rx_pkt_log_lite(pdev); 1277 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1278 dp_cdp_err("%pK: Pktlog lite filters set failed", 1279 soc); 1280 dp_mon_filter_reset_rx_pkt_log_lite(pdev); 1281 mon_pdev->rx_pktlog_mode = 1282 DP_RX_PKTLOG_DISABLED; 1283 return 0; 1284 } 1285 1286 dp_monitor_reap_timer_start(soc, 1287 CDP_MON_REAP_SOURCE_PKTLOG); 1288 break; 1289 case WDI_EVENT_LITE_T2H: 1290 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 1291 int mac_for_pdev = dp_get_mac_id_for_pdev( 1292 mac_id, pdev->pdev_id); 1293 1294 mon_pdev->pktlog_ppdu_stats = true; 1295 dp_h2t_cfg_stats_msg_send(pdev, 1296 DP_PPDU_TXLITE_STATS_BITMASK_CFG, 1297 mac_for_pdev); 1298 } 1299 break; 1300 1301 case WDI_EVENT_RX_CBF: 1302 /* Nothing needs to be done if monitor mode is 1303 * enabled 1304 */ 1305 if (mon_pdev->mvdev) 1306 return 0; 1307 1308 if (mon_pdev->rx_pktlog_cbf) 1309 break; 1310 1311 mon_pdev->rx_pktlog_cbf = true; 1312 mon_pdev->monitor_configured = true; 1313 if (mon_ops->mon_vdev_set_monitor_mode_buf_rings) 1314 mon_ops->mon_vdev_set_monitor_mode_buf_rings( 1315 pdev); 1316 1317 /* 1318 * Set the packet log lite mode filter. 1319 */ 1320 qdf_info("Non mon mode: Enable destination ring"); 1321 1322 dp_mon_filter_setup_rx_pkt_log_cbf(pdev); 1323 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1324 dp_mon_err("Pktlog set CBF filters failed"); 1325 dp_mon_filter_reset_rx_pktlog_cbf(pdev); 1326 mon_pdev->rx_pktlog_mode = 1327 DP_RX_PKTLOG_DISABLED; 1328 mon_pdev->monitor_configured = false; 1329 return 0; 1330 } 1331 1332 dp_monitor_reap_timer_start(soc, 1333 CDP_MON_REAP_SOURCE_PKTLOG); 1334 break; 1335 case WDI_EVENT_HYBRID_TX: 1336 if (!dp_set_hybrid_pktlog_enable(pdev, mon_pdev, soc)) 1337 return 0; 1338 break; 1339 1340 default: 1341 /* Nothing needs to be done for other pktlog types */ 1342 break; 1343 } 1344 } else { 1345 switch (event) { 1346 case WDI_EVENT_RX_DESC: 1347 case WDI_EVENT_LITE_RX: 1348 /* Nothing needs to be done if monitor mode is 1349 * enabled 1350 */ 1351 if (mon_pdev->mvdev) 1352 return 0; 1353 1354 if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_DISABLED) 1355 break; 1356 1357 mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED; 1358 dp_mon_filter_reset_rx_pkt_log_full(pdev); 1359 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1360 dp_cdp_err("%pK: Pktlog filters reset failed", 1361 soc); 1362 return 0; 1363 } 1364 1365 dp_mon_filter_reset_rx_pkt_log_lite(pdev); 1366 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1367 dp_cdp_err("%pK: Pktlog filters reset failed", 1368 soc); 1369 return 0; 1370 } 1371 1372 dp_monitor_reap_timer_stop(soc, 1373 CDP_MON_REAP_SOURCE_PKTLOG); 1374 break; 1375 case WDI_EVENT_LITE_T2H: 1376 /* 1377 * To disable HTT_H2T_MSG_TYPE_PPDU_STATS_CFG in FW 1378 * passing value 0. Once these macros will define in htt 1379 * header file will use proper macros 1380 */ 1381 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 1382 int mac_for_pdev = 1383 dp_get_mac_id_for_pdev(mac_id, 1384 pdev->pdev_id); 1385 1386 mon_pdev->pktlog_ppdu_stats = false; 1387 if (!mon_pdev->enhanced_stats_en && 1388 !mon_pdev->tx_sniffer_enable && 1389 !mon_pdev->mcopy_mode) { 1390 dp_h2t_cfg_stats_msg_send(pdev, 0, 1391 mac_for_pdev); 1392 } else if (mon_pdev->tx_sniffer_enable || 1393 mon_pdev->mcopy_mode) { 1394 dp_h2t_cfg_stats_msg_send(pdev, 1395 DP_PPDU_STATS_CFG_SNIFFER, 1396 mac_for_pdev); 1397 } else if (mon_pdev->enhanced_stats_en) { 1398 dp_h2t_cfg_stats_msg_send(pdev, 1399 DP_PPDU_STATS_CFG_ENH_STATS, 1400 mac_for_pdev); 1401 } 1402 } 1403 1404 break; 1405 case WDI_EVENT_RX_CBF: 1406 mon_pdev->rx_pktlog_cbf = false; 1407 break; 1408 1409 case WDI_EVENT_HYBRID_TX: 1410 dp_set_hybrid_pktlog_disable(mon_pdev); 1411 break; 1412 1413 default: 1414 /* Nothing needs to be done for other pktlog types */ 1415 break; 1416 } 1417 } 1418 return 0; 1419 } 1420 #endif 1421 1422 /* MCL specific functions */ 1423 #if defined(DP_CON_MON) && !defined(REMOVE_PKT_LOG) dp_pktlogmod_exit(struct dp_pdev * pdev)1424 void dp_pktlogmod_exit(struct dp_pdev *pdev) 1425 { 1426 struct dp_soc *soc = pdev->soc; 1427 struct hif_opaque_softc *scn = soc->hif_handle; 1428 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1429 1430 if (!scn) { 1431 dp_mon_err("Invalid hif(scn) handle"); 1432 return; 1433 } 1434 1435 dp_monitor_reap_timer_stop(soc, CDP_MON_REAP_SOURCE_PKTLOG); 1436 pktlogmod_exit(scn); 1437 mon_pdev->pkt_log_init = false; 1438 } 1439 #endif /*DP_CON_MON*/ 1440 1441 #if defined(WDI_EVENT_ENABLE) && defined(QCA_ENHANCED_STATS_SUPPORT) 1442 #ifdef IPA_OFFLOAD 1443 static void dp_peer_get_tx_rx_stats(struct dp_peer * peer,struct cdp_interface_peer_stats * peer_stats_intf)1444 dp_peer_get_tx_rx_stats(struct dp_peer *peer, 1445 struct cdp_interface_peer_stats *peer_stats_intf) 1446 { 1447 struct dp_rx_tid *rx_tid = NULL; 1448 uint8_t i = 0; 1449 1450 for (i = 0; i < DP_MAX_TIDS; i++) { 1451 rx_tid = &peer->rx_tid[i]; 1452 peer_stats_intf->rx_byte_count += 1453 rx_tid->rx_msdu_cnt.bytes; 1454 peer_stats_intf->rx_packet_count += 1455 rx_tid->rx_msdu_cnt.num; 1456 } 1457 peer_stats_intf->tx_packet_count = 1458 peer->monitor_peer->stats.tx.tx_ucast_success.num; 1459 peer_stats_intf->tx_byte_count = 1460 peer->monitor_peer->stats.tx.tx_ucast_success.bytes; 1461 } 1462 #else 1463 static void dp_peer_get_tx_rx_stats(struct dp_peer * peer,struct cdp_interface_peer_stats * peer_stats_intf)1464 dp_peer_get_tx_rx_stats(struct dp_peer *peer, 1465 struct cdp_interface_peer_stats *peer_stats_intf) 1466 { 1467 struct dp_txrx_peer *txrx_peer = NULL; 1468 struct dp_peer *tgt_peer = NULL; 1469 uint8_t inx = 0; 1470 uint8_t stats_arr_size; 1471 1472 tgt_peer = dp_get_tgt_peer_from_peer(peer); 1473 txrx_peer = tgt_peer->txrx_peer; 1474 peer_stats_intf->rx_packet_count = txrx_peer->to_stack.num; 1475 peer_stats_intf->rx_byte_count = txrx_peer->to_stack.bytes; 1476 stats_arr_size = txrx_peer->stats_arr_size; 1477 1478 for (inx = 0; inx < stats_arr_size; inx++) { 1479 peer_stats_intf->tx_packet_count += 1480 txrx_peer->stats[inx].per_pkt_stats.tx.ucast.num; 1481 peer_stats_intf->tx_byte_count += 1482 txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes; 1483 } 1484 } 1485 #endif 1486 dp_peer_stats_notify(struct dp_pdev * dp_pdev,struct dp_peer * peer)1487 QDF_STATUS dp_peer_stats_notify(struct dp_pdev *dp_pdev, struct dp_peer *peer) 1488 { 1489 struct cdp_interface_peer_stats peer_stats_intf = {0}; 1490 struct dp_mon_peer_stats *mon_peer_stats = NULL; 1491 struct dp_peer *tgt_peer = NULL; 1492 struct dp_txrx_peer *txrx_peer = NULL; 1493 1494 if (qdf_unlikely(!peer || !peer->vdev || !peer->monitor_peer)) 1495 return QDF_STATUS_E_FAULT; 1496 1497 tgt_peer = dp_get_tgt_peer_from_peer(peer); 1498 if (qdf_unlikely(!tgt_peer)) 1499 return QDF_STATUS_E_FAULT; 1500 1501 txrx_peer = tgt_peer->txrx_peer; 1502 if (!qdf_unlikely(txrx_peer)) 1503 return QDF_STATUS_E_FAULT; 1504 1505 mon_peer_stats = &peer->monitor_peer->stats; 1506 1507 if (mon_peer_stats->rx.last_snr != mon_peer_stats->rx.snr) 1508 peer_stats_intf.rssi_changed = true; 1509 1510 if ((mon_peer_stats->rx.snr && peer_stats_intf.rssi_changed) || 1511 (mon_peer_stats->tx.tx_rate && 1512 mon_peer_stats->tx.tx_rate != mon_peer_stats->tx.last_tx_rate)) { 1513 qdf_mem_copy(peer_stats_intf.peer_mac, peer->mac_addr.raw, 1514 QDF_MAC_ADDR_SIZE); 1515 peer_stats_intf.vdev_id = peer->vdev->vdev_id; 1516 peer_stats_intf.last_peer_tx_rate = 1517 mon_peer_stats->tx.last_tx_rate; 1518 peer_stats_intf.peer_tx_rate = mon_peer_stats->tx.tx_rate; 1519 peer_stats_intf.peer_rssi = mon_peer_stats->rx.snr; 1520 peer_stats_intf.ack_rssi = mon_peer_stats->tx.last_ack_rssi; 1521 dp_peer_get_tx_rx_stats(peer, &peer_stats_intf); 1522 peer_stats_intf.per = tgt_peer->stats.tx.last_per; 1523 peer_stats_intf.free_buff = INVALID_FREE_BUFF; 1524 dp_wdi_event_handler(WDI_EVENT_PEER_STATS, dp_pdev->soc, 1525 (void *)&peer_stats_intf, 0, 1526 WDI_NO_VAL, dp_pdev->pdev_id); 1527 } 1528 1529 return QDF_STATUS_SUCCESS; 1530 } 1531 #endif 1532 1533 #ifdef FEATURE_NAC_RSSI 1534 /** 1535 * dp_rx_nac_filter() - Function to perform filtering of non-associated 1536 * clients 1537 * @pdev: DP pdev handle 1538 * @rx_pkt_hdr: Rx packet Header 1539 * 1540 * Return: dp_vdev* 1541 */ 1542 static dp_rx_nac_filter(struct dp_pdev * pdev,uint8_t * rx_pkt_hdr)1543 struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev, 1544 uint8_t *rx_pkt_hdr) 1545 { 1546 struct ieee80211_frame *wh; 1547 struct dp_neighbour_peer *peer = NULL; 1548 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1549 1550 wh = (struct ieee80211_frame *)rx_pkt_hdr; 1551 1552 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_TODS) 1553 return NULL; 1554 1555 qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex); 1556 TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list, 1557 neighbour_peer_list_elem) { 1558 if (qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0], 1559 wh->i_addr2, QDF_MAC_ADDR_SIZE) == 0) { 1560 dp_rx_debug("%pK: NAC configuration matched for mac-%2x:%2x:%2x:%2x:%2x:%2x", 1561 pdev->soc, 1562 peer->neighbour_peers_macaddr.raw[0], 1563 peer->neighbour_peers_macaddr.raw[1], 1564 peer->neighbour_peers_macaddr.raw[2], 1565 peer->neighbour_peers_macaddr.raw[3], 1566 peer->neighbour_peers_macaddr.raw[4], 1567 peer->neighbour_peers_macaddr.raw[5]); 1568 1569 qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex); 1570 1571 return mon_pdev->mvdev; 1572 } 1573 } 1574 qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex); 1575 1576 return NULL; 1577 } 1578 dp_filter_neighbour_peer(struct dp_pdev * pdev,uint8_t * rx_pkt_hdr)1579 QDF_STATUS dp_filter_neighbour_peer(struct dp_pdev *pdev, 1580 uint8_t *rx_pkt_hdr) 1581 { 1582 struct dp_vdev *vdev = NULL; 1583 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1584 1585 if (mon_pdev->filter_neighbour_peers) { 1586 /* Next Hop scenario not yet handle */ 1587 vdev = dp_rx_nac_filter(pdev, rx_pkt_hdr); 1588 if (vdev) { 1589 dp_rx_mon_deliver(pdev->soc, pdev->pdev_id, 1590 pdev->invalid_peer_head_msdu, 1591 pdev->invalid_peer_tail_msdu); 1592 1593 pdev->invalid_peer_head_msdu = NULL; 1594 pdev->invalid_peer_tail_msdu = NULL; 1595 return QDF_STATUS_SUCCESS; 1596 } 1597 } 1598 1599 return QDF_STATUS_E_FAILURE; 1600 } 1601 #endif 1602 1603 /** 1604 * dp_update_mon_mac_filter() - Set/reset monitor mac filter 1605 * @soc_hdl: cdp soc handle 1606 * @vdev_id: id of virtual device object 1607 * @cmd: Add/Del command 1608 * 1609 * Return: 0 for success. nonzero for failure. 1610 */ dp_update_mon_mac_filter(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint32_t cmd)1611 static QDF_STATUS dp_update_mon_mac_filter(struct cdp_soc_t *soc_hdl, 1612 uint8_t vdev_id, uint32_t cmd) 1613 { 1614 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 1615 struct dp_pdev *pdev; 1616 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 1617 DP_MOD_ID_CDP); 1618 struct dp_mon_pdev *mon_pdev; 1619 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1620 1621 if (!vdev) 1622 return status; 1623 1624 pdev = vdev->pdev; 1625 if (!pdev) { 1626 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 1627 return status; 1628 } 1629 1630 mon_pdev = pdev->monitor_pdev; 1631 if (cmd == DP_NAC_PARAM_ADD) { 1632 /* first neighbour added */ 1633 dp_mon_filter_set_reset_mon_mac_filter(pdev, true); 1634 status = dp_mon_filter_update(pdev); 1635 if (status != QDF_STATUS_SUCCESS) { 1636 dp_cdp_err("%pK: Mon mac filter set failed", soc); 1637 dp_mon_filter_set_reset_mon_mac_filter(pdev, false); 1638 } 1639 } else if (cmd == DP_NAC_PARAM_DEL) { 1640 /* last neighbour deleted */ 1641 dp_mon_filter_set_reset_mon_mac_filter(pdev, false); 1642 status = dp_mon_filter_update(pdev); 1643 if (status != QDF_STATUS_SUCCESS) 1644 dp_cdp_err("%pK: Mon mac filter reset failed", soc); 1645 } 1646 1647 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 1648 return status; 1649 } 1650 1651 1652 bool dp_enable_mon_reap_timer(struct cdp_soc_t * soc_hdl,enum cdp_mon_reap_source source,bool enable)1653 dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, 1654 enum cdp_mon_reap_source source, 1655 bool enable) 1656 { 1657 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 1658 1659 if (enable) 1660 return dp_monitor_reap_timer_start(soc, source); 1661 else 1662 return dp_monitor_reap_timer_stop(soc, source); 1663 } 1664 1665 #if defined(DP_CON_MON) 1666 #ifndef REMOVE_PKT_LOG dp_pkt_log_init(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1667 void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn) 1668 { 1669 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 1670 struct dp_pdev *handle = 1671 dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1672 struct dp_mon_pdev *mon_pdev; 1673 1674 if (!handle) { 1675 dp_mon_err("pdev handle is NULL"); 1676 return; 1677 } 1678 1679 mon_pdev = handle->monitor_pdev; 1680 1681 if (mon_pdev->pkt_log_init) { 1682 dp_mon_err("%pK: Packet log not initialized", soc); 1683 return; 1684 } 1685 1686 pktlog_sethandle(&mon_pdev->pl_dev, scn); 1687 pktlog_set_pdev_id(mon_pdev->pl_dev, pdev_id); 1688 pktlog_set_callback_regtype(PKTLOG_DEFAULT_CALLBACK_REGISTRATION); 1689 1690 if (pktlogmod_init(scn)) { 1691 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 1692 "%s: pktlogmod_init failed", __func__); 1693 mon_pdev->pkt_log_init = false; 1694 } else { 1695 mon_pdev->pkt_log_init = true; 1696 } 1697 } 1698 1699 /** 1700 * dp_pkt_log_con_service() - connect packet log service 1701 * @soc_hdl: Datapath soc handle 1702 * @pdev_id: id of data path pdev handle 1703 * @scn: device context 1704 * 1705 * Return: none 1706 */ dp_pkt_log_con_service(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1707 static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl, 1708 uint8_t pdev_id, void *scn) 1709 { 1710 dp_pkt_log_init(soc_hdl, pdev_id, scn); 1711 pktlog_htc_attach(); 1712 } 1713 1714 /** 1715 * dp_pkt_log_exit() - Wrapper API to cleanup pktlog info 1716 * @soc_hdl: Datapath soc handle 1717 * @pdev_id: id of data path pdev handle 1718 * 1719 * Return: none 1720 */ dp_pkt_log_exit(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1721 static void dp_pkt_log_exit(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 1722 { 1723 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 1724 struct dp_pdev *pdev = 1725 dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1726 1727 if (!pdev) { 1728 dp_err("pdev handle is NULL"); 1729 return; 1730 } 1731 1732 dp_pktlogmod_exit(pdev); 1733 } 1734 1735 #else dp_pkt_log_con_service(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1736 static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl, 1737 uint8_t pdev_id, void *scn) 1738 { 1739 } 1740 dp_pkt_log_exit(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1741 static void dp_pkt_log_exit(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 1742 { 1743 } 1744 #endif 1745 #endif 1746 dp_neighbour_peers_detach(struct dp_pdev * pdev)1747 void dp_neighbour_peers_detach(struct dp_pdev *pdev) 1748 { 1749 struct dp_neighbour_peer *peer = NULL; 1750 struct dp_neighbour_peer *temp_peer = NULL; 1751 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1752 1753 TAILQ_FOREACH_SAFE(peer, &mon_pdev->neighbour_peers_list, 1754 neighbour_peer_list_elem, temp_peer) { 1755 /* delete this peer from the list */ 1756 TAILQ_REMOVE(&mon_pdev->neighbour_peers_list, 1757 peer, neighbour_peer_list_elem); 1758 qdf_mem_free(peer); 1759 } 1760 1761 qdf_spinlock_destroy(&mon_pdev->neighbour_peer_mutex); 1762 } 1763 1764 #ifdef QCA_ENHANCED_STATS_SUPPORT 1765 /** 1766 * dp_mon_tx_enable_enhanced_stats() - Enable enhanced Tx stats 1767 * @pdev: Datapath pdev handle 1768 * 1769 * Return: void 1770 */ dp_mon_tx_enable_enhanced_stats(struct dp_pdev * pdev)1771 static void dp_mon_tx_enable_enhanced_stats(struct dp_pdev *pdev) 1772 { 1773 struct dp_soc *soc = pdev->soc; 1774 struct dp_mon_ops *mon_ops = NULL; 1775 1776 mon_ops = dp_mon_ops_get(soc); 1777 if (mon_ops && mon_ops->mon_tx_enable_enhanced_stats) 1778 mon_ops->mon_tx_enable_enhanced_stats(pdev); 1779 } 1780 1781 /** 1782 * dp_enable_enhanced_stats()- API to enable enhanced statistcs 1783 * @soc: DP_SOC handle 1784 * @pdev_id: id of DP_PDEV handle 1785 * 1786 * Return: QDF_STATUS 1787 */ 1788 QDF_STATUS dp_enable_enhanced_stats(struct cdp_soc_t * soc,uint8_t pdev_id)1789 dp_enable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id) 1790 { 1791 struct dp_pdev *pdev = NULL; 1792 QDF_STATUS status = QDF_STATUS_SUCCESS; 1793 struct dp_mon_pdev *mon_pdev; 1794 struct dp_soc *dp_soc = cdp_soc_t_to_dp_soc(soc); 1795 1796 pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 1797 pdev_id); 1798 1799 if (!pdev) 1800 return QDF_STATUS_E_FAILURE; 1801 1802 mon_pdev = pdev->monitor_pdev; 1803 1804 if (!mon_pdev) 1805 return QDF_STATUS_E_FAILURE; 1806 1807 if (mon_pdev->enhanced_stats_en == 0) 1808 dp_cal_client_timer_start(mon_pdev->cal_client_ctx); 1809 1810 mon_pdev->enhanced_stats_en = 1; 1811 pdev->enhanced_stats_en = 1; 1812 pdev->link_peer_stats = wlan_cfg_is_peer_link_stats_enabled( 1813 dp_soc->wlan_cfg_ctx); 1814 1815 dp_mon_filter_setup_enhanced_stats(pdev); 1816 status = dp_mon_filter_update(pdev); 1817 if (status != QDF_STATUS_SUCCESS) { 1818 dp_cdp_err("%pK: Failed to set enhanced mode filters", soc); 1819 dp_mon_filter_reset_enhanced_stats(pdev); 1820 dp_cal_client_timer_stop(mon_pdev->cal_client_ctx); 1821 mon_pdev->enhanced_stats_en = 0; 1822 pdev->enhanced_stats_en = 0; 1823 pdev->link_peer_stats = 0; 1824 return QDF_STATUS_E_FAILURE; 1825 } 1826 1827 dp_mon_tx_enable_enhanced_stats(pdev); 1828 1829 /* reset the tx fast path flag, as enhanced stats are enabled */ 1830 pdev->tx_fast_flag &= ~DP_TX_DESC_FLAG_SIMPLE; 1831 if (dp_soc->hw_txrx_stats_en) 1832 pdev->tx_fast_flag &= ~DP_TX_DESC_FLAG_FASTPATH_SIMPLE; 1833 1834 return QDF_STATUS_SUCCESS; 1835 } 1836 1837 /** 1838 * dp_mon_tx_disable_enhanced_stats() - Disable enhanced Tx stats 1839 * @pdev: Datapath pdev handle 1840 * 1841 * Return: void 1842 */ dp_mon_tx_disable_enhanced_stats(struct dp_pdev * pdev)1843 static void dp_mon_tx_disable_enhanced_stats(struct dp_pdev *pdev) 1844 { 1845 struct dp_soc *soc = pdev->soc; 1846 struct dp_mon_ops *mon_ops = NULL; 1847 1848 mon_ops = dp_mon_ops_get(soc); 1849 if (mon_ops && mon_ops->mon_tx_disable_enhanced_stats) 1850 mon_ops->mon_tx_disable_enhanced_stats(pdev); 1851 } 1852 1853 /** 1854 * dp_disable_enhanced_stats()- API to disable enhanced statistcs 1855 * 1856 * @soc: the soc handle 1857 * @pdev_id: pdev_id of pdev 1858 * 1859 * Return: QDF_STATUS 1860 */ 1861 QDF_STATUS dp_disable_enhanced_stats(struct cdp_soc_t * soc,uint8_t pdev_id)1862 dp_disable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id) 1863 { 1864 struct dp_pdev *pdev = 1865 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 1866 pdev_id); 1867 struct dp_soc *dp_soc = cdp_soc_t_to_dp_soc(soc); 1868 struct dp_mon_pdev *mon_pdev; 1869 1870 if (!pdev || !pdev->monitor_pdev) 1871 return QDF_STATUS_E_FAILURE; 1872 1873 mon_pdev = pdev->monitor_pdev; 1874 1875 if (mon_pdev->enhanced_stats_en == 1) 1876 dp_cal_client_timer_stop(mon_pdev->cal_client_ctx); 1877 1878 mon_pdev->enhanced_stats_en = 0; 1879 pdev->enhanced_stats_en = 0; 1880 pdev->link_peer_stats = 0; 1881 1882 dp_mon_tx_disable_enhanced_stats(pdev); 1883 1884 dp_mon_filter_reset_enhanced_stats(pdev); 1885 if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { 1886 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 1887 FL("Failed to reset enhanced mode filters")); 1888 } 1889 1890 /* set the tx fast path flag, as enhanced stats are disabled */ 1891 pdev->tx_fast_flag |= DP_TX_DESC_FLAG_SIMPLE; 1892 if (dp_soc->hw_txrx_stats_en) 1893 pdev->tx_fast_flag |= DP_TX_DESC_FLAG_FASTPATH_SIMPLE; 1894 1895 return QDF_STATUS_SUCCESS; 1896 } 1897 1898 #ifdef WDI_EVENT_ENABLE dp_peer_qos_stats_notify(struct dp_pdev * dp_pdev,struct cdp_rx_stats_ppdu_user * ppdu_user)1899 QDF_STATUS dp_peer_qos_stats_notify(struct dp_pdev *dp_pdev, 1900 struct cdp_rx_stats_ppdu_user *ppdu_user) 1901 { 1902 struct cdp_interface_peer_qos_stats qos_stats_intf = {0}; 1903 1904 if (qdf_unlikely(ppdu_user->peer_id == HTT_INVALID_PEER)) { 1905 dp_mon_warn("Invalid peer id: %u", ppdu_user->peer_id); 1906 return QDF_STATUS_E_FAILURE; 1907 } 1908 1909 qdf_mem_copy(qos_stats_intf.peer_mac, ppdu_user->mac_addr, 1910 QDF_MAC_ADDR_SIZE); 1911 qos_stats_intf.frame_control = ppdu_user->frame_control; 1912 qos_stats_intf.frame_control_info_valid = 1913 ppdu_user->frame_control_info_valid; 1914 qos_stats_intf.qos_control = ppdu_user->qos_control; 1915 qos_stats_intf.qos_control_info_valid = 1916 ppdu_user->qos_control_info_valid; 1917 qos_stats_intf.vdev_id = ppdu_user->vdev_id; 1918 dp_wdi_event_handler(WDI_EVENT_PEER_QOS_STATS, dp_pdev->soc, 1919 (void *)&qos_stats_intf, 0, 1920 WDI_NO_VAL, dp_pdev->pdev_id); 1921 1922 return QDF_STATUS_SUCCESS; 1923 } 1924 #else 1925 static inline QDF_STATUS dp_peer_qos_stats_notify(struct dp_pdev * dp_pdev,struct cdp_rx_stats_ppdu_user * ppdu_user)1926 dp_peer_qos_stats_notify(struct dp_pdev *dp_pdev, 1927 struct cdp_rx_stats_ppdu_user *ppdu_user) 1928 { 1929 return QDF_STATUS_SUCCESS; 1930 } 1931 #endif 1932 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 1933 1934 /** 1935 * dp_enable_peer_based_pktlog() - Set Flag for peer based filtering 1936 * for pktlog 1937 * @soc: cdp_soc handle 1938 * @pdev_id: id of dp pdev handle 1939 * @mac_addr: Peer mac address 1940 * @enb_dsb: Enable or disable peer based filtering 1941 * 1942 * Return: QDF_STATUS 1943 */ 1944 static int dp_enable_peer_based_pktlog(struct cdp_soc_t * soc,uint8_t pdev_id,uint8_t * mac_addr,uint8_t enb_dsb)1945 dp_enable_peer_based_pktlog(struct cdp_soc_t *soc, uint8_t pdev_id, 1946 uint8_t *mac_addr, uint8_t enb_dsb) 1947 { 1948 struct dp_peer *peer; 1949 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1950 struct dp_pdev *pdev = 1951 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 1952 pdev_id); 1953 struct dp_mon_pdev *mon_pdev; 1954 1955 if (!pdev) 1956 return QDF_STATUS_E_FAILURE; 1957 1958 mon_pdev = pdev->monitor_pdev; 1959 1960 peer = dp_peer_find_hash_find((struct dp_soc *)soc, mac_addr, 1961 0, DP_VDEV_ALL, DP_MOD_ID_CDP); 1962 1963 if (!peer) { 1964 dp_mon_err("Peer is NULL"); 1965 return QDF_STATUS_E_FAILURE; 1966 } 1967 1968 if (!IS_MLO_DP_MLD_PEER(peer) && peer->monitor_peer) { 1969 peer->monitor_peer->peer_based_pktlog_filter = enb_dsb; 1970 mon_pdev->dp_peer_based_pktlog = enb_dsb; 1971 status = QDF_STATUS_SUCCESS; 1972 } 1973 1974 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 1975 1976 return status; 1977 } 1978 1979 /** 1980 * dp_peer_update_pkt_capture_params() - Set Rx & Tx Capture flags for a peer 1981 * @soc: DP_SOC handle 1982 * @pdev_id: id of DP_PDEV handle 1983 * @is_rx_pkt_cap_enable: enable/disable Rx packet capture in monitor mode 1984 * @is_tx_pkt_cap_enable: enable/disable/delete/print 1985 * Tx packet capture in monitor mode 1986 * @peer_mac: MAC address for which the above need to be enabled/disabled 1987 * 1988 * Return: Success if Rx & Tx capture is enabled for peer, false otherwise 1989 */ 1990 #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) 1991 static QDF_STATUS dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,uint8_t pdev_id,bool is_rx_pkt_cap_enable,uint8_t is_tx_pkt_cap_enable,uint8_t * peer_mac)1992 dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc, 1993 uint8_t pdev_id, 1994 bool is_rx_pkt_cap_enable, 1995 uint8_t is_tx_pkt_cap_enable, 1996 uint8_t *peer_mac) 1997 { 1998 struct dp_peer *peer; 1999 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2000 struct dp_pdev *pdev = 2001 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 2002 pdev_id); 2003 if (!pdev) 2004 return QDF_STATUS_E_FAILURE; 2005 2006 peer = dp_peer_find_hash_find((struct dp_soc *)soc, 2007 peer_mac, 0, DP_VDEV_ALL, 2008 DP_MOD_ID_CDP); 2009 if (!peer) 2010 return QDF_STATUS_E_FAILURE; 2011 2012 /* we need to set tx pkt capture for non associated peer */ 2013 if (!IS_MLO_DP_MLD_PEER(peer)) { 2014 status = dp_monitor_tx_peer_filter(pdev, peer, 2015 is_tx_pkt_cap_enable, 2016 peer_mac); 2017 2018 status = dp_peer_set_rx_capture_enabled(pdev, peer, 2019 is_rx_pkt_cap_enable, 2020 peer_mac); 2021 } 2022 2023 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 2024 2025 return status; 2026 } 2027 #endif 2028 2029 #ifdef QCA_MCOPY_SUPPORT dp_mcopy_check_deliver(struct dp_pdev * pdev,uint16_t peer_id,uint32_t ppdu_id,uint8_t first_msdu)2030 QDF_STATUS dp_mcopy_check_deliver(struct dp_pdev *pdev, 2031 uint16_t peer_id, 2032 uint32_t ppdu_id, 2033 uint8_t first_msdu) 2034 { 2035 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 2036 2037 if (mon_pdev->mcopy_mode) { 2038 if (mon_pdev->mcopy_mode == M_COPY) { 2039 if ((mon_pdev->m_copy_id.tx_ppdu_id == ppdu_id) && 2040 (mon_pdev->m_copy_id.tx_peer_id == peer_id)) { 2041 return QDF_STATUS_E_INVAL; 2042 } 2043 } 2044 2045 if (!first_msdu) 2046 return QDF_STATUS_E_INVAL; 2047 2048 mon_pdev->m_copy_id.tx_ppdu_id = ppdu_id; 2049 mon_pdev->m_copy_id.tx_peer_id = peer_id; 2050 } 2051 2052 return QDF_STATUS_SUCCESS; 2053 } 2054 #endif 2055 2056 #ifdef WDI_EVENT_ENABLE 2057 #ifndef REMOVE_PKT_LOG dp_get_pldev(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)2058 static void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 2059 { 2060 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 2061 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 2062 2063 if (!pdev || !pdev->monitor_pdev) 2064 return NULL; 2065 2066 return pdev->monitor_pdev->pl_dev; 2067 } 2068 #else dp_get_pldev(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)2069 static void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 2070 { 2071 return NULL; 2072 } 2073 #endif 2074 #endif 2075 dp_rx_populate_cbf_hdr(struct dp_soc * soc,uint32_t mac_id,uint32_t event,qdf_nbuf_t mpdu,uint32_t msdu_timestamp)2076 QDF_STATUS dp_rx_populate_cbf_hdr(struct dp_soc *soc, 2077 uint32_t mac_id, 2078 uint32_t event, 2079 qdf_nbuf_t mpdu, 2080 uint32_t msdu_timestamp) 2081 { 2082 uint32_t data_size, hdr_size, ppdu_id, align4byte; 2083 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 2084 uint32_t *msg_word; 2085 2086 if (!pdev) 2087 return QDF_STATUS_E_INVAL; 2088 2089 ppdu_id = pdev->monitor_pdev->ppdu_info.com_info.ppdu_id; 2090 2091 hdr_size = HTT_T2H_PPDU_STATS_IND_HDR_SIZE 2092 + qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload); 2093 2094 data_size = qdf_nbuf_len(mpdu); 2095 2096 qdf_nbuf_push_head(mpdu, hdr_size); 2097 2098 msg_word = (uint32_t *)qdf_nbuf_data(mpdu); 2099 /* 2100 * Populate the PPDU Stats Indication header 2101 */ 2102 HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_T2H_MSG_TYPE_PPDU_STATS_IND); 2103 HTT_T2H_PPDU_STATS_MAC_ID_SET(*msg_word, mac_id); 2104 HTT_T2H_PPDU_STATS_PDEV_ID_SET(*msg_word, pdev->pdev_id); 2105 align4byte = ((data_size + 2106 qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload) 2107 + 3) >> 2) << 2; 2108 HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_SET(*msg_word, align4byte); 2109 msg_word++; 2110 HTT_T2H_PPDU_STATS_PPDU_ID_SET(*msg_word, ppdu_id); 2111 msg_word++; 2112 2113 *msg_word = msdu_timestamp; 2114 msg_word++; 2115 /* Skip reserved field */ 2116 msg_word++; 2117 /* 2118 * Populate MGMT_CTRL Payload TLV first 2119 */ 2120 HTT_STATS_TLV_TAG_SET(*msg_word, 2121 HTT_PPDU_STATS_RX_MGMTCTRL_PAYLOAD_TLV); 2122 2123 align4byte = ((data_size - sizeof(htt_tlv_hdr_t) + 2124 qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload) 2125 + 3) >> 2) << 2; 2126 HTT_STATS_TLV_LENGTH_SET(*msg_word, align4byte); 2127 msg_word++; 2128 2129 HTT_PPDU_STATS_RX_MGMTCTRL_TLV_FRAME_LENGTH_SET( 2130 *msg_word, data_size); 2131 msg_word++; 2132 2133 dp_wdi_event_handler(event, soc, (void *)mpdu, 2134 HTT_INVALID_PEER, WDI_NO_VAL, pdev->pdev_id); 2135 2136 qdf_nbuf_pull_head(mpdu, hdr_size); 2137 2138 return QDF_STATUS_SUCCESS; 2139 } 2140 2141 #ifdef ATH_SUPPORT_EXT_STAT 2142 #ifdef WLAN_CONFIG_TELEMETRY_AGENT 2143 /** 2144 * dp_pdev_clear_link_airtime_stats() - clear airtime stats for given pdev 2145 * @pdev: DP PDEV handle 2146 */ 2147 static inline dp_pdev_clear_link_airtime_stats(struct dp_pdev * pdev)2148 void dp_pdev_clear_link_airtime_stats(struct dp_pdev *pdev) 2149 { 2150 uint8_t ac; 2151 2152 for (ac = 0; ac < WME_AC_MAX; ac++) 2153 pdev->stats.telemetry_stats.link_airtime[ac] = 0; 2154 } 2155 2156 /** 2157 * dp_peer_update_telemetry_stats() - update peer telemetry stats 2158 * @soc: Datapath soc 2159 * @peer: Datapath peer 2160 * @arg: argument to callback function 2161 */ 2162 static inline dp_peer_update_telemetry_stats(struct dp_soc * soc,struct dp_peer * peer,void * arg)2163 void dp_peer_update_telemetry_stats(struct dp_soc *soc, 2164 struct dp_peer *peer, 2165 void *arg) 2166 { 2167 struct dp_pdev *pdev; 2168 struct dp_vdev *vdev; 2169 struct dp_mon_peer *mon_peer = NULL; 2170 uint8_t ac; 2171 uint64_t current_time = qdf_get_log_timestamp(); 2172 uint32_t remn, time_diff, usage; 2173 uint16_t usage_per_sec; 2174 struct dp_mon_peer_airtime_stats *stat_airtime; 2175 struct dp_mon_peer_airtime_consumption *consump; 2176 2177 vdev = peer->vdev; 2178 if (!vdev) 2179 return; 2180 2181 pdev = vdev->pdev; 2182 if (!pdev) 2183 return; 2184 2185 mon_peer = peer->monitor_peer; 2186 if (qdf_likely(mon_peer)) { 2187 stat_airtime = &mon_peer->stats.airtime_stats; 2188 time_diff = (uint32_t)(current_time - 2189 stat_airtime->last_update_time); 2190 for (ac = 0; ac < WME_AC_MAX; ac++) { 2191 consump = &stat_airtime->tx_airtime_consumption[ac]; 2192 usage = consump->consumption; 2193 usage_per_sec = (uint8_t)qdf_do_div((uint64_t) 2194 (usage * 100), time_diff); 2195 remn = qdf_do_div_rem((uint64_t) 2196 (usage * 100), time_diff); 2197 if (remn < time_diff / 2) { 2198 if (remn && usage_per_sec == 0) 2199 usage_per_sec++; 2200 } else { 2201 if (usage_per_sec < 100) 2202 usage_per_sec++; 2203 } 2204 consump->avg_consumption_per_sec = usage_per_sec; 2205 /* Store each peer airtime consumption in pdev 2206 * link_airtime to calculate pdev's total airtime 2207 * consumption 2208 */ 2209 DP_STATS_INC(pdev, 2210 telemetry_stats.link_airtime[ac], 2211 consump->consumption); 2212 consump->consumption = 0; 2213 2214 consump = &stat_airtime->rx_airtime_consumption[ac]; 2215 usage = consump->consumption; 2216 usage_per_sec = (uint8_t)qdf_do_div((uint64_t) 2217 (usage * 100), time_diff); 2218 remn = qdf_do_div_rem((uint64_t) 2219 (usage * 100), time_diff); 2220 if (remn < time_diff / 2) { 2221 if (remn && usage_per_sec == 0) 2222 usage_per_sec++; 2223 } else { 2224 if (usage_per_sec < 100) 2225 usage_per_sec++; 2226 } 2227 consump->avg_consumption_per_sec = usage_per_sec; 2228 /* Store each peer airtime consumption in pdev 2229 * link_airtime to calculate pdev's total airtime 2230 * consumption 2231 */ 2232 DP_STATS_INC(pdev, 2233 telemetry_stats.link_airtime[ac], 2234 consump->consumption); 2235 consump->consumption = 0; 2236 } 2237 stat_airtime->last_update_time = current_time; 2238 } 2239 } 2240 dp_pdev_update_telemetry_airtime_stats(struct cdp_soc_t * soc,uint8_t pdev_id)2241 QDF_STATUS dp_pdev_update_telemetry_airtime_stats(struct cdp_soc_t *soc, 2242 uint8_t pdev_id) 2243 { 2244 struct dp_pdev *pdev = 2245 dp_get_pdev_from_soc_pdev_id_wifi3(cdp_soc_t_to_dp_soc(soc), 2246 pdev_id); 2247 if (!pdev) 2248 return QDF_STATUS_E_FAILURE; 2249 2250 /* Clear current airtime stats as the below API will increment the stats 2251 * for all peers on top of current value 2252 */ 2253 dp_pdev_clear_link_airtime_stats(pdev); 2254 dp_pdev_iterate_peer(pdev, dp_peer_update_telemetry_stats, NULL, 2255 DP_MOD_ID_CDP); 2256 2257 return QDF_STATUS_SUCCESS; 2258 } 2259 #endif 2260 2261 /** 2262 * dp_peer_cal_clients_stats_update() - update peer stats on cal client timer 2263 * @soc: Datapath SOC 2264 * @peer: Datapath peer 2265 * @arg: argument to iter function 2266 */ 2267 #ifdef IPA_OFFLOAD 2268 static void dp_peer_cal_clients_stats_update(struct dp_soc * soc,struct dp_peer * peer,void * arg)2269 dp_peer_cal_clients_stats_update(struct dp_soc *soc, 2270 struct dp_peer *peer, 2271 void *arg) 2272 { 2273 struct cdp_calibr_stats_intf peer_stats_intf = {0}; 2274 struct dp_peer *tgt_peer = NULL; 2275 struct dp_txrx_peer *txrx_peer = NULL; 2276 2277 if (!dp_peer_is_primary_link_peer(peer)) 2278 return; 2279 2280 tgt_peer = dp_get_tgt_peer_from_peer(peer); 2281 if (!tgt_peer || !(tgt_peer->txrx_peer)) 2282 return; 2283 2284 txrx_peer = tgt_peer->txrx_peer; 2285 peer_stats_intf.to_stack = txrx_peer->to_stack; 2286 peer_stats_intf.tx_success = 2287 peer->monitor_peer->stats.tx.tx_ucast_success; 2288 peer_stats_intf.tx_ucast = 2289 peer->monitor_peer->stats.tx.tx_ucast_total; 2290 2291 dp_cal_client_update_peer_stats_wifi3(&peer_stats_intf, 2292 &tgt_peer->stats); 2293 dp_peer_get_rxtid_stats_ipa(peer, dp_peer_update_tid_stats_from_reo); 2294 } 2295 #else 2296 static void dp_peer_cal_clients_stats_update(struct dp_soc * soc,struct dp_peer * peer,void * arg)2297 dp_peer_cal_clients_stats_update(struct dp_soc *soc, 2298 struct dp_peer *peer, 2299 void *arg) 2300 { 2301 struct cdp_calibr_stats_intf peer_stats_intf = {0}; 2302 struct dp_peer *tgt_peer = NULL; 2303 struct dp_txrx_peer *txrx_peer = NULL; 2304 uint8_t inx = 0; 2305 uint8_t stats_arr_size; 2306 2307 if (!dp_peer_is_primary_link_peer(peer)) 2308 return; 2309 2310 tgt_peer = dp_get_tgt_peer_from_peer(peer); 2311 if (!tgt_peer || !(tgt_peer->txrx_peer)) 2312 return; 2313 2314 txrx_peer = tgt_peer->txrx_peer; 2315 peer_stats_intf.to_stack = txrx_peer->to_stack; 2316 stats_arr_size = txrx_peer->stats_arr_size; 2317 2318 for (inx = 0; inx < stats_arr_size; inx++) { 2319 peer_stats_intf.tx_success.num += 2320 txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.num; 2321 peer_stats_intf.tx_success.bytes += 2322 txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes; 2323 peer_stats_intf.tx_ucast.num += 2324 txrx_peer->stats[inx].per_pkt_stats.tx.ucast.num; 2325 peer_stats_intf.tx_ucast.bytes += 2326 txrx_peer->stats[inx].per_pkt_stats.tx.ucast.bytes; 2327 } 2328 2329 dp_cal_client_update_peer_stats_wifi3(&peer_stats_intf, 2330 &tgt_peer->stats); 2331 } 2332 #endif 2333 2334 /** 2335 * dp_iterate_update_peer_list() - update peer stats on cal client timer 2336 * @pdev_hdl: pdev handle 2337 */ dp_iterate_update_peer_list(struct cdp_pdev * pdev_hdl)2338 static void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl) 2339 { 2340 struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; 2341 2342 dp_pdev_iterate_peer(pdev, dp_peer_cal_clients_stats_update, NULL, 2343 DP_MOD_ID_CDP); 2344 } 2345 #else dp_iterate_update_peer_list(struct cdp_pdev * pdev_hdl)2346 static void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl) 2347 { 2348 } 2349 #endif 2350 2351 #ifdef ATH_SUPPORT_NAC dp_set_filter_neigh_peers(struct dp_pdev * pdev,bool val)2352 int dp_set_filter_neigh_peers(struct dp_pdev *pdev, 2353 bool val) 2354 { 2355 /* Enable/Disable smart mesh filtering. This flag will be checked 2356 * during rx processing to check if packets are from NAC clients. 2357 */ 2358 pdev->monitor_pdev->filter_neighbour_peers = val; 2359 return 0; 2360 } 2361 #endif /* ATH_SUPPORT_NAC */ 2362 2363 #ifdef WLAN_ATF_ENABLE dp_set_atf_stats_enable(struct dp_pdev * pdev,bool value)2364 void dp_set_atf_stats_enable(struct dp_pdev *pdev, bool value) 2365 { 2366 if (!pdev) { 2367 dp_cdp_err("pdev is NULL"); 2368 return; 2369 } 2370 2371 pdev->monitor_pdev->dp_atf_stats_enable = value; 2372 } 2373 #endif 2374 2375 #ifdef QCA_ENHANCED_STATS_SUPPORT 2376 /** 2377 * dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv() - Process 2378 * htt_ppdu_stats_tx_mgmtctrl_payload_tlv 2379 * @pdev: DP PDEV handle 2380 * @tag_buf: buffer containing the htt_ppdu_stats_tx_mgmtctrl_payload_tlv 2381 * @ppdu_id: PPDU Id 2382 * 2383 * Return: QDF_STATUS_SUCCESS if nbuf has to be freed in caller 2384 */ 2385 static QDF_STATUS dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev * pdev,qdf_nbuf_t tag_buf,uint32_t ppdu_id)2386 dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev *pdev, 2387 qdf_nbuf_t tag_buf, 2388 uint32_t ppdu_id) 2389 { 2390 uint32_t *nbuf_ptr; 2391 uint8_t trim_size; 2392 size_t head_size; 2393 struct cdp_tx_mgmt_comp_info *ptr_mgmt_comp_info; 2394 uint32_t *msg_word; 2395 uint32_t tsf_hdr; 2396 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 2397 2398 if ((!mon_pdev->tx_sniffer_enable) && (!mon_pdev->mcopy_mode) && 2399 (!mon_pdev->bpr_enable) && (!mon_pdev->tx_capture_enabled)) 2400 return QDF_STATUS_SUCCESS; 2401 2402 /* 2403 * get timestamp from htt_t2h_ppdu_stats_ind_hdr_t 2404 */ 2405 msg_word = (uint32_t *)qdf_nbuf_data(tag_buf); 2406 msg_word = msg_word + 2; 2407 tsf_hdr = *msg_word; 2408 2409 trim_size = ((mon_pdev->mgmtctrl_frm_info.mgmt_buf + 2410 HTT_MGMT_CTRL_TLV_HDR_RESERVERD_LEN) - 2411 qdf_nbuf_data(tag_buf)); 2412 2413 if (!qdf_nbuf_pull_head(tag_buf, trim_size)) 2414 return QDF_STATUS_SUCCESS; 2415 2416 qdf_nbuf_trim_tail(tag_buf, qdf_nbuf_len(tag_buf) - 2417 mon_pdev->mgmtctrl_frm_info.mgmt_buf_len); 2418 2419 if (mon_pdev->tx_capture_enabled) { 2420 head_size = sizeof(struct cdp_tx_mgmt_comp_info); 2421 if (qdf_unlikely(qdf_nbuf_headroom(tag_buf) < head_size)) { 2422 qdf_err("Fail to get headroom h_sz %zu h_avail %d\n", 2423 head_size, qdf_nbuf_headroom(tag_buf)); 2424 qdf_assert_always(0); 2425 return QDF_STATUS_E_NOMEM; 2426 } 2427 ptr_mgmt_comp_info = (struct cdp_tx_mgmt_comp_info *) 2428 qdf_nbuf_push_head(tag_buf, head_size); 2429 qdf_assert_always(ptr_mgmt_comp_info); 2430 ptr_mgmt_comp_info->ppdu_id = ppdu_id; 2431 ptr_mgmt_comp_info->is_sgen_pkt = true; 2432 ptr_mgmt_comp_info->tx_tsf = tsf_hdr; 2433 } else { 2434 head_size = sizeof(ppdu_id); 2435 nbuf_ptr = (uint32_t *)qdf_nbuf_push_head(tag_buf, head_size); 2436 *nbuf_ptr = ppdu_id; 2437 } 2438 if (mon_pdev->bpr_enable) { 2439 dp_wdi_event_handler(WDI_EVENT_TX_BEACON, pdev->soc, 2440 tag_buf, HTT_INVALID_PEER, 2441 WDI_NO_VAL, pdev->pdev_id); 2442 } 2443 2444 dp_deliver_mgmt_frm(pdev, tag_buf); 2445 2446 return QDF_STATUS_E_ALREADY; 2447 } 2448 2449 int dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap)2450 dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap) 2451 { 2452 if (bitmap == (HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_64)) 2453 return HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_64; 2454 else if (bitmap == (HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_256)) 2455 return HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_256; 2456 2457 return 0; 2458 } 2459 2460 /** 2461 * dp_peer_copy_delay_stats() - copy ppdu stats to peer delayed stats. 2462 * @peer: Datapath peer handle 2463 * @ppdu: User PPDU Descriptor 2464 * @cur_ppdu_id: PPDU_ID 2465 * 2466 * Return: None 2467 * 2468 * on Tx data frame, we may get delayed ba set 2469 * in htt_ppdu_stats_user_common_tlv. which mean we get Block Ack(BA) after we 2470 * request Block Ack Request(BAR). Successful msdu is received only after Block 2471 * Ack. To populate peer stats we need successful msdu(data frame). 2472 * So we hold the Tx data stats on delayed_ba for stats update. 2473 */ 2474 static void dp_peer_copy_delay_stats(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu,uint32_t cur_ppdu_id)2475 dp_peer_copy_delay_stats(struct dp_peer *peer, 2476 struct cdp_tx_completion_ppdu_user *ppdu, 2477 uint32_t cur_ppdu_id) 2478 { 2479 struct dp_pdev *pdev; 2480 struct dp_vdev *vdev; 2481 struct dp_mon_peer *mon_peer = peer->monitor_peer; 2482 2483 if (mon_peer->last_delayed_ba) { 2484 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 2485 "BA not yet recv for prev delayed ppdu[%d] - cur ppdu[%d]", 2486 mon_peer->last_delayed_ba_ppduid, cur_ppdu_id); 2487 vdev = peer->vdev; 2488 if (vdev) { 2489 pdev = vdev->pdev; 2490 pdev->stats.cdp_delayed_ba_not_recev++; 2491 } 2492 } 2493 2494 mon_peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size; 2495 mon_peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc; 2496 mon_peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re; 2497 mon_peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf; 2498 mon_peer->delayed_ba_ppdu_stats.bw = ppdu->bw; 2499 mon_peer->delayed_ba_ppdu_stats.nss = ppdu->nss; 2500 mon_peer->delayed_ba_ppdu_stats.gi = ppdu->gi; 2501 mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; 2502 mon_peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc; 2503 mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; 2504 mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast = 2505 ppdu->mpdu_tried_ucast; 2506 mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast = 2507 ppdu->mpdu_tried_mcast; 2508 mon_peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl; 2509 mon_peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl; 2510 mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; 2511 2512 mon_peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start; 2513 mon_peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones; 2514 mon_peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast; 2515 2516 mon_peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos; 2517 mon_peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id; 2518 2519 mon_peer->last_delayed_ba = true; 2520 2521 ppdu->debug_copied = true; 2522 } 2523 2524 /** 2525 * dp_peer_copy_stats_to_bar() - copy delayed stats to ppdu stats. 2526 * @peer: Datapath peer handle 2527 * @ppdu: PPDU Descriptor 2528 * 2529 * Return: None 2530 * 2531 * For Tx BAR, PPDU stats TLV include Block Ack info. PPDU info 2532 * from Tx BAR frame not required to populate peer stats. 2533 * But we need successful MPDU and MSDU to update previous 2534 * transmitted Tx data frame. Overwrite ppdu stats with the previous 2535 * stored ppdu stats. 2536 */ 2537 static void dp_peer_copy_stats_to_bar(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu)2538 dp_peer_copy_stats_to_bar(struct dp_peer *peer, 2539 struct cdp_tx_completion_ppdu_user *ppdu) 2540 { 2541 struct dp_mon_peer *mon_peer = peer->monitor_peer; 2542 2543 ppdu->ltf_size = mon_peer->delayed_ba_ppdu_stats.ltf_size; 2544 ppdu->stbc = mon_peer->delayed_ba_ppdu_stats.stbc; 2545 ppdu->he_re = mon_peer->delayed_ba_ppdu_stats.he_re; 2546 ppdu->txbf = mon_peer->delayed_ba_ppdu_stats.txbf; 2547 ppdu->bw = mon_peer->delayed_ba_ppdu_stats.bw; 2548 ppdu->nss = mon_peer->delayed_ba_ppdu_stats.nss; 2549 ppdu->gi = mon_peer->delayed_ba_ppdu_stats.gi; 2550 ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm; 2551 ppdu->ldpc = mon_peer->delayed_ba_ppdu_stats.ldpc; 2552 ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm; 2553 ppdu->mpdu_tried_ucast = 2554 mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast; 2555 ppdu->mpdu_tried_mcast = 2556 mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast; 2557 ppdu->frame_ctrl = mon_peer->delayed_ba_ppdu_stats.frame_ctrl; 2558 ppdu->qos_ctrl = mon_peer->delayed_ba_ppdu_stats.qos_ctrl; 2559 ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm; 2560 2561 ppdu->ru_start = mon_peer->delayed_ba_ppdu_stats.ru_start; 2562 ppdu->ru_tones = mon_peer->delayed_ba_ppdu_stats.ru_tones; 2563 ppdu->is_mcast = mon_peer->delayed_ba_ppdu_stats.is_mcast; 2564 2565 ppdu->user_pos = mon_peer->delayed_ba_ppdu_stats.user_pos; 2566 ppdu->mu_group_id = mon_peer->delayed_ba_ppdu_stats.mu_group_id; 2567 2568 mon_peer->last_delayed_ba = false; 2569 2570 ppdu->debug_copied = true; 2571 } 2572 2573 /** 2574 * dp_tx_rate_stats_update() - Update rate per-peer statistics 2575 * @peer: Datapath peer handle 2576 * @ppdu: PPDU Descriptor 2577 * 2578 * Return: None 2579 */ 2580 static void dp_tx_rate_stats_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu)2581 dp_tx_rate_stats_update(struct dp_peer *peer, 2582 struct cdp_tx_completion_ppdu_user *ppdu) 2583 { 2584 uint32_t ratekbps = 0; 2585 uint64_t ppdu_tx_rate = 0; 2586 uint32_t rix; 2587 uint16_t ratecode = 0; 2588 struct dp_mon_peer *mon_peer = NULL; 2589 2590 if (!peer || !ppdu) 2591 return; 2592 2593 if (ppdu->completion_status != HTT_PPDU_STATS_USER_STATUS_OK) 2594 return; 2595 2596 mon_peer = peer->monitor_peer; 2597 if (!mon_peer) 2598 return; 2599 2600 ratekbps = dp_getrateindex(ppdu->gi, 2601 ppdu->mcs, 2602 ppdu->nss, 2603 ppdu->preamble, 2604 ppdu->bw, 2605 ppdu->punc_mode, 2606 &rix, 2607 &ratecode); 2608 2609 if (!ratekbps) 2610 return; 2611 2612 /* Calculate goodput in non-training period 2613 * In training period, don't do anything as 2614 * pending pkt is send as goodput. 2615 */ 2616 if ((!peer->bss_peer) && (!ppdu->sa_is_training)) { 2617 ppdu->sa_goodput = ((ratekbps / CDP_NUM_KB_IN_MB) * 2618 (CDP_PERCENT_MACRO - ppdu->current_rate_per)); 2619 } 2620 ppdu->rix = rix; 2621 ppdu->tx_ratekbps = ratekbps; 2622 ppdu->tx_ratecode = ratecode; 2623 DP_STATS_UPD(mon_peer, tx.tx_rate, ratekbps); 2624 mon_peer->stats.tx.avg_tx_rate = 2625 dp_ath_rate_lpf(mon_peer->stats.tx.avg_tx_rate, ratekbps); 2626 ppdu_tx_rate = dp_ath_rate_out(mon_peer->stats.tx.avg_tx_rate); 2627 DP_STATS_UPD(mon_peer, tx.rnd_avg_tx_rate, ppdu_tx_rate); 2628 2629 mon_peer->stats.tx.bw_info = ppdu->bw; 2630 mon_peer->stats.tx.gi_info = ppdu->gi; 2631 mon_peer->stats.tx.nss_info = ppdu->nss; 2632 mon_peer->stats.tx.mcs_info = ppdu->mcs; 2633 mon_peer->stats.tx.preamble_info = ppdu->preamble; 2634 if (peer->vdev) { 2635 /* 2636 * In STA mode: 2637 * We get ucast stats as BSS peer stats. 2638 * 2639 * In AP mode: 2640 * We get mcast stats as BSS peer stats. 2641 * We get ucast stats as assoc peer stats. 2642 */ 2643 if (peer->vdev->opmode == wlan_op_mode_ap && peer->bss_peer) { 2644 peer->vdev->stats.tx.mcast_last_tx_rate = ratekbps; 2645 peer->vdev->stats.tx.mcast_last_tx_rate_mcs = ppdu->mcs; 2646 } else { 2647 peer->vdev->stats.tx.last_tx_rate = ratekbps; 2648 peer->vdev->stats.tx.last_tx_rate_mcs = ppdu->mcs; 2649 } 2650 } 2651 } 2652 2653 #if defined(FEATURE_PERPKT_INFO) && defined(WDI_EVENT_ENABLE) dp_send_stats_event(struct dp_pdev * pdev,struct dp_peer * peer,uint16_t peer_id)2654 void dp_send_stats_event(struct dp_pdev *pdev, struct dp_peer *peer, 2655 uint16_t peer_id) 2656 { 2657 struct cdp_interface_peer_stats peer_stats_intf = {0}; 2658 struct dp_mon_peer *mon_peer = peer->monitor_peer; 2659 struct dp_txrx_peer *txrx_peer = NULL; 2660 uint8_t inx = 0; 2661 uint8_t stats_arr_size; 2662 2663 if (qdf_unlikely(!mon_peer)) 2664 return; 2665 2666 mon_peer->stats.rx.rx_snr_measured_time = qdf_system_ticks(); 2667 peer_stats_intf.rx_avg_snr = mon_peer->stats.rx.avg_snr; 2668 2669 txrx_peer = dp_get_txrx_peer(peer); 2670 if (qdf_likely(txrx_peer)) { 2671 stats_arr_size = txrx_peer->stats_arr_size; 2672 peer_stats_intf.rx_byte_count = txrx_peer->to_stack.bytes; 2673 for (inx = 0; inx < stats_arr_size; inx++) 2674 peer_stats_intf.tx_byte_count += 2675 txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes; 2676 } 2677 2678 dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, 2679 &peer_stats_intf, peer_id, 2680 UPDATE_PEER_STATS, pdev->pdev_id); 2681 } 2682 #endif 2683 2684 #ifdef WLAN_FEATURE_11BE 2685 /** 2686 * dp_get_ru_index_frm_ru_tones() - get ru index 2687 * @ru_tones: ru tones 2688 * 2689 * Return: ru index 2690 */ dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)2691 static inline enum cdp_ru_index dp_get_ru_index_frm_ru_tones(uint16_t ru_tones) 2692 { 2693 enum cdp_ru_index ru_index; 2694 2695 switch (ru_tones) { 2696 case RU_26: 2697 ru_index = RU_26_INDEX; 2698 break; 2699 case RU_52: 2700 ru_index = RU_52_INDEX; 2701 break; 2702 case RU_52_26: 2703 ru_index = RU_52_26_INDEX; 2704 break; 2705 case RU_106: 2706 ru_index = RU_106_INDEX; 2707 break; 2708 case RU_106_26: 2709 ru_index = RU_106_26_INDEX; 2710 break; 2711 case RU_242: 2712 ru_index = RU_242_INDEX; 2713 break; 2714 case RU_484: 2715 ru_index = RU_484_INDEX; 2716 break; 2717 case RU_484_242: 2718 ru_index = RU_484_242_INDEX; 2719 break; 2720 case RU_996: 2721 ru_index = RU_996_INDEX; 2722 break; 2723 case RU_996_484: 2724 ru_index = RU_996_484_INDEX; 2725 break; 2726 case RU_996_484_242: 2727 ru_index = RU_996_484_242_INDEX; 2728 break; 2729 case RU_2X996: 2730 ru_index = RU_2X996_INDEX; 2731 break; 2732 case RU_2X996_484: 2733 ru_index = RU_2X996_484_INDEX; 2734 break; 2735 case RU_3X996: 2736 ru_index = RU_3X996_INDEX; 2737 break; 2738 case RU_3X996_484: 2739 ru_index = RU_2X996_484_INDEX; 2740 break; 2741 case RU_4X996: 2742 ru_index = RU_4X996_INDEX; 2743 break; 2744 default: 2745 ru_index = RU_INDEX_MAX; 2746 break; 2747 } 2748 2749 return ru_index; 2750 } 2751 2752 /** 2753 * dp_mon_get_ru_width_from_ru_size() - get ru_width from ru_size enum 2754 * @ru_size: HTT ru_size enum 2755 * 2756 * Return: ru_width of uint32_t type 2757 */ dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)2758 static uint32_t dp_mon_get_ru_width_from_ru_size(uint16_t ru_size) 2759 { 2760 uint32_t width = 0; 2761 2762 switch (ru_size) { 2763 case HTT_PPDU_STATS_RU_26: 2764 width = RU_26; 2765 break; 2766 case HTT_PPDU_STATS_RU_52: 2767 width = RU_52; 2768 break; 2769 case HTT_PPDU_STATS_RU_52_26: 2770 width = RU_52_26; 2771 break; 2772 case HTT_PPDU_STATS_RU_106: 2773 width = RU_106; 2774 break; 2775 case HTT_PPDU_STATS_RU_106_26: 2776 width = RU_106_26; 2777 break; 2778 case HTT_PPDU_STATS_RU_242: 2779 width = RU_242; 2780 break; 2781 case HTT_PPDU_STATS_RU_484: 2782 width = RU_484; 2783 break; 2784 case HTT_PPDU_STATS_RU_484_242: 2785 width = RU_484_242; 2786 break; 2787 case HTT_PPDU_STATS_RU_996: 2788 width = RU_996; 2789 break; 2790 case HTT_PPDU_STATS_RU_996_484: 2791 width = RU_996_484; 2792 break; 2793 case HTT_PPDU_STATS_RU_996_484_242: 2794 width = RU_996_484_242; 2795 break; 2796 case HTT_PPDU_STATS_RU_996x2: 2797 width = RU_2X996; 2798 break; 2799 case HTT_PPDU_STATS_RU_996x2_484: 2800 width = RU_2X996_484; 2801 break; 2802 case HTT_PPDU_STATS_RU_996x3: 2803 width = RU_3X996; 2804 break; 2805 case HTT_PPDU_STATS_RU_996x3_484: 2806 width = RU_3X996_484; 2807 break; 2808 case HTT_PPDU_STATS_RU_996x4: 2809 width = RU_4X996; 2810 break; 2811 default: 2812 dp_mon_debug("Unsupported ru_size: %d rcvd", ru_size); 2813 } 2814 2815 return width; 2816 } 2817 #else dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)2818 static inline enum cdp_ru_index dp_get_ru_index_frm_ru_tones(uint16_t ru_tones) 2819 { 2820 enum cdp_ru_index ru_index; 2821 2822 switch (ru_tones) { 2823 case RU_26: 2824 ru_index = RU_26_INDEX; 2825 break; 2826 case RU_52: 2827 ru_index = RU_52_INDEX; 2828 break; 2829 case RU_106: 2830 ru_index = RU_106_INDEX; 2831 break; 2832 case RU_242: 2833 ru_index = RU_242_INDEX; 2834 break; 2835 case RU_484: 2836 ru_index = RU_484_INDEX; 2837 break; 2838 case RU_996: 2839 ru_index = RU_996_INDEX; 2840 break; 2841 default: 2842 ru_index = RU_INDEX_MAX; 2843 break; 2844 } 2845 2846 return ru_index; 2847 } 2848 dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)2849 static uint32_t dp_mon_get_ru_width_from_ru_size(uint16_t ru_size) 2850 { 2851 uint32_t width = 0; 2852 2853 switch (ru_size) { 2854 case HTT_PPDU_STATS_RU_26: 2855 width = RU_26; 2856 break; 2857 case HTT_PPDU_STATS_RU_52: 2858 width = RU_52; 2859 break; 2860 case HTT_PPDU_STATS_RU_106: 2861 width = RU_106; 2862 break; 2863 case HTT_PPDU_STATS_RU_242: 2864 width = RU_242; 2865 break; 2866 case HTT_PPDU_STATS_RU_484: 2867 width = RU_484; 2868 break; 2869 case HTT_PPDU_STATS_RU_996: 2870 width = RU_996; 2871 break; 2872 default: 2873 dp_mon_debug("Unsupported ru_size: %d rcvd", ru_size); 2874 } 2875 2876 return width; 2877 } 2878 #endif 2879 2880 #ifdef WLAN_CONFIG_TELEMETRY_AGENT 2881 /** 2882 * dp_pdev_telemetry_stats_update() - Update pdev telemetry stats 2883 * @pdev: Datapath pdev handle 2884 * @ppdu: PPDU Descriptor 2885 * 2886 * Return: None 2887 */ 2888 static void dp_pdev_telemetry_stats_update(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu_user * ppdu)2889 dp_pdev_telemetry_stats_update( 2890 struct dp_pdev *pdev, 2891 struct cdp_tx_completion_ppdu_user *ppdu) 2892 { 2893 uint16_t mpdu_tried; 2894 uint16_t mpdu_failed; 2895 uint16_t num_mpdu; 2896 uint8_t ac = 0; 2897 2898 num_mpdu = ppdu->mpdu_success; 2899 mpdu_tried = ppdu->mpdu_tried_ucast + ppdu->mpdu_tried_mcast; 2900 mpdu_failed = mpdu_tried - num_mpdu; 2901 2902 ac = TID_TO_WME_AC(ppdu->tid); 2903 2904 DP_STATS_INC(pdev, telemetry_stats.tx_mpdu_failed[ac], 2905 mpdu_failed); 2906 2907 DP_STATS_INC(pdev, telemetry_stats.tx_mpdu_total[ac], 2908 mpdu_tried); 2909 } 2910 2911 /* 2912 * dp_ppdu_desc_get_txmode() - Get TX mode 2913 * @ppdu: PPDU Descriptor 2914 * 2915 * Return: None 2916 */ 2917 static inline dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu * ppdu)2918 void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu) 2919 { 2920 uint16_t frame_type = ppdu->htt_frame_type; 2921 2922 ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN; 2923 2924 if (ppdu->frame_type == CDP_PPDU_FTYPE_CTRL && 2925 (frame_type != HTT_STATS_FTYPE_SGEN_MU_TRIG && 2926 frame_type != HTT_STATS_FTYPE_SGEN_BE_MU_TRIG)) 2927 return; 2928 2929 if (frame_type == HTT_STATS_FTYPE_SGEN_MU_BAR || 2930 frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_BAR) { 2931 ppdu->txmode = TX_MODE_UL_OFDMA_MU_BAR_TRIGGER; 2932 ppdu->txmode_type = TX_MODE_TYPE_UL; 2933 2934 return; 2935 } 2936 2937 switch (ppdu->htt_seq_type) { 2938 case HTT_SEQTYPE_SU: 2939 if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_SU) { 2940 ppdu->txmode = TX_MODE_DL_SU_DATA; 2941 ppdu->txmode_type = TX_MODE_TYPE_DL; 2942 } 2943 break; 2944 case HTT_SEQTYPE_MU_OFDMA: 2945 case HTT_SEQTYPE_BE_MU_OFDMA: 2946 if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) { 2947 ppdu->txmode = TX_MODE_DL_OFDMA_DATA; 2948 ppdu->txmode_type = TX_MODE_TYPE_DL; 2949 } 2950 break; 2951 case HTT_SEQTYPE_AC_MU_MIMO: 2952 case HTT_SEQTYPE_AX_MU_MIMO: 2953 case HTT_SEQTYPE_BE_MU_MIMO: 2954 if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) { 2955 ppdu->txmode = TX_MODE_DL_MUMIMO_DATA; 2956 ppdu->txmode_type = TX_MODE_TYPE_DL; 2957 } 2958 break; 2959 case HTT_SEQTYPE_UL_MU_OFDMA_TRIG: 2960 case HTT_SEQTYPE_BE_UL_MU_OFDMA_TRIG: 2961 if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG || 2962 frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) { 2963 ppdu->txmode = TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA; 2964 ppdu->txmode_type = TX_MODE_TYPE_UL; 2965 } 2966 break; 2967 case HTT_SEQTYPE_UL_MU_MIMO_TRIG: 2968 case HTT_SEQTYPE_BE_UL_MU_MIMO_TRIG: 2969 if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG || 2970 frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) { 2971 ppdu->txmode = TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA; 2972 ppdu->txmode_type = TX_MODE_TYPE_UL; 2973 } 2974 break; 2975 default: 2976 ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN; 2977 break; 2978 } 2979 } 2980 2981 /* 2982 * dp_pdev_update_deter_stats() - Update pdev deterministic stats 2983 * @pdev: Datapath pdev handle 2984 * @ppdu: PPDU Descriptor 2985 * 2986 * Return: None 2987 */ 2988 static inline void dp_pdev_update_deter_stats(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu * ppdu)2989 dp_pdev_update_deter_stats(struct dp_pdev *pdev, 2990 struct cdp_tx_completion_ppdu *ppdu) 2991 { 2992 uint32_t user_idx; 2993 2994 if (!pdev || !ppdu) 2995 return; 2996 2997 if (ppdu->txmode_type == TX_MODE_TYPE_UNKNOWN) 2998 return; 2999 3000 if (ppdu->backoff_ac_valid) { 3001 if (ppdu->backoff_ac >= WME_AC_MAX) { 3002 dp_mon_err("backoff_ac %d exceed max limit", 3003 ppdu->backoff_ac); 3004 return; 3005 } 3006 DP_STATS_UPD(pdev, 3007 deter_stats.ch_access_delay[ppdu->backoff_ac], 3008 ppdu->ch_access_delay); 3009 } 3010 3011 if (ppdu->txmode_type == TX_MODE_TYPE_DL) { 3012 DP_STATS_INC(pdev, 3013 deter_stats.dl_mode_cnt[ppdu->txmode], 3014 1); 3015 if (!ppdu->num_users) { 3016 dp_mon_err("dl users is %d", ppdu->num_users); 3017 return; 3018 } 3019 user_idx = ppdu->num_users - 1; 3020 switch (ppdu->txmode) { 3021 case TX_MODE_DL_OFDMA_DATA: 3022 DP_STATS_INC(pdev, 3023 deter_stats.dl_ofdma_usr[user_idx], 3024 1); 3025 break; 3026 case TX_MODE_DL_MUMIMO_DATA: 3027 if (user_idx >= CDP_MU_MAX_MIMO_USERS) { 3028 dp_mon_err("dl mimo users %d exceed max limit", 3029 ppdu->num_users); 3030 return; 3031 } 3032 DP_STATS_INC(pdev, 3033 deter_stats.dl_mimo_usr[user_idx], 3034 1); 3035 break; 3036 } 3037 } else { 3038 DP_STATS_INC(pdev, 3039 deter_stats.ul_mode_cnt[ppdu->txmode], 3040 1); 3041 3042 if (!ppdu->num_ul_users) { 3043 dp_mon_err("dl users is %d", ppdu->num_ul_users); 3044 return; 3045 } 3046 user_idx = ppdu->num_ul_users - 1; 3047 switch (ppdu->txmode) { 3048 case TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA: 3049 DP_STATS_INC(pdev, 3050 deter_stats.ul_ofdma_usr[user_idx], 3051 1); 3052 break; 3053 case TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA: 3054 if (user_idx >= CDP_MU_MAX_MIMO_USERS) { 3055 dp_mon_err("ul mimo users %d exceed max limit", 3056 ppdu->num_ul_users); 3057 return; 3058 } 3059 DP_STATS_INC(pdev, 3060 deter_stats.ul_mimo_usr[user_idx], 3061 1); 3062 break; 3063 } 3064 if (ppdu->num_ul_user_resp_valid) { 3065 if (ppdu->num_ul_user_resp) { 3066 DP_STATS_INC(pdev, 3067 deter_stats.ts[ppdu->txmode].trigger_success, 3068 1); 3069 } else { 3070 DP_STATS_INC(pdev, 3071 deter_stats.ts[ppdu->txmode].trigger_fail, 3072 1); 3073 } 3074 } 3075 } 3076 } 3077 3078 /* 3079 * dp_ppdu_desc_get_msduq() - Get msduq index from bitmap 3080 * @ppdu: PPDU Descriptor 3081 * @msduq_index: MSDUQ index 3082 * 3083 * Return: None 3084 */ 3085 static inline void dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap,uint32_t * msduq_index)3086 dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index) 3087 { 3088 if ((msduq_bitmap & BIT(HTT_MSDUQ_INDEX_NON_UDP)) || 3089 (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_UDP))) { 3090 *msduq_index = MSDUQ_INDEX_DEFAULT; 3091 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_0)) { 3092 *msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_0; 3093 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_1)) { 3094 *msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_1; 3095 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_0)) { 3096 *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_0; 3097 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_1)) { 3098 *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_1; 3099 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_2)) { 3100 *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_2; 3101 } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_3)) { 3102 *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_3; 3103 } else { 3104 *msduq_index = MSDUQ_INDEX_MAX; 3105 } 3106 } 3107 3108 /* 3109 * dp_ppdu_desc_user_deter_stats_update() - Update per-peer deterministic stats 3110 * @pdev: Datapath pdev handle 3111 * @peer: Datapath peer handle 3112 * @ppdu_desc: PPDU Descriptor 3113 * @user: PPDU Descriptor per user 3114 * 3115 * Return: None 3116 */ 3117 static void dp_ppdu_desc_user_deter_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)3118 dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev, 3119 struct dp_peer *peer, 3120 struct cdp_tx_completion_ppdu *ppdu_desc, 3121 struct cdp_tx_completion_ppdu_user *user) 3122 { 3123 struct dp_mon_peer *mon_peer = NULL; 3124 uint64_t avg_tx_rate = 0; 3125 uint32_t ratekbps = 0; 3126 uint32_t rix; 3127 uint32_t msduq; 3128 uint16_t ratecode = 0; 3129 uint8_t txmode; 3130 uint8_t tid; 3131 3132 if (!pdev || !ppdu_desc || !user || !peer) 3133 return; 3134 3135 mon_peer = peer->monitor_peer; 3136 if (qdf_unlikely(!mon_peer)) 3137 return; 3138 3139 if (ppdu_desc->txmode_type == TX_MODE_TYPE_UNKNOWN) 3140 return; 3141 3142 if (ppdu_desc->txmode_type == TX_MODE_TYPE_UL && 3143 (ppdu_desc->txmode != TX_MODE_UL_OFDMA_MU_BAR_TRIGGER)) { 3144 if (user->tid < CDP_UL_TRIG_BK_TID || 3145 user->tid > CDP_UL_TRIG_VO_TID) 3146 return; 3147 3148 user->tid = UL_TRIGGER_TID_TO_DATA_TID(user->tid); 3149 } 3150 3151 if (user->tid >= CDP_DATA_TID_MAX) 3152 return; 3153 3154 ratekbps = dp_getrateindex(user->gi, 3155 user->mcs, 3156 user->nss, 3157 user->preamble, 3158 user->bw, 3159 user->punc_mode, 3160 &rix, 3161 &ratecode); 3162 3163 if (!ratekbps) 3164 return; 3165 3166 avg_tx_rate = mon_peer->stats.deter_stats.avg_tx_rate; 3167 avg_tx_rate = dp_ath_rate_lpf(avg_tx_rate, 3168 ratekbps); 3169 DP_STATS_UPD(mon_peer, 3170 deter_stats.avg_tx_rate, 3171 avg_tx_rate); 3172 3173 txmode = ppdu_desc->txmode; 3174 tid = user->tid; 3175 3176 if (ppdu_desc->txmode_type == TX_MODE_TYPE_DL) { 3177 dp_ppdu_desc_get_msduq(user->msduq_bitmap, &msduq); 3178 if (msduq == MSDUQ_INDEX_MAX) 3179 return; 3180 3181 DP_STATS_INC(mon_peer, 3182 deter_stats.deter[tid].dl_det[msduq][txmode].mode_cnt, 3183 1); 3184 3185 DP_STATS_UPD(mon_peer, 3186 deter_stats.deter[tid].dl_det[msduq][txmode].avg_rate, 3187 avg_tx_rate); 3188 } else { 3189 DP_STATS_INC(mon_peer, 3190 deter_stats.deter[tid].ul_det[txmode].mode_cnt, 3191 1); 3192 3193 DP_STATS_UPD(mon_peer, 3194 deter_stats.deter[tid].ul_det[txmode].avg_rate, 3195 avg_tx_rate); 3196 if (!user->completion_status) { 3197 DP_STATS_INC(mon_peer, 3198 deter_stats.deter[tid].ul_det[txmode].trigger_success, 3199 1); 3200 } else { 3201 DP_STATS_INC(mon_peer, 3202 deter_stats.deter[tid].ul_det[txmode].trigger_fail, 3203 1); 3204 } 3205 } 3206 } 3207 #else 3208 static inline dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu * ppdu)3209 void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu) 3210 { 3211 } 3212 3213 static inline void dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap,uint32_t * msduq_index)3214 dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index) 3215 { 3216 } 3217 3218 static void dp_ppdu_desc_user_deter_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)3219 dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev, 3220 struct dp_peer *peer, 3221 struct cdp_tx_completion_ppdu *ppdu_desc, 3222 struct cdp_tx_completion_ppdu_user *user) 3223 { 3224 } 3225 3226 static inline void dp_pdev_telemetry_stats_update(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu_user * ppdu)3227 dp_pdev_telemetry_stats_update( 3228 struct dp_pdev *pdev, 3229 struct cdp_tx_completion_ppdu_user *ppdu) 3230 { } 3231 3232 static inline void dp_pdev_update_deter_stats(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu * ppdu)3233 dp_pdev_update_deter_stats(struct dp_pdev *pdev, 3234 struct cdp_tx_completion_ppdu *ppdu) 3235 { } 3236 #endif 3237 3238 /** 3239 * dp_tx_stats_update() - Update per-peer statistics 3240 * @pdev: Datapath pdev handle 3241 * @peer: Datapath peer handle 3242 * @ppdu: PPDU Descriptor per user 3243 * @ppdu_desc: PPDU Descriptor 3244 * 3245 * Return: None 3246 */ 3247 static void dp_tx_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu,struct cdp_tx_completion_ppdu * ppdu_desc)3248 dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, 3249 struct cdp_tx_completion_ppdu_user *ppdu, 3250 struct cdp_tx_completion_ppdu *ppdu_desc) 3251 { 3252 uint8_t preamble, mcs, res_mcs = 0; 3253 uint16_t num_msdu; 3254 uint16_t num_mpdu; 3255 uint16_t mpdu_tried; 3256 uint16_t mpdu_failed; 3257 struct dp_mon_ops *mon_ops; 3258 enum cdp_ru_index ru_index; 3259 struct dp_mon_peer *mon_peer = NULL; 3260 uint32_t ratekbps = 0; 3261 uint64_t tx_byte_count; 3262 uint8_t idx = 0; 3263 bool is_preamble_valid = true; 3264 3265 preamble = ppdu->preamble; 3266 mcs = ppdu->mcs; 3267 num_msdu = ppdu->num_msdu; 3268 num_mpdu = ppdu->mpdu_success; 3269 mpdu_tried = ppdu->mpdu_tried_ucast + ppdu->mpdu_tried_mcast; 3270 mpdu_failed = mpdu_tried - num_mpdu; 3271 tx_byte_count = ppdu->success_bytes; 3272 3273 /* If the peer statistics are already processed as part of 3274 * per-MSDU completion handler, do not process these again in per-PPDU 3275 * indications 3276 */ 3277 if (pdev->soc->process_tx_status) 3278 return; 3279 3280 mon_peer = peer->monitor_peer; 3281 if (!mon_peer) 3282 return; 3283 3284 if (!ppdu->is_mcast) { 3285 DP_STATS_INC(mon_peer, tx.tx_ucast_total.num, num_msdu); 3286 DP_STATS_INC(mon_peer, tx.tx_ucast_total.bytes, 3287 tx_byte_count); 3288 } 3289 3290 if (ppdu->completion_status != HTT_PPDU_STATS_USER_STATUS_OK) { 3291 /* 3292 * All failed mpdu will be retried, so incrementing 3293 * retries mpdu based on mpdu failed. Even for 3294 * ack failure i.e for long retries we get 3295 * mpdu failed equal mpdu tried. 3296 */ 3297 DP_STATS_INC(mon_peer, tx.retries, mpdu_failed); 3298 dp_pdev_telemetry_stats_update(pdev, ppdu); 3299 return; 3300 } 3301 3302 if (ppdu->is_ppdu_cookie_valid) 3303 DP_STATS_INC(mon_peer, tx.num_ppdu_cookie_valid, 1); 3304 3305 if (ppdu->mu_group_id <= MAX_MU_GROUP_ID && 3306 ppdu->ppdu_type != HTT_PPDU_STATS_PPDU_TYPE_SU) { 3307 if (qdf_unlikely(ppdu->mu_group_id && 3308 !(ppdu->mu_group_id & (MAX_MU_GROUP_ID - 1)))) 3309 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 3310 "mu_group_id out of bound!!\n"); 3311 else 3312 DP_STATS_UPD(mon_peer, tx.mu_group_id[ppdu->mu_group_id], 3313 (ppdu->user_pos + 1)); 3314 } 3315 3316 if (ppdu->ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA || 3317 ppdu->ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA) { 3318 DP_STATS_UPD(mon_peer, tx.ru_tones, ppdu->ru_tones); 3319 DP_STATS_UPD(mon_peer, tx.ru_start, ppdu->ru_start); 3320 ru_index = dp_get_ru_index_frm_ru_tones(ppdu->ru_tones); 3321 if (ru_index != RU_INDEX_MAX) { 3322 DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].num_msdu, 3323 num_msdu); 3324 DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].num_mpdu, 3325 num_mpdu); 3326 DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].mpdu_tried, 3327 mpdu_tried); 3328 } 3329 } 3330 3331 /* 3332 * All failed mpdu will be retried, so incrementing 3333 * retries mpdu based on mpdu failed. Even for 3334 * ack failure i.e for long retries we get 3335 * mpdu failed equal mpdu tried. 3336 */ 3337 DP_STATS_INC(mon_peer, tx.retries, mpdu_failed); 3338 3339 DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].num_msdu, 3340 num_msdu); 3341 DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].num_mpdu, 3342 num_mpdu); 3343 DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].mpdu_tried, 3344 mpdu_tried); 3345 3346 DP_STATS_INC(mon_peer, tx.sgi_count[ppdu->gi], num_msdu); 3347 DP_STATS_INC(mon_peer, tx.bw[ppdu->bw], num_msdu); 3348 DP_STATS_INC(mon_peer, tx.nss[ppdu->nss], num_msdu); 3349 if (ppdu->tid < CDP_DATA_TID_MAX) { 3350 DP_STATS_INC(mon_peer, tx.wme_ac_type[TID_TO_WME_AC(ppdu->tid)], 3351 num_msdu); 3352 DP_STATS_INC(mon_peer, 3353 tx.wme_ac_type_bytes[TID_TO_WME_AC(ppdu->tid)], 3354 tx_byte_count); 3355 } 3356 3357 DP_STATS_INCC(mon_peer, tx.stbc, num_msdu, ppdu->stbc); 3358 DP_STATS_INCC(mon_peer, tx.ldpc, num_msdu, ppdu->ldpc); 3359 if (!(ppdu->is_mcast) && ppdu->ack_rssi_valid) 3360 DP_STATS_UPD(mon_peer, tx.last_ack_rssi, ppdu_desc->ack_rssi); 3361 3362 if (!ppdu->is_mcast) { 3363 DP_STATS_INC(mon_peer, tx.tx_ucast_success.num, num_msdu); 3364 DP_STATS_INC(mon_peer, tx.tx_ucast_success.bytes, 3365 tx_byte_count); 3366 } 3367 3368 switch (preamble) { 3369 case DOT11_A: 3370 res_mcs = (mcs < MAX_MCS_11A) ? mcs : (MAX_MCS - 1); 3371 break; 3372 case DOT11_B: 3373 res_mcs = (mcs < MAX_MCS_11B) ? mcs : (MAX_MCS - 1); 3374 break; 3375 case DOT11_N: 3376 res_mcs = (mcs < MAX_MCS_11N) ? mcs : (MAX_MCS - 1); 3377 break; 3378 case DOT11_AC: 3379 res_mcs = (mcs < MAX_MCS_11AC) ? mcs : (MAX_MCS - 1); 3380 break; 3381 case DOT11_AX: 3382 res_mcs = (mcs < MAX_MCS_11AX) ? mcs : (MAX_MCS - 1); 3383 break; 3384 default: 3385 is_preamble_valid = false; 3386 } 3387 3388 DP_STATS_INCC(mon_peer, 3389 tx.pkt_type[preamble].mcs_count[res_mcs], num_msdu, 3390 is_preamble_valid); 3391 DP_STATS_INCC(mon_peer, tx.ampdu_cnt, num_mpdu, ppdu->is_ampdu); 3392 DP_STATS_INCC(mon_peer, tx.non_ampdu_cnt, num_mpdu, !(ppdu->is_ampdu)); 3393 DP_STATS_INCC(mon_peer, tx.pream_punct_cnt, 1, ppdu->pream_punct); 3394 DP_STATS_INC(mon_peer, tx.tx_ppdus, 1); 3395 DP_STATS_INC(mon_peer, tx.tx_mpdus_success, num_mpdu); 3396 DP_STATS_INC(mon_peer, tx.tx_mpdus_tried, mpdu_tried); 3397 3398 for (idx = 0; idx < CDP_RSSI_CHAIN_LEN; idx++) 3399 DP_STATS_UPD(mon_peer, tx.rssi_chain[idx], ppdu->rssi_chain[idx]); 3400 3401 mon_ops = dp_mon_ops_get(pdev->soc); 3402 if (mon_ops && mon_ops->mon_tx_stats_update) 3403 mon_ops->mon_tx_stats_update(mon_peer, ppdu); 3404 3405 if (!ppdu->fixed_rate_used) 3406 dp_tx_rate_stats_update(peer, ppdu); 3407 3408 dp_pdev_telemetry_stats_update(pdev, ppdu); 3409 3410 dp_peer_stats_notify(pdev, peer); 3411 3412 ratekbps = mon_peer->stats.tx.tx_rate; 3413 DP_STATS_UPD(mon_peer, tx.last_tx_rate, ratekbps); 3414 3415 dp_send_stats_event(pdev, peer, ppdu->peer_id); 3416 } 3417 3418 /** 3419 * dp_get_ppdu_info_user_index() - Find and allocate a per-user 3420 * descriptor for a PPDU, if a new peer id arrives in a PPDU 3421 * @pdev: DP pdev handle 3422 * @peer_id: peer unique identifier 3423 * @ppdu_info: per ppdu tlv structure 3424 * 3425 * Return: user index to be populated 3426 */ dp_get_ppdu_info_user_index(struct dp_pdev * pdev,uint16_t peer_id,struct ppdu_info * ppdu_info)3427 static uint8_t dp_get_ppdu_info_user_index(struct dp_pdev *pdev, 3428 uint16_t peer_id, 3429 struct ppdu_info *ppdu_info) 3430 { 3431 uint8_t user_index = 0; 3432 struct cdp_tx_completion_ppdu *ppdu_desc; 3433 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3434 3435 ppdu_desc = 3436 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3437 3438 while ((user_index + 1) <= ppdu_info->last_user) { 3439 ppdu_user_desc = &ppdu_desc->user[user_index]; 3440 if (ppdu_user_desc->peer_id != peer_id) { 3441 user_index++; 3442 continue; 3443 } else { 3444 /* Max users possible is 8 so user array index should 3445 * not exceed 7 3446 */ 3447 qdf_assert_always(user_index <= (ppdu_desc->max_users - 1)); 3448 return user_index; 3449 } 3450 } 3451 3452 ppdu_info->last_user++; 3453 /* Max users possible is 8 so last user should not exceed 8 */ 3454 qdf_assert_always(ppdu_info->last_user <= ppdu_desc->max_users); 3455 return ppdu_info->last_user - 1; 3456 } 3457 3458 /** 3459 * dp_process_ppdu_stats_common_tlv() - Process htt_ppdu_stats_common_tlv 3460 * @pdev: DP pdev handle 3461 * @tag_buf: buffer containing the tlv htt_ppdu_stats_common_tlv 3462 * @ppdu_info: per ppdu tlv structure 3463 * 3464 * Return: void 3465 */ 3466 static void dp_process_ppdu_stats_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3467 dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev, 3468 uint32_t *tag_buf, 3469 struct ppdu_info *ppdu_info) 3470 { 3471 uint16_t frame_type; 3472 uint16_t frame_ctrl; 3473 uint16_t freq; 3474 struct dp_soc *soc = NULL; 3475 struct cdp_tx_completion_ppdu *ppdu_desc = NULL; 3476 uint64_t ppdu_start_timestamp; 3477 uint32_t eval_start_timestamp; 3478 uint32_t *start_tag_buf; 3479 uint32_t *ts_tag_buf; 3480 3481 start_tag_buf = tag_buf; 3482 ppdu_desc = 3483 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3484 3485 ppdu_desc->ppdu_id = ppdu_info->ppdu_id; 3486 3487 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RING_ID_SCH_CMD_ID); 3488 ppdu_info->sched_cmdid = 3489 HTT_PPDU_STATS_COMMON_TLV_SCH_CMDID_GET(*tag_buf); 3490 ppdu_desc->num_users = 3491 HTT_PPDU_STATS_COMMON_TLV_NUM_USERS_GET(*tag_buf); 3492 3493 qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); 3494 3495 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(QTYPE_FRM_TYPE); 3496 frame_type = HTT_PPDU_STATS_COMMON_TLV_FRM_TYPE_GET(*tag_buf); 3497 ppdu_desc->htt_frame_type = frame_type; 3498 3499 ppdu_desc->htt_seq_type = 3500 HTT_PPDU_STATS_COMMON_TLV_PPDU_SEQ_TYPE_GET(*tag_buf); 3501 3502 frame_ctrl = ppdu_desc->frame_ctrl; 3503 3504 ppdu_desc->bar_ppdu_id = ppdu_info->ppdu_id; 3505 3506 switch (frame_type) { 3507 case HTT_STATS_FTYPE_TIDQ_DATA_SU: 3508 case HTT_STATS_FTYPE_TIDQ_DATA_MU: 3509 case HTT_STATS_FTYPE_SGEN_QOS_NULL: 3510 /* 3511 * for management packet, frame type come as DATA_SU 3512 * need to check frame_ctrl before setting frame_type 3513 */ 3514 if (HTT_GET_FRAME_CTRL_TYPE(frame_ctrl) <= FRAME_CTRL_TYPE_CTRL) 3515 ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL; 3516 else 3517 ppdu_desc->frame_type = CDP_PPDU_FTYPE_DATA; 3518 break; 3519 case HTT_STATS_FTYPE_SGEN_MU_BAR: 3520 case HTT_STATS_FTYPE_SGEN_BAR: 3521 case HTT_STATS_FTYPE_SGEN_BE_MU_BAR: 3522 ppdu_desc->frame_type = CDP_PPDU_FTYPE_BAR; 3523 break; 3524 default: 3525 ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL; 3526 break; 3527 } 3528 3529 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(FES_DUR_US); 3530 ppdu_desc->tx_duration = *tag_buf; 3531 3532 tag_buf = start_tag_buf + 3533 HTT_GET_STATS_CMN_INDEX(SCH_EVAL_START_TSTMP_L32_US); 3534 eval_start_timestamp = *tag_buf; 3535 3536 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_L32_US); 3537 ppdu_desc->ppdu_start_timestamp = *tag_buf; 3538 3539 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(CHAN_MHZ_PHY_MODE); 3540 freq = HTT_PPDU_STATS_COMMON_TLV_CHAN_MHZ_GET(*tag_buf); 3541 if (freq != ppdu_desc->channel) { 3542 soc = pdev->soc; 3543 ppdu_desc->channel = freq; 3544 pdev->operating_channel.freq = freq; 3545 if (soc && soc->cdp_soc.ol_ops->freq_to_channel) 3546 pdev->operating_channel.num = 3547 soc->cdp_soc.ol_ops->freq_to_channel(soc->ctrl_psoc, 3548 pdev->pdev_id, 3549 freq); 3550 3551 if (soc && soc->cdp_soc.ol_ops->freq_to_band) 3552 pdev->operating_channel.band = 3553 soc->cdp_soc.ol_ops->freq_to_band(soc->ctrl_psoc, 3554 pdev->pdev_id, 3555 freq); 3556 } 3557 3558 ppdu_desc->phy_mode = HTT_PPDU_STATS_COMMON_TLV_PHY_MODE_GET(*tag_buf); 3559 3560 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RESV_NUM_UL_BEAM); 3561 ppdu_desc->phy_ppdu_tx_time_us = 3562 HTT_PPDU_STATS_COMMON_TLV_PHY_PPDU_TX_TIME_US_GET(*tag_buf); 3563 ppdu_desc->beam_change = 3564 HTT_PPDU_STATS_COMMON_TLV_BEAM_CHANGE_GET(*tag_buf); 3565 ppdu_desc->doppler = 3566 HTT_PPDU_STATS_COMMON_TLV_DOPPLER_INDICATION_GET(*tag_buf); 3567 ppdu_desc->spatial_reuse = 3568 HTT_PPDU_STATS_COMMON_TLV_SPATIAL_REUSE_GET(*tag_buf); 3569 ppdu_desc->num_ul_users = 3570 HTT_PPDU_STATS_COMMON_TLV_NUM_UL_EXPECTED_USERS_GET(*tag_buf); 3571 3572 dp_tx_capture_htt_frame_counter(pdev, frame_type); 3573 3574 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_U32_US); 3575 ppdu_start_timestamp = *tag_buf; 3576 ppdu_desc->ppdu_start_timestamp |= ((ppdu_start_timestamp << 3577 HTT_SHIFT_UPPER_TIMESTAMP) & 3578 HTT_MASK_UPPER_TIMESTAMP); 3579 3580 ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp + 3581 ppdu_desc->tx_duration; 3582 /* Ack time stamp is same as end time stamp*/ 3583 ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp; 3584 3585 ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp + 3586 ppdu_desc->tx_duration; 3587 3588 ppdu_desc->bar_ppdu_start_timestamp = ppdu_desc->ppdu_start_timestamp; 3589 ppdu_desc->bar_ppdu_end_timestamp = ppdu_desc->ppdu_end_timestamp; 3590 ppdu_desc->bar_tx_duration = ppdu_desc->tx_duration; 3591 3592 /* Ack time stamp is same as end time stamp*/ 3593 ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp; 3594 3595 tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(BSSCOLOR_OBSS_PSR); 3596 ppdu_desc->bss_color = 3597 HTT_PPDU_STATS_COMMON_TLV_BSS_COLOR_ID_GET(*tag_buf); 3598 3599 ppdu_desc->backoff_ac_valid = 3600 HTT_PPDU_STATS_COMMON_TLV_BACKOFF_AC_VALID_GET(*tag_buf); 3601 if (ppdu_desc->backoff_ac_valid) { 3602 ppdu_desc->backoff_ac = 3603 HTT_PPDU_STATS_COMMON_TLV_BACKOFF_AC_GET(*tag_buf); 3604 ts_tag_buf = start_tag_buf + 3605 HTT_GET_STATS_CMN_INDEX(SCH_EVAL_START_TSTMP_L32_US); 3606 eval_start_timestamp = *ts_tag_buf; 3607 3608 ts_tag_buf = start_tag_buf + 3609 HTT_GET_STATS_CMN_INDEX(START_TSTMP_L32_US); 3610 ppdu_desc->ch_access_delay = 3611 *ts_tag_buf - eval_start_timestamp; 3612 } 3613 ppdu_desc->num_ul_user_resp_valid = 3614 HTT_PPDU_STATS_COMMON_TLV_NUM_UL_USER_RESPONSES_VALID_GET(*tag_buf); 3615 if (ppdu_desc->num_ul_user_resp_valid) 3616 ppdu_desc->num_ul_user_resp = 3617 HTT_PPDU_STATS_COMMON_TLV_NUM_UL_USER_RESPONSES_GET(*tag_buf); 3618 } 3619 3620 /** 3621 * dp_process_ppdu_stats_user_common_tlv() - Process ppdu_stats_user_common 3622 * @pdev: DP PDEV handle 3623 * @tag_buf: buffer containing the tlv htt_ppdu_stats_user_common_tlv 3624 * @ppdu_info: per ppdu tlv structure 3625 * 3626 * Return: void 3627 */ dp_process_ppdu_stats_user_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3628 static void dp_process_ppdu_stats_user_common_tlv( 3629 struct dp_pdev *pdev, uint32_t *tag_buf, 3630 struct ppdu_info *ppdu_info) 3631 { 3632 uint16_t peer_id; 3633 struct cdp_tx_completion_ppdu *ppdu_desc; 3634 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3635 uint8_t curr_user_index = 0; 3636 struct dp_peer *peer; 3637 struct dp_vdev *vdev; 3638 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 3639 3640 ppdu_desc = 3641 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3642 3643 tag_buf++; 3644 peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf); 3645 3646 curr_user_index = 3647 dp_get_ppdu_info_user_index(pdev, 3648 peer_id, ppdu_info); 3649 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 3650 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 3651 3652 ppdu_desc->vdev_id = 3653 HTT_PPDU_STATS_USER_COMMON_TLV_VAP_ID_GET(*tag_buf); 3654 3655 ppdu_user_desc->peer_id = peer_id; 3656 3657 tag_buf++; 3658 3659 if (HTT_PPDU_STATS_USER_COMMON_TLV_DELAYED_BA_GET(*tag_buf)) { 3660 ppdu_user_desc->delayed_ba = 1; 3661 ppdu_desc->delayed_ba = 1; 3662 } 3663 3664 if (HTT_PPDU_STATS_USER_COMMON_TLV_MCAST_GET(*tag_buf)) { 3665 ppdu_user_desc->is_mcast = true; 3666 ppdu_user_desc->mpdu_tried_mcast = 3667 HTT_PPDU_STATS_USER_COMMON_TLV_MPDUS_TRIED_GET(*tag_buf); 3668 ppdu_user_desc->num_mpdu = ppdu_user_desc->mpdu_tried_mcast; 3669 } else { 3670 ppdu_user_desc->mpdu_tried_ucast = 3671 HTT_PPDU_STATS_USER_COMMON_TLV_MPDUS_TRIED_GET(*tag_buf); 3672 } 3673 3674 ppdu_user_desc->is_seq_num_valid = 3675 HTT_PPDU_STATS_USER_COMMON_TLV_IS_SQNUM_VALID_IN_BUFFER_GET(*tag_buf); 3676 tag_buf++; 3677 3678 ppdu_user_desc->qos_ctrl = 3679 HTT_PPDU_STATS_USER_COMMON_TLV_QOS_CTRL_GET(*tag_buf); 3680 ppdu_user_desc->frame_ctrl = 3681 HTT_PPDU_STATS_USER_COMMON_TLV_FRAME_CTRL_GET(*tag_buf); 3682 ppdu_desc->frame_ctrl = ppdu_user_desc->frame_ctrl; 3683 3684 if (ppdu_user_desc->delayed_ba) 3685 ppdu_user_desc->mpdu_success = 0; 3686 3687 tag_buf += 3; 3688 3689 if (HTT_PPDU_STATS_IS_OPAQUE_VALID_GET(*tag_buf)) { 3690 ppdu_user_desc->ppdu_cookie = 3691 HTT_PPDU_STATS_HOST_OPAQUE_COOKIE_GET(*tag_buf); 3692 ppdu_user_desc->is_ppdu_cookie_valid = 1; 3693 } 3694 3695 /* returning earlier causes other feilds unpopulated */ 3696 if (peer_id == DP_SCAN_PEER_ID) { 3697 vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id, 3698 DP_MOD_ID_TX_PPDU_STATS); 3699 if (!vdev) 3700 return; 3701 qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw, 3702 QDF_MAC_ADDR_SIZE); 3703 dp_vdev_unref_delete(pdev->soc, vdev, DP_MOD_ID_TX_PPDU_STATS); 3704 } else { 3705 peer = dp_peer_get_ref_by_id(pdev->soc, peer_id, 3706 DP_MOD_ID_TX_PPDU_STATS); 3707 if (!peer) { 3708 /* 3709 * fw sends peer_id which is about to removed but 3710 * it was already removed in host. 3711 * eg: for disassoc, fw send ppdu stats 3712 * with peer id equal to previously associated 3713 * peer's peer_id but it was removed 3714 */ 3715 vdev = dp_vdev_get_ref_by_id(pdev->soc, 3716 ppdu_desc->vdev_id, 3717 DP_MOD_ID_TX_PPDU_STATS); 3718 if (!vdev) 3719 return; 3720 qdf_mem_copy(ppdu_user_desc->mac_addr, 3721 vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE); 3722 dp_vdev_unref_delete(pdev->soc, vdev, 3723 DP_MOD_ID_TX_PPDU_STATS); 3724 return; 3725 } 3726 qdf_mem_copy(ppdu_user_desc->mac_addr, 3727 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 3728 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 3729 } 3730 3731 tag_buf += 10; 3732 ppdu_user_desc->msduq_bitmap = *tag_buf; 3733 } 3734 3735 /** 3736 * dp_process_ppdu_stats_user_rate_tlv() - Process htt_ppdu_stats_user_rate_tlv 3737 * @pdev: DP pdev handle 3738 * @tag_buf: T2H message buffer carrying the user rate TLV 3739 * @ppdu_info: per ppdu tlv structure 3740 * 3741 * Return: void 3742 */ 3743 static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3744 dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev, 3745 uint32_t *tag_buf, 3746 struct ppdu_info *ppdu_info) 3747 { 3748 uint16_t peer_id; 3749 struct cdp_tx_completion_ppdu *ppdu_desc; 3750 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3751 uint8_t curr_user_index = 0; 3752 struct dp_vdev *vdev; 3753 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 3754 uint8_t bw, ru_format; 3755 uint16_t ru_size; 3756 htt_ppdu_stats_user_rate_tlv *stats_buf = 3757 (htt_ppdu_stats_user_rate_tlv *)tag_buf; 3758 3759 ppdu_desc = 3760 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3761 3762 tag_buf++; 3763 peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf); 3764 3765 curr_user_index = 3766 dp_get_ppdu_info_user_index(pdev, 3767 peer_id, ppdu_info); 3768 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 3769 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 3770 if (peer_id == DP_SCAN_PEER_ID) { 3771 vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id, 3772 DP_MOD_ID_TX_PPDU_STATS); 3773 if (!vdev) 3774 return; 3775 dp_vdev_unref_delete(pdev->soc, vdev, 3776 DP_MOD_ID_TX_PPDU_STATS); 3777 } 3778 ppdu_user_desc->peer_id = peer_id; 3779 3780 ppdu_user_desc->tid = 3781 HTT_PPDU_STATS_USER_RATE_TLV_TID_NUM_GET(*tag_buf); 3782 3783 tag_buf += 1; 3784 3785 ppdu_user_desc->user_pos = 3786 HTT_PPDU_STATS_USER_RATE_TLV_USER_POS_GET(*tag_buf); 3787 ppdu_user_desc->mu_group_id = 3788 HTT_PPDU_STATS_USER_RATE_TLV_MU_GROUPID_GET(*tag_buf); 3789 3790 ru_format = HTT_PPDU_STATS_USER_RATE_TLV_RU_FORMAT_GET(*tag_buf); 3791 3792 tag_buf += 1; 3793 3794 if (!ru_format) { 3795 /* ru_format = 0: ru_end, ru_start */ 3796 ppdu_user_desc->ru_start = 3797 HTT_PPDU_STATS_USER_RATE_TLV_RU_START_GET(*tag_buf); 3798 ppdu_user_desc->ru_tones = 3799 (HTT_PPDU_STATS_USER_RATE_TLV_RU_END_GET(*tag_buf) - 3800 HTT_PPDU_STATS_USER_RATE_TLV_RU_START_GET(*tag_buf)) + 1; 3801 } else if (ru_format == 1) { 3802 /* ru_format = 1: ru_index, ru_size */ 3803 ru_size = HTT_PPDU_STATS_USER_RATE_TLV_RU_SIZE_GET(*tag_buf); 3804 ppdu_user_desc->ru_tones = 3805 dp_mon_get_ru_width_from_ru_size(ru_size); 3806 } else { 3807 dp_mon_debug("Unsupported ru_format: %d rcvd", ru_format); 3808 } 3809 ppdu_desc->usr_ru_tones_sum += ppdu_user_desc->ru_tones; 3810 3811 tag_buf += 2; 3812 3813 ppdu_user_desc->ppdu_type = 3814 HTT_PPDU_STATS_USER_RATE_TLV_PPDU_TYPE_GET(*tag_buf); 3815 3816 tag_buf++; 3817 ppdu_user_desc->tx_rate = *tag_buf; 3818 3819 ppdu_user_desc->ltf_size = 3820 HTT_PPDU_STATS_USER_RATE_TLV_LTF_SIZE_GET(*tag_buf); 3821 ppdu_user_desc->stbc = 3822 HTT_PPDU_STATS_USER_RATE_TLV_STBC_GET(*tag_buf); 3823 ppdu_user_desc->he_re = 3824 HTT_PPDU_STATS_USER_RATE_TLV_HE_RE_GET(*tag_buf); 3825 ppdu_user_desc->txbf = 3826 HTT_PPDU_STATS_USER_RATE_TLV_TXBF_GET(*tag_buf); 3827 bw = HTT_PPDU_STATS_USER_RATE_TLV_BW_GET(*tag_buf); 3828 /* Align bw value as per host data structures */ 3829 if (bw == HTT_PPDU_STATS_BANDWIDTH_320MHZ) 3830 ppdu_user_desc->bw = bw - 3; 3831 else 3832 ppdu_user_desc->bw = bw - 2; 3833 ppdu_user_desc->nss = HTT_PPDU_STATS_USER_RATE_TLV_NSS_GET(*tag_buf); 3834 ppdu_desc->usr_nss_sum += ppdu_user_desc->nss; 3835 ppdu_user_desc->mcs = HTT_PPDU_STATS_USER_RATE_TLV_MCS_GET(*tag_buf); 3836 ppdu_user_desc->preamble = 3837 HTT_PPDU_STATS_USER_RATE_TLV_PREAMBLE_GET(*tag_buf); 3838 ppdu_user_desc->gi = HTT_PPDU_STATS_USER_RATE_TLV_GI_GET(*tag_buf); 3839 ppdu_user_desc->dcm = HTT_PPDU_STATS_USER_RATE_TLV_DCM_GET(*tag_buf); 3840 ppdu_user_desc->ldpc = HTT_PPDU_STATS_USER_RATE_TLV_LDPC_GET(*tag_buf); 3841 3842 tag_buf += 2; 3843 ppdu_user_desc->punc_pattern_bitmap = 3844 HTT_PPDU_STATS_USER_RATE_TLV_PUNC_PATTERN_BITMAP_GET(*tag_buf); 3845 ppdu_user_desc->fixed_rate_used = stats_buf->is_min_rate; 3846 } 3847 3848 /** 3849 * dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv() - Process 3850 * htt_ppdu_stats_enq_mpdu_bitmap_64_tlv 3851 * @pdev: DP PDEV handle 3852 * @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_64_tlv 3853 * @ppdu_info: per ppdu tlv structure 3854 * 3855 * Return: void 3856 */ dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3857 static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv( 3858 struct dp_pdev *pdev, uint32_t *tag_buf, 3859 struct ppdu_info *ppdu_info) 3860 { 3861 htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *dp_stats_buf = 3862 (htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *)tag_buf; 3863 3864 struct cdp_tx_completion_ppdu *ppdu_desc; 3865 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3866 uint8_t curr_user_index = 0; 3867 uint16_t peer_id; 3868 uint32_t size = CDP_BA_64_BIT_MAP_SIZE_DWORDS; 3869 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 3870 3871 ppdu_desc = 3872 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3873 3874 tag_buf++; 3875 3876 peer_id = 3877 HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf); 3878 3879 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 3880 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 3881 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 3882 ppdu_user_desc->peer_id = peer_id; 3883 3884 ppdu_user_desc->start_seq = dp_stats_buf->start_seq; 3885 qdf_mem_copy(&ppdu_user_desc->enq_bitmap, &dp_stats_buf->enq_bitmap, 3886 sizeof(uint32_t) * CDP_BA_64_BIT_MAP_SIZE_DWORDS); 3887 3888 dp_process_ppdu_stats_update_failed_bitmap(pdev, 3889 (void *)ppdu_user_desc, 3890 ppdu_info->ppdu_id, 3891 size); 3892 } 3893 3894 /** 3895 * dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv() - Process 3896 * htt_ppdu_stats_enq_mpdu_bitmap_256_tlv 3897 * @pdev: DP PDEV handle 3898 * @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_256_tlv 3899 * @ppdu_info: per ppdu tlv structure 3900 * 3901 * Return: void 3902 */ dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3903 static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv( 3904 struct dp_pdev *pdev, uint32_t *tag_buf, 3905 struct ppdu_info *ppdu_info) 3906 { 3907 htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *dp_stats_buf = 3908 (htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *)tag_buf; 3909 3910 struct cdp_tx_completion_ppdu *ppdu_desc; 3911 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3912 uint8_t curr_user_index = 0; 3913 uint16_t peer_id; 3914 uint32_t size = CDP_BA_256_BIT_MAP_SIZE_DWORDS; 3915 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 3916 3917 ppdu_desc = 3918 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3919 3920 tag_buf++; 3921 3922 peer_id = 3923 HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf); 3924 3925 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 3926 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 3927 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 3928 ppdu_user_desc->peer_id = peer_id; 3929 3930 ppdu_user_desc->start_seq = dp_stats_buf->start_seq; 3931 qdf_mem_copy(&ppdu_user_desc->enq_bitmap, &dp_stats_buf->enq_bitmap, 3932 sizeof(uint32_t) * CDP_BA_256_BIT_MAP_SIZE_DWORDS); 3933 3934 dp_process_ppdu_stats_update_failed_bitmap(pdev, 3935 (void *)ppdu_user_desc, 3936 ppdu_info->ppdu_id, 3937 size); 3938 } 3939 3940 /** 3941 * dp_process_ppdu_stats_user_cmpltn_common_tlv() - Process 3942 * htt_ppdu_stats_user_cmpltn_common_tlv 3943 * @pdev: DP PDEV handle 3944 * @tag_buf: buffer containing the tlv htt_ppdu_stats_user_cmpltn_common_tlv 3945 * @ppdu_info: per ppdu tlv structure 3946 * 3947 * Return: void 3948 */ dp_process_ppdu_stats_user_cmpltn_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3949 static void dp_process_ppdu_stats_user_cmpltn_common_tlv( 3950 struct dp_pdev *pdev, uint32_t *tag_buf, 3951 struct ppdu_info *ppdu_info) 3952 { 3953 uint16_t peer_id; 3954 struct cdp_tx_completion_ppdu *ppdu_desc; 3955 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 3956 uint8_t curr_user_index = 0; 3957 uint8_t bw_iter; 3958 htt_ppdu_stats_user_cmpltn_common_tlv *dp_stats_buf = 3959 (htt_ppdu_stats_user_cmpltn_common_tlv *)tag_buf; 3960 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 3961 3962 ppdu_desc = 3963 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 3964 3965 tag_buf++; 3966 peer_id = 3967 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SW_PEER_ID_GET(*tag_buf); 3968 3969 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 3970 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 3971 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 3972 ppdu_user_desc->peer_id = peer_id; 3973 3974 ppdu_user_desc->completion_status = 3975 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_COMPLETION_STATUS_GET( 3976 *tag_buf); 3977 3978 ppdu_user_desc->tid = 3979 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TID_NUM_GET(*tag_buf); 3980 3981 tag_buf++; 3982 if (qdf_likely(ppdu_user_desc->completion_status == 3983 HTT_PPDU_STATS_USER_STATUS_OK)) { 3984 ppdu_desc->ack_rssi = dp_stats_buf->ack_rssi; 3985 ppdu_user_desc->usr_ack_rssi = dp_stats_buf->ack_rssi; 3986 ppdu_user_desc->ack_rssi_valid = 1; 3987 } else { 3988 ppdu_user_desc->ack_rssi_valid = 0; 3989 } 3990 3991 tag_buf++; 3992 3993 ppdu_user_desc->mpdu_success = 3994 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_SUCCESS_GET(*tag_buf); 3995 3996 ppdu_user_desc->mpdu_failed = 3997 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_TRIED_GET(*tag_buf) - 3998 ppdu_user_desc->mpdu_success; 3999 4000 tag_buf++; 4001 4002 ppdu_user_desc->long_retries = 4003 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_LONG_RETRY_GET(*tag_buf); 4004 4005 ppdu_user_desc->short_retries = 4006 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SHORT_RETRY_GET(*tag_buf); 4007 ppdu_user_desc->retry_mpdus = 4008 ppdu_user_desc->long_retries + ppdu_user_desc->short_retries; 4009 4010 ppdu_user_desc->is_ampdu = 4011 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_AMPDU_GET(*tag_buf); 4012 ppdu_info->is_ampdu = ppdu_user_desc->is_ampdu; 4013 4014 ppdu_desc->resp_type = 4015 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RESP_TYPE_GET(*tag_buf); 4016 ppdu_desc->mprot_type = 4017 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPROT_TYPE_GET(*tag_buf); 4018 ppdu_desc->rts_success = 4019 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_SUCCESS_GET(*tag_buf); 4020 ppdu_desc->rts_failure = 4021 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_FAILURE_GET(*tag_buf); 4022 4023 ppdu_user_desc->mprot_type = ppdu_desc->mprot_type; 4024 ppdu_user_desc->rts_success = ppdu_desc->rts_success; 4025 ppdu_user_desc->rts_failure = ppdu_desc->rts_failure; 4026 4027 ppdu_user_desc->pream_punct = 4028 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PREAM_PUNC_TX_GET(*tag_buf); 4029 4030 ppdu_info->compltn_common_tlv++; 4031 4032 /* 4033 * MU BAR may send request to n users but we may received ack only from 4034 * m users. To have count of number of users respond back, we have a 4035 * separate counter bar_num_users per PPDU that get increment for every 4036 * htt_ppdu_stats_user_cmpltn_common_tlv 4037 */ 4038 ppdu_desc->bar_num_users++; 4039 4040 tag_buf++; 4041 for (bw_iter = 0; bw_iter < CDP_RSSI_CHAIN_LEN; bw_iter++) { 4042 ppdu_user_desc->rssi_chain[bw_iter] = 4043 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CHAIN_RSSI_GET(*tag_buf); 4044 tag_buf++; 4045 } 4046 4047 ppdu_user_desc->sa_tx_antenna = 4048 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TX_ANTENNA_MASK_GET(*tag_buf); 4049 4050 tag_buf++; 4051 ppdu_user_desc->sa_is_training = 4052 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_TRAINING_GET(*tag_buf); 4053 if (ppdu_user_desc->sa_is_training) { 4054 ppdu_user_desc->sa_goodput = 4055 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PENDING_TRAINING_PKTS_GET(*tag_buf); 4056 } 4057 4058 tag_buf++; 4059 for (bw_iter = 0; bw_iter < CDP_NUM_SA_BW; bw_iter++) { 4060 ppdu_user_desc->sa_max_rates[bw_iter] = 4061 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(tag_buf[bw_iter]); 4062 } 4063 4064 tag_buf += CDP_NUM_SA_BW; 4065 ppdu_user_desc->current_rate_per = 4066 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CURRENT_RATE_PER_GET(*tag_buf); 4067 4068 tag_buf++; 4069 /* Skip SW RTS */ 4070 4071 tag_buf++; 4072 /* Extract 320MHz MAX PHY ratecode */ 4073 ppdu_user_desc->sa_max_rates[CDP_SA_BW320_INX] = 4074 HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(*tag_buf); 4075 } 4076 4077 /** 4078 * dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv() - Process 4079 * htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv 4080 * @pdev: DP PDEV handle 4081 * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv 4082 * @ppdu_info: per ppdu tlv structure 4083 * 4084 * Return: void 4085 */ dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4086 static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv( 4087 struct dp_pdev *pdev, uint32_t *tag_buf, 4088 struct ppdu_info *ppdu_info) 4089 { 4090 htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *dp_stats_buf = 4091 (htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *)tag_buf; 4092 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 4093 struct cdp_tx_completion_ppdu *ppdu_desc; 4094 uint8_t curr_user_index = 0; 4095 uint16_t peer_id; 4096 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 4097 4098 ppdu_desc = 4099 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 4100 4101 tag_buf++; 4102 4103 peer_id = 4104 HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf); 4105 4106 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 4107 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 4108 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 4109 ppdu_user_desc->peer_id = peer_id; 4110 4111 ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no; 4112 qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap, 4113 sizeof(uint32_t) * CDP_BA_64_BIT_MAP_SIZE_DWORDS); 4114 ppdu_user_desc->ba_size = CDP_BA_64_BIT_MAP_SIZE_DWORDS * 32; 4115 } 4116 4117 /** 4118 * dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv() - Process 4119 * htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv 4120 * @pdev: DP PDEV handle 4121 * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv 4122 * @ppdu_info: per ppdu tlv structure 4123 * 4124 * Return: void 4125 */ dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4126 static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv( 4127 struct dp_pdev *pdev, uint32_t *tag_buf, 4128 struct ppdu_info *ppdu_info) 4129 { 4130 htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *dp_stats_buf = 4131 (htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *)tag_buf; 4132 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 4133 struct cdp_tx_completion_ppdu *ppdu_desc; 4134 uint8_t curr_user_index = 0; 4135 uint16_t peer_id; 4136 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 4137 4138 ppdu_desc = 4139 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 4140 4141 tag_buf++; 4142 4143 peer_id = 4144 HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf); 4145 4146 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 4147 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 4148 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 4149 ppdu_user_desc->peer_id = peer_id; 4150 4151 ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no; 4152 qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap, 4153 sizeof(uint32_t) * CDP_BA_256_BIT_MAP_SIZE_DWORDS); 4154 ppdu_user_desc->ba_size = CDP_BA_256_BIT_MAP_SIZE_DWORDS * 32; 4155 } 4156 4157 /** 4158 * dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv() - Process 4159 * htt_ppdu_stats_user_compltn_ack_ba_status_tlv 4160 * @pdev: DP PDEV handle 4161 * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv 4162 * @ppdu_info: per ppdu tlv structure 4163 * 4164 * Return: void 4165 */ dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4166 static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv( 4167 struct dp_pdev *pdev, uint32_t *tag_buf, 4168 struct ppdu_info *ppdu_info) 4169 { 4170 uint16_t peer_id; 4171 struct cdp_tx_completion_ppdu *ppdu_desc; 4172 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 4173 uint8_t curr_user_index = 0; 4174 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 4175 4176 ppdu_desc = 4177 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 4178 4179 tag_buf += 2; 4180 peer_id = 4181 HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_SW_PEER_ID_GET(*tag_buf); 4182 4183 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 4184 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 4185 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 4186 if (!ppdu_user_desc->ack_ba_tlv) { 4187 ppdu_user_desc->ack_ba_tlv = 1; 4188 } else { 4189 pdev->stats.ack_ba_comes_twice++; 4190 return; 4191 } 4192 4193 ppdu_user_desc->peer_id = peer_id; 4194 4195 tag_buf++; 4196 /* not to update ppdu_desc->tid from this TLV */ 4197 ppdu_user_desc->num_mpdu = 4198 HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MPDU_GET(*tag_buf); 4199 4200 ppdu_user_desc->num_msdu = 4201 HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MSDU_GET(*tag_buf); 4202 4203 ppdu_user_desc->success_msdus = ppdu_user_desc->num_msdu; 4204 4205 tag_buf++; 4206 ppdu_user_desc->start_seq = 4207 HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_START_SEQ_GET( 4208 *tag_buf); 4209 4210 tag_buf++; 4211 ppdu_user_desc->success_bytes = *tag_buf; 4212 4213 /* increase ack ba tlv counter on successful mpdu */ 4214 if (ppdu_user_desc->num_mpdu) 4215 ppdu_info->ack_ba_tlv++; 4216 4217 if (ppdu_user_desc->ba_size == 0) { 4218 ppdu_user_desc->ba_seq_no = ppdu_user_desc->start_seq; 4219 ppdu_user_desc->ba_bitmap[0] = 1; 4220 ppdu_user_desc->ba_size = 1; 4221 } 4222 } 4223 4224 /** 4225 * dp_process_ppdu_stats_user_common_array_tlv() - Process 4226 * htt_ppdu_stats_user_common_array_tlv 4227 * @pdev: DP PDEV handle 4228 * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv 4229 * @ppdu_info: per ppdu tlv structure 4230 * 4231 * Return: void 4232 */ dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4233 static void dp_process_ppdu_stats_user_common_array_tlv( 4234 struct dp_pdev *pdev, uint32_t *tag_buf, 4235 struct ppdu_info *ppdu_info) 4236 { 4237 uint32_t peer_id; 4238 struct cdp_tx_completion_ppdu *ppdu_desc; 4239 struct cdp_tx_completion_ppdu_user *ppdu_user_desc; 4240 uint8_t curr_user_index = 0; 4241 struct htt_tx_ppdu_stats_info *dp_stats_buf; 4242 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 4243 4244 ppdu_desc = 4245 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 4246 4247 tag_buf++; 4248 dp_stats_buf = (struct htt_tx_ppdu_stats_info *)tag_buf; 4249 tag_buf += 3; 4250 peer_id = 4251 HTT_PPDU_STATS_ARRAY_ITEM_TLV_PEERID_GET(*tag_buf); 4252 4253 if (!dp_peer_find_by_id_valid(pdev->soc, peer_id)) { 4254 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 4255 "Peer with peer_id: %u not found", peer_id); 4256 return; 4257 } 4258 4259 curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info); 4260 4261 ppdu_user_desc = &ppdu_desc->user[curr_user_index]; 4262 ppdu_user_desc->tlv_bitmap |= (1 << tlv_type); 4263 4264 ppdu_user_desc->retry_bytes = dp_stats_buf->tx_retry_bytes; 4265 ppdu_user_desc->failed_bytes = dp_stats_buf->tx_failed_bytes; 4266 4267 tag_buf++; 4268 4269 ppdu_user_desc->success_msdus = 4270 HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_SUCC_MSDUS_GET(*tag_buf); 4271 ppdu_user_desc->retry_msdus = 4272 HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_RETRY_MSDUS_GET(*tag_buf); 4273 tag_buf++; 4274 ppdu_user_desc->failed_msdus = 4275 HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_FAILED_MSDUS_GET(*tag_buf); 4276 } 4277 4278 /** 4279 * dp_process_ppdu_stats_user_compltn_flush_tlv() - Process 4280 * htt_ppdu_stats_flush_tlv 4281 * @pdev: DP PDEV handle 4282 * @tag_buf: buffer containing the htt_ppdu_stats_flush_tlv 4283 * @ppdu_info: per ppdu tlv structure 4284 * 4285 * Return: void 4286 */ 4287 static void dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4288 dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev, 4289 uint32_t *tag_buf, 4290 struct ppdu_info *ppdu_info) 4291 { 4292 struct cdp_tx_completion_ppdu *ppdu_desc; 4293 uint32_t peer_id; 4294 uint8_t tid; 4295 struct dp_peer *peer; 4296 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 4297 struct dp_mon_peer *mon_peer = NULL; 4298 4299 ppdu_desc = (struct cdp_tx_completion_ppdu *) 4300 qdf_nbuf_data(ppdu_info->nbuf); 4301 ppdu_desc->is_flush = 1; 4302 4303 tag_buf++; 4304 ppdu_desc->drop_reason = *tag_buf; 4305 4306 tag_buf++; 4307 ppdu_desc->num_msdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MSDU_GET(*tag_buf); 4308 ppdu_desc->num_mpdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MPDU_GET(*tag_buf); 4309 ppdu_desc->flow_type = HTT_PPDU_STATS_FLUSH_TLV_FLOW_TYPE_GET(*tag_buf); 4310 4311 tag_buf++; 4312 peer_id = HTT_PPDU_STATS_FLUSH_TLV_SW_PEER_ID_GET(*tag_buf); 4313 tid = HTT_PPDU_STATS_FLUSH_TLV_TID_NUM_GET(*tag_buf); 4314 4315 ppdu_desc->num_users = 1; 4316 ppdu_desc->user[0].peer_id = peer_id; 4317 ppdu_desc->user[0].tid = tid; 4318 4319 ppdu_desc->queue_type = 4320 HTT_PPDU_STATS_FLUSH_TLV_QUEUE_TYPE_GET(*tag_buf); 4321 4322 peer = dp_peer_get_ref_by_id(pdev->soc, peer_id, 4323 DP_MOD_ID_TX_PPDU_STATS); 4324 if (!peer) 4325 goto add_ppdu_to_sched_list; 4326 4327 if (ppdu_desc->drop_reason == HTT_FLUSH_EXCESS_RETRIES) { 4328 mon_peer = peer->monitor_peer; 4329 DP_STATS_INC(mon_peer, 4330 tx.excess_retries_per_ac[TID_TO_WME_AC(tid)], 4331 ppdu_desc->num_msdu); 4332 } 4333 4334 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 4335 4336 add_ppdu_to_sched_list: 4337 ppdu_info->done = 1; 4338 TAILQ_REMOVE(&mon_pdev->ppdu_info_list, ppdu_info, ppdu_info_list_elem); 4339 mon_pdev->list_depth--; 4340 TAILQ_INSERT_TAIL(&mon_pdev->sched_comp_ppdu_list, ppdu_info, 4341 ppdu_info_list_elem); 4342 mon_pdev->sched_comp_list_depth++; 4343 } 4344 4345 /** 4346 * dp_process_ppdu_stats_sch_cmd_status_tlv() - Process schedule command status tlv 4347 * Here we are not going to process the buffer. 4348 * @pdev: DP PDEV handle 4349 * @ppdu_info: per ppdu tlv structure 4350 * 4351 * Return: void 4352 */ 4353 static void dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4354 dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev, 4355 struct ppdu_info *ppdu_info) 4356 { 4357 struct cdp_tx_completion_ppdu *ppdu_desc; 4358 struct dp_peer *peer; 4359 uint8_t num_users; 4360 uint8_t i; 4361 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 4362 4363 ppdu_desc = (struct cdp_tx_completion_ppdu *) 4364 qdf_nbuf_data(ppdu_info->nbuf); 4365 4366 num_users = ppdu_desc->bar_num_users; 4367 4368 for (i = 0; i < num_users; i++) { 4369 if (ppdu_desc->user[i].user_pos == 0) { 4370 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) { 4371 /* update phy mode for bar frame */ 4372 ppdu_desc->phy_mode = 4373 ppdu_desc->user[i].preamble; 4374 ppdu_desc->user[0].mcs = ppdu_desc->user[i].mcs; 4375 break; 4376 } 4377 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_CTRL) { 4378 ppdu_desc->frame_ctrl = 4379 ppdu_desc->user[i].frame_ctrl; 4380 break; 4381 } 4382 } 4383 } 4384 4385 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA && 4386 ppdu_desc->delayed_ba) { 4387 qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); 4388 4389 for (i = 0; i < ppdu_desc->num_users; i++) { 4390 struct cdp_delayed_tx_completion_ppdu_user *delay_ppdu; 4391 uint64_t start_tsf; 4392 uint64_t end_tsf; 4393 uint32_t ppdu_id; 4394 struct dp_mon_peer *mon_peer; 4395 4396 ppdu_id = ppdu_desc->ppdu_id; 4397 peer = dp_peer_get_ref_by_id 4398 (pdev->soc, ppdu_desc->user[i].peer_id, 4399 DP_MOD_ID_TX_PPDU_STATS); 4400 /* 4401 * This check is to make sure peer is not deleted 4402 * after processing the TLVs. 4403 */ 4404 if (!peer) 4405 continue; 4406 4407 if (!peer->monitor_peer) { 4408 dp_peer_unref_delete(peer, 4409 DP_MOD_ID_TX_PPDU_STATS); 4410 continue; 4411 } 4412 4413 mon_peer = peer->monitor_peer; 4414 delay_ppdu = &mon_peer->delayed_ba_ppdu_stats; 4415 start_tsf = ppdu_desc->ppdu_start_timestamp; 4416 end_tsf = ppdu_desc->ppdu_end_timestamp; 4417 /* 4418 * save delayed ba user info 4419 */ 4420 if (ppdu_desc->user[i].delayed_ba) { 4421 dp_peer_copy_delay_stats(peer, 4422 &ppdu_desc->user[i], 4423 ppdu_id); 4424 mon_peer->last_delayed_ba_ppduid = ppdu_id; 4425 delay_ppdu->ppdu_start_timestamp = start_tsf; 4426 delay_ppdu->ppdu_end_timestamp = end_tsf; 4427 } 4428 ppdu_desc->user[i].peer_last_delayed_ba = 4429 mon_peer->last_delayed_ba; 4430 4431 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 4432 4433 if (ppdu_desc->user[i].delayed_ba && 4434 !ppdu_desc->user[i].debug_copied) { 4435 QDF_TRACE(QDF_MODULE_ID_TXRX, 4436 QDF_TRACE_LEVEL_INFO_MED, 4437 "%s: %d ppdu_id[%d] bar_ppdu_id[%d] num_users[%d] usr[%d] htt_frame_type[%d]\n", 4438 __func__, __LINE__, 4439 ppdu_desc->ppdu_id, 4440 ppdu_desc->bar_ppdu_id, 4441 ppdu_desc->num_users, 4442 i, 4443 ppdu_desc->htt_frame_type); 4444 } 4445 } 4446 } 4447 4448 /* 4449 * when frame type is BAR and STATS_COMMON_TLV is set 4450 * copy the store peer delayed info to BAR status 4451 */ 4452 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) { 4453 for (i = 0; i < ppdu_desc->bar_num_users; i++) { 4454 struct cdp_delayed_tx_completion_ppdu_user *delay_ppdu; 4455 uint64_t start_tsf; 4456 uint64_t end_tsf; 4457 struct dp_mon_peer *mon_peer; 4458 4459 peer = dp_peer_get_ref_by_id 4460 (pdev->soc, 4461 ppdu_desc->user[i].peer_id, 4462 DP_MOD_ID_TX_PPDU_STATS); 4463 /* 4464 * This check is to make sure peer is not deleted 4465 * after processing the TLVs. 4466 */ 4467 if (!peer) 4468 continue; 4469 4470 if (!peer->monitor_peer) { 4471 dp_peer_unref_delete(peer, 4472 DP_MOD_ID_TX_PPDU_STATS); 4473 continue; 4474 } 4475 4476 mon_peer = peer->monitor_peer; 4477 if (ppdu_desc->user[i].completion_status != 4478 HTT_PPDU_STATS_USER_STATUS_OK) { 4479 dp_peer_unref_delete(peer, 4480 DP_MOD_ID_TX_PPDU_STATS); 4481 continue; 4482 } 4483 4484 delay_ppdu = &mon_peer->delayed_ba_ppdu_stats; 4485 start_tsf = delay_ppdu->ppdu_start_timestamp; 4486 end_tsf = delay_ppdu->ppdu_end_timestamp; 4487 4488 if (mon_peer->last_delayed_ba) { 4489 dp_peer_copy_stats_to_bar(peer, 4490 &ppdu_desc->user[i]); 4491 ppdu_desc->ppdu_id = 4492 mon_peer->last_delayed_ba_ppduid; 4493 ppdu_desc->ppdu_start_timestamp = start_tsf; 4494 ppdu_desc->ppdu_end_timestamp = end_tsf; 4495 } 4496 ppdu_desc->user[i].peer_last_delayed_ba = 4497 mon_peer->last_delayed_ba; 4498 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 4499 } 4500 } 4501 4502 TAILQ_REMOVE(&mon_pdev->ppdu_info_list, ppdu_info, ppdu_info_list_elem); 4503 mon_pdev->list_depth--; 4504 TAILQ_INSERT_TAIL(&mon_pdev->sched_comp_ppdu_list, ppdu_info, 4505 ppdu_info_list_elem); 4506 mon_pdev->sched_comp_list_depth++; 4507 } 4508 4509 /** 4510 * dp_validate_fix_ppdu_tlv() - Function to validate the length of PPDU 4511 * @pdev: DP pdev handle 4512 * @tag_buf: TLV buffer 4513 * @tlv_expected_size: Expected size of Tag 4514 * @tlv_len: TLV length received from FW 4515 * 4516 * If the TLV length sent as part of PPDU TLV is less that expected size i.e 4517 * size of corresponding data structure, pad the remaining bytes with zeros 4518 * and continue processing the TLVs 4519 * 4520 * Return: Pointer to updated TLV 4521 */ dp_validate_fix_ppdu_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,uint16_t tlv_expected_size,uint16_t tlv_len)4522 static inline uint32_t *dp_validate_fix_ppdu_tlv(struct dp_pdev *pdev, 4523 uint32_t *tag_buf, 4524 uint16_t tlv_expected_size, 4525 uint16_t tlv_len) 4526 { 4527 uint32_t *tlv_desc = tag_buf; 4528 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 4529 4530 qdf_assert_always(tlv_len != 0); 4531 4532 if (tlv_len < tlv_expected_size) { 4533 qdf_mem_zero(mon_pdev->ppdu_tlv_buf, tlv_expected_size); 4534 qdf_mem_copy(mon_pdev->ppdu_tlv_buf, tag_buf, tlv_len); 4535 tlv_desc = mon_pdev->ppdu_tlv_buf; 4536 } 4537 4538 return tlv_desc; 4539 } 4540 4541 /** 4542 * dp_process_ppdu_tag() - Function to process the PPDU TLVs 4543 * @pdev: DP pdev handle 4544 * @tag_buf: TLV buffer 4545 * @tlv_len: length of tlv 4546 * @ppdu_info: per ppdu tlv structure 4547 * 4548 * Return: void 4549 */ dp_process_ppdu_tag(struct dp_pdev * pdev,uint32_t * tag_buf,uint32_t tlv_len,struct ppdu_info * ppdu_info)4550 static void dp_process_ppdu_tag(struct dp_pdev *pdev, 4551 uint32_t *tag_buf, 4552 uint32_t tlv_len, 4553 struct ppdu_info *ppdu_info) 4554 { 4555 uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf); 4556 uint16_t tlv_expected_size; 4557 uint32_t *tlv_desc; 4558 4559 switch (tlv_type) { 4560 case HTT_PPDU_STATS_COMMON_TLV: 4561 tlv_expected_size = sizeof(htt_ppdu_stats_common_tlv); 4562 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4563 tlv_expected_size, tlv_len); 4564 dp_process_ppdu_stats_common_tlv(pdev, tlv_desc, ppdu_info); 4565 break; 4566 case HTT_PPDU_STATS_USR_COMMON_TLV: 4567 tlv_expected_size = sizeof(htt_ppdu_stats_user_common_tlv); 4568 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4569 tlv_expected_size, tlv_len); 4570 dp_process_ppdu_stats_user_common_tlv(pdev, tlv_desc, 4571 ppdu_info); 4572 break; 4573 case HTT_PPDU_STATS_USR_RATE_TLV: 4574 tlv_expected_size = sizeof(htt_ppdu_stats_user_rate_tlv); 4575 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4576 tlv_expected_size, tlv_len); 4577 dp_process_ppdu_stats_user_rate_tlv(pdev, tlv_desc, 4578 ppdu_info); 4579 break; 4580 case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_64_TLV: 4581 tlv_expected_size = 4582 sizeof(htt_ppdu_stats_enq_mpdu_bitmap_64_tlv); 4583 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4584 tlv_expected_size, tlv_len); 4585 dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv( 4586 pdev, tlv_desc, ppdu_info); 4587 break; 4588 case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_256_TLV: 4589 tlv_expected_size = 4590 sizeof(htt_ppdu_stats_enq_mpdu_bitmap_256_tlv); 4591 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4592 tlv_expected_size, tlv_len); 4593 dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv( 4594 pdev, tlv_desc, ppdu_info); 4595 break; 4596 case HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV: 4597 tlv_expected_size = 4598 sizeof(htt_ppdu_stats_user_cmpltn_common_tlv); 4599 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4600 tlv_expected_size, tlv_len); 4601 dp_process_ppdu_stats_user_cmpltn_common_tlv( 4602 pdev, tlv_desc, ppdu_info); 4603 break; 4604 case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_64_TLV: 4605 tlv_expected_size = 4606 sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv); 4607 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4608 tlv_expected_size, tlv_len); 4609 dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv( 4610 pdev, tlv_desc, ppdu_info); 4611 break; 4612 case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV: 4613 tlv_expected_size = 4614 sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv); 4615 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4616 tlv_expected_size, tlv_len); 4617 dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv( 4618 pdev, tlv_desc, ppdu_info); 4619 break; 4620 case HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV: 4621 tlv_expected_size = 4622 sizeof(htt_ppdu_stats_user_compltn_ack_ba_status_tlv); 4623 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4624 tlv_expected_size, tlv_len); 4625 dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv( 4626 pdev, tlv_desc, ppdu_info); 4627 break; 4628 case HTT_PPDU_STATS_USR_COMMON_ARRAY_TLV: 4629 tlv_expected_size = 4630 sizeof(htt_ppdu_stats_usr_common_array_tlv_v); 4631 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4632 tlv_expected_size, tlv_len); 4633 dp_process_ppdu_stats_user_common_array_tlv( 4634 pdev, tlv_desc, ppdu_info); 4635 break; 4636 case HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV: 4637 tlv_expected_size = sizeof(htt_ppdu_stats_flush_tlv); 4638 tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, 4639 tlv_expected_size, tlv_len); 4640 dp_process_ppdu_stats_user_compltn_flush_tlv(pdev, tlv_desc, 4641 ppdu_info); 4642 break; 4643 case HTT_PPDU_STATS_SCH_CMD_STATUS_TLV: 4644 dp_process_ppdu_stats_sch_cmd_status_tlv(pdev, ppdu_info); 4645 break; 4646 default: 4647 break; 4648 } 4649 } 4650 4651 #ifdef WLAN_CONFIG_TELEMETRY_AGENT 4652 static inline dp_ppdu_desc_user_airtime_consumption_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4653 void dp_ppdu_desc_user_airtime_consumption_update( 4654 struct dp_peer *peer, 4655 struct cdp_tx_completion_ppdu_user *user) 4656 { 4657 struct dp_mon_peer *mon_peer = NULL; 4658 uint8_t ac = 0; 4659 4660 mon_peer = peer->monitor_peer; 4661 if (qdf_unlikely(!mon_peer)) 4662 return; 4663 4664 ac = TID_TO_WME_AC(user->tid); 4665 DP_STATS_INC(mon_peer, airtime_stats.tx_airtime_consumption[ac].consumption, 4666 user->phy_tx_time_us); 4667 } 4668 #else 4669 static inline dp_ppdu_desc_user_airtime_consumption_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4670 void dp_ppdu_desc_user_airtime_consumption_update( 4671 struct dp_peer *peer, 4672 struct cdp_tx_completion_ppdu_user *user) 4673 { } 4674 #endif 4675 4676 #if defined(WLAN_ATF_ENABLE) || defined(WLAN_CONFIG_TELEMETRY_AGENT) 4677 static void dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)4678 dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev *pdev, 4679 struct dp_peer *peer, 4680 struct cdp_tx_completion_ppdu *ppdu_desc, 4681 struct cdp_tx_completion_ppdu_user *user) 4682 { 4683 uint32_t nss_ru_width_sum = 0; 4684 struct dp_mon_peer *mon_peer = NULL; 4685 4686 if (!pdev || !ppdu_desc || !user || !peer) 4687 return; 4688 4689 if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_DATA) 4690 return; 4691 4692 mon_peer = peer->monitor_peer; 4693 if (qdf_unlikely(!mon_peer)) 4694 return; 4695 4696 nss_ru_width_sum = ppdu_desc->usr_nss_sum * ppdu_desc->usr_ru_tones_sum; 4697 if (!nss_ru_width_sum) 4698 nss_ru_width_sum = 1; 4699 4700 /* 4701 * For SU-MIMO PPDU phy Tx time is same for the single user. 4702 * For MU-MIMO phy Tx time is calculated per user as below 4703 * user phy tx time = 4704 * Entire PPDU duration * MU Ratio * OFDMA Ratio 4705 * MU Ratio = usr_nss / Sum_of_nss_of_all_users 4706 * OFDMA_ratio = usr_ru_width / Sum_of_ru_width_of_all_users 4707 * usr_ru_widt = ru_end – ru_start + 1 4708 */ 4709 if (ppdu_desc->htt_frame_type == HTT_STATS_FTYPE_TIDQ_DATA_SU) { 4710 user->phy_tx_time_us = ppdu_desc->phy_ppdu_tx_time_us; 4711 } else { 4712 user->phy_tx_time_us = (ppdu_desc->phy_ppdu_tx_time_us * 4713 user->nss * user->ru_tones) / nss_ru_width_sum; 4714 } 4715 4716 dp_ppdu_desc_user_airtime_consumption_update(peer, user); 4717 } 4718 #else 4719 static void dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)4720 dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev *pdev, 4721 struct dp_peer *peer, 4722 struct cdp_tx_completion_ppdu *ppdu_desc, 4723 struct cdp_tx_completion_ppdu_user *user) 4724 { 4725 } 4726 #endif 4727 4728 #ifdef WLAN_SUPPORT_CTRL_FRAME_STATS 4729 static void dp_tx_ctrl_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4730 dp_tx_ctrl_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, 4731 struct cdp_tx_completion_ppdu_user *user) 4732 { 4733 struct dp_mon_peer *mon_peer = NULL; 4734 uint16_t fc = 0; 4735 4736 if (!pdev || !peer || !user) 4737 return; 4738 4739 mon_peer = peer->monitor_peer; 4740 if (qdf_unlikely(!mon_peer)) 4741 return; 4742 4743 if (user->mprot_type) { 4744 DP_STATS_INCC(mon_peer, 4745 tx.rts_success, 1, user->rts_success); 4746 DP_STATS_INCC(mon_peer, 4747 tx.rts_failure, 1, user->rts_failure); 4748 } 4749 fc = user->frame_ctrl; 4750 if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_TYPE_MASK) == 4751 QDF_IEEE80211_FC0_TYPE_CTL) { 4752 if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_SUBTYPE_MASK) == 4753 QDF_IEEE80211_FC0_SUBTYPE_VHT_NDP_AN) 4754 DP_STATS_INC(mon_peer, tx.ndpa_cnt, 1); 4755 if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_SUBTYPE_MASK) == 4756 QDF_IEEE80211_FC0_SUBTYPE_BAR) 4757 DP_STATS_INC(mon_peer, tx.bar_cnt, 1); 4758 } 4759 } 4760 #else 4761 static void dp_tx_ctrl_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4762 dp_tx_ctrl_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, 4763 struct cdp_tx_completion_ppdu_user *user) 4764 { 4765 } 4766 #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */ 4767 4768 void dp_ppdu_desc_user_stats_update(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4769 dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, 4770 struct ppdu_info *ppdu_info) 4771 { 4772 struct cdp_tx_completion_ppdu *ppdu_desc = NULL; 4773 struct dp_peer *peer = NULL; 4774 uint32_t tlv_bitmap_expected; 4775 uint32_t tlv_bitmap_default; 4776 uint16_t i; 4777 uint32_t num_users; 4778 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 4779 4780 ppdu_desc = (struct cdp_tx_completion_ppdu *) 4781 qdf_nbuf_data(ppdu_info->nbuf); 4782 4783 if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_BAR) 4784 ppdu_desc->ppdu_id = ppdu_info->ppdu_id; 4785 4786 tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP; 4787 if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode || 4788 mon_pdev->tx_capture_enabled) { 4789 if (ppdu_info->is_ampdu) 4790 tlv_bitmap_expected = 4791 dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap( 4792 ppdu_info->tlv_bitmap); 4793 } 4794 4795 tlv_bitmap_default = tlv_bitmap_expected; 4796 4797 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) { 4798 num_users = ppdu_desc->bar_num_users; 4799 ppdu_desc->num_users = ppdu_desc->bar_num_users; 4800 } else { 4801 num_users = ppdu_desc->num_users; 4802 } 4803 qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); 4804 4805 if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) { 4806 dp_ppdu_desc_get_txmode(ppdu_desc); 4807 dp_pdev_update_deter_stats(pdev, ppdu_desc); 4808 } 4809 4810 for (i = 0; i < num_users; i++) { 4811 ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu; 4812 ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu; 4813 4814 peer = dp_peer_get_ref_by_id(pdev->soc, 4815 ppdu_desc->user[i].peer_id, 4816 DP_MOD_ID_TX_PPDU_STATS); 4817 /* 4818 * This check is to make sure peer is not deleted 4819 * after processing the TLVs. 4820 */ 4821 if (!peer) 4822 continue; 4823 4824 ppdu_desc->user[i].is_bss_peer = peer->bss_peer; 4825 4826 dp_ppdu_desc_user_phy_tx_time_update(pdev, peer, ppdu_desc, 4827 &ppdu_desc->user[i]); 4828 4829 dp_tx_ctrl_stats_update(pdev, peer, &ppdu_desc->user[i]); 4830 4831 if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) { 4832 dp_ppdu_desc_user_deter_stats_update(pdev, 4833 peer, 4834 ppdu_desc, 4835 &ppdu_desc->user[i]); 4836 } 4837 4838 /* 4839 * different frame like DATA, BAR or CTRL has different 4840 * tlv bitmap expected. Apart from ACK_BA_STATUS TLV, we 4841 * receive other tlv in-order/sequential from fw. 4842 * Since ACK_BA_STATUS TLV come from Hardware it is 4843 * asynchronous So we need to depend on some tlv to confirm 4844 * all tlv is received for a ppdu. 4845 * So we depend on both SCHED_CMD_STATUS_TLV and 4846 * ACK_BA_STATUS_TLV. for failure packet we won't get 4847 * ACK_BA_STATUS_TLV. 4848 */ 4849 if (!(ppdu_info->tlv_bitmap & 4850 (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)) || 4851 (!(ppdu_info->tlv_bitmap & 4852 (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)) && 4853 (ppdu_desc->user[i].completion_status == 4854 HTT_PPDU_STATS_USER_STATUS_OK))) { 4855 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 4856 continue; 4857 } 4858 4859 /* 4860 * Update tx stats for data frames having Qos as well as 4861 * non-Qos data tid 4862 */ 4863 4864 if ((ppdu_desc->user[i].tid < CDP_DATA_TID_MAX || 4865 (ppdu_desc->user[i].tid == CDP_DATA_NON_QOS_TID) || 4866 (ppdu_desc->htt_frame_type == 4867 HTT_STATS_FTYPE_SGEN_QOS_NULL) || 4868 ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) && 4869 (ppdu_desc->num_mpdu > 1))) && 4870 (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL)) { 4871 dp_tx_stats_update(pdev, peer, 4872 &ppdu_desc->user[i], 4873 ppdu_desc); 4874 } 4875 4876 dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); 4877 tlv_bitmap_expected = tlv_bitmap_default; 4878 } 4879 } 4880 4881 #if !defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_PKT_CAPTURE_TX_2_0) || \ 4882 defined(WLAN_PKT_CAPTURE_RX_2_0) 4883 /** 4884 * dp_tx_ppdu_desc_notify() - Notify to upper layer about PPDU via WDI 4885 * 4886 * @pdev: Datapath pdev handle 4887 * @nbuf: Buffer to be delivered to upper layer 4888 * 4889 * Return: void 4890 */ dp_tx_ppdu_desc_notify(struct dp_pdev * pdev,qdf_nbuf_t nbuf)4891 static void dp_tx_ppdu_desc_notify(struct dp_pdev *pdev, qdf_nbuf_t nbuf) 4892 { 4893 struct dp_soc *soc = pdev->soc; 4894 struct dp_mon_ops *mon_ops = NULL; 4895 4896 mon_ops = dp_mon_ops_get(soc); 4897 if (mon_ops && mon_ops->mon_ppdu_desc_notify) 4898 mon_ops->mon_ppdu_desc_notify(pdev, nbuf); 4899 else 4900 qdf_nbuf_free(nbuf); 4901 } 4902 dp_ppdu_desc_deliver(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4903 void dp_ppdu_desc_deliver(struct dp_pdev *pdev, 4904 struct ppdu_info *ppdu_info) 4905 { 4906 struct ppdu_info *s_ppdu_info = NULL; 4907 struct ppdu_info *ppdu_info_next = NULL; 4908 struct cdp_tx_completion_ppdu *ppdu_desc = NULL; 4909 qdf_nbuf_t nbuf; 4910 uint32_t time_delta = 0; 4911 bool starved = 0; 4912 bool matched = 0; 4913 bool recv_ack_ba_done = 0; 4914 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 4915 4916 if (ppdu_info->tlv_bitmap & 4917 (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) && 4918 ppdu_info->done) 4919 recv_ack_ba_done = 1; 4920 4921 mon_pdev->last_sched_cmdid = ppdu_info->sched_cmdid; 4922 4923 s_ppdu_info = TAILQ_FIRST(&mon_pdev->sched_comp_ppdu_list); 4924 4925 TAILQ_FOREACH_SAFE(s_ppdu_info, &mon_pdev->sched_comp_ppdu_list, 4926 ppdu_info_list_elem, ppdu_info_next) { 4927 if (s_ppdu_info->tsf_l32 > ppdu_info->tsf_l32) 4928 time_delta = (MAX_TSF_32 - s_ppdu_info->tsf_l32) + 4929 ppdu_info->tsf_l32; 4930 else 4931 time_delta = ppdu_info->tsf_l32 - s_ppdu_info->tsf_l32; 4932 4933 if (!s_ppdu_info->done && !recv_ack_ba_done) { 4934 if (time_delta < MAX_SCHED_STARVE) { 4935 dp_mon_info("pdev[%d] ppdu_id[%d] sched_cmdid[%d] TLV_B[0x%x] TSF[%u] D[%d]", 4936 pdev->pdev_id, 4937 s_ppdu_info->ppdu_id, 4938 s_ppdu_info->sched_cmdid, 4939 s_ppdu_info->tlv_bitmap, 4940 s_ppdu_info->tsf_l32, 4941 s_ppdu_info->done); 4942 break; 4943 } 4944 starved = 1; 4945 } 4946 4947 mon_pdev->delivered_sched_cmdid = s_ppdu_info->sched_cmdid; 4948 TAILQ_REMOVE(&mon_pdev->sched_comp_ppdu_list, s_ppdu_info, 4949 ppdu_info_list_elem); 4950 mon_pdev->sched_comp_list_depth--; 4951 4952 nbuf = s_ppdu_info->nbuf; 4953 qdf_assert_always(nbuf); 4954 ppdu_desc = (struct cdp_tx_completion_ppdu *) 4955 qdf_nbuf_data(nbuf); 4956 ppdu_desc->tlv_bitmap = s_ppdu_info->tlv_bitmap; 4957 4958 if (starved) { 4959 dp_mon_info("ppdu starved fc[0x%x] h_ftype[%d] tlv_bitmap[0x%x] cs[%d]\n", 4960 ppdu_desc->frame_ctrl, 4961 ppdu_desc->htt_frame_type, 4962 ppdu_desc->tlv_bitmap, 4963 ppdu_desc->user[0].completion_status); 4964 starved = 0; 4965 } 4966 4967 if (ppdu_info->ppdu_id == s_ppdu_info->ppdu_id && 4968 ppdu_info->sched_cmdid == s_ppdu_info->sched_cmdid) 4969 matched = 1; 4970 4971 dp_ppdu_desc_user_stats_update(pdev, s_ppdu_info); 4972 4973 qdf_mem_free(s_ppdu_info); 4974 4975 dp_tx_ppdu_desc_notify(pdev, nbuf); 4976 4977 if (matched) 4978 break; 4979 } 4980 } 4981 #endif 4982 4983 /** 4984 * dp_tx_ppdu_desc_deliver() - Deliver PPDU desc to upper layer 4985 * @pdev: Datapath pdev handle 4986 * @ppdu_info: per PPDU TLV descriptor 4987 * 4988 * Return: void 4989 */ dp_tx_ppdu_desc_deliver(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4990 static void dp_tx_ppdu_desc_deliver(struct dp_pdev *pdev, 4991 struct ppdu_info *ppdu_info) 4992 { 4993 struct dp_soc *soc = pdev->soc; 4994 struct dp_mon_ops *mon_ops = NULL; 4995 4996 mon_ops = dp_mon_ops_get(soc); 4997 4998 if (mon_ops && mon_ops->mon_ppdu_desc_deliver) { 4999 mon_ops->mon_ppdu_desc_deliver(pdev, ppdu_info); 5000 } else { 5001 qdf_nbuf_free(ppdu_info->nbuf); 5002 ppdu_info->nbuf = NULL; 5003 qdf_mem_free(ppdu_info); 5004 } 5005 } 5006 5007 /** 5008 * dp_get_ppdu_desc() - Function to allocate new PPDU status 5009 * desc for new ppdu id 5010 * @pdev: DP pdev handle 5011 * @ppdu_id: PPDU unique identifier 5012 * @tlv_type: TLV type received 5013 * @tsf_l32: timestamp received along with ppdu stats indication header 5014 * @max_users: Maximum user for that particular ppdu 5015 * 5016 * Return: ppdu_info per ppdu tlv structure 5017 */ 5018 static dp_get_ppdu_desc(struct dp_pdev * pdev,uint32_t ppdu_id,uint8_t tlv_type,uint32_t tsf_l32,uint8_t max_users)5019 struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, 5020 uint8_t tlv_type, uint32_t tsf_l32, 5021 uint8_t max_users) 5022 { 5023 struct ppdu_info *ppdu_info = NULL; 5024 struct ppdu_info *s_ppdu_info = NULL; 5025 struct ppdu_info *ppdu_info_next = NULL; 5026 struct cdp_tx_completion_ppdu *ppdu_desc = NULL; 5027 uint32_t size = 0; 5028 struct cdp_tx_completion_ppdu *tmp_ppdu_desc = NULL; 5029 struct cdp_tx_completion_ppdu_user *tmp_user; 5030 uint32_t time_delta; 5031 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5032 5033 /* 5034 * Find ppdu_id node exists or not 5035 */ 5036 TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->ppdu_info_list, 5037 ppdu_info_list_elem, ppdu_info_next) { 5038 if (ppdu_info && (ppdu_info->ppdu_id == ppdu_id)) { 5039 if (ppdu_info->tsf_l32 > tsf_l32) 5040 time_delta = (MAX_TSF_32 - 5041 ppdu_info->tsf_l32) + tsf_l32; 5042 else 5043 time_delta = tsf_l32 - ppdu_info->tsf_l32; 5044 5045 if (time_delta > WRAP_DROP_TSF_DELTA) { 5046 TAILQ_REMOVE(&mon_pdev->ppdu_info_list, 5047 ppdu_info, ppdu_info_list_elem); 5048 mon_pdev->list_depth--; 5049 pdev->stats.ppdu_wrap_drop++; 5050 tmp_ppdu_desc = 5051 (struct cdp_tx_completion_ppdu *) 5052 qdf_nbuf_data(ppdu_info->nbuf); 5053 tmp_user = &tmp_ppdu_desc->user[0]; 5054 dp_htt_tx_stats_info("S_PID [%d] S_TSF[%u] TLV_BITMAP[0x%x] [CMPLTN - %d ACK_BA - %d] CS[%d] - R_PID[%d] R_TSF[%u] R_TLV_TAG[0x%x]\n", 5055 ppdu_info->ppdu_id, 5056 ppdu_info->tsf_l32, 5057 ppdu_info->tlv_bitmap, 5058 tmp_user->completion_status, 5059 ppdu_info->compltn_common_tlv, 5060 ppdu_info->ack_ba_tlv, 5061 ppdu_id, tsf_l32, 5062 tlv_type); 5063 qdf_nbuf_free(ppdu_info->nbuf); 5064 ppdu_info->nbuf = NULL; 5065 qdf_mem_free(ppdu_info); 5066 } else { 5067 break; 5068 } 5069 } 5070 } 5071 5072 /* 5073 * check if it is ack ba tlv and if it is not there in ppdu info 5074 * list then check it in sched completion ppdu list 5075 */ 5076 if (!ppdu_info && 5077 tlv_type == HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) { 5078 TAILQ_FOREACH(s_ppdu_info, 5079 &mon_pdev->sched_comp_ppdu_list, 5080 ppdu_info_list_elem) { 5081 if (s_ppdu_info && (s_ppdu_info->ppdu_id == ppdu_id)) { 5082 if (s_ppdu_info->tsf_l32 > tsf_l32) 5083 time_delta = (MAX_TSF_32 - 5084 s_ppdu_info->tsf_l32) + 5085 tsf_l32; 5086 else 5087 time_delta = tsf_l32 - 5088 s_ppdu_info->tsf_l32; 5089 if (time_delta < WRAP_DROP_TSF_DELTA) { 5090 ppdu_info = s_ppdu_info; 5091 break; 5092 } 5093 } else { 5094 /* 5095 * ACK BA STATUS TLV comes sequential order 5096 * if we received ack ba status tlv for second 5097 * ppdu and first ppdu is still waiting for 5098 * ACK BA STATUS TLV. Based on fw comment 5099 * we won't receive it tlv later. So we can 5100 * set ppdu info done. 5101 */ 5102 if (s_ppdu_info) 5103 s_ppdu_info->done = 1; 5104 } 5105 } 5106 } 5107 5108 if (ppdu_info) { 5109 if (ppdu_info->tlv_bitmap & (1 << tlv_type)) { 5110 /* 5111 * if we get tlv_type that is already been processed 5112 * for ppdu, that means we got a new ppdu with same 5113 * ppdu id. Hence Flush the older ppdu 5114 * for MUMIMO and OFDMA, In a PPDU we have 5115 * multiple user with same tlv types. tlv bitmap is 5116 * used to check whether SU or MU_MIMO/OFDMA 5117 */ 5118 if (!(ppdu_info->tlv_bitmap & 5119 (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV))) 5120 return ppdu_info; 5121 5122 ppdu_desc = (struct cdp_tx_completion_ppdu *) 5123 qdf_nbuf_data(ppdu_info->nbuf); 5124 5125 /* 5126 * apart from ACK BA STATUS TLV rest all comes in order 5127 * so if tlv type not ACK BA STATUS TLV we can deliver 5128 * ppdu_info 5129 */ 5130 if ((tlv_type == 5131 HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) && 5132 ((ppdu_desc->htt_frame_type == 5133 HTT_STATS_FTYPE_SGEN_MU_BAR) || 5134 (ppdu_desc->htt_frame_type == 5135 HTT_STATS_FTYPE_SGEN_BE_MU_BAR))) 5136 return ppdu_info; 5137 5138 dp_tx_ppdu_desc_deliver(pdev, ppdu_info); 5139 } else { 5140 return ppdu_info; 5141 } 5142 } 5143 5144 /* 5145 * Flush the head ppdu descriptor if ppdu desc list reaches max 5146 * threshold 5147 */ 5148 if (mon_pdev->list_depth > HTT_PPDU_DESC_MAX_DEPTH) { 5149 ppdu_info = TAILQ_FIRST(&mon_pdev->ppdu_info_list); 5150 TAILQ_REMOVE(&mon_pdev->ppdu_info_list, 5151 ppdu_info, ppdu_info_list_elem); 5152 mon_pdev->list_depth--; 5153 pdev->stats.ppdu_drop++; 5154 qdf_nbuf_free(ppdu_info->nbuf); 5155 ppdu_info->nbuf = NULL; 5156 qdf_mem_free(ppdu_info); 5157 } 5158 5159 size = sizeof(struct cdp_tx_completion_ppdu) + 5160 (max_users * sizeof(struct cdp_tx_completion_ppdu_user)); 5161 5162 /* 5163 * Allocate new ppdu_info node 5164 */ 5165 ppdu_info = qdf_mem_malloc(sizeof(struct ppdu_info)); 5166 if (!ppdu_info) 5167 return NULL; 5168 5169 ppdu_info->nbuf = qdf_nbuf_alloc(pdev->soc->osdev, size, 5170 0, 4, TRUE); 5171 if (!ppdu_info->nbuf) { 5172 qdf_mem_free(ppdu_info); 5173 return NULL; 5174 } 5175 5176 ppdu_info->ppdu_desc = 5177 (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); 5178 qdf_mem_zero(qdf_nbuf_data(ppdu_info->nbuf), size); 5179 5180 if (!qdf_nbuf_put_tail(ppdu_info->nbuf, size)) { 5181 dp_mon_err("No tailroom for HTT PPDU"); 5182 qdf_nbuf_free(ppdu_info->nbuf); 5183 ppdu_info->nbuf = NULL; 5184 ppdu_info->last_user = 0; 5185 qdf_mem_free(ppdu_info); 5186 return NULL; 5187 } 5188 5189 ppdu_info->ppdu_desc->max_users = max_users; 5190 ppdu_info->tsf_l32 = tsf_l32; 5191 /* 5192 * No lock is needed because all PPDU TLVs are processed in 5193 * same context and this list is updated in same context 5194 */ 5195 TAILQ_INSERT_TAIL(&mon_pdev->ppdu_info_list, ppdu_info, 5196 ppdu_info_list_elem); 5197 mon_pdev->list_depth++; 5198 return ppdu_info; 5199 } 5200 5201 #define DP_HTT_PPDU_ID_MASK 0x00FFFFFF 5202 /** 5203 * dp_htt_mask_ppdu_id() - Function to mask ppdu_id 5204 * @ppdu_id: PPDU ID 5205 * 5206 * Return: Masked ppdu_id 5207 */ dp_htt_mask_ppdu_id(uint32_t ppdu_id)5208 static inline uint32_t dp_htt_mask_ppdu_id(uint32_t ppdu_id) 5209 { 5210 return (ppdu_id & DP_HTT_PPDU_ID_MASK); 5211 } 5212 5213 /** 5214 * dp_htt_process_tlv() - Function to process each PPDU TLVs 5215 * @pdev: DP pdev handle 5216 * @htt_t2h_msg: HTT target to host message 5217 * 5218 * Return: ppdu_info per ppdu tlv structure 5219 */ dp_htt_process_tlv(struct dp_pdev * pdev,qdf_nbuf_t htt_t2h_msg)5220 static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, 5221 qdf_nbuf_t htt_t2h_msg) 5222 { 5223 uint32_t length; 5224 uint32_t ppdu_id; 5225 uint8_t tlv_type; 5226 uint32_t tlv_length, tlv_bitmap_expected; 5227 uint8_t *tlv_buf; 5228 struct ppdu_info *ppdu_info = NULL; 5229 struct cdp_tx_completion_ppdu *ppdu_desc = NULL; 5230 uint8_t max_users = CDP_MU_MAX_USERS; 5231 uint32_t tsf_l32; 5232 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5233 5234 uint32_t *msg_word = (uint32_t *)qdf_nbuf_data(htt_t2h_msg); 5235 5236 length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word); 5237 5238 msg_word = msg_word + 1; 5239 ppdu_id = HTT_T2H_PPDU_STATS_PPDU_ID_GET(*msg_word); 5240 ppdu_id = dp_htt_mask_ppdu_id(ppdu_id); 5241 5242 msg_word = msg_word + 1; 5243 tsf_l32 = (uint32_t)(*msg_word); 5244 5245 msg_word = msg_word + 2; 5246 while (length > 0) { 5247 tlv_buf = (uint8_t *)msg_word; 5248 tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word); 5249 tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word); 5250 if (qdf_likely(tlv_type < CDP_PPDU_STATS_MAX_TAG)) 5251 pdev->stats.ppdu_stats_counter[tlv_type]++; 5252 5253 if (tlv_length == 0) 5254 break; 5255 5256 tlv_length += HTT_TLV_HDR_LEN; 5257 5258 /* 5259 * Not allocating separate ppdu descriptor for MGMT Payload 5260 * TLV as this is sent as separate WDI indication and it 5261 * doesn't contain any ppdu information 5262 */ 5263 if (tlv_type == HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) { 5264 mon_pdev->mgmtctrl_frm_info.mgmt_buf = tlv_buf; 5265 mon_pdev->mgmtctrl_frm_info.ppdu_id = ppdu_id; 5266 mon_pdev->mgmtctrl_frm_info.mgmt_buf_len = 5267 HTT_PPDU_STATS_TX_MGMTCTRL_TLV_FRAME_LENGTH_GET 5268 (*(msg_word + 1)); 5269 msg_word = 5270 (uint32_t *)((uint8_t *)tlv_buf + tlv_length); 5271 length -= (tlv_length); 5272 continue; 5273 } 5274 5275 /* 5276 * retrieve max_users if it's USERS_INFO, 5277 * else, it's 1 for COMPLTN_FLUSH, 5278 * else, use CDP_MU_MAX_USERS 5279 */ 5280 if (tlv_type == HTT_PPDU_STATS_USERS_INFO_TLV) { 5281 max_users = 5282 HTT_PPDU_STATS_USERS_INFO_TLV_MAX_USERS_GET(*(msg_word + 1)); 5283 } else if (tlv_type == HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) { 5284 max_users = 1; 5285 } 5286 5287 ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type, 5288 tsf_l32, max_users); 5289 if (!ppdu_info) 5290 return NULL; 5291 5292 ppdu_info->ppdu_id = ppdu_id; 5293 ppdu_info->tlv_bitmap |= (1 << tlv_type); 5294 5295 dp_process_ppdu_tag(pdev, msg_word, tlv_length, ppdu_info); 5296 5297 /* 5298 * Increment pdev level tlv count to monitor 5299 * missing TLVs 5300 */ 5301 mon_pdev->tlv_count++; 5302 ppdu_info->last_tlv_cnt = mon_pdev->tlv_count; 5303 msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length); 5304 length -= (tlv_length); 5305 } 5306 5307 if (!ppdu_info) 5308 return NULL; 5309 5310 mon_pdev->last_ppdu_id = ppdu_id; 5311 5312 tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP; 5313 5314 if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode || 5315 mon_pdev->tx_capture_enabled) { 5316 if (ppdu_info->is_ampdu) 5317 tlv_bitmap_expected = 5318 dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap( 5319 ppdu_info->tlv_bitmap); 5320 } 5321 5322 ppdu_desc = ppdu_info->ppdu_desc; 5323 5324 if (!ppdu_desc) 5325 return NULL; 5326 5327 if (ppdu_desc->user[ppdu_desc->last_usr_index].completion_status != 5328 HTT_PPDU_STATS_USER_STATUS_OK) { 5329 tlv_bitmap_expected = tlv_bitmap_expected & 0xFF; 5330 } 5331 5332 /* 5333 * for frame type DATA and BAR, we update stats based on MSDU, 5334 * successful msdu and mpdu are populate from ACK BA STATUS TLV 5335 * which comes out of order. successful mpdu also populated from 5336 * COMPLTN COMMON TLV which comes in order. for every ppdu_info 5337 * we store successful mpdu from both tlv and compare before delivering 5338 * to make sure we received ACK BA STATUS TLV. For some self generated 5339 * frame we won't get ack ba status tlv so no need to wait for 5340 * ack ba status tlv. 5341 */ 5342 if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL && 5343 ppdu_desc->htt_frame_type != HTT_STATS_FTYPE_SGEN_QOS_NULL) { 5344 /* 5345 * most of the time bar frame will have duplicate ack ba 5346 * status tlv 5347 */ 5348 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR && 5349 (ppdu_info->compltn_common_tlv != ppdu_info->ack_ba_tlv)) 5350 return NULL; 5351 /* 5352 * For data frame, compltn common tlv should match ack ba status 5353 * tlv and completion status. Reason we are checking first user 5354 * for ofdma, completion seen at next MU BAR frm, for mimo 5355 * only for first user completion will be immediate. 5356 */ 5357 if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA && 5358 (ppdu_desc->user[0].completion_status == 0 && 5359 (ppdu_info->compltn_common_tlv != ppdu_info->ack_ba_tlv))) 5360 return NULL; 5361 } 5362 5363 /* 5364 * Once all the TLVs for a given PPDU has been processed, 5365 * return PPDU status to be delivered to higher layer. 5366 * tlv_bitmap_expected can't be available for different frame type. 5367 * But SCHED CMD STATS TLV is the last TLV from the FW for a ppdu. 5368 * apart from ACK BA TLV, FW sends other TLV in sequential order. 5369 * flush tlv comes separate. 5370 */ 5371 if ((ppdu_info->tlv_bitmap != 0 && 5372 (ppdu_info->tlv_bitmap & 5373 (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV))) || 5374 (ppdu_info->tlv_bitmap & 5375 (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV))) { 5376 ppdu_info->done = 1; 5377 return ppdu_info; 5378 } 5379 5380 return NULL; 5381 } 5382 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 5383 5384 #ifdef QCA_ENHANCED_STATS_SUPPORT 5385 /** 5386 * dp_tx_ppdu_stats_feat_enable_check() - Check if feature(s) is enabled to 5387 * consume stats received from FW via HTT 5388 * @pdev: Datapath pdev handle 5389 * 5390 * Return: void 5391 */ dp_tx_ppdu_stats_feat_enable_check(struct dp_pdev * pdev)5392 static bool dp_tx_ppdu_stats_feat_enable_check(struct dp_pdev *pdev) 5393 { 5394 struct dp_soc *soc = pdev->soc; 5395 struct dp_mon_ops *mon_ops = NULL; 5396 5397 mon_ops = dp_mon_ops_get(soc); 5398 if (mon_ops && mon_ops->mon_ppdu_stats_feat_enable_check) 5399 return mon_ops->mon_ppdu_stats_feat_enable_check(pdev); 5400 else 5401 return false; 5402 } 5403 #endif 5404 5405 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 dp_htt_process_smu_ppdu_stats_tlv(struct dp_soc * soc,qdf_nbuf_t htt_t2h_msg)5406 static void dp_htt_process_smu_ppdu_stats_tlv(struct dp_soc *soc, 5407 qdf_nbuf_t htt_t2h_msg) 5408 { 5409 uint32_t length; 5410 uint8_t tlv_type; 5411 uint32_t tlv_length, tlv_expected_size; 5412 uint8_t *tlv_buf; 5413 5414 uint32_t *msg_word = (uint32_t *)qdf_nbuf_data(htt_t2h_msg); 5415 5416 length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word); 5417 5418 msg_word = msg_word + 4; 5419 5420 while (length > 0) { 5421 tlv_buf = (uint8_t *)msg_word; 5422 tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word); 5423 tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word); 5424 5425 if (tlv_length == 0) 5426 break; 5427 5428 tlv_length += HTT_TLV_HDR_LEN; 5429 5430 if (tlv_type == HTT_PPDU_STATS_FOR_SMU_TLV) { 5431 tlv_expected_size = sizeof(htt_ppdu_stats_for_smu_tlv); 5432 5433 if (tlv_length >= tlv_expected_size) 5434 dp_wdi_event_handler( 5435 WDI_EVENT_PKT_CAPTURE_PPDU_STATS, 5436 soc, msg_word, HTT_INVALID_VDEV, 5437 WDI_NO_VAL, 0); 5438 } 5439 msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length); 5440 length -= (tlv_length); 5441 } 5442 } 5443 #endif 5444 5445 #if defined(WDI_EVENT_ENABLE) 5446 #ifdef QCA_ENHANCED_STATS_SUPPORT 5447 /** 5448 * dp_txrx_ppdu_stats_handler() - Function to process HTT PPDU stats from FW 5449 * @soc: DP SOC handle 5450 * @pdev_id: pdev id 5451 * @htt_t2h_msg: HTT message nbuf 5452 * 5453 * Return: void 5454 */ dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5455 static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, 5456 uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg) 5457 { 5458 struct dp_pdev *pdev; 5459 struct ppdu_info *ppdu_info = NULL; 5460 bool free_buf = true; 5461 struct dp_mon_pdev *mon_pdev; 5462 5463 if (pdev_id >= MAX_PDEV_CNT) 5464 return true; 5465 5466 pdev = soc->pdev_list[pdev_id]; 5467 if (!pdev) 5468 return true; 5469 5470 mon_pdev = pdev->monitor_pdev; 5471 if (!mon_pdev) 5472 return true; 5473 5474 if (!dp_tx_ppdu_stats_feat_enable_check(pdev)) 5475 return free_buf; 5476 5477 qdf_spin_lock_bh(&mon_pdev->ppdu_stats_lock); 5478 ppdu_info = dp_htt_process_tlv(pdev, htt_t2h_msg); 5479 5480 if (mon_pdev->mgmtctrl_frm_info.mgmt_buf) { 5481 if (dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv 5482 (pdev, htt_t2h_msg, mon_pdev->mgmtctrl_frm_info.ppdu_id) != 5483 QDF_STATUS_SUCCESS) 5484 free_buf = false; 5485 } 5486 5487 if (ppdu_info) 5488 dp_tx_ppdu_desc_deliver(pdev, ppdu_info); 5489 5490 mon_pdev->mgmtctrl_frm_info.mgmt_buf = NULL; 5491 mon_pdev->mgmtctrl_frm_info.mgmt_buf_len = 0; 5492 mon_pdev->mgmtctrl_frm_info.ppdu_id = 0; 5493 5494 qdf_spin_unlock_bh(&mon_pdev->ppdu_stats_lock); 5495 5496 return free_buf; 5497 } 5498 #elif defined(WLAN_FEATURE_PKT_CAPTURE_V2) dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5499 static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, 5500 uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg) 5501 { 5502 if (wlan_cfg_get_pkt_capture_mode(soc->wlan_cfg_ctx)) 5503 dp_htt_process_smu_ppdu_stats_tlv(soc, htt_t2h_msg); 5504 5505 return true; 5506 } 5507 #elif (!defined(REMOVE_PKT_LOG)) dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5508 static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, 5509 uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg) 5510 { 5511 return true; 5512 } 5513 #endif/* QCA_ENHANCED_STATS_SUPPORT */ 5514 #endif 5515 5516 #if defined(WDI_EVENT_ENABLE) &&\ 5517 (defined(QCA_ENHANCED_STATS_SUPPORT) || !defined(REMOVE_PKT_LOG) || \ 5518 defined(WLAN_FEATURE_PKT_CAPTURE_V2)) 5519 bool dp_ppdu_stats_ind_handler(struct htt_soc * soc,uint32_t * msg_word,qdf_nbuf_t htt_t2h_msg)5520 dp_ppdu_stats_ind_handler(struct htt_soc *soc, 5521 uint32_t *msg_word, 5522 qdf_nbuf_t htt_t2h_msg) 5523 { 5524 u_int8_t pdev_id; 5525 u_int8_t target_pdev_id; 5526 bool free_buf; 5527 5528 target_pdev_id = HTT_T2H_PPDU_STATS_PDEV_ID_GET(*msg_word); 5529 pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc, 5530 target_pdev_id); 5531 dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc, 5532 htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL, 5533 pdev_id); 5534 5535 free_buf = dp_txrx_ppdu_stats_handler(soc->dp_soc, pdev_id, 5536 htt_t2h_msg); 5537 5538 return free_buf; 5539 } 5540 #endif 5541 5542 void dp_mon_set_bsscolor(struct dp_pdev * pdev,uint8_t bsscolor)5543 dp_mon_set_bsscolor(struct dp_pdev *pdev, uint8_t bsscolor) 5544 { 5545 pdev->monitor_pdev->rx_mon_recv_status.bsscolor = bsscolor; 5546 } 5547 dp_pdev_get_filter_ucast_data(struct cdp_pdev * pdev_handle)5548 bool dp_pdev_get_filter_ucast_data(struct cdp_pdev *pdev_handle) 5549 { 5550 struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; 5551 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5552 5553 if ((mon_pdev->fp_data_filter & FILTER_DATA_UCAST) || 5554 (mon_pdev->mo_data_filter & FILTER_DATA_UCAST)) 5555 return true; 5556 5557 return false; 5558 } 5559 dp_pdev_get_filter_mcast_data(struct cdp_pdev * pdev_handle)5560 bool dp_pdev_get_filter_mcast_data(struct cdp_pdev *pdev_handle) 5561 { 5562 struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; 5563 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5564 5565 if ((mon_pdev->fp_data_filter & FILTER_DATA_MCAST) || 5566 (mon_pdev->mo_data_filter & FILTER_DATA_MCAST)) 5567 return true; 5568 5569 return false; 5570 } 5571 dp_pdev_get_filter_non_data(struct cdp_pdev * pdev_handle)5572 bool dp_pdev_get_filter_non_data(struct cdp_pdev *pdev_handle) 5573 { 5574 struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; 5575 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5576 5577 if ((mon_pdev->fp_mgmt_filter & FILTER_MGMT_ALL) || 5578 (mon_pdev->mo_mgmt_filter & FILTER_MGMT_ALL)) { 5579 if ((mon_pdev->fp_ctrl_filter & FILTER_CTRL_ALL) || 5580 (mon_pdev->mo_ctrl_filter & FILTER_CTRL_ALL)) { 5581 return true; 5582 } 5583 } 5584 5585 return false; 5586 } 5587 dp_mon_soc_cfg_init(struct dp_soc * soc)5588 QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc) 5589 { 5590 int target_type; 5591 struct dp_mon_soc *mon_soc = soc->monitor_soc; 5592 struct cdp_mon_ops *cdp_ops; 5593 5594 cdp_ops = dp_mon_cdp_ops_get(soc); 5595 target_type = hal_get_target_type(soc->hal_soc); 5596 switch (target_type) { 5597 case TARGET_TYPE_QCA6290: 5598 case TARGET_TYPE_QCA6390: 5599 case TARGET_TYPE_QCA6490: 5600 case TARGET_TYPE_QCA6750: 5601 case TARGET_TYPE_KIWI: 5602 case TARGET_TYPE_MANGO: 5603 case TARGET_TYPE_PEACH: 5604 case TARGET_TYPE_WCN6450: 5605 /* do nothing */ 5606 break; 5607 case TARGET_TYPE_QCA8074: 5608 wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx, 5609 MON_BUF_MIN_ENTRIES); 5610 break; 5611 case TARGET_TYPE_QCA8074V2: 5612 case TARGET_TYPE_QCA6018: 5613 case TARGET_TYPE_QCA9574: 5614 wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx, 5615 MON_BUF_MIN_ENTRIES); 5616 mon_soc->hw_nac_monitor_support = 1; 5617 break; 5618 case TARGET_TYPE_QCN9000: 5619 wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx, 5620 MON_BUF_MIN_ENTRIES); 5621 mon_soc->hw_nac_monitor_support = 1; 5622 if (cfg_get(soc->ctrl_psoc, CFG_DP_FULL_MON_MODE)) { 5623 if (cdp_ops && cdp_ops->config_full_mon_mode) 5624 cdp_ops->config_full_mon_mode((struct cdp_soc_t *)soc, 1); 5625 } 5626 break; 5627 case TARGET_TYPE_QCA5018: 5628 case TARGET_TYPE_QCN6122: 5629 case TARGET_TYPE_QCN9160: 5630 wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx, 5631 MON_BUF_MIN_ENTRIES); 5632 mon_soc->hw_nac_monitor_support = 1; 5633 break; 5634 case TARGET_TYPE_QCN9224: 5635 case TARGET_TYPE_QCA5332: 5636 case TARGET_TYPE_QCN6432: 5637 wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx, 5638 MON_BUF_MIN_ENTRIES); 5639 mon_soc->hw_nac_monitor_support = 1; 5640 mon_soc->monitor_mode_v2 = 1; 5641 break; 5642 default: 5643 dp_mon_info("%s: Unknown tgt type %d\n", __func__, target_type); 5644 qdf_assert_always(0); 5645 break; 5646 } 5647 5648 dp_mon_info("hw_nac_monitor_support = %d", 5649 mon_soc->hw_nac_monitor_support); 5650 5651 return QDF_STATUS_SUCCESS; 5652 } 5653 5654 /** 5655 * dp_mon_pdev_per_target_config() - Target specific monitor pdev configuration 5656 * @pdev: PDEV handle [Should be valid] 5657 * 5658 * Return: None 5659 */ dp_mon_pdev_per_target_config(struct dp_pdev * pdev)5660 static void dp_mon_pdev_per_target_config(struct dp_pdev *pdev) 5661 { 5662 struct dp_soc *soc = pdev->soc; 5663 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 5664 int target_type; 5665 5666 target_type = hal_get_target_type(soc->hal_soc); 5667 switch (target_type) { 5668 case TARGET_TYPE_KIWI: 5669 case TARGET_TYPE_QCN9224: 5670 case TARGET_TYPE_QCA5332: 5671 case TARGET_TYPE_QCN6432: 5672 case TARGET_TYPE_MANGO: 5673 mon_pdev->is_tlv_hdr_64_bit = true; 5674 mon_pdev->tlv_hdr_size = HAL_RX_TLV64_HDR_SIZE; 5675 break; 5676 case TARGET_TYPE_PEACH: 5677 default: 5678 mon_pdev->is_tlv_hdr_64_bit = false; 5679 mon_pdev->tlv_hdr_size = HAL_RX_TLV32_HDR_SIZE; 5680 break; 5681 } 5682 } 5683 5684 static dp_mon_rings_alloc(struct dp_pdev * pdev)5685 QDF_STATUS dp_mon_rings_alloc(struct dp_pdev *pdev) 5686 { 5687 QDF_STATUS status = QDF_STATUS_SUCCESS; 5688 struct dp_mon_ops *mon_ops; 5689 5690 mon_ops = dp_mon_ops_get(pdev->soc); 5691 if (!mon_ops) { 5692 dp_mon_err("mon_ops is NULL"); 5693 return QDF_STATUS_E_FAILURE; 5694 } 5695 5696 if (mon_ops->mon_rings_alloc[0]) { 5697 status = mon_ops->mon_rings_alloc[0](pdev); 5698 if (QDF_IS_STATUS_ERROR(status)) { 5699 dp_mon_err("error: %d", status); 5700 goto error; 5701 } 5702 } 5703 5704 if (mon_ops->mon_rings_alloc[1]) { 5705 status = mon_ops->mon_rings_alloc[1](pdev); 5706 if (QDF_IS_STATUS_ERROR(status)) { 5707 dp_mon_err("error: %d", status); 5708 goto error; 5709 } 5710 } 5711 5712 error: 5713 return status; 5714 } 5715 5716 static dp_mon_rings_free(struct dp_pdev * pdev)5717 void dp_mon_rings_free(struct dp_pdev *pdev) 5718 { 5719 struct dp_mon_ops *mon_ops; 5720 5721 mon_ops = dp_mon_ops_get(pdev->soc); 5722 if (!mon_ops) { 5723 dp_mon_err("mon_ops is NULL"); 5724 return; 5725 } 5726 5727 if (mon_ops->mon_rings_free[0]) 5728 mon_ops->mon_rings_free[0](pdev); 5729 5730 if (mon_ops->mon_rings_free[1]) 5731 mon_ops->mon_rings_free[1](pdev); 5732 } 5733 5734 static dp_mon_rings_init(struct dp_pdev * pdev)5735 QDF_STATUS dp_mon_rings_init(struct dp_pdev *pdev) 5736 { 5737 QDF_STATUS status = QDF_STATUS_SUCCESS; 5738 struct dp_mon_ops *mon_ops; 5739 5740 mon_ops = dp_mon_ops_get(pdev->soc); 5741 if (!mon_ops) { 5742 dp_mon_err("mon_ops is NULL"); 5743 return QDF_STATUS_E_FAILURE; 5744 } 5745 5746 if (mon_ops->mon_rings_init[0]) { 5747 status = mon_ops->mon_rings_init[0](pdev); 5748 if (QDF_IS_STATUS_ERROR(status)) { 5749 dp_mon_err("error: %d", status); 5750 goto error; 5751 } 5752 } 5753 5754 if (mon_ops->mon_rings_init[1]) { 5755 status = mon_ops->mon_rings_init[1](pdev); 5756 if (QDF_IS_STATUS_ERROR(status)) { 5757 dp_mon_err("error: %d", status); 5758 goto error; 5759 } 5760 } 5761 5762 error: 5763 return status; 5764 } 5765 5766 static dp_mon_rings_deinit(struct dp_pdev * pdev)5767 void dp_mon_rings_deinit(struct dp_pdev *pdev) 5768 { 5769 struct dp_mon_ops *mon_ops; 5770 5771 mon_ops = dp_mon_ops_get(pdev->soc); 5772 if (!mon_ops) { 5773 dp_mon_err("mon_ops is NULL"); 5774 return; 5775 } 5776 5777 if (mon_ops->mon_rings_deinit[0]) 5778 mon_ops->mon_rings_deinit[0](pdev); 5779 5780 if (mon_ops->mon_rings_deinit[1]) 5781 mon_ops->mon_rings_deinit[1](pdev); 5782 } 5783 dp_mon_pdev_attach(struct dp_pdev * pdev)5784 QDF_STATUS dp_mon_pdev_attach(struct dp_pdev *pdev) 5785 { 5786 struct dp_soc *soc; 5787 struct dp_mon_pdev *mon_pdev; 5788 struct dp_mon_ops *mon_ops; 5789 qdf_size_t mon_pdev_context_size; 5790 5791 if (!pdev) { 5792 dp_mon_err("pdev is NULL"); 5793 goto fail0; 5794 } 5795 5796 soc = pdev->soc; 5797 5798 mon_pdev_context_size = soc->arch_ops.txrx_get_mon_context_size(DP_CONTEXT_TYPE_MON_PDEV); 5799 mon_pdev = dp_context_alloc_mem(soc, DP_MON_PDEV_TYPE, mon_pdev_context_size); 5800 if (!mon_pdev) { 5801 dp_mon_err("%pK: MONITOR pdev allocation failed", pdev); 5802 goto fail0; 5803 } 5804 5805 pdev->monitor_pdev = mon_pdev; 5806 mon_ops = dp_mon_ops_get(pdev->soc); 5807 if (!mon_ops) { 5808 dp_mon_err("%pK: Invalid monitor ops", pdev); 5809 goto fail1; 5810 } 5811 5812 if (mon_ops->mon_pdev_alloc) { 5813 if (mon_ops->mon_pdev_alloc(pdev)) { 5814 dp_mon_err("%pK: MONITOR pdev alloc failed", pdev); 5815 goto fail1; 5816 } 5817 } 5818 5819 if (dp_mon_rings_alloc(pdev)) { 5820 dp_mon_err("%pK: MONITOR rings setup failed", pdev); 5821 goto fail2; 5822 } 5823 5824 /* Rx monitor mode specific init */ 5825 if (mon_ops->rx_mon_desc_pool_alloc) { 5826 if (mon_ops->rx_mon_desc_pool_alloc(pdev)) { 5827 dp_mon_err("%pK: dp_rx_pdev_mon_attach failed", pdev); 5828 goto fail3; 5829 } 5830 } 5831 5832 if (mon_ops->mon_rx_ppdu_info_cache_create) { 5833 if (mon_ops->mon_rx_ppdu_info_cache_create(pdev)) { 5834 dp_mon_err("%pK: dp_rx_pdev_mon_attach failed", pdev); 5835 goto fail4; 5836 } 5837 } 5838 pdev->monitor_pdev = mon_pdev; 5839 dp_mon_pdev_per_target_config(pdev); 5840 5841 return QDF_STATUS_SUCCESS; 5842 fail4: 5843 if (mon_ops->rx_mon_desc_pool_free) 5844 mon_ops->rx_mon_desc_pool_free(pdev); 5845 fail3: 5846 dp_mon_rings_free(pdev); 5847 fail2: 5848 if (mon_ops->mon_pdev_free) 5849 mon_ops->mon_pdev_free(pdev); 5850 fail1: 5851 pdev->monitor_pdev = NULL; 5852 dp_context_free_mem(soc, DP_MON_PDEV_TYPE, mon_pdev); 5853 fail0: 5854 return QDF_STATUS_E_NOMEM; 5855 } 5856 dp_mon_pdev_detach(struct dp_pdev * pdev)5857 QDF_STATUS dp_mon_pdev_detach(struct dp_pdev *pdev) 5858 { 5859 struct dp_mon_pdev *mon_pdev; 5860 struct dp_mon_ops *mon_ops = NULL; 5861 5862 if (!pdev) { 5863 dp_mon_err("pdev is NULL"); 5864 return QDF_STATUS_E_FAILURE; 5865 } 5866 5867 mon_pdev = pdev->monitor_pdev; 5868 if (!mon_pdev) { 5869 dp_mon_err("Monitor pdev is NULL"); 5870 return QDF_STATUS_E_FAILURE; 5871 } 5872 5873 mon_ops = dp_mon_ops_get(pdev->soc); 5874 if (!mon_ops) { 5875 dp_mon_err("Monitor ops is NULL"); 5876 return QDF_STATUS_E_FAILURE; 5877 } 5878 5879 if (mon_ops->mon_rx_ppdu_info_cache_destroy) 5880 mon_ops->mon_rx_ppdu_info_cache_destroy(pdev); 5881 if (mon_ops->rx_mon_desc_pool_free) 5882 mon_ops->rx_mon_desc_pool_free(pdev); 5883 dp_mon_rings_free(pdev); 5884 if (mon_ops->mon_pdev_free) 5885 mon_ops->mon_pdev_free(pdev); 5886 5887 dp_context_free_mem(pdev->soc, DP_MON_PDEV_TYPE, mon_pdev); 5888 pdev->monitor_pdev = NULL; 5889 return QDF_STATUS_SUCCESS; 5890 } 5891 5892 #ifdef WLAN_TX_PKT_CAPTURE_ENH dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5893 void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops) 5894 { 5895 mon_ops->mon_tx_ppdu_stats_attach = dp_tx_ppdu_stats_attach_1_0; 5896 mon_ops->mon_tx_ppdu_stats_detach = dp_tx_ppdu_stats_detach_1_0; 5897 mon_ops->mon_peer_tx_capture_filter_check = 5898 dp_peer_tx_capture_filter_check_1_0; 5899 } 5900 #elif defined(WLAN_TX_PKT_CAPTURE_ENH_BE) && defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE) dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5901 void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops) 5902 { 5903 mon_ops->mon_tx_ppdu_stats_attach = dp_tx_ppdu_stats_attach_2_0; 5904 mon_ops->mon_tx_ppdu_stats_detach = dp_tx_ppdu_stats_detach_2_0; 5905 mon_ops->mon_peer_tx_capture_filter_check = NULL; 5906 } 5907 #elif (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH)) dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5908 void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops) 5909 { 5910 mon_ops->mon_tx_ppdu_stats_attach = NULL; 5911 mon_ops->mon_tx_ppdu_stats_detach = NULL; 5912 mon_ops->mon_peer_tx_capture_filter_check = NULL; 5913 } 5914 #endif 5915 5916 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 5917 #if !defined(DISABLE_MON_CONFIG) dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5918 static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops) 5919 { 5920 mon_ops->mon_pdev_htt_srng_setup[0] = dp_mon_htt_srng_setup_1_0; 5921 mon_ops->mon_pdev_htt_srng_setup[1] = dp_mon_pdev_htt_srng_setup_2_0; 5922 mon_ops->mon_soc_htt_srng_setup = dp_mon_soc_htt_srng_setup_2_0; 5923 } 5924 #else dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5925 static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops) 5926 { 5927 } 5928 #endif 5929 dp_mon_register_lpc_ops_1_0(struct dp_mon_ops * mon_ops)5930 void dp_mon_register_lpc_ops_1_0(struct dp_mon_ops *mon_ops) 5931 { 5932 mon_ops->mon_soc_attach[0] = NULL; 5933 mon_ops->mon_soc_detach[0] = NULL; 5934 mon_ops->mon_soc_init[0] = NULL; 5935 mon_ops->mon_soc_deinit[0] = NULL; 5936 mon_ops->mon_soc_attach[1] = dp_mon_soc_attach_2_0; 5937 mon_ops->mon_soc_detach[1] = dp_mon_soc_detach_2_0; 5938 mon_ops->mon_soc_init[1] = dp_mon_soc_init_2_0; 5939 mon_ops->mon_soc_deinit[1] = dp_mon_soc_deinit_2_0; 5940 5941 dp_mon_config_register_ops(mon_ops); 5942 5943 mon_ops->mon_rings_alloc[0] = dp_mon_rings_alloc_1_0; 5944 mon_ops->mon_rings_free[0] = dp_mon_rings_free_1_0; 5945 mon_ops->mon_rings_init[0] = dp_mon_rings_init_1_0; 5946 mon_ops->mon_rings_deinit[0] = dp_mon_rings_deinit_1_0; 5947 mon_ops->mon_rings_alloc[1] = dp_pdev_mon_rings_alloc_2_0; 5948 mon_ops->mon_rings_free[1] = dp_pdev_mon_rings_free_2_0; 5949 mon_ops->mon_rings_init[1] = dp_pdev_mon_rings_init_2_0; 5950 mon_ops->mon_rings_deinit[1] = dp_pdev_mon_rings_deinit_2_0; 5951 5952 mon_ops->mon_filter_setup_tx_mon_mode = 5953 dp_mon_filter_setup_local_pkt_capture_tx; 5954 mon_ops->mon_filter_reset_tx_mon_mode = 5955 dp_mon_filter_reset_local_pkt_capture_tx; 5956 mon_ops->tx_mon_filter_update = dp_tx_mon_filter_update_2_0; 5957 5958 mon_ops->rx_hdr_length_set = dp_rx_mon_hdr_length_set; 5959 dp_mon_register_tx_pkt_enh_ops_1_0(mon_ops); 5960 } 5961 #else 5962 #if !defined(DISABLE_MON_CONFIG) dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5963 static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops) 5964 { 5965 mon_ops->mon_pdev_htt_srng_setup[0] = dp_mon_htt_srng_setup_1_0; 5966 mon_ops->mon_pdev_htt_srng_setup[1] = NULL; 5967 mon_ops->mon_soc_htt_srng_setup = NULL; 5968 } 5969 #else dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5970 static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops) 5971 { 5972 } 5973 #endif 5974 dp_mon_register_lpc_ops_1_0(struct dp_mon_ops * mon_ops)5975 void dp_mon_register_lpc_ops_1_0(struct dp_mon_ops *mon_ops) 5976 { 5977 mon_ops->mon_soc_attach[0] = NULL; 5978 mon_ops->mon_soc_detach[0] = NULL; 5979 mon_ops->mon_soc_init[0] = NULL; 5980 mon_ops->mon_soc_deinit[0] = NULL; 5981 mon_ops->mon_soc_attach[1] = NULL; 5982 mon_ops->mon_soc_detach[1] = NULL; 5983 mon_ops->mon_soc_init[1] = NULL; 5984 mon_ops->mon_soc_deinit[1] = NULL; 5985 5986 dp_mon_config_register_ops(mon_ops); 5987 5988 mon_ops->mon_rings_alloc[0] = dp_mon_rings_alloc_1_0; 5989 mon_ops->mon_rings_free[0] = dp_mon_rings_free_1_0; 5990 mon_ops->mon_rings_init[0] = dp_mon_rings_init_1_0; 5991 mon_ops->mon_rings_deinit[0] = dp_mon_rings_deinit_1_0; 5992 mon_ops->mon_rings_alloc[1] = NULL; 5993 mon_ops->mon_rings_free[1] = NULL; 5994 mon_ops->mon_rings_init[1] = NULL; 5995 mon_ops->mon_rings_deinit[1] = NULL; 5996 5997 mon_ops->mon_filter_setup_tx_mon_mode = NULL; 5998 mon_ops->mon_filter_reset_tx_mon_mode = NULL; 5999 mon_ops->tx_mon_filter_update = NULL; 6000 6001 mon_ops->rx_hdr_length_set = NULL; 6002 dp_mon_register_tx_pkt_enh_ops_1_0(mon_ops); 6003 } 6004 #endif 6005 dp_mon_pdev_init(struct dp_pdev * pdev)6006 QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev) 6007 { 6008 struct dp_mon_pdev *mon_pdev; 6009 struct dp_mon_ops *mon_ops = NULL; 6010 6011 if (!pdev) { 6012 dp_mon_err("pdev is NULL"); 6013 return QDF_STATUS_E_FAILURE; 6014 } 6015 6016 mon_pdev = pdev->monitor_pdev; 6017 6018 mon_pdev->invalid_mon_peer = qdf_mem_malloc(sizeof(struct dp_mon_peer)); 6019 if (!mon_pdev->invalid_mon_peer) { 6020 dp_mon_err("%pK: Memory allocation failed for invalid " 6021 "monitor peer", pdev); 6022 return QDF_STATUS_E_NOMEM; 6023 } 6024 6025 mon_ops = dp_mon_ops_get(pdev->soc); 6026 if (!mon_ops) { 6027 dp_mon_err("Monitor ops is NULL"); 6028 goto fail0; 6029 } 6030 6031 mon_pdev->filter = dp_mon_filter_alloc(mon_pdev); 6032 if (!mon_pdev->filter) { 6033 dp_mon_err("%pK: Memory allocation failed for monitor filter", 6034 pdev); 6035 goto fail0; 6036 } 6037 6038 if (mon_ops->tx_mon_filter_alloc) { 6039 if (mon_ops->tx_mon_filter_alloc(pdev)) { 6040 dp_mon_err("%pK: Memory allocation failed for tx monitor " 6041 "filter", pdev); 6042 goto fail1; 6043 } 6044 } 6045 6046 qdf_spinlock_create(&mon_pdev->ppdu_stats_lock); 6047 qdf_spinlock_create(&mon_pdev->neighbour_peer_mutex); 6048 mon_pdev->monitor_configured = false; 6049 mon_pdev->mon_chan_band = REG_BAND_UNKNOWN; 6050 6051 TAILQ_INIT(&mon_pdev->neighbour_peers_list); 6052 mon_pdev->neighbour_peers_added = false; 6053 mon_pdev->monitor_configured = false; 6054 6055 dp_mon_pdev_filter_init(mon_pdev); 6056 /* 6057 * initialize ppdu tlv list 6058 */ 6059 TAILQ_INIT(&mon_pdev->ppdu_info_list); 6060 TAILQ_INIT(&mon_pdev->sched_comp_ppdu_list); 6061 6062 mon_pdev->list_depth = 0; 6063 mon_pdev->tlv_count = 0; 6064 /* initlialize cal client timer */ 6065 dp_cal_client_attach(&mon_pdev->cal_client_ctx, 6066 dp_pdev_to_cdp_pdev(pdev), 6067 pdev->soc->osdev, 6068 &dp_iterate_update_peer_list); 6069 if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS) 6070 goto fail2; 6071 6072 if (mon_ops->mon_lite_mon_alloc) { 6073 if (mon_ops->mon_lite_mon_alloc(pdev) != QDF_STATUS_SUCCESS) { 6074 dp_mon_err("%pK: lite mon alloc failed", pdev); 6075 goto fail3; 6076 } 6077 } 6078 6079 if (dp_mon_rings_init(pdev)) { 6080 dp_mon_err("%pK: MONITOR rings setup failed", pdev); 6081 goto fail4; 6082 } 6083 6084 /* initialize sw monitor rx descriptors */ 6085 if (mon_ops->rx_mon_desc_pool_init) 6086 mon_ops->rx_mon_desc_pool_init(pdev); 6087 6088 /* allocate buffers and replenish the monitor RxDMA ring */ 6089 if (mon_ops->rx_mon_buffers_alloc) { 6090 if (mon_ops->rx_mon_buffers_alloc(pdev)) { 6091 dp_mon_err("%pK: rx mon buffers alloc failed", pdev); 6092 goto fail5; 6093 } 6094 } 6095 6096 /* attach monitor function */ 6097 dp_monitor_tx_ppdu_stats_attach(pdev); 6098 6099 /* mon pdev extended init */ 6100 if (mon_ops->mon_pdev_ext_init) 6101 mon_ops->mon_pdev_ext_init(pdev); 6102 6103 if (mon_ops->mon_rx_pdev_tlv_logger_init) 6104 mon_ops->mon_rx_pdev_tlv_logger_init(pdev); 6105 6106 mon_pdev->is_dp_mon_pdev_initialized = true; 6107 dp_mon_set_local_pkt_capture_running(mon_pdev, false); 6108 6109 return QDF_STATUS_SUCCESS; 6110 6111 fail5: 6112 if (mon_ops->rx_mon_desc_pool_deinit) 6113 mon_ops->rx_mon_desc_pool_deinit(pdev); 6114 6115 dp_mon_rings_deinit(pdev); 6116 fail4: 6117 if (mon_ops->mon_lite_mon_dealloc) 6118 mon_ops->mon_lite_mon_dealloc(pdev); 6119 fail3: 6120 dp_htt_ppdu_stats_detach(pdev); 6121 fail2: 6122 qdf_spinlock_destroy(&mon_pdev->neighbour_peer_mutex); 6123 qdf_spinlock_destroy(&mon_pdev->ppdu_stats_lock); 6124 if (mon_ops->tx_mon_filter_dealloc) 6125 mon_ops->tx_mon_filter_dealloc(pdev); 6126 fail1: 6127 dp_mon_filter_dealloc(mon_pdev); 6128 fail0: 6129 qdf_mem_free(mon_pdev->invalid_mon_peer); 6130 return QDF_STATUS_E_FAILURE; 6131 } 6132 dp_mon_pdev_deinit(struct dp_pdev * pdev)6133 QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev) 6134 { 6135 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 6136 struct dp_mon_ops *mon_ops = NULL; 6137 6138 mon_ops = dp_mon_ops_get(pdev->soc); 6139 if (!mon_ops) { 6140 dp_mon_err("Monitor ops is NULL"); 6141 return QDF_STATUS_E_FAILURE; 6142 } 6143 6144 if (!mon_pdev->is_dp_mon_pdev_initialized) 6145 return QDF_STATUS_SUCCESS; 6146 6147 dp_mon_filters_reset(pdev); 6148 6149 /* mon pdev extended deinit */ 6150 if (mon_ops->mon_pdev_ext_deinit) 6151 mon_ops->mon_pdev_ext_deinit(pdev); 6152 6153 if (mon_ops->mon_rx_pdev_tlv_logger_deinit) 6154 mon_ops->mon_rx_pdev_tlv_logger_deinit(pdev); 6155 6156 /* detach monitor function */ 6157 dp_monitor_tx_ppdu_stats_detach(pdev); 6158 6159 if (mon_ops->mon_lite_mon_dealloc) 6160 mon_ops->mon_lite_mon_dealloc(pdev); 6161 6162 if (mon_ops->rx_mon_buffers_free) 6163 mon_ops->rx_mon_buffers_free(pdev); 6164 if (mon_ops->rx_mon_desc_pool_deinit) 6165 mon_ops->rx_mon_desc_pool_deinit(pdev); 6166 dp_mon_rings_deinit(pdev); 6167 dp_cal_client_detach(&mon_pdev->cal_client_ctx); 6168 dp_htt_ppdu_stats_detach(pdev); 6169 qdf_spinlock_destroy(&mon_pdev->ppdu_stats_lock); 6170 dp_neighbour_peers_detach(pdev); 6171 dp_pktlogmod_exit(pdev); 6172 if (mon_ops->tx_mon_filter_dealloc) 6173 mon_ops->tx_mon_filter_dealloc(pdev); 6174 if (mon_pdev->filter) 6175 dp_mon_filter_dealloc(mon_pdev); 6176 if (mon_pdev->invalid_mon_peer) 6177 qdf_mem_free(mon_pdev->invalid_mon_peer); 6178 mon_pdev->is_dp_mon_pdev_initialized = false; 6179 dp_mon_set_local_pkt_capture_running(mon_pdev, false); 6180 6181 return QDF_STATUS_SUCCESS; 6182 } 6183 dp_mon_vdev_attach(struct dp_vdev * vdev)6184 QDF_STATUS dp_mon_vdev_attach(struct dp_vdev *vdev) 6185 { 6186 struct dp_mon_vdev *mon_vdev; 6187 struct dp_pdev *pdev = vdev->pdev; 6188 6189 mon_vdev = (struct dp_mon_vdev *)qdf_mem_malloc(sizeof(*mon_vdev)); 6190 if (!mon_vdev) { 6191 dp_mon_err("%pK: Monitor vdev allocation failed", vdev); 6192 return QDF_STATUS_E_NOMEM; 6193 } 6194 6195 if (pdev && pdev->monitor_pdev && 6196 pdev->monitor_pdev->scan_spcl_vap_configured) 6197 dp_scan_spcl_vap_stats_attach(mon_vdev); 6198 6199 vdev->monitor_vdev = mon_vdev; 6200 6201 return QDF_STATUS_SUCCESS; 6202 } 6203 dp_mon_vdev_detach(struct dp_vdev * vdev)6204 QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev) 6205 { 6206 struct dp_mon_vdev *mon_vdev = vdev->monitor_vdev; 6207 struct dp_pdev *pdev = vdev->pdev; 6208 struct dp_mon_ops *mon_ops = dp_mon_ops_get(pdev->soc); 6209 6210 if (!mon_ops) 6211 return QDF_STATUS_E_FAILURE; 6212 6213 if (!mon_vdev) 6214 return QDF_STATUS_E_FAILURE; 6215 6216 if (pdev->monitor_pdev->scan_spcl_vap_configured) 6217 dp_scan_spcl_vap_stats_detach(mon_vdev); 6218 6219 qdf_mem_free(mon_vdev); 6220 vdev->monitor_vdev = NULL; 6221 /* set mvdev to NULL only if detach is called for monitor/special vap 6222 */ 6223 if (pdev->monitor_pdev->mvdev == vdev) 6224 pdev->monitor_pdev->mvdev = NULL; 6225 6226 if (mon_ops->mon_lite_mon_vdev_delete) 6227 mon_ops->mon_lite_mon_vdev_delete(pdev, vdev); 6228 6229 return QDF_STATUS_SUCCESS; 6230 } 6231 6232 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 6233 /** 6234 * dp_mon_peer_attach_notify() - Raise WDI event for peer create 6235 * @peer: DP Peer handle 6236 * 6237 * Return: none 6238 */ 6239 static inline dp_mon_peer_attach_notify(struct dp_peer * peer)6240 void dp_mon_peer_attach_notify(struct dp_peer *peer) 6241 { 6242 struct dp_mon_peer *mon_peer = peer->monitor_peer; 6243 struct dp_pdev *pdev; 6244 struct dp_soc *soc; 6245 struct cdp_peer_cookie peer_cookie; 6246 6247 pdev = peer->vdev->pdev; 6248 soc = pdev->soc; 6249 6250 qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, 6251 QDF_MAC_ADDR_SIZE); 6252 6253 peer_cookie.ctx = NULL; 6254 peer_cookie.pdev_id = pdev->pdev_id; 6255 peer_cookie.cookie = pdev->next_peer_cookie++; 6256 6257 dp_wdi_event_handler(WDI_EVENT_PEER_CREATE, soc, 6258 (void *)&peer_cookie, 6259 peer->peer_id, WDI_NO_VAL, pdev->pdev_id); 6260 6261 if (soc->peerstats_enabled) { 6262 if (!peer_cookie.ctx) { 6263 pdev->next_peer_cookie--; 6264 qdf_err("Failed to initialize peer rate stats"); 6265 mon_peer->peerstats_ctx = NULL; 6266 } else { 6267 mon_peer->peerstats_ctx = 6268 (struct cdp_peer_rate_stats_ctx *) 6269 peer_cookie.ctx; 6270 } 6271 } 6272 } 6273 6274 /** 6275 * dp_mon_peer_detach_notify() - Raise WDI event for peer destroy 6276 * @peer: DP Peer handle 6277 * 6278 * Return: none 6279 */ 6280 static inline dp_mon_peer_detach_notify(struct dp_peer * peer)6281 void dp_mon_peer_detach_notify(struct dp_peer *peer) 6282 { 6283 struct dp_mon_peer *mon_peer = peer->monitor_peer; 6284 struct dp_pdev *pdev; 6285 struct dp_soc *soc; 6286 struct cdp_peer_cookie peer_cookie; 6287 6288 pdev = peer->vdev->pdev; 6289 soc = pdev->soc; 6290 /* send peer destroy event to upper layer */ 6291 qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, 6292 QDF_MAC_ADDR_SIZE); 6293 peer_cookie.ctx = NULL; 6294 peer_cookie.ctx = (struct cdp_stats_cookie *)mon_peer->peerstats_ctx; 6295 6296 dp_wdi_event_handler(WDI_EVENT_PEER_DESTROY, 6297 soc, 6298 (void *)&peer_cookie, 6299 peer->peer_id, 6300 WDI_NO_VAL, 6301 pdev->pdev_id); 6302 6303 mon_peer->peerstats_ctx = NULL; 6304 } 6305 #else 6306 static inline dp_mon_peer_attach_notify(struct dp_peer * peer)6307 void dp_mon_peer_attach_notify(struct dp_peer *peer) 6308 { 6309 peer->monitor_peer->peerstats_ctx = NULL; 6310 } 6311 6312 static inline dp_mon_peer_detach_notify(struct dp_peer * peer)6313 void dp_mon_peer_detach_notify(struct dp_peer *peer) 6314 { 6315 peer->monitor_peer->peerstats_ctx = NULL; 6316 } 6317 #endif 6318 6319 #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(FEATURE_PERPKT_INFO) dp_mon_peer_attach(struct dp_peer * peer)6320 QDF_STATUS dp_mon_peer_attach(struct dp_peer *peer) 6321 { 6322 struct dp_mon_peer *mon_peer; 6323 struct dp_pdev *pdev; 6324 6325 mon_peer = (struct dp_mon_peer *)qdf_mem_malloc(sizeof(*mon_peer)); 6326 if (!mon_peer) { 6327 dp_mon_err("%pK: MONITOR peer allocation failed", peer); 6328 return QDF_STATUS_E_NOMEM; 6329 } 6330 6331 peer->monitor_peer = mon_peer; 6332 pdev = peer->vdev->pdev; 6333 /* 6334 * In tx_monitor mode, filter may be set for unassociated peer 6335 * when unassociated peer get associated peer need to 6336 * update tx_cap_enabled flag to support peer filter. 6337 */ 6338 dp_monitor_peer_tx_capture_filter_check(pdev, peer); 6339 6340 DP_STATS_INIT(mon_peer); 6341 DP_STATS_UPD(mon_peer, rx.avg_snr, CDP_INVALID_SNR); 6342 6343 dp_mon_peer_attach_notify(peer); 6344 6345 return QDF_STATUS_SUCCESS; 6346 } 6347 #endif 6348 dp_mon_peer_detach(struct dp_peer * peer)6349 QDF_STATUS dp_mon_peer_detach(struct dp_peer *peer) 6350 { 6351 struct dp_mon_peer *mon_peer = peer->monitor_peer; 6352 6353 if (!mon_peer) 6354 return QDF_STATUS_SUCCESS; 6355 6356 dp_mon_peer_detach_notify(peer); 6357 6358 qdf_mem_free(mon_peer); 6359 peer->monitor_peer = NULL; 6360 6361 return QDF_STATUS_SUCCESS; 6362 } 6363 6364 #ifndef DISABLE_MON_CONFIG dp_mon_register_intr_ops(struct dp_soc * soc)6365 void dp_mon_register_intr_ops(struct dp_soc *soc) 6366 { 6367 struct dp_mon_ops *mon_ops = NULL; 6368 6369 mon_ops = dp_mon_ops_get(soc); 6370 if (!mon_ops) { 6371 dp_mon_err("Monitor ops is NULL"); 6372 return; 6373 } 6374 if (mon_ops->mon_register_intr_ops) 6375 mon_ops->mon_register_intr_ops(soc); 6376 } 6377 #endif 6378 dp_mon_peer_get_peerstats_ctx(struct dp_peer * peer)6379 struct cdp_peer_rate_stats_ctx *dp_mon_peer_get_peerstats_ctx(struct 6380 dp_peer *peer) 6381 { 6382 struct dp_mon_peer *mon_peer = peer->monitor_peer; 6383 6384 if (mon_peer) 6385 return mon_peer->peerstats_ctx; 6386 else 6387 return NULL; 6388 } 6389 6390 #ifdef QCA_ENHANCED_STATS_SUPPORT dp_mon_peer_reset_stats(struct dp_peer * peer)6391 void dp_mon_peer_reset_stats(struct dp_peer *peer) 6392 { 6393 struct dp_mon_peer *mon_peer = NULL; 6394 6395 mon_peer = peer->monitor_peer; 6396 if (!mon_peer) 6397 return; 6398 6399 DP_STATS_CLR(mon_peer); 6400 DP_STATS_UPD(mon_peer, rx.avg_snr, CDP_INVALID_SNR); 6401 } 6402 dp_mon_peer_get_stats(struct dp_peer * peer,void * arg,enum cdp_stat_update_type type)6403 void dp_mon_peer_get_stats(struct dp_peer *peer, void *arg, 6404 enum cdp_stat_update_type type) 6405 { 6406 struct dp_mon_peer *mon_peer = peer->monitor_peer; 6407 struct dp_mon_peer_stats *mon_peer_stats; 6408 6409 if (!mon_peer || !arg) 6410 return; 6411 6412 mon_peer_stats = &mon_peer->stats; 6413 6414 switch (type) { 6415 case UPDATE_PEER_STATS: 6416 { 6417 struct cdp_peer_stats *peer_stats = 6418 (struct cdp_peer_stats *)arg; 6419 DP_UPDATE_MON_STATS(peer_stats, mon_peer_stats); 6420 break; 6421 } 6422 case UPDATE_VDEV_STATS_MLD: 6423 { 6424 struct cdp_vdev_stats *vdev_stats = 6425 (struct cdp_vdev_stats *)arg; 6426 DP_UPDATE_MON_STATS(vdev_stats, mon_peer_stats); 6427 break; 6428 } 6429 case UPDATE_VDEV_STATS: 6430 { 6431 struct dp_vdev_stats *vdev_stats = 6432 (struct dp_vdev_stats *)arg; 6433 DP_UPDATE_MON_STATS(vdev_stats, mon_peer_stats); 6434 break; 6435 } 6436 default: 6437 dp_mon_err("Invalid stats_update_type: %u", type); 6438 } 6439 } 6440 dp_mon_invalid_peer_update_pdev_stats(struct dp_pdev * pdev)6441 void dp_mon_invalid_peer_update_pdev_stats(struct dp_pdev *pdev) 6442 { 6443 struct dp_mon_peer *mon_peer; 6444 struct dp_mon_peer_stats *mon_peer_stats; 6445 struct cdp_pdev_stats *pdev_stats; 6446 6447 if (!pdev || !pdev->monitor_pdev) 6448 return; 6449 6450 mon_peer = pdev->monitor_pdev->invalid_mon_peer; 6451 if (!mon_peer) 6452 return; 6453 6454 mon_peer_stats = &mon_peer->stats; 6455 pdev_stats = &pdev->stats; 6456 DP_UPDATE_MON_STATS(pdev_stats, mon_peer_stats); 6457 } 6458 6459 QDF_STATUS dp_mon_peer_get_stats_param(struct dp_peer * peer,enum cdp_peer_stats_type type,cdp_peer_stats_param_t * buf)6460 dp_mon_peer_get_stats_param(struct dp_peer *peer, enum cdp_peer_stats_type type, 6461 cdp_peer_stats_param_t *buf) 6462 { 6463 QDF_STATUS ret = QDF_STATUS_SUCCESS; 6464 struct dp_mon_peer *mon_peer; 6465 6466 mon_peer = peer->monitor_peer; 6467 if (!mon_peer) 6468 return QDF_STATUS_E_FAILURE; 6469 6470 switch (type) { 6471 case cdp_peer_tx_rate: 6472 buf->tx_rate = mon_peer->stats.tx.tx_rate; 6473 break; 6474 case cdp_peer_tx_last_tx_rate: 6475 buf->last_tx_rate = mon_peer->stats.tx.last_tx_rate; 6476 break; 6477 case cdp_peer_tx_ratecode: 6478 buf->tx_ratecode = mon_peer->stats.tx.tx_ratecode; 6479 break; 6480 case cdp_peer_rx_rate: 6481 buf->rx_rate = mon_peer->stats.rx.rx_rate; 6482 break; 6483 case cdp_peer_rx_last_rx_rate: 6484 buf->last_rx_rate = mon_peer->stats.rx.last_rx_rate; 6485 break; 6486 case cdp_peer_rx_ratecode: 6487 buf->rx_ratecode = mon_peer->stats.rx.rx_ratecode; 6488 break; 6489 case cdp_peer_rx_avg_snr: 6490 buf->rx_avg_snr = mon_peer->stats.rx.avg_snr; 6491 break; 6492 case cdp_peer_rx_snr: 6493 buf->rx_snr = mon_peer->stats.rx.snr; 6494 break; 6495 case cdp_peer_rx_avg_rate: 6496 buf->rx_rate_avg = mon_peer->stats.rx.rnd_avg_rx_rate; 6497 break; 6498 case cdp_peer_tx_avg_rate: 6499 buf->tx_rate_avg = mon_peer->stats.tx.rnd_avg_tx_rate; 6500 break; 6501 default: 6502 dp_err("Invalid stats type: %u requested", type); 6503 ret = QDF_STATUS_E_FAILURE; 6504 } 6505 6506 return ret; 6507 } 6508 #endif 6509 dp_mon_ops_register(struct dp_soc * soc)6510 void dp_mon_ops_register(struct dp_soc *soc) 6511 { 6512 struct dp_mon_soc *mon_soc = soc->monitor_soc; 6513 uint32_t target_type; 6514 6515 target_type = hal_get_target_type(soc->hal_soc); 6516 switch (target_type) { 6517 case TARGET_TYPE_QCA6290: 6518 case TARGET_TYPE_QCA6390: 6519 case TARGET_TYPE_QCA6490: 6520 case TARGET_TYPE_QCA6750: 6521 case TARGET_TYPE_KIWI: 6522 case TARGET_TYPE_MANGO: 6523 case TARGET_TYPE_PEACH: 6524 case TARGET_TYPE_QCA8074: 6525 case TARGET_TYPE_QCA8074V2: 6526 case TARGET_TYPE_QCA6018: 6527 case TARGET_TYPE_QCA9574: 6528 case TARGET_TYPE_QCN9160: 6529 case TARGET_TYPE_QCN9000: 6530 case TARGET_TYPE_QCA5018: 6531 case TARGET_TYPE_QCN6122: 6532 case TARGET_TYPE_WCN6450: 6533 dp_mon_ops_register_1_0(mon_soc); 6534 dp_mon_ops_register_cmn_2_0(mon_soc); 6535 dp_mon_ops_register_tx_2_0(mon_soc); 6536 break; 6537 case TARGET_TYPE_QCN9224: 6538 case TARGET_TYPE_QCA5332: 6539 case TARGET_TYPE_QCN6432: 6540 #if defined(WLAN_PKT_CAPTURE_TX_2_0) || defined(WLAN_PKT_CAPTURE_RX_2_0) 6541 dp_mon_ops_register_2_0(mon_soc); 6542 #endif 6543 break; 6544 default: 6545 dp_mon_err("%s: Unknown tgt type %d", __func__, target_type); 6546 qdf_assert_always(0); 6547 break; 6548 } 6549 } 6550 6551 #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT dp_mon_ops_free(struct dp_soc * soc)6552 void dp_mon_ops_free(struct dp_soc *soc) 6553 { 6554 struct cdp_ops *ops = soc->cdp_soc.ops; 6555 struct cdp_mon_ops *cdp_mon_ops = ops->mon_ops; 6556 struct dp_mon_soc *mon_soc = soc->monitor_soc; 6557 struct dp_mon_ops *mon_ops = mon_soc->mon_ops; 6558 6559 if (cdp_mon_ops) 6560 qdf_mem_free(cdp_mon_ops); 6561 6562 if (mon_ops) 6563 qdf_mem_free(mon_ops); 6564 } 6565 #else dp_mon_ops_free(struct dp_soc * soc)6566 void dp_mon_ops_free(struct dp_soc *soc) 6567 { 6568 } 6569 #endif 6570 dp_mon_cdp_ops_register(struct dp_soc * soc)6571 void dp_mon_cdp_ops_register(struct dp_soc *soc) 6572 { 6573 struct cdp_ops *ops = soc->cdp_soc.ops; 6574 uint32_t target_type; 6575 6576 if (!ops) { 6577 dp_mon_err("cdp_ops is NULL"); 6578 return; 6579 } 6580 6581 target_type = hal_get_target_type(soc->hal_soc); 6582 switch (target_type) { 6583 case TARGET_TYPE_QCA6290: 6584 case TARGET_TYPE_QCA6390: 6585 case TARGET_TYPE_QCA6490: 6586 case TARGET_TYPE_QCA6750: 6587 case TARGET_TYPE_KIWI: 6588 case TARGET_TYPE_MANGO: 6589 case TARGET_TYPE_PEACH: 6590 case TARGET_TYPE_QCA8074: 6591 case TARGET_TYPE_QCA8074V2: 6592 case TARGET_TYPE_QCA6018: 6593 case TARGET_TYPE_QCA9574: 6594 case TARGET_TYPE_QCN9160: 6595 case TARGET_TYPE_QCN9000: 6596 case TARGET_TYPE_QCA5018: 6597 case TARGET_TYPE_QCN6122: 6598 case TARGET_TYPE_WCN6450: 6599 dp_mon_cdp_ops_register_1_0(ops); 6600 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 6601 dp_cfr_filter_register_1_0(ops); 6602 #endif 6603 if (target_type == TARGET_TYPE_QCN9000 || 6604 target_type == TARGET_TYPE_QCN9160) 6605 ops->mon_ops->txrx_update_mon_mac_filter = 6606 dp_update_mon_mac_filter; 6607 break; 6608 case TARGET_TYPE_QCN9224: 6609 case TARGET_TYPE_QCA5332: 6610 case TARGET_TYPE_QCN6432: 6611 #if defined(WLAN_PKT_CAPTURE_TX_2_0) || defined(WLAN_PKT_CAPTURE_RX_2_0) 6612 dp_mon_cdp_ops_register_2_0(ops); 6613 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 6614 dp_cfr_filter_register_2_0(ops); 6615 #endif 6616 #endif /* WLAN_PKT_CAPTURE_TX_2_0 && WLAN_PKT_CAPTURE_RX_2_0 */ 6617 break; 6618 default: 6619 dp_mon_err("%s: Unknown tgt type %d", __func__, target_type); 6620 qdf_assert_always(0); 6621 break; 6622 } 6623 6624 ops->cmn_drv_ops->txrx_set_monitor_mode = dp_vdev_set_monitor_mode; 6625 ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev = 6626 dp_get_mon_vdev_from_pdev_wifi3; 6627 #ifdef DP_PEER_EXTENDED_API 6628 ops->misc_ops->pkt_log_init = dp_pkt_log_init; 6629 ops->misc_ops->pkt_log_con_service = dp_pkt_log_con_service; 6630 ops->misc_ops->pkt_log_exit = dp_pkt_log_exit; 6631 #endif 6632 ops->ctrl_ops->enable_peer_based_pktlog = 6633 dp_enable_peer_based_pktlog; 6634 #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) 6635 ops->ctrl_ops->txrx_update_peer_pkt_capture_params = 6636 dp_peer_update_pkt_capture_params; 6637 #endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */ 6638 #ifdef WDI_EVENT_ENABLE 6639 ops->ctrl_ops->txrx_get_pldev = dp_get_pldev; 6640 #endif 6641 #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS 6642 ops->host_stats_ops->txrx_get_scan_spcl_vap_stats = 6643 dp_get_scan_spcl_vap_stats; 6644 #endif 6645 return; 6646 } 6647 6648 #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT 6649 static inline void dp_mon_cdp_mon_ops_deregister(struct cdp_ops * ops)6650 dp_mon_cdp_mon_ops_deregister(struct cdp_ops *ops) 6651 { 6652 if (ops->mon_ops) { 6653 qdf_mem_free(ops->mon_ops); 6654 ops->mon_ops = NULL; 6655 } 6656 } 6657 #else 6658 static inline void dp_mon_cdp_mon_ops_deregister(struct cdp_ops * ops)6659 dp_mon_cdp_mon_ops_deregister(struct cdp_ops *ops) 6660 { 6661 ops->mon_ops = NULL; 6662 } 6663 #endif 6664 dp_mon_cdp_ops_deregister(struct dp_soc * soc)6665 void dp_mon_cdp_ops_deregister(struct dp_soc *soc) 6666 { 6667 struct cdp_ops *ops = soc->cdp_soc.ops; 6668 6669 if (!ops) { 6670 dp_mon_err("cdp_ops is NULL"); 6671 return; 6672 } 6673 6674 dp_mon_cdp_mon_ops_deregister(ops); 6675 6676 ops->cmn_drv_ops->txrx_set_monitor_mode = NULL; 6677 ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev = NULL; 6678 #ifdef DP_PEER_EXTENDED_API 6679 ops->misc_ops->pkt_log_init = NULL; 6680 ops->misc_ops->pkt_log_con_service = NULL; 6681 ops->misc_ops->pkt_log_exit = NULL; 6682 #endif 6683 ops->ctrl_ops->enable_peer_based_pktlog = NULL; 6684 #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) 6685 ops->ctrl_ops->txrx_update_peer_pkt_capture_params = NULL; 6686 #endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */ 6687 #ifdef WDI_EVENT_ENABLE 6688 ops->ctrl_ops->txrx_get_pldev = NULL; 6689 #endif 6690 return; 6691 } 6692 6693 #if defined(WDI_EVENT_ENABLE) &&\ 6694 (defined(QCA_ENHANCED_STATS_SUPPORT) || !defined(REMOVE_PKT_LOG)) 6695 static inline dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc * mon_soc)6696 void dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc *mon_soc) 6697 { 6698 mon_soc->mon_ops->mon_ppdu_stats_ind_handler = NULL; 6699 } 6700 #else 6701 static inline dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc * mon_soc)6702 void dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc *mon_soc) 6703 { 6704 } 6705 #endif 6706 6707 #ifdef QCA_RSSI_DB2DBM 6708 /** 6709 * dp_mon_compute_min_nf() - calculate the min nf value in the 6710 * active chains 20 MHz subbands. 6711 * @conv_params: cdp_rssi_dbm_conv_param_dp structure value 6712 * @min_nf: location to store min NF value 6713 * @chain_idx: active chain index in nfHwdbm array 6714 * 6715 * computation: Need to calculate nfInDbm[][] to A_MIN(nfHwDbm[][]) 6716 * considering row index as active chains and column 6717 * index as 20MHZ subbands per chain. 6718 * example: chain_mask = 0x07 (consider 3 active chains 0,1,2 index) 6719 * BandWidth = 40MHZ (40MHZ includes two 20MHZ subbands so need to 6720 * consider 0,1 index calculate min_nf value) 6721 * 6722 * Return: QDF_STATUS_SUCCESS if value set successfully 6723 * QDF_STATUS_E_INVAL false if error 6724 */ 6725 static QDF_STATUS dp_mon_compute_min_nf(struct cdp_rssi_dbm_conv_param_dp * conv_params,int8_t * min_nf,int chain_idx)6726 dp_mon_compute_min_nf(struct cdp_rssi_dbm_conv_param_dp *conv_params, 6727 int8_t *min_nf, int chain_idx) 6728 { 6729 int j; 6730 *min_nf = conv_params->nf_hw_dbm[chain_idx][0]; 6731 6732 switch (conv_params->curr_bw) { 6733 case CHAN_WIDTH_20: 6734 case CHAN_WIDTH_5: 6735 case CHAN_WIDTH_10: 6736 break; 6737 case CHAN_WIDTH_40: 6738 for (j = 1; j < SUB40BW; j++) { 6739 if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) 6740 *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; 6741 } 6742 break; 6743 case CHAN_WIDTH_80: 6744 for (j = 1; j < SUB80BW; j++) { 6745 if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) 6746 *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; 6747 } 6748 break; 6749 case CHAN_WIDTH_160: 6750 case CHAN_WIDTH_80P80: 6751 case CHAN_WIDTH_165: 6752 for (j = 1; j < SUB160BW; j++) { 6753 if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) 6754 *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; 6755 } 6756 break; 6757 case CHAN_WIDTH_160P160: 6758 case CHAN_WIDTH_320: 6759 for (j = 1; j < SUB320BW; j++) { 6760 if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) 6761 *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; 6762 } 6763 break; 6764 default: 6765 dp_cdp_err("Invalid bandwidth %u", conv_params->curr_bw); 6766 return QDF_STATUS_E_INVAL; 6767 } 6768 return QDF_STATUS_SUCCESS; 6769 } 6770 6771 /** 6772 * dp_mon_pdev_params_rssi_dbm_conv() - to set rssi in dbm conversion 6773 * params into monitor pdev. 6774 * @cdp_soc: dp soc handle. 6775 * @params: cdp_rssi_db2dbm_param_dp structure value. 6776 * 6777 * Return: QDF_STATUS_SUCCESS if value set successfully 6778 * QDF_STATUS_E_INVAL false if error 6779 */ 6780 QDF_STATUS dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t * cdp_soc,struct cdp_rssi_db2dbm_param_dp * params)6781 dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t *cdp_soc, 6782 struct cdp_rssi_db2dbm_param_dp *params) 6783 { 6784 struct cdp_rssi_db2dbm_param_dp *dp_rssi_params = params; 6785 uint8_t pdev_id = params->pdev_id; 6786 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 6787 struct dp_pdev *pdev = 6788 dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 6789 struct dp_mon_pdev *mon_pdev; 6790 struct cdp_rssi_temp_off_param_dp temp_off_param; 6791 struct cdp_rssi_dbm_conv_param_dp conv_params; 6792 int8_t min_nf = 0; 6793 int i; 6794 6795 if (!soc->features.rssi_dbm_conv_support) { 6796 dp_cdp_err("rssi dbm conversion support is false"); 6797 return QDF_STATUS_E_INVAL; 6798 } 6799 if (!pdev || !pdev->monitor_pdev) { 6800 dp_cdp_err("Invalid pdev_id %u", pdev_id); 6801 return QDF_STATUS_E_FAILURE; 6802 } 6803 6804 mon_pdev = pdev->monitor_pdev; 6805 mon_pdev->rssi_dbm_conv_support = 6806 soc->features.rssi_dbm_conv_support; 6807 6808 if (dp_rssi_params->rssi_temp_off_present) { 6809 temp_off_param = dp_rssi_params->temp_off_param; 6810 mon_pdev->rssi_offsets.rssi_temp_offset = 6811 temp_off_param.rssi_temp_offset; 6812 } 6813 if (dp_rssi_params->rssi_dbm_info_present) { 6814 conv_params = dp_rssi_params->rssi_dbm_param; 6815 for (i = 0; i < CDP_MAX_NUM_ANTENNA; i++) { 6816 if (conv_params.curr_rx_chainmask & (0x01 << i)) { 6817 if (QDF_STATUS_E_INVAL == dp_mon_compute_min_nf 6818 (&conv_params, &min_nf, i)) 6819 return QDF_STATUS_E_INVAL; 6820 } else { 6821 continue; 6822 } 6823 } 6824 mon_pdev->rssi_offsets.xlna_bypass_offset = 6825 conv_params.xlna_bypass_offset; 6826 mon_pdev->rssi_offsets.xlna_bypass_threshold = 6827 conv_params.xlna_bypass_threshold; 6828 mon_pdev->rssi_offsets.xbar_config = conv_params.xbar_config; 6829 mon_pdev->rssi_offsets.min_nf_dbm = min_nf; 6830 mon_pdev->rssi_offsets.rssi_offset = 6831 mon_pdev->rssi_offsets.min_nf_dbm + 6832 mon_pdev->rssi_offsets.rssi_temp_offset; 6833 } 6834 return QDF_STATUS_SUCCESS; 6835 } 6836 #endif 6837 dp_mon_intr_ops_deregister(struct dp_soc * soc)6838 void dp_mon_intr_ops_deregister(struct dp_soc *soc) 6839 { 6840 struct dp_mon_soc *mon_soc = soc->monitor_soc; 6841 6842 mon_soc->mon_rx_process = NULL; 6843 dp_mon_ppdu_stats_handler_deregister(mon_soc); 6844 } 6845 dp_mon_feature_ops_deregister(struct dp_soc * soc)6846 void dp_mon_feature_ops_deregister(struct dp_soc *soc) 6847 { 6848 struct dp_mon_ops *mon_ops = dp_mon_ops_get(soc); 6849 6850 if (!mon_ops) { 6851 dp_err("mon_ops is NULL"); 6852 return; 6853 } 6854 6855 mon_ops->mon_config_debug_sniffer = NULL; 6856 mon_ops->mon_peer_tx_init = NULL; 6857 mon_ops->mon_peer_tx_cleanup = NULL; 6858 mon_ops->mon_htt_ppdu_stats_attach = NULL; 6859 mon_ops->mon_htt_ppdu_stats_detach = NULL; 6860 mon_ops->mon_print_pdev_rx_mon_stats = NULL; 6861 mon_ops->mon_set_bsscolor = NULL; 6862 mon_ops->mon_pdev_get_filter_ucast_data = NULL; 6863 mon_ops->mon_pdev_get_filter_mcast_data = NULL; 6864 mon_ops->mon_pdev_get_filter_non_data = NULL; 6865 mon_ops->mon_neighbour_peer_add_ast = NULL; 6866 #ifdef WLAN_TX_PKT_CAPTURE_ENH 6867 mon_ops->mon_peer_tid_peer_id_update = NULL; 6868 mon_ops->mon_tx_ppdu_stats_attach = NULL; 6869 mon_ops->mon_tx_ppdu_stats_detach = NULL; 6870 mon_ops->mon_tx_capture_debugfs_init = NULL; 6871 mon_ops->mon_tx_add_to_comp_queue = NULL; 6872 mon_ops->mon_peer_tx_capture_filter_check = NULL; 6873 mon_ops->mon_print_pdev_tx_capture_stats = NULL; 6874 mon_ops->mon_config_enh_tx_capture = NULL; 6875 #endif 6876 #ifdef WLAN_RX_PKT_CAPTURE_ENH 6877 mon_ops->mon_config_enh_rx_capture = NULL; 6878 #endif 6879 #ifdef QCA_SUPPORT_BPR 6880 mon_ops->mon_set_bpr_enable = NULL; 6881 #endif 6882 #ifdef ATH_SUPPORT_NAC 6883 mon_ops->mon_set_filter_neigh_peers = NULL; 6884 #endif 6885 #ifdef WLAN_ATF_ENABLE 6886 mon_ops->mon_set_atf_stats_enable = NULL; 6887 #endif 6888 #ifdef FEATURE_NAC_RSSI 6889 mon_ops->mon_filter_neighbour_peer = NULL; 6890 #endif 6891 #ifdef QCA_MCOPY_SUPPORT 6892 mon_ops->mon_filter_setup_mcopy_mode = NULL; 6893 mon_ops->mon_filter_reset_mcopy_mode = NULL; 6894 mon_ops->mon_mcopy_check_deliver = NULL; 6895 #endif 6896 #ifdef QCA_ENHANCED_STATS_SUPPORT 6897 mon_ops->mon_filter_setup_enhanced_stats = NULL; 6898 mon_ops->mon_tx_enable_enhanced_stats = NULL; 6899 mon_ops->mon_tx_disable_enhanced_stats = NULL; 6900 mon_ops->mon_ppdu_desc_deliver = NULL; 6901 mon_ops->mon_ppdu_desc_notify = NULL; 6902 mon_ops->mon_ppdu_stats_feat_enable_check = NULL; 6903 #ifdef WLAN_FEATURE_11BE 6904 mon_ops->mon_tx_stats_update = NULL; 6905 #endif 6906 #endif 6907 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) 6908 mon_ops->mon_filter_setup_smart_monitor = NULL; 6909 #endif 6910 mon_ops->mon_filter_set_reset_mon_mac_filter = NULL; 6911 #ifdef WLAN_RX_PKT_CAPTURE_ENH 6912 mon_ops->mon_filter_setup_rx_enh_capture = NULL; 6913 #endif 6914 #ifdef WDI_EVENT_ENABLE 6915 mon_ops->mon_set_pktlog_wifi3 = NULL; 6916 mon_ops->mon_filter_setup_rx_pkt_log_full = NULL; 6917 mon_ops->mon_filter_reset_rx_pkt_log_full = NULL; 6918 mon_ops->mon_filter_setup_rx_pkt_log_lite = NULL; 6919 mon_ops->mon_filter_reset_rx_pkt_log_lite = NULL; 6920 mon_ops->mon_filter_setup_rx_pkt_log_cbf = NULL; 6921 mon_ops->mon_filter_reset_rx_pkt_log_cbf = NULL; 6922 #ifdef BE_PKTLOG_SUPPORT 6923 mon_ops->mon_filter_setup_pktlog_hybrid = NULL; 6924 mon_ops->mon_filter_reset_pktlog_hybrid = NULL; 6925 #endif 6926 #endif 6927 #if defined(DP_CON_MON) && !defined(REMOVE_PKT_LOG) 6928 mon_ops->mon_pktlogmod_exit = NULL; 6929 #endif 6930 mon_ops->rx_hdr_length_set = NULL; 6931 mon_ops->rx_packet_length_set = NULL; 6932 mon_ops->rx_wmask_subscribe = NULL; 6933 mon_ops->rx_pkt_tlv_offset = NULL; 6934 mon_ops->rx_enable_mpdu_logging = NULL; 6935 mon_ops->rx_enable_fpmo = NULL; 6936 mon_ops->mon_neighbour_peers_detach = NULL; 6937 mon_ops->mon_vdev_set_monitor_mode_buf_rings = NULL; 6938 mon_ops->mon_vdev_set_monitor_mode_rings = NULL; 6939 #ifdef QCA_ENHANCED_STATS_SUPPORT 6940 mon_ops->mon_rx_stats_update = NULL; 6941 mon_ops->mon_rx_populate_ppdu_usr_info = NULL; 6942 mon_ops->mon_rx_populate_ppdu_info = NULL; 6943 #endif 6944 } 6945 dp_mon_soc_attach(struct dp_soc * soc)6946 QDF_STATUS dp_mon_soc_attach(struct dp_soc *soc) 6947 { 6948 struct dp_mon_soc *mon_soc; 6949 qdf_size_t soc_context_size; 6950 6951 if (!soc) { 6952 dp_mon_err("dp_soc is NULL"); 6953 return QDF_STATUS_E_FAILURE; 6954 } 6955 6956 if (soc->arch_ops.txrx_get_mon_context_size) { 6957 soc_context_size = soc->arch_ops.txrx_get_mon_context_size(DP_CONTEXT_TYPE_MON_SOC); 6958 mon_soc = dp_context_alloc_mem(soc, DP_MON_SOC_TYPE, 6959 soc_context_size); 6960 } else { 6961 mon_soc = (struct dp_mon_soc *)qdf_mem_malloc(sizeof(*mon_soc)); 6962 } 6963 if (!mon_soc) { 6964 dp_mon_err("%pK: mem allocation failed", soc); 6965 return QDF_STATUS_E_NOMEM; 6966 } 6967 /* register monitor ops */ 6968 soc->monitor_soc = mon_soc; 6969 dp_mon_ops_register(soc); 6970 dp_mon_register_intr_ops(soc); 6971 6972 dp_mon_cdp_ops_register(soc); 6973 dp_monitor_soc_attach(soc); 6974 dp_mon_register_feature_ops(soc); 6975 return QDF_STATUS_SUCCESS; 6976 } 6977 dp_mon_soc_detach(struct dp_soc * soc)6978 QDF_STATUS dp_mon_soc_detach(struct dp_soc *soc) 6979 { 6980 struct dp_mon_soc *mon_soc; 6981 6982 if (!soc) { 6983 dp_mon_err("dp_soc is NULL"); 6984 return QDF_STATUS_E_FAILURE; 6985 } 6986 6987 mon_soc = soc->monitor_soc; 6988 dp_monitor_vdev_timer_deinit(soc); 6989 dp_mon_cdp_ops_deregister(soc); 6990 dp_monitor_soc_detach(soc); 6991 soc->monitor_soc = NULL; 6992 qdf_mem_free(mon_soc); 6993 return QDF_STATUS_SUCCESS; 6994 } 6995 6996 #ifdef QCA_SUPPORT_FULL_MON print_ring_tracker_stats(struct dp_mon_pdev * mon_pdev,uint8_t target)6997 static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev, 6998 uint8_t target) 6999 { 7000 struct dp_ring_ppdu_id_tracker *tracker; 7001 uint8_t i; 7002 7003 if (target) 7004 tracker = mon_pdev->hist_ppdu_id_mon_s; 7005 else 7006 tracker = mon_pdev->hist_ppdu_id_mon_d; 7007 7008 for (i = 0; i < DP_HIST_TRACK_SIZE; i++) { 7009 qdf_print("idx: %d dest_ppdu_id: %d dest_time: %lld d_hp: %d ", 7010 i, tracker[i].ppdu_id_mon_dest, 7011 tracker[i].time_ppdu_id_mon_dest, 7012 tracker[i].dest_hp); 7013 qdf_print("d_tp: %d d_hw_hp: %d d_hw_tp: %d status_ppdu_id: %d", 7014 tracker[i].dest_tp, 7015 tracker[i].dest_hw_hp, 7016 tracker[i].dest_hw_tp, 7017 tracker[i].ppdu_id_mon_status); 7018 qdf_print(" status_time: %lld s_hp: %d s_tp: %d s_hw_hp: %d ", 7019 tracker[i].time_ppdu_id_mon_status, 7020 tracker[i].status_hp, 7021 tracker[i].status_tp, 7022 tracker[i].status_hw_hp); 7023 qdf_print("s_hw_tp: %d\n", 7024 tracker[i].status_hw_tp); 7025 } 7026 } 7027 #else print_ring_tracker_stats(struct dp_mon_pdev * mon_pdev,uint8_t target)7028 static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev, 7029 uint8_t target) 7030 { 7031 } 7032 #endif 7033 7034 void dp_check_and_dump_full_mon_info(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int war)7035 dp_check_and_dump_full_mon_info(struct dp_soc *soc, struct dp_pdev *pdev, 7036 int mac_id, int war) 7037 { 7038 struct dp_mon_soc *mon_soc = soc->monitor_soc; 7039 struct dp_mon_pdev *mon_pdev; 7040 hal_soc_handle_t hal_soc; 7041 uint64_t buf_addr; 7042 void *mon_status_srng; 7043 void *rxdma_mon_status_ring_entry; 7044 struct hal_buf_info hbi; 7045 hal_ring_handle_t mon_dest_srng; 7046 void *ring_desc; 7047 struct hal_rx_mon_desc_info desc_info = {0}; 7048 struct dp_rx_desc *rx_desc; 7049 uint64_t ppdu_id = 0; 7050 7051 if (!mon_soc) { 7052 dp_err("Monitor soc is NULL\n"); 7053 return; 7054 } 7055 7056 if (!mon_soc->full_mon_mode) { 7057 dp_err("Full monitor mode is disable\n"); 7058 return; 7059 } 7060 7061 /** 7062 * As rx_mon_ring_mask is set but workdone is 0 7063 * there is a more chance backpressure can happen. 7064 * dump the content of rx monitor status and destination ring 7065 * and move to next pointers. 7066 */ 7067 mon_pdev = pdev->monitor_pdev; 7068 if (!mon_pdev) { 7069 dp_err("mon_pdev is NULL\n"); 7070 return; 7071 } 7072 7073 hal_soc = soc->hal_soc; 7074 7075 if (!war) 7076 qdf_spin_lock_bh(&mon_pdev->mon_lock); 7077 7078 mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng; 7079 if (!mon_status_srng) 7080 goto unlock_monitor; 7081 7082 dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_status_ring[mac_id], 7083 RXDMA_MONITOR_STATUS); 7084 rxdma_mon_status_ring_entry = 7085 hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng); 7086 7087 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7088 "hold_mon_dest_ring: %d\n", mon_pdev->hold_mon_dest_ring); 7089 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7090 "mon_pdev last_ppdu_id: %d\n", mon_pdev->last_ppdu_id); 7091 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7092 "soc: %d\n", hal_get_target_type(hal_soc)); 7093 7094 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7095 "reap_status:\n"); 7096 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7097 "\t DP_MON_STATUS_NO_DMA : %lld\n", 7098 mon_pdev->reap_status[DP_MON_STATUS_NO_DMA]); 7099 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7100 "\t DP_MON_STATUS_MATCH : %lld\n", 7101 mon_pdev->reap_status[DP_MON_STATUS_MATCH]); 7102 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7103 "\t DP_MON_STATUS_LAG : %lld\n", 7104 mon_pdev->reap_status[DP_MON_STATUS_LAG]); 7105 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7106 "\t DP_MON_STATUS_LEAD : %lld\n", 7107 mon_pdev->reap_status[DP_MON_STATUS_LEAD]); 7108 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7109 "\t DP_MON_STATUS_REPLENISH : %lld\n", 7110 mon_pdev->reap_status[DP_MON_STATUS_REPLENISH]); 7111 7112 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7113 "prev_status:\n"); 7114 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7115 "\t DP_MON_STATUS_NO_DMA : %lld\n", 7116 mon_pdev->prev_status[DP_MON_STATUS_NO_DMA]); 7117 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7118 "\t DP_MON_STATUS_MATCH : %lld\n", 7119 mon_pdev->prev_status[DP_MON_STATUS_MATCH]); 7120 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7121 "\t DP_MON_STATUS_LAG : %lld\n", 7122 mon_pdev->prev_status[DP_MON_STATUS_LAG]); 7123 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7124 "\t DP_MON_STATUS_LEAD : %lld\n", 7125 mon_pdev->prev_status[DP_MON_STATUS_LEAD]); 7126 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7127 "\t DP_MON_STATUS_REPLENISH : %lld\n", 7128 mon_pdev->prev_status[DP_MON_STATUS_REPLENISH]); 7129 7130 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7131 "match_stats:\n"); 7132 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7133 "\t DP_MON_STATUS_LAG : %lld\n", 7134 mon_pdev->status_match[DP_MON_STATUS_LAG]); 7135 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7136 "\t DP_MON_STATUS_LEAD : %lld\n", 7137 mon_pdev->status_match[DP_MON_STATUS_LEAD]); 7138 7139 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7140 "mismatch: %d\n", 7141 mon_pdev->rx_mon_stats.ppdu_id_mismatch); 7142 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7143 "status_ppdu_drop: %d\n", 7144 mon_pdev->rx_mon_stats.status_ppdu_drop); 7145 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7146 "dest_ppdu_drop: %d\n", 7147 mon_pdev->rx_mon_stats.dest_ppdu_drop); 7148 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7149 "tlv_tag_status_err: %d\n", 7150 mon_pdev->rx_mon_stats.tlv_tag_status_err); 7151 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7152 "status_buf_done_war: %d\n", 7153 mon_pdev->rx_mon_stats.status_buf_done_war); 7154 7155 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7156 "soc[%pK] pdev[%pK] mac_id[%d]\n", 7157 soc, pdev, mac_id); 7158 7159 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7160 "MON DEST TRACKER STATS:\n"); 7161 print_ring_tracker_stats(mon_pdev, 0); 7162 7163 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7164 "MON STA TRACKER STATS:\n"); 7165 print_ring_tracker_stats(mon_pdev, 1); 7166 7167 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7168 "rxdma_mon_status_ring:\n"); 7169 if (!rxdma_mon_status_ring_entry) { 7170 dp_err("rxdma_mon_status_ring_entry NULL\n"); 7171 goto dump_mon_destination_ring; 7172 } 7173 7174 buf_addr = 7175 (HAL_RX_BUFFER_ADDR_31_0_GET(rxdma_mon_status_ring_entry) | 7176 ((uint64_t) 7177 (HAL_RX_BUFFER_ADDR_39_32_GET(rxdma_mon_status_ring_entry)) 7178 << 32)); 7179 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7180 "Buffer address : %llx\n", buf_addr); 7181 if (!buf_addr) 7182 goto dump_mon_destination_ring; 7183 7184 hal_rx_buf_cookie_rbm_get(soc->hal_soc, 7185 (uint32_t *)rxdma_mon_status_ring_entry, 7186 &hbi); 7187 7188 print_hex_dump(KERN_ERR, "\tHAL_BUF_INFO: ", DUMP_PREFIX_NONE, 32, 4, 7189 &hbi, sizeof(struct hal_buf_info), false); 7190 7191 rx_desc = dp_rx_cookie_2_va_mon_status(soc, hbi.sw_cookie); 7192 if (!rx_desc) { 7193 dp_err("rx_desc is NULL\n"); 7194 goto dump_mon_destination_ring; 7195 } 7196 7197 print_hex_dump(KERN_ERR, "\tRX_DESC: ", DUMP_PREFIX_NONE, 32, 4, 7198 rx_desc, sizeof(struct dp_rx_desc), false); 7199 7200 dump_mon_destination_ring: 7201 7202 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7203 "rxdma_mon_destination_ring:\n"); 7204 mon_dest_srng = pdev->soc->rxdma_mon_dst_ring[mac_id].hal_srng; 7205 7206 if (!mon_dest_srng) { 7207 dp_err("rxdma_mon_dst_ring hal_srng is NULL\n"); 7208 goto unlock_monitor; 7209 } 7210 7211 dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_dst_ring[mac_id], 7212 RXDMA_MONITOR_DST); 7213 7214 ring_desc = hal_srng_dst_peek(hal_soc, mon_dest_srng); 7215 if (!ring_desc) 7216 goto unlock_monitor; 7217 7218 ppdu_id = hal_rx_hw_desc_get_ppduid_get(hal_soc, NULL, ring_desc); 7219 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7220 "Next dest ring ppdu id: %lld\n", ppdu_id); 7221 hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc, 7222 ring_desc, &desc_info); 7223 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 7224 "Next desc_info ppdu_id: %d\n", desc_info.ppdu_id); 7225 7226 print_hex_dump(KERN_ERR, "\tDESC_INFO: ", DUMP_PREFIX_NONE, 32, 4, 7227 &desc_info, sizeof(struct hal_rx_mon_desc_info), false); 7228 7229 unlock_monitor: 7230 if (!war) 7231 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 7232 } 7233