1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <wlan_ipa_obj_mgmt_api.h> 21 #include <qdf_types.h> 22 #include <qdf_lock.h> 23 #include <qdf_net_types.h> 24 #include <qdf_lro.h> 25 #include <qdf_module.h> 26 #include <hal_hw_headers.h> 27 #include <hal_api.h> 28 #include <hif.h> 29 #include <htt.h> 30 #include <wdi_event.h> 31 #include <queue.h> 32 #include "dp_types.h" 33 #include "dp_rings.h" 34 #include "dp_internal.h" 35 #include "dp_tx.h" 36 #include "dp_tx_desc.h" 37 #include "dp_rx.h" 38 #ifdef DP_RATETABLE_SUPPORT 39 #include "dp_ratetable.h" 40 #endif 41 #include <cdp_txrx_handle.h> 42 #include <wlan_cfg.h> 43 #include <wlan_utility.h> 44 #include "cdp_txrx_cmn_struct.h" 45 #include "cdp_txrx_stats_struct.h" 46 #include "cdp_txrx_cmn_reg.h" 47 #include <qdf_util.h> 48 #include "dp_peer.h" 49 #include "htt_stats.h" 50 #include "dp_htt.h" 51 #ifdef WLAN_SUPPORT_RX_FISA 52 #include <wlan_dp_fisa_rx.h> 53 #endif 54 #include "htt_ppdu_stats.h" 55 #include "qdf_mem.h" /* qdf_mem_malloc,free */ 56 #include "cfg_ucfg_api.h" 57 #include <wlan_module_ids.h> 58 59 #ifdef QCA_LL_TX_FLOW_CONTROL_V2 60 #include "cdp_txrx_flow_ctrl_v2.h" 61 #else 62 63 static inline void 64 cdp_dump_flow_pool_info(struct cdp_soc_t *soc) 65 { 66 return; 67 } 68 #endif 69 #ifdef WIFI_MONITOR_SUPPORT 70 #include <dp_mon.h> 71 #endif 72 #include "dp_ipa.h" 73 #ifdef FEATURE_WDS 74 #include "dp_txrx_wds.h" 75 #endif 76 #ifdef WLAN_SUPPORT_MSCS 77 #include "dp_mscs.h" 78 #endif 79 #ifdef WLAN_SUPPORT_MESH_LATENCY 80 #include "dp_mesh_latency.h" 81 #endif 82 #ifdef WLAN_SUPPORT_SCS 83 #include "dp_scs.h" 84 #endif 85 #ifdef ATH_SUPPORT_IQUE 86 #include "dp_txrx_me.h" 87 #endif 88 #if defined(DP_CON_MON) 89 #ifndef REMOVE_PKT_LOG 90 #include <pktlog_ac_api.h> 91 #include <pktlog_ac.h> 92 #endif 93 #endif 94 #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR 95 #include <wlan_dp_swlm.h> 96 #endif 97 #ifdef CONFIG_SAWF_DEF_QUEUES 98 #include "dp_sawf.h" 99 #endif 100 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 101 #include <target_if_dp.h> 102 #endif 103 104 #if defined(DP_PEER_EXTENDED_API) || defined(WLAN_DP_PENDING_MEM_FLUSH) 105 #define SET_PEER_REF_CNT_ONE(_peer) \ 106 qdf_atomic_set(&(_peer)->ref_cnt, 1) 107 #else 108 #define SET_PEER_REF_CNT_ONE(_peer) 109 #endif 110 111 #ifdef WLAN_SYSFS_DP_STATS 112 /* sysfs event wait time for firmware stat request unit milliseconds */ 113 #define WLAN_SYSFS_STAT_REQ_WAIT_MS 3000 114 #endif 115 116 #ifdef QCA_DP_TX_FW_METADATA_V2 117 #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val) \ 118 HTT_TX_TCL_METADATA_V2_PDEV_ID_SET(_var, _val) 119 #else 120 #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val) \ 121 HTT_TX_TCL_METADATA_PDEV_ID_SET(_var, _val) 122 #endif 123 124 QDF_COMPILE_TIME_ASSERT(max_rx_rings_check, 125 MAX_REO_DEST_RINGS == CDP_MAX_RX_RINGS); 126 127 QDF_COMPILE_TIME_ASSERT(max_tx_rings_check, 128 MAX_TCL_DATA_RINGS == CDP_MAX_TX_COMP_RINGS); 129 130 void dp_configure_arch_ops(struct dp_soc *soc); 131 qdf_size_t dp_get_soc_context_size(uint16_t device_id); 132 133 /* 134 * The max size of cdp_peer_stats_param_t is limited to 16 bytes. 135 * If the buffer size is exceeding this size limit, 136 * dp_txrx_get_peer_stats is to be used instead. 137 */ 138 QDF_COMPILE_TIME_ASSERT(cdp_peer_stats_param_t_max_size, 139 (sizeof(cdp_peer_stats_param_t) <= 16)); 140 141 #ifdef WLAN_FEATURE_DP_EVENT_HISTORY 142 /* 143 * If WLAN_CFG_INT_NUM_CONTEXTS is changed, HIF_NUM_INT_CONTEXTS 144 * also should be updated accordingly 145 */ 146 QDF_COMPILE_TIME_ASSERT(num_intr_grps, 147 HIF_NUM_INT_CONTEXTS == WLAN_CFG_INT_NUM_CONTEXTS); 148 149 /* 150 * HIF_EVENT_HIST_MAX should always be power of 2 151 */ 152 QDF_COMPILE_TIME_ASSERT(hif_event_history_size, 153 (HIF_EVENT_HIST_MAX & (HIF_EVENT_HIST_MAX - 1)) == 0); 154 #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ 155 156 /* 157 * If WLAN_CFG_INT_NUM_CONTEXTS is changed, 158 * WLAN_CFG_INT_NUM_CONTEXTS_MAX should also be updated 159 */ 160 QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs, 161 WLAN_CFG_INT_NUM_CONTEXTS_MAX >= 162 WLAN_CFG_INT_NUM_CONTEXTS); 163 164 static QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl); 165 static QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl); 166 167 static void dp_pdev_srng_deinit(struct dp_pdev *pdev); 168 static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev); 169 static void dp_pdev_srng_free(struct dp_pdev *pdev); 170 static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev); 171 172 static inline 173 QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, 174 struct cdp_pdev_attach_params *params); 175 176 static int dp_pdev_post_attach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id); 177 178 static QDF_STATUS 179 dp_pdev_init_wifi3(struct cdp_soc_t *txrx_soc, 180 HTC_HANDLE htc_handle, 181 qdf_device_t qdf_osdev, 182 uint8_t pdev_id); 183 184 static QDF_STATUS 185 dp_pdev_deinit_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, int force); 186 187 static void dp_soc_detach_wifi3(struct cdp_soc_t *txrx_soc); 188 static void dp_soc_deinit_wifi3(struct cdp_soc_t *txrx_soc); 189 190 static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force); 191 static QDF_STATUS dp_pdev_detach_wifi3(struct cdp_soc_t *psoc, 192 uint8_t pdev_id, 193 int force); 194 static struct dp_soc * 195 dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, 196 struct cdp_soc_attach_params *params); 197 static inline QDF_STATUS dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, 198 uint8_t vdev_id, 199 uint8_t *peer_mac_addr, 200 enum cdp_peer_type peer_type); 201 static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, 202 uint8_t vdev_id, 203 uint8_t *peer_mac, uint32_t bitmap, 204 enum cdp_peer_type peer_type); 205 static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, 206 bool unmap_only, 207 bool mlo_peers_only); 208 #ifdef ENABLE_VERBOSE_DEBUG 209 bool is_dp_verbose_debug_enabled; 210 #endif 211 212 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 213 static bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); 214 static void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 215 bool enable); 216 static inline void 217 dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 218 struct cdp_cfr_rcc_stats *cfr_rcc_stats); 219 static inline void 220 dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); 221 #endif 222 223 #ifdef DP_UMAC_HW_RESET_SUPPORT 224 static QDF_STATUS dp_umac_reset_action_trigger_recovery(struct dp_soc *soc); 225 static QDF_STATUS dp_umac_reset_handle_pre_reset(struct dp_soc *soc); 226 static QDF_STATUS dp_umac_reset_handle_post_reset(struct dp_soc *soc); 227 static QDF_STATUS dp_umac_reset_handle_post_reset_complete(struct dp_soc *soc); 228 #endif 229 230 #define MON_VDEV_TIMER_INIT 0x1 231 #define MON_VDEV_TIMER_RUNNING 0x2 232 233 #define DP_MCS_LENGTH (6*MAX_MCS) 234 235 #define DP_CURR_FW_STATS_AVAIL 19 236 #define DP_HTT_DBG_EXT_STATS_MAX 256 237 #define DP_MAX_SLEEP_TIME 100 238 #ifndef QCA_WIFI_3_0_EMU 239 #define SUSPEND_DRAIN_WAIT 500 240 #else 241 #define SUSPEND_DRAIN_WAIT 3000 242 #endif 243 244 #ifdef IPA_OFFLOAD 245 /* Exclude IPA rings from the interrupt context */ 246 #define TX_RING_MASK_VAL 0xb 247 #define RX_RING_MASK_VAL 0x7 248 #else 249 #define TX_RING_MASK_VAL 0xF 250 #define RX_RING_MASK_VAL 0xF 251 #endif 252 253 #define STR_MAXLEN 64 254 255 #define RNG_ERR "SRNG setup failed for" 256 257 /** 258 * enum dp_stats_type - Select the type of statistics 259 * @STATS_FW: Firmware-based statistic 260 * @STATS_HOST: Host-based statistic 261 * @STATS_TYPE_MAX: maximum enumeration 262 */ 263 enum dp_stats_type { 264 STATS_FW = 0, 265 STATS_HOST = 1, 266 STATS_TYPE_MAX = 2, 267 }; 268 269 /** 270 * enum dp_fw_stats - General Firmware statistics options 271 * @TXRX_FW_STATS_INVALID: statistic is not available 272 */ 273 enum dp_fw_stats { 274 TXRX_FW_STATS_INVALID = -1, 275 }; 276 277 /* 278 * dp_stats_mapping_table - Firmware and Host statistics 279 * currently supported 280 */ 281 const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { 282 {HTT_DBG_EXT_STATS_RESET, TXRX_HOST_STATS_INVALID}, 283 {HTT_DBG_EXT_STATS_PDEV_TX, TXRX_HOST_STATS_INVALID}, 284 {HTT_DBG_EXT_STATS_PDEV_RX, TXRX_HOST_STATS_INVALID}, 285 {HTT_DBG_EXT_STATS_PDEV_TX_HWQ, TXRX_HOST_STATS_INVALID}, 286 {HTT_DBG_EXT_STATS_PDEV_TX_SCHED, TXRX_HOST_STATS_INVALID}, 287 {HTT_DBG_EXT_STATS_PDEV_ERROR, TXRX_HOST_STATS_INVALID}, 288 {HTT_DBG_EXT_STATS_PDEV_TQM, TXRX_HOST_STATS_INVALID}, 289 {HTT_DBG_EXT_STATS_TQM_CMDQ, TXRX_HOST_STATS_INVALID}, 290 {HTT_DBG_EXT_STATS_TX_DE_INFO, TXRX_HOST_STATS_INVALID}, 291 {HTT_DBG_EXT_STATS_PDEV_TX_RATE, TXRX_HOST_STATS_INVALID}, 292 {HTT_DBG_EXT_STATS_PDEV_RX_RATE, TXRX_HOST_STATS_INVALID}, 293 {TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID}, 294 {HTT_DBG_EXT_STATS_TX_SELFGEN_INFO, TXRX_HOST_STATS_INVALID}, 295 {HTT_DBG_EXT_STATS_TX_MU_HWQ, TXRX_HOST_STATS_INVALID}, 296 {HTT_DBG_EXT_STATS_RING_IF_INFO, TXRX_HOST_STATS_INVALID}, 297 {HTT_DBG_EXT_STATS_SRNG_INFO, TXRX_HOST_STATS_INVALID}, 298 {HTT_DBG_EXT_STATS_SFM_INFO, TXRX_HOST_STATS_INVALID}, 299 {HTT_DBG_EXT_STATS_PDEV_TX_MU, TXRX_HOST_STATS_INVALID}, 300 {HTT_DBG_EXT_STATS_ACTIVE_PEERS_LIST, TXRX_HOST_STATS_INVALID}, 301 /* Last ENUM for HTT FW STATS */ 302 {DP_HTT_DBG_EXT_STATS_MAX, TXRX_HOST_STATS_INVALID}, 303 {TXRX_FW_STATS_INVALID, TXRX_CLEAR_STATS}, 304 {TXRX_FW_STATS_INVALID, TXRX_RX_RATE_STATS}, 305 {TXRX_FW_STATS_INVALID, TXRX_TX_RATE_STATS}, 306 {TXRX_FW_STATS_INVALID, TXRX_TX_HOST_STATS}, 307 {TXRX_FW_STATS_INVALID, TXRX_RX_HOST_STATS}, 308 {TXRX_FW_STATS_INVALID, TXRX_AST_STATS}, 309 {TXRX_FW_STATS_INVALID, TXRX_SRNG_PTR_STATS}, 310 {TXRX_FW_STATS_INVALID, TXRX_RX_MON_STATS}, 311 {TXRX_FW_STATS_INVALID, TXRX_REO_QUEUE_STATS}, 312 {TXRX_FW_STATS_INVALID, TXRX_SOC_CFG_PARAMS}, 313 {TXRX_FW_STATS_INVALID, TXRX_PDEV_CFG_PARAMS}, 314 {TXRX_FW_STATS_INVALID, TXRX_NAPI_STATS}, 315 {TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS}, 316 {TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS}, 317 {TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS}, 318 {TXRX_FW_STATS_INVALID, TXRX_SOC_REO_HW_DESC_DUMP}, 319 {TXRX_FW_STATS_INVALID, TXRX_SOC_WBM_IDLE_HPTP_DUMP}, 320 {TXRX_FW_STATS_INVALID, TXRX_SRNG_USAGE_WM_STATS}, 321 {HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, TXRX_HOST_STATS_INVALID}, 322 {HTT_DBG_EXT_STATS_TX_SOUNDING_INFO, TXRX_HOST_STATS_INVALID} 323 }; 324 325 /* MCL specific functions */ 326 #if defined(DP_CON_MON) 327 328 #ifdef IPA_OFFLOAD 329 /** 330 * dp_get_num_rx_contexts() - get number of RX contexts 331 * @soc_hdl: cdp opaque soc handle 332 * 333 * Return: number of RX contexts 334 */ 335 static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl) 336 { 337 int num_rx_contexts; 338 uint32_t reo_ring_map; 339 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 340 341 reo_ring_map = wlan_cfg_get_reo_rings_mapping(soc->wlan_cfg_ctx); 342 343 switch (soc->arch_id) { 344 case CDP_ARCH_TYPE_BE: 345 /* 2 REO rings are used for IPA */ 346 reo_ring_map &= ~(BIT(3) | BIT(7)); 347 348 break; 349 case CDP_ARCH_TYPE_LI: 350 /* 1 REO ring is used for IPA */ 351 reo_ring_map &= ~BIT(3); 352 break; 353 default: 354 dp_err("unknown arch_id 0x%x", soc->arch_id); 355 QDF_BUG(0); 356 } 357 /* 358 * qdf_get_hweight32 prefer over qdf_get_hweight8 in case map is scaled 359 * in future 360 */ 361 num_rx_contexts = qdf_get_hweight32(reo_ring_map); 362 363 return num_rx_contexts; 364 } 365 #else 366 static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl) 367 { 368 int num_rx_contexts; 369 uint32_t reo_config; 370 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 371 372 reo_config = wlan_cfg_get_reo_rings_mapping(soc->wlan_cfg_ctx); 373 /* 374 * qdf_get_hweight32 prefer over qdf_get_hweight8 in case map is scaled 375 * in future 376 */ 377 num_rx_contexts = qdf_get_hweight32(reo_config); 378 379 return num_rx_contexts; 380 } 381 #endif 382 383 #endif 384 385 #ifdef FEATURE_MEC 386 void dp_peer_mec_flush_entries(struct dp_soc *soc) 387 { 388 unsigned int index; 389 struct dp_mec_entry *mecentry, *mecentry_next; 390 391 TAILQ_HEAD(, dp_mec_entry) free_list; 392 TAILQ_INIT(&free_list); 393 394 if (!soc->mec_hash.mask) 395 return; 396 397 if (!soc->mec_hash.bins) 398 return; 399 400 if (!qdf_atomic_read(&soc->mec_cnt)) 401 return; 402 403 qdf_spin_lock_bh(&soc->mec_lock); 404 for (index = 0; index <= soc->mec_hash.mask; index++) { 405 if (!TAILQ_EMPTY(&soc->mec_hash.bins[index])) { 406 TAILQ_FOREACH_SAFE(mecentry, &soc->mec_hash.bins[index], 407 hash_list_elem, mecentry_next) { 408 dp_peer_mec_detach_entry(soc, mecentry, &free_list); 409 } 410 } 411 } 412 qdf_spin_unlock_bh(&soc->mec_lock); 413 414 dp_peer_mec_free_list(soc, &free_list); 415 } 416 417 /** 418 * dp_print_mec_stats() - Dump MEC entries in table 419 * @soc: Datapath soc handle 420 * 421 * Return: none 422 */ 423 static void dp_print_mec_stats(struct dp_soc *soc) 424 { 425 int i; 426 uint32_t index; 427 struct dp_mec_entry *mecentry = NULL, *mec_list; 428 uint32_t num_entries = 0; 429 430 DP_PRINT_STATS("MEC Stats:"); 431 DP_PRINT_STATS(" Entries Added = %d", soc->stats.mec.added); 432 DP_PRINT_STATS(" Entries Deleted = %d", soc->stats.mec.deleted); 433 434 if (!qdf_atomic_read(&soc->mec_cnt)) 435 return; 436 437 mec_list = qdf_mem_malloc(sizeof(*mecentry) * DP_PEER_MAX_MEC_ENTRY); 438 if (!mec_list) { 439 dp_peer_warn("%pK: failed to allocate mec_list", soc); 440 return; 441 } 442 443 DP_PRINT_STATS("MEC Table:"); 444 for (index = 0; index <= soc->mec_hash.mask; index++) { 445 qdf_spin_lock_bh(&soc->mec_lock); 446 if (TAILQ_EMPTY(&soc->mec_hash.bins[index])) { 447 qdf_spin_unlock_bh(&soc->mec_lock); 448 continue; 449 } 450 451 TAILQ_FOREACH(mecentry, &soc->mec_hash.bins[index], 452 hash_list_elem) { 453 qdf_mem_copy(&mec_list[num_entries], mecentry, 454 sizeof(*mecentry)); 455 num_entries++; 456 } 457 qdf_spin_unlock_bh(&soc->mec_lock); 458 } 459 460 if (!num_entries) { 461 qdf_mem_free(mec_list); 462 return; 463 } 464 465 for (i = 0; i < num_entries; i++) { 466 DP_PRINT_STATS("%6d mac_addr = " QDF_MAC_ADDR_FMT 467 " is_active = %d pdev_id = %d vdev_id = %d", 468 i, 469 QDF_MAC_ADDR_REF(mec_list[i].mac_addr.raw), 470 mec_list[i].is_active, 471 mec_list[i].pdev_id, 472 mec_list[i].vdev_id); 473 } 474 qdf_mem_free(mec_list); 475 } 476 #else 477 static void dp_print_mec_stats(struct dp_soc *soc) 478 { 479 } 480 #endif 481 482 static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl, 483 uint8_t vdev_id, 484 uint8_t *peer_mac, 485 uint8_t *mac_addr, 486 enum cdp_txrx_ast_entry_type type, 487 uint32_t flags) 488 { 489 int ret = -1; 490 QDF_STATUS status = QDF_STATUS_SUCCESS; 491 struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl, 492 peer_mac, 0, vdev_id, 493 DP_MOD_ID_CDP); 494 495 if (!peer) { 496 dp_peer_debug("Peer is NULL!"); 497 return ret; 498 } 499 500 status = dp_peer_add_ast((struct dp_soc *)soc_hdl, 501 peer, 502 mac_addr, 503 type, 504 flags); 505 if ((status == QDF_STATUS_SUCCESS) || 506 (status == QDF_STATUS_E_ALREADY) || 507 (status == QDF_STATUS_E_AGAIN)) 508 ret = 0; 509 510 dp_hmwds_ast_add_notify(peer, mac_addr, 511 type, status, false); 512 513 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 514 515 return ret; 516 } 517 518 static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl, 519 uint8_t vdev_id, 520 uint8_t *peer_mac, 521 uint8_t *wds_macaddr, 522 uint32_t flags) 523 { 524 int status = -1; 525 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 526 struct dp_ast_entry *ast_entry = NULL; 527 struct dp_peer *peer; 528 529 if (soc->ast_offload_support) 530 return status; 531 532 peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl, 533 peer_mac, 0, vdev_id, 534 DP_MOD_ID_CDP); 535 536 if (!peer) { 537 dp_peer_debug("Peer is NULL!"); 538 return status; 539 } 540 541 qdf_spin_lock_bh(&soc->ast_lock); 542 ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr, 543 peer->vdev->pdev->pdev_id); 544 545 if (ast_entry) { 546 status = dp_peer_update_ast(soc, 547 peer, 548 ast_entry, flags); 549 } 550 qdf_spin_unlock_bh(&soc->ast_lock); 551 552 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 553 554 return status; 555 } 556 557 /** 558 * dp_peer_reset_ast_entries() - Deletes all HMWDS entries for a peer 559 * @soc: Datapath SOC handle 560 * @peer: DP peer 561 * @arg: callback argument 562 * 563 * Return: None 564 */ 565 static void 566 dp_peer_reset_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg) 567 { 568 struct dp_ast_entry *ast_entry = NULL; 569 struct dp_ast_entry *tmp_ast_entry; 570 571 DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, tmp_ast_entry) { 572 if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) || 573 (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC)) 574 dp_peer_del_ast(soc, ast_entry); 575 } 576 } 577 578 /** 579 * dp_wds_reset_ast_wifi3() - Reset the is_active param for ast entry 580 * @soc_hdl: Datapath SOC handle 581 * @wds_macaddr: WDS entry MAC Address 582 * @peer_mac_addr: WDS entry MAC Address 583 * @vdev_id: id of vdev handle 584 * 585 * Return: QDF_STATUS 586 */ 587 static QDF_STATUS dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl, 588 uint8_t *wds_macaddr, 589 uint8_t *peer_mac_addr, 590 uint8_t vdev_id) 591 { 592 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 593 struct dp_ast_entry *ast_entry = NULL; 594 struct dp_peer *peer; 595 struct dp_pdev *pdev; 596 struct dp_vdev *vdev; 597 598 if (soc->ast_offload_support) 599 return QDF_STATUS_E_FAILURE; 600 601 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 602 603 if (!vdev) 604 return QDF_STATUS_E_FAILURE; 605 606 pdev = vdev->pdev; 607 608 if (peer_mac_addr) { 609 peer = dp_peer_find_hash_find(soc, peer_mac_addr, 610 0, vdev->vdev_id, 611 DP_MOD_ID_CDP); 612 if (!peer) { 613 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 614 return QDF_STATUS_E_FAILURE; 615 } 616 617 qdf_spin_lock_bh(&soc->ast_lock); 618 dp_peer_reset_ast_entries(soc, peer, NULL); 619 qdf_spin_unlock_bh(&soc->ast_lock); 620 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 621 } else if (wds_macaddr) { 622 qdf_spin_lock_bh(&soc->ast_lock); 623 ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr, 624 pdev->pdev_id); 625 626 if (ast_entry) { 627 if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) || 628 (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC)) 629 dp_peer_del_ast(soc, ast_entry); 630 } 631 qdf_spin_unlock_bh(&soc->ast_lock); 632 } 633 634 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 635 return QDF_STATUS_SUCCESS; 636 } 637 638 /** 639 * dp_wds_reset_ast_table_wifi3() - Reset the is_active param for all ast entry 640 * @soc_hdl: Datapath SOC handle 641 * @vdev_id: id of vdev object 642 * 643 * Return: QDF_STATUS 644 */ 645 static QDF_STATUS 646 dp_wds_reset_ast_table_wifi3(struct cdp_soc_t *soc_hdl, 647 uint8_t vdev_id) 648 { 649 struct dp_soc *soc = (struct dp_soc *) soc_hdl; 650 651 if (soc->ast_offload_support) 652 return QDF_STATUS_SUCCESS; 653 654 qdf_spin_lock_bh(&soc->ast_lock); 655 656 dp_soc_iterate_peer(soc, dp_peer_reset_ast_entries, NULL, 657 DP_MOD_ID_CDP); 658 qdf_spin_unlock_bh(&soc->ast_lock); 659 660 return QDF_STATUS_SUCCESS; 661 } 662 663 /** 664 * dp_peer_flush_ast_entries() - Delete all wds and hmwds ast entries of a peer 665 * @soc: Datapath SOC 666 * @peer: Datapath peer 667 * @arg: arg to callback 668 * 669 * Return: None 670 */ 671 static void 672 dp_peer_flush_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg) 673 { 674 struct dp_ast_entry *ase = NULL; 675 struct dp_ast_entry *temp_ase; 676 677 DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) { 678 if ((ase->type == 679 CDP_TXRX_AST_TYPE_STATIC) || 680 (ase->type == 681 CDP_TXRX_AST_TYPE_SELF) || 682 (ase->type == 683 CDP_TXRX_AST_TYPE_STA_BSS)) 684 continue; 685 dp_peer_del_ast(soc, ase); 686 } 687 } 688 689 /** 690 * dp_wds_flush_ast_table_wifi3() - Delete all wds and hmwds ast entry 691 * @soc_hdl: Datapath SOC handle 692 * 693 * Return: None 694 */ 695 static void dp_wds_flush_ast_table_wifi3(struct cdp_soc_t *soc_hdl) 696 { 697 struct dp_soc *soc = (struct dp_soc *) soc_hdl; 698 699 qdf_spin_lock_bh(&soc->ast_lock); 700 701 dp_soc_iterate_peer(soc, dp_peer_flush_ast_entries, NULL, 702 DP_MOD_ID_CDP); 703 704 qdf_spin_unlock_bh(&soc->ast_lock); 705 dp_peer_mec_flush_entries(soc); 706 } 707 708 #if defined(IPA_WDS_EASYMESH_FEATURE) && defined(FEATURE_AST) 709 /** 710 * dp_peer_send_wds_disconnect() - Send Disconnect event to IPA for each peer 711 * @soc: Datapath SOC 712 * @peer: Datapath peer 713 * 714 * Return: None 715 */ 716 static void 717 dp_peer_send_wds_disconnect(struct dp_soc *soc, struct dp_peer *peer) 718 { 719 struct dp_ast_entry *ase = NULL; 720 struct dp_ast_entry *temp_ase; 721 722 DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) { 723 if (ase->type == CDP_TXRX_AST_TYPE_WDS) { 724 soc->cdp_soc.ol_ops->peer_send_wds_disconnect(soc->ctrl_psoc, 725 ase->mac_addr.raw, 726 ase->vdev_id); 727 } 728 } 729 } 730 #elif defined(FEATURE_AST) 731 static void 732 dp_peer_send_wds_disconnect(struct dp_soc *soc, struct dp_peer *peer) 733 { 734 } 735 #endif 736 737 /** 738 * dp_peer_get_ast_info_by_soc_wifi3() - search the soc AST hash table 739 * and return ast entry information 740 * of first ast entry found in the 741 * table with given mac address 742 * @soc_hdl: data path soc handle 743 * @ast_mac_addr: AST entry mac address 744 * @ast_entry_info: ast entry information 745 * 746 * Return: true if ast entry found with ast_mac_addr 747 * false if ast entry not found 748 */ 749 static bool dp_peer_get_ast_info_by_soc_wifi3 750 (struct cdp_soc_t *soc_hdl, 751 uint8_t *ast_mac_addr, 752 struct cdp_ast_entry_info *ast_entry_info) 753 { 754 struct dp_ast_entry *ast_entry = NULL; 755 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 756 struct dp_peer *peer = NULL; 757 758 if (soc->ast_offload_support) 759 return false; 760 761 qdf_spin_lock_bh(&soc->ast_lock); 762 763 ast_entry = dp_peer_ast_hash_find_soc(soc, ast_mac_addr); 764 if ((!ast_entry) || 765 (ast_entry->delete_in_progress && !ast_entry->callback)) { 766 qdf_spin_unlock_bh(&soc->ast_lock); 767 return false; 768 } 769 770 peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id, 771 DP_MOD_ID_AST); 772 if (!peer) { 773 qdf_spin_unlock_bh(&soc->ast_lock); 774 return false; 775 } 776 777 ast_entry_info->type = ast_entry->type; 778 ast_entry_info->pdev_id = ast_entry->pdev_id; 779 ast_entry_info->vdev_id = ast_entry->vdev_id; 780 ast_entry_info->peer_id = ast_entry->peer_id; 781 qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], 782 &peer->mac_addr.raw[0], 783 QDF_MAC_ADDR_SIZE); 784 dp_peer_unref_delete(peer, DP_MOD_ID_AST); 785 qdf_spin_unlock_bh(&soc->ast_lock); 786 return true; 787 } 788 789 /** 790 * dp_peer_get_ast_info_by_pdevid_wifi3() - search the soc AST hash table 791 * and return ast entry information 792 * if mac address and pdev_id matches 793 * @soc_hdl: data path soc handle 794 * @ast_mac_addr: AST entry mac address 795 * @pdev_id: pdev_id 796 * @ast_entry_info: ast entry information 797 * 798 * Return: true if ast entry found with ast_mac_addr 799 * false if ast entry not found 800 */ 801 static bool dp_peer_get_ast_info_by_pdevid_wifi3 802 (struct cdp_soc_t *soc_hdl, 803 uint8_t *ast_mac_addr, 804 uint8_t pdev_id, 805 struct cdp_ast_entry_info *ast_entry_info) 806 { 807 struct dp_ast_entry *ast_entry; 808 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 809 struct dp_peer *peer = NULL; 810 811 if (soc->ast_offload_support) 812 return false; 813 814 qdf_spin_lock_bh(&soc->ast_lock); 815 816 ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, ast_mac_addr, 817 pdev_id); 818 819 if ((!ast_entry) || 820 (ast_entry->delete_in_progress && !ast_entry->callback)) { 821 qdf_spin_unlock_bh(&soc->ast_lock); 822 return false; 823 } 824 825 peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id, 826 DP_MOD_ID_AST); 827 if (!peer) { 828 qdf_spin_unlock_bh(&soc->ast_lock); 829 return false; 830 } 831 832 ast_entry_info->type = ast_entry->type; 833 ast_entry_info->pdev_id = ast_entry->pdev_id; 834 ast_entry_info->vdev_id = ast_entry->vdev_id; 835 ast_entry_info->peer_id = ast_entry->peer_id; 836 qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], 837 &peer->mac_addr.raw[0], 838 QDF_MAC_ADDR_SIZE); 839 dp_peer_unref_delete(peer, DP_MOD_ID_AST); 840 qdf_spin_unlock_bh(&soc->ast_lock); 841 return true; 842 } 843 844 /** 845 * dp_peer_ast_entry_del_by_soc() - delete the ast entry from soc AST hash table 846 * with given mac address 847 * @soc_handle: data path soc handle 848 * @mac_addr: AST entry mac address 849 * @callback: callback function to called on ast delete response from FW 850 * @cookie: argument to be passed to callback 851 * 852 * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete 853 * is sent 854 * QDF_STATUS_E_INVAL false if ast entry not found 855 */ 856 static QDF_STATUS dp_peer_ast_entry_del_by_soc(struct cdp_soc_t *soc_handle, 857 uint8_t *mac_addr, 858 txrx_ast_free_cb callback, 859 void *cookie) 860 861 { 862 struct dp_soc *soc = (struct dp_soc *)soc_handle; 863 struct dp_ast_entry *ast_entry = NULL; 864 txrx_ast_free_cb cb = NULL; 865 void *arg = NULL; 866 867 if (soc->ast_offload_support) 868 return -QDF_STATUS_E_INVAL; 869 870 qdf_spin_lock_bh(&soc->ast_lock); 871 ast_entry = dp_peer_ast_hash_find_soc(soc, mac_addr); 872 if (!ast_entry) { 873 qdf_spin_unlock_bh(&soc->ast_lock); 874 return -QDF_STATUS_E_INVAL; 875 } 876 877 if (ast_entry->callback) { 878 cb = ast_entry->callback; 879 arg = ast_entry->cookie; 880 } 881 882 ast_entry->callback = callback; 883 ast_entry->cookie = cookie; 884 885 /* 886 * if delete_in_progress is set AST delete is sent to target 887 * and host is waiting for response should not send delete 888 * again 889 */ 890 if (!ast_entry->delete_in_progress) 891 dp_peer_del_ast(soc, ast_entry); 892 893 qdf_spin_unlock_bh(&soc->ast_lock); 894 if (cb) { 895 cb(soc->ctrl_psoc, 896 dp_soc_to_cdp_soc(soc), 897 arg, 898 CDP_TXRX_AST_DELETE_IN_PROGRESS); 899 } 900 return QDF_STATUS_SUCCESS; 901 } 902 903 /** 904 * dp_peer_ast_entry_del_by_pdev() - delete the ast entry from soc AST hash 905 * table if mac address and pdev_id matches 906 * @soc_handle: data path soc handle 907 * @mac_addr: AST entry mac address 908 * @pdev_id: pdev id 909 * @callback: callback function to called on ast delete response from FW 910 * @cookie: argument to be passed to callback 911 * 912 * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete 913 * is sent 914 * QDF_STATUS_E_INVAL false if ast entry not found 915 */ 916 917 static QDF_STATUS dp_peer_ast_entry_del_by_pdev(struct cdp_soc_t *soc_handle, 918 uint8_t *mac_addr, 919 uint8_t pdev_id, 920 txrx_ast_free_cb callback, 921 void *cookie) 922 923 { 924 struct dp_soc *soc = (struct dp_soc *)soc_handle; 925 struct dp_ast_entry *ast_entry; 926 txrx_ast_free_cb cb = NULL; 927 void *arg = NULL; 928 929 if (soc->ast_offload_support) 930 return -QDF_STATUS_E_INVAL; 931 932 qdf_spin_lock_bh(&soc->ast_lock); 933 ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, mac_addr, pdev_id); 934 935 if (!ast_entry) { 936 qdf_spin_unlock_bh(&soc->ast_lock); 937 return -QDF_STATUS_E_INVAL; 938 } 939 940 if (ast_entry->callback) { 941 cb = ast_entry->callback; 942 arg = ast_entry->cookie; 943 } 944 945 ast_entry->callback = callback; 946 ast_entry->cookie = cookie; 947 948 /* 949 * if delete_in_progress is set AST delete is sent to target 950 * and host is waiting for response should not sent delete 951 * again 952 */ 953 if (!ast_entry->delete_in_progress) 954 dp_peer_del_ast(soc, ast_entry); 955 956 qdf_spin_unlock_bh(&soc->ast_lock); 957 958 if (cb) { 959 cb(soc->ctrl_psoc, 960 dp_soc_to_cdp_soc(soc), 961 arg, 962 CDP_TXRX_AST_DELETE_IN_PROGRESS); 963 } 964 return QDF_STATUS_SUCCESS; 965 } 966 967 /** 968 * dp_peer_HMWDS_ast_entry_del() - delete the ast entry from soc AST hash 969 * table if HMWDS rem-addr command is issued 970 * 971 * @soc_handle: data path soc handle 972 * @vdev_id: vdev id 973 * @wds_macaddr: AST entry mac address to delete 974 * @type: cdp_txrx_ast_entry_type to send to FW 975 * @delete_in_fw: flag to indicate AST entry deletion in FW 976 * 977 * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete 978 * is sent 979 * QDF_STATUS_E_INVAL false if ast entry not found 980 */ 981 static QDF_STATUS dp_peer_HMWDS_ast_entry_del(struct cdp_soc_t *soc_handle, 982 uint8_t vdev_id, 983 uint8_t *wds_macaddr, 984 uint8_t type, 985 uint8_t delete_in_fw) 986 { 987 struct dp_soc *soc = (struct dp_soc *)soc_handle; 988 989 if (soc->ast_offload_support) { 990 dp_del_wds_entry_wrapper(soc, vdev_id, wds_macaddr, type, 991 delete_in_fw); 992 return QDF_STATUS_SUCCESS; 993 } 994 995 return -QDF_STATUS_E_INVAL; 996 } 997 998 #ifdef FEATURE_AST 999 /** 1000 * dp_print_mlo_ast_stats() - Print AST stats for MLO peers 1001 * 1002 * @soc: core DP soc context 1003 * 1004 * Return: void 1005 */ 1006 static void dp_print_mlo_ast_stats(struct dp_soc *soc) 1007 { 1008 if (soc->arch_ops.print_mlo_ast_stats) 1009 soc->arch_ops.print_mlo_ast_stats(soc); 1010 } 1011 1012 void 1013 dp_print_peer_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg) 1014 { 1015 struct dp_ast_entry *ase, *tmp_ase; 1016 uint32_t num_entries = 0; 1017 char type[CDP_TXRX_AST_TYPE_MAX][10] = { 1018 "NONE", "STATIC", "SELF", "WDS", "HMWDS", "BSS", 1019 "DA", "HMWDS_SEC", "MLD"}; 1020 1021 DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) { 1022 DP_PRINT_STATS("%6d mac_addr = "QDF_MAC_ADDR_FMT 1023 " peer_mac_addr = "QDF_MAC_ADDR_FMT 1024 " peer_id = %u" 1025 " type = %s" 1026 " next_hop = %d" 1027 " is_active = %d" 1028 " ast_idx = %d" 1029 " ast_hash = %d" 1030 " delete_in_progress = %d" 1031 " pdev_id = %d" 1032 " vdev_id = %d", 1033 ++num_entries, 1034 QDF_MAC_ADDR_REF(ase->mac_addr.raw), 1035 QDF_MAC_ADDR_REF(peer->mac_addr.raw), 1036 ase->peer_id, 1037 type[ase->type], 1038 ase->next_hop, 1039 ase->is_active, 1040 ase->ast_idx, 1041 ase->ast_hash_value, 1042 ase->delete_in_progress, 1043 ase->pdev_id, 1044 ase->vdev_id); 1045 } 1046 } 1047 1048 void dp_print_ast_stats(struct dp_soc *soc) 1049 { 1050 DP_PRINT_STATS("AST Stats:"); 1051 DP_PRINT_STATS(" Entries Added = %d", soc->stats.ast.added); 1052 DP_PRINT_STATS(" Entries Deleted = %d", soc->stats.ast.deleted); 1053 DP_PRINT_STATS(" Entries Agedout = %d", soc->stats.ast.aged_out); 1054 DP_PRINT_STATS(" Entries MAP ERR = %d", soc->stats.ast.map_err); 1055 DP_PRINT_STATS(" Entries Mismatch ERR = %d", 1056 soc->stats.ast.ast_mismatch); 1057 1058 DP_PRINT_STATS("AST Table:"); 1059 1060 qdf_spin_lock_bh(&soc->ast_lock); 1061 1062 dp_soc_iterate_peer(soc, dp_print_peer_ast_entries, NULL, 1063 DP_MOD_ID_GENERIC_STATS); 1064 1065 qdf_spin_unlock_bh(&soc->ast_lock); 1066 1067 dp_print_mlo_ast_stats(soc); 1068 } 1069 #else 1070 void dp_print_ast_stats(struct dp_soc *soc) 1071 { 1072 DP_PRINT_STATS("AST Stats not available.Enable FEATURE_AST"); 1073 return; 1074 } 1075 #endif 1076 1077 /** 1078 * dp_print_peer_info() - Dump peer info 1079 * @soc: Datapath soc handle 1080 * @peer: Datapath peer handle 1081 * @arg: argument to iter function 1082 * 1083 * Return: void 1084 */ 1085 static void 1086 dp_print_peer_info(struct dp_soc *soc, struct dp_peer *peer, void *arg) 1087 { 1088 struct dp_txrx_peer *txrx_peer = NULL; 1089 1090 txrx_peer = dp_get_txrx_peer(peer); 1091 if (!txrx_peer) 1092 return; 1093 1094 DP_PRINT_STATS(" peer id = %d" 1095 " peer_mac_addr = "QDF_MAC_ADDR_FMT 1096 " nawds_enabled = %d" 1097 " bss_peer = %d" 1098 " wds_enabled = %d" 1099 " tx_cap_enabled = %d" 1100 " rx_cap_enabled = %d", 1101 peer->peer_id, 1102 QDF_MAC_ADDR_REF(peer->mac_addr.raw), 1103 txrx_peer->nawds_enabled, 1104 txrx_peer->bss_peer, 1105 txrx_peer->wds_enabled, 1106 dp_monitor_is_tx_cap_enabled(peer), 1107 dp_monitor_is_rx_cap_enabled(peer)); 1108 } 1109 1110 /** 1111 * dp_print_peer_table() - Dump all Peer stats 1112 * @vdev: Datapath Vdev handle 1113 * 1114 * Return: void 1115 */ 1116 static void dp_print_peer_table(struct dp_vdev *vdev) 1117 { 1118 DP_PRINT_STATS("Dumping Peer Table Stats:"); 1119 dp_vdev_iterate_peer(vdev, dp_print_peer_info, NULL, 1120 DP_MOD_ID_GENERIC_STATS); 1121 } 1122 1123 #ifdef DP_MEM_PRE_ALLOC 1124 1125 void *dp_context_alloc_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, 1126 size_t ctxt_size) 1127 { 1128 void *ctxt_mem; 1129 1130 if (!soc->cdp_soc.ol_ops->dp_prealloc_get_context) { 1131 dp_warn("dp_prealloc_get_context null!"); 1132 goto dynamic_alloc; 1133 } 1134 1135 ctxt_mem = soc->cdp_soc.ol_ops->dp_prealloc_get_context(ctxt_type, 1136 ctxt_size); 1137 1138 if (ctxt_mem) 1139 goto end; 1140 1141 dynamic_alloc: 1142 dp_info("switch to dynamic-alloc for type %d, size %zu", 1143 ctxt_type, ctxt_size); 1144 ctxt_mem = qdf_mem_malloc(ctxt_size); 1145 end: 1146 return ctxt_mem; 1147 } 1148 1149 void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, 1150 void *vaddr) 1151 { 1152 QDF_STATUS status; 1153 1154 if (soc->cdp_soc.ol_ops->dp_prealloc_put_context) { 1155 status = soc->cdp_soc.ol_ops->dp_prealloc_put_context( 1156 ctxt_type, 1157 vaddr); 1158 } else { 1159 dp_warn("dp_prealloc_put_context null!"); 1160 status = QDF_STATUS_E_NOSUPPORT; 1161 } 1162 1163 if (QDF_IS_STATUS_ERROR(status)) { 1164 dp_info("Context type %d not pre-allocated", ctxt_type); 1165 qdf_mem_free(vaddr); 1166 } 1167 } 1168 1169 static inline 1170 void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc, 1171 struct dp_srng *srng, 1172 uint32_t ring_type) 1173 { 1174 void *mem; 1175 1176 qdf_assert(!srng->is_mem_prealloc); 1177 1178 if (!soc->cdp_soc.ol_ops->dp_prealloc_get_consistent) { 1179 dp_warn("dp_prealloc_get_consistent is null!"); 1180 goto qdf; 1181 } 1182 1183 mem = 1184 soc->cdp_soc.ol_ops->dp_prealloc_get_consistent 1185 (&srng->alloc_size, 1186 &srng->base_vaddr_unaligned, 1187 &srng->base_paddr_unaligned, 1188 &srng->base_paddr_aligned, 1189 DP_RING_BASE_ALIGN, ring_type); 1190 1191 if (mem) { 1192 srng->is_mem_prealloc = true; 1193 goto end; 1194 } 1195 qdf: 1196 mem = qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size, 1197 &srng->base_vaddr_unaligned, 1198 &srng->base_paddr_unaligned, 1199 &srng->base_paddr_aligned, 1200 DP_RING_BASE_ALIGN); 1201 end: 1202 dp_info("%s memory %pK dp_srng %pK ring_type %d alloc_size %d num_entries %d", 1203 srng->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", mem, 1204 srng, ring_type, srng->alloc_size, srng->num_entries); 1205 return mem; 1206 } 1207 1208 static inline void dp_srng_mem_free_consistent(struct dp_soc *soc, 1209 struct dp_srng *srng) 1210 { 1211 if (srng->is_mem_prealloc) { 1212 if (!soc->cdp_soc.ol_ops->dp_prealloc_put_consistent) { 1213 dp_warn("dp_prealloc_put_consistent is null!"); 1214 QDF_BUG(0); 1215 return; 1216 } 1217 soc->cdp_soc.ol_ops->dp_prealloc_put_consistent 1218 (srng->alloc_size, 1219 srng->base_vaddr_unaligned, 1220 srng->base_paddr_unaligned); 1221 1222 } else { 1223 qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, 1224 srng->alloc_size, 1225 srng->base_vaddr_unaligned, 1226 srng->base_paddr_unaligned, 0); 1227 } 1228 } 1229 1230 void dp_desc_multi_pages_mem_alloc(struct dp_soc *soc, 1231 enum dp_desc_type desc_type, 1232 struct qdf_mem_multi_page_t *pages, 1233 size_t element_size, 1234 uint32_t element_num, 1235 qdf_dma_context_t memctxt, 1236 bool cacheable) 1237 { 1238 if (!soc->cdp_soc.ol_ops->dp_get_multi_pages) { 1239 dp_warn("dp_get_multi_pages is null!"); 1240 goto qdf; 1241 } 1242 1243 pages->num_pages = 0; 1244 pages->is_mem_prealloc = 0; 1245 soc->cdp_soc.ol_ops->dp_get_multi_pages(desc_type, 1246 element_size, 1247 element_num, 1248 pages, 1249 cacheable); 1250 if (pages->num_pages) 1251 goto end; 1252 1253 qdf: 1254 qdf_mem_multi_pages_alloc(soc->osdev, pages, element_size, 1255 element_num, memctxt, cacheable); 1256 end: 1257 dp_info("%s desc_type %d element_size %d element_num %d cacheable %d", 1258 pages->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", 1259 desc_type, (int)element_size, element_num, cacheable); 1260 } 1261 1262 void dp_desc_multi_pages_mem_free(struct dp_soc *soc, 1263 enum dp_desc_type desc_type, 1264 struct qdf_mem_multi_page_t *pages, 1265 qdf_dma_context_t memctxt, 1266 bool cacheable) 1267 { 1268 if (pages->is_mem_prealloc) { 1269 if (!soc->cdp_soc.ol_ops->dp_put_multi_pages) { 1270 dp_warn("dp_put_multi_pages is null!"); 1271 QDF_BUG(0); 1272 return; 1273 } 1274 1275 soc->cdp_soc.ol_ops->dp_put_multi_pages(desc_type, pages); 1276 qdf_mem_zero(pages, sizeof(*pages)); 1277 } else { 1278 qdf_mem_multi_pages_free(soc->osdev, pages, 1279 memctxt, cacheable); 1280 } 1281 } 1282 1283 #else 1284 1285 static inline 1286 void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc, 1287 struct dp_srng *srng, 1288 uint32_t ring_type) 1289 1290 { 1291 void *mem; 1292 1293 mem = qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size, 1294 &srng->base_vaddr_unaligned, 1295 &srng->base_paddr_unaligned, 1296 &srng->base_paddr_aligned, 1297 DP_RING_BASE_ALIGN); 1298 if (mem) 1299 qdf_mem_set(srng->base_vaddr_unaligned, 0, srng->alloc_size); 1300 1301 return mem; 1302 } 1303 1304 static inline void dp_srng_mem_free_consistent(struct dp_soc *soc, 1305 struct dp_srng *srng) 1306 { 1307 qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, 1308 srng->alloc_size, 1309 srng->base_vaddr_unaligned, 1310 srng->base_paddr_unaligned, 0); 1311 } 1312 1313 #endif /* DP_MEM_PRE_ALLOC */ 1314 1315 #ifdef QCA_SUPPORT_WDS_EXTENDED 1316 bool dp_vdev_is_wds_ext_enabled(struct dp_vdev *vdev) 1317 { 1318 return vdev->wds_ext_enabled; 1319 } 1320 #else 1321 bool dp_vdev_is_wds_ext_enabled(struct dp_vdev *vdev) 1322 { 1323 return false; 1324 } 1325 #endif 1326 1327 void dp_pdev_update_fast_rx_flag(struct dp_soc *soc, struct dp_pdev *pdev) 1328 { 1329 struct dp_vdev *vdev = NULL; 1330 uint8_t rx_fast_flag = true; 1331 1332 /* Check if protocol tagging enable */ 1333 if (pdev->is_rx_protocol_tagging_enabled && !pdev->enhanced_stats_en) { 1334 rx_fast_flag = false; 1335 goto update_flag; 1336 } 1337 1338 qdf_spin_lock_bh(&pdev->vdev_list_lock); 1339 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 1340 /* Check if any VDEV has NAWDS enabled */ 1341 if (vdev->nawds_enabled) { 1342 rx_fast_flag = false; 1343 break; 1344 } 1345 1346 /* Check if any VDEV has multipass enabled */ 1347 if (vdev->multipass_en) { 1348 rx_fast_flag = false; 1349 break; 1350 } 1351 1352 /* Check if any VDEV has mesh enabled */ 1353 if (vdev->mesh_vdev) { 1354 rx_fast_flag = false; 1355 break; 1356 } 1357 } 1358 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 1359 1360 update_flag: 1361 dp_init_info("Updated Rx fast flag to %u", rx_fast_flag); 1362 pdev->rx_fast_flag = rx_fast_flag; 1363 } 1364 1365 void dp_srng_free(struct dp_soc *soc, struct dp_srng *srng) 1366 { 1367 if (srng->alloc_size && srng->base_vaddr_unaligned) { 1368 if (!srng->cached) { 1369 dp_srng_mem_free_consistent(soc, srng); 1370 } else { 1371 qdf_mem_free(srng->base_vaddr_unaligned); 1372 } 1373 srng->alloc_size = 0; 1374 srng->base_vaddr_unaligned = NULL; 1375 } 1376 srng->hal_srng = NULL; 1377 } 1378 1379 qdf_export_symbol(dp_srng_free); 1380 1381 QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, int ring_type, 1382 int ring_num, int mac_id) 1383 { 1384 return soc->arch_ops.txrx_srng_init(soc, srng, ring_type, 1385 ring_num, mac_id); 1386 } 1387 1388 qdf_export_symbol(dp_srng_init); 1389 1390 QDF_STATUS dp_srng_alloc(struct dp_soc *soc, struct dp_srng *srng, 1391 int ring_type, uint32_t num_entries, 1392 bool cached) 1393 { 1394 hal_soc_handle_t hal_soc = soc->hal_soc; 1395 uint32_t entry_size = hal_srng_get_entrysize(hal_soc, ring_type); 1396 uint32_t max_entries = hal_srng_max_entries(hal_soc, ring_type); 1397 1398 if (srng->base_vaddr_unaligned) { 1399 dp_init_err("%pK: Ring type: %d, is already allocated", 1400 soc, ring_type); 1401 return QDF_STATUS_SUCCESS; 1402 } 1403 1404 num_entries = (num_entries > max_entries) ? max_entries : num_entries; 1405 srng->hal_srng = NULL; 1406 srng->alloc_size = num_entries * entry_size; 1407 srng->num_entries = num_entries; 1408 srng->cached = cached; 1409 1410 if (!cached) { 1411 srng->base_vaddr_aligned = 1412 dp_srng_aligned_mem_alloc_consistent(soc, 1413 srng, 1414 ring_type); 1415 } else { 1416 srng->base_vaddr_aligned = qdf_aligned_malloc( 1417 &srng->alloc_size, 1418 &srng->base_vaddr_unaligned, 1419 &srng->base_paddr_unaligned, 1420 &srng->base_paddr_aligned, 1421 DP_RING_BASE_ALIGN); 1422 } 1423 1424 if (!srng->base_vaddr_aligned) 1425 return QDF_STATUS_E_NOMEM; 1426 1427 return QDF_STATUS_SUCCESS; 1428 } 1429 1430 qdf_export_symbol(dp_srng_alloc); 1431 1432 void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng, 1433 int ring_type, int ring_num) 1434 { 1435 if (!srng->hal_srng) { 1436 dp_init_err("%pK: Ring type: %d, num:%d not setup", 1437 soc, ring_type, ring_num); 1438 return; 1439 } 1440 1441 if (dp_check_umac_reset_in_progress(soc)) 1442 goto srng_cleanup; 1443 1444 if (soc->arch_ops.dp_free_ppeds_interrupts) 1445 soc->arch_ops.dp_free_ppeds_interrupts(soc, srng, ring_type, 1446 ring_num); 1447 1448 srng_cleanup: 1449 hal_srng_cleanup(soc->hal_soc, srng->hal_srng, 1450 dp_check_umac_reset_in_progress(soc)); 1451 srng->hal_srng = NULL; 1452 } 1453 1454 qdf_export_symbol(dp_srng_deinit); 1455 1456 /* TODO: Need this interface from HIF */ 1457 void *hif_get_hal_handle(struct hif_opaque_softc *hif_handle); 1458 1459 #ifdef WLAN_FEATURE_DP_EVENT_HISTORY 1460 int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, 1461 hal_ring_handle_t hal_ring_hdl) 1462 { 1463 hal_soc_handle_t hal_soc = dp_soc->hal_soc; 1464 uint32_t hp, tp; 1465 uint8_t ring_id; 1466 1467 if (!int_ctx) 1468 return dp_hal_srng_access_start(hal_soc, hal_ring_hdl); 1469 1470 hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); 1471 ring_id = hal_srng_ring_id_get(hal_ring_hdl); 1472 1473 hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id, 1474 ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_START); 1475 1476 return dp_hal_srng_access_start(hal_soc, hal_ring_hdl); 1477 } 1478 1479 void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc, 1480 hal_ring_handle_t hal_ring_hdl) 1481 { 1482 hal_soc_handle_t hal_soc = dp_soc->hal_soc; 1483 uint32_t hp, tp; 1484 uint8_t ring_id; 1485 1486 if (!int_ctx) 1487 return dp_hal_srng_access_end(hal_soc, hal_ring_hdl); 1488 1489 hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); 1490 ring_id = hal_srng_ring_id_get(hal_ring_hdl); 1491 1492 hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id, 1493 ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_END); 1494 1495 return dp_hal_srng_access_end(hal_soc, hal_ring_hdl); 1496 } 1497 1498 static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc, 1499 uint8_t hist_group_id) 1500 { 1501 hif_record_event(dp_soc->hif_handle, hist_group_id, 1502 0, 0, 0, HIF_EVENT_TIMER_ENTRY); 1503 } 1504 1505 static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc, 1506 uint8_t hist_group_id) 1507 { 1508 hif_record_event(dp_soc->hif_handle, hist_group_id, 1509 0, 0, 0, HIF_EVENT_TIMER_EXIT); 1510 } 1511 #else 1512 1513 static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc, 1514 uint8_t hist_group_id) 1515 { 1516 } 1517 1518 static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc, 1519 uint8_t hist_group_id) 1520 { 1521 } 1522 1523 #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ 1524 1525 enum timer_yield_status 1526 dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done, 1527 uint64_t start_time) 1528 { 1529 uint64_t cur_time = qdf_get_log_timestamp(); 1530 1531 if (!work_done) 1532 return DP_TIMER_WORK_DONE; 1533 1534 if (cur_time - start_time > DP_MAX_TIMER_EXEC_TIME_TICKS) 1535 return DP_TIMER_TIME_EXHAUST; 1536 1537 return DP_TIMER_NO_YIELD; 1538 } 1539 1540 qdf_export_symbol(dp_should_timer_irq_yield); 1541 1542 void dp_interrupt_timer(void *arg) 1543 { 1544 struct dp_soc *soc = (struct dp_soc *) arg; 1545 struct dp_pdev *pdev = soc->pdev_list[0]; 1546 enum timer_yield_status yield = DP_TIMER_NO_YIELD; 1547 uint32_t work_done = 0, total_work_done = 0; 1548 int budget = 0xffff, i; 1549 uint32_t remaining_quota = budget; 1550 uint64_t start_time; 1551 uint32_t lmac_id = DP_MON_INVALID_LMAC_ID; 1552 uint8_t dp_intr_id = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); 1553 uint32_t lmac_iter; 1554 int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); 1555 enum reg_wifi_band mon_band; 1556 int cpu = dp_srng_get_cpu(); 1557 1558 /* 1559 * this logic makes all data path interfacing rings (UMAC/LMAC) 1560 * and Monitor rings polling mode when NSS offload is disabled 1561 */ 1562 if (wlan_cfg_is_poll_mode_enabled(soc->wlan_cfg_ctx) && 1563 !wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) { 1564 if (qdf_atomic_read(&soc->cmn_init_done)) { 1565 for (i = 0; i < wlan_cfg_get_num_contexts( 1566 soc->wlan_cfg_ctx); i++) 1567 dp_service_srngs(&soc->intr_ctx[i], 0xffff, 1568 cpu); 1569 1570 qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); 1571 } 1572 return; 1573 } 1574 1575 if (!qdf_atomic_read(&soc->cmn_init_done)) 1576 return; 1577 1578 if (dp_monitor_is_chan_band_known(pdev)) { 1579 mon_band = dp_monitor_get_chan_band(pdev); 1580 lmac_id = pdev->ch_band_lmac_id_mapping[mon_band]; 1581 if (qdf_likely(lmac_id != DP_MON_INVALID_LMAC_ID)) { 1582 dp_intr_id = soc->mon_intr_id_lmac_map[lmac_id]; 1583 dp_srng_record_timer_entry(soc, dp_intr_id); 1584 } 1585 } 1586 1587 start_time = qdf_get_log_timestamp(); 1588 dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings); 1589 1590 while (yield == DP_TIMER_NO_YIELD) { 1591 for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) { 1592 if (lmac_iter == lmac_id) 1593 work_done = dp_monitor_process(soc, 1594 &soc->intr_ctx[dp_intr_id], 1595 lmac_iter, remaining_quota); 1596 else 1597 work_done = 1598 dp_monitor_drop_packets_for_mac(pdev, 1599 lmac_iter, 1600 remaining_quota); 1601 if (work_done) { 1602 budget -= work_done; 1603 if (budget <= 0) { 1604 yield = DP_TIMER_WORK_EXHAUST; 1605 goto budget_done; 1606 } 1607 remaining_quota = budget; 1608 total_work_done += work_done; 1609 } 1610 } 1611 1612 yield = dp_should_timer_irq_yield(soc, total_work_done, 1613 start_time); 1614 total_work_done = 0; 1615 } 1616 1617 budget_done: 1618 if (yield == DP_TIMER_WORK_EXHAUST || 1619 yield == DP_TIMER_TIME_EXHAUST) 1620 qdf_timer_mod(&soc->int_timer, 1); 1621 else 1622 qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); 1623 1624 if (lmac_id != DP_MON_INVALID_LMAC_ID) 1625 dp_srng_record_timer_exit(soc, dp_intr_id); 1626 } 1627 1628 #if defined(DP_INTR_POLL_BOTH) 1629 /** 1630 * dp_soc_interrupt_attach_wrapper() - Register handlers for DP interrupts 1631 * @txrx_soc: DP SOC handle 1632 * 1633 * Call the appropriate attach function based on the mode of operation. 1634 * This is a WAR for enabling monitor mode. 1635 * 1636 * Return: 0 for success. nonzero for failure. 1637 */ 1638 static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) 1639 { 1640 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 1641 1642 if (!(soc->wlan_cfg_ctx->napi_enabled) || 1643 (dp_is_monitor_mode_using_poll(soc) && 1644 soc->cdp_soc.ol_ops->get_con_mode && 1645 soc->cdp_soc.ol_ops->get_con_mode() == 1646 QDF_GLOBAL_MONITOR_MODE)) { 1647 dp_info("Poll mode"); 1648 return dp_soc_attach_poll(txrx_soc); 1649 } else { 1650 dp_info("Interrupt mode"); 1651 return dp_soc_interrupt_attach(txrx_soc); 1652 } 1653 } 1654 #else 1655 #if defined(DP_INTR_POLL_BASED) && DP_INTR_POLL_BASED 1656 static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) 1657 { 1658 return dp_soc_attach_poll(txrx_soc); 1659 } 1660 #else 1661 static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) 1662 { 1663 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 1664 1665 if (wlan_cfg_is_poll_mode_enabled(soc->wlan_cfg_ctx)) 1666 return dp_soc_attach_poll(txrx_soc); 1667 else 1668 return dp_soc_interrupt_attach(txrx_soc); 1669 } 1670 #endif 1671 #endif 1672 1673 /** 1674 * dp_soc_ppeds_stop() - Stop PPE DS processing 1675 * @soc_handle: DP SOC handle 1676 * 1677 * Return: none 1678 */ 1679 static void dp_soc_ppeds_stop(struct cdp_soc_t *soc_handle) 1680 { 1681 struct dp_soc *soc = (struct dp_soc *)soc_handle; 1682 1683 if (soc->arch_ops.txrx_soc_ppeds_stop) 1684 soc->arch_ops.txrx_soc_ppeds_stop(soc); 1685 } 1686 1687 #ifdef ENABLE_VERBOSE_DEBUG 1688 void dp_enable_verbose_debug(struct dp_soc *soc) 1689 { 1690 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1691 1692 soc_cfg_ctx = soc->wlan_cfg_ctx; 1693 1694 if (soc_cfg_ctx->per_pkt_trace & dp_verbose_debug_mask) 1695 is_dp_verbose_debug_enabled = true; 1696 1697 if (soc_cfg_ctx->per_pkt_trace & hal_verbose_debug_mask) 1698 hal_set_verbose_debug(true); 1699 else 1700 hal_set_verbose_debug(false); 1701 } 1702 #else 1703 void dp_enable_verbose_debug(struct dp_soc *soc) 1704 { 1705 } 1706 #endif 1707 1708 static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) 1709 { 1710 struct cdp_lro_hash_config lro_hash; 1711 QDF_STATUS status; 1712 1713 if (!wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) && 1714 !wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx) && 1715 !wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { 1716 dp_err("LRO, GRO and RX hash disabled"); 1717 return QDF_STATUS_E_FAILURE; 1718 } 1719 1720 qdf_mem_zero(&lro_hash, sizeof(lro_hash)); 1721 1722 if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) || 1723 wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx)) { 1724 lro_hash.lro_enable = 1; 1725 lro_hash.tcp_flag = QDF_TCPHDR_ACK; 1726 lro_hash.tcp_flag_mask = QDF_TCPHDR_FIN | QDF_TCPHDR_SYN | 1727 QDF_TCPHDR_RST | QDF_TCPHDR_ACK | QDF_TCPHDR_URG | 1728 QDF_TCPHDR_ECE | QDF_TCPHDR_CWR; 1729 } 1730 1731 soc->arch_ops.get_rx_hash_key(soc, &lro_hash); 1732 1733 qdf_assert(soc->cdp_soc.ol_ops->lro_hash_config); 1734 1735 if (!soc->cdp_soc.ol_ops->lro_hash_config) { 1736 QDF_BUG(0); 1737 dp_err("lro_hash_config not configured"); 1738 return QDF_STATUS_E_FAILURE; 1739 } 1740 1741 status = soc->cdp_soc.ol_ops->lro_hash_config(soc->ctrl_psoc, 1742 pdev->pdev_id, 1743 &lro_hash); 1744 if (!QDF_IS_STATUS_SUCCESS(status)) { 1745 dp_err("failed to send lro_hash_config to FW %u", status); 1746 return status; 1747 } 1748 1749 dp_info("LRO CMD config: lro_enable: 0x%x tcp_flag 0x%x tcp_flag_mask 0x%x", 1750 lro_hash.lro_enable, lro_hash.tcp_flag, 1751 lro_hash.tcp_flag_mask); 1752 1753 dp_info("toeplitz_hash_ipv4:"); 1754 qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, 1755 lro_hash.toeplitz_hash_ipv4, 1756 (sizeof(lro_hash.toeplitz_hash_ipv4[0]) * 1757 LRO_IPV4_SEED_ARR_SZ)); 1758 1759 dp_info("toeplitz_hash_ipv6:"); 1760 qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, 1761 lro_hash.toeplitz_hash_ipv6, 1762 (sizeof(lro_hash.toeplitz_hash_ipv6[0]) * 1763 LRO_IPV6_SEED_ARR_SZ)); 1764 1765 return status; 1766 } 1767 1768 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 1769 /** 1770 * dp_reap_timer_init() - initialize the reap timer 1771 * @soc: data path SoC handle 1772 * 1773 * Return: void 1774 */ 1775 static void dp_reap_timer_init(struct dp_soc *soc) 1776 { 1777 /* 1778 * Timer to reap rxdma status rings. 1779 * Needed until we enable ppdu end interrupts 1780 */ 1781 dp_monitor_reap_timer_init(soc); 1782 dp_monitor_vdev_timer_init(soc); 1783 } 1784 1785 /** 1786 * dp_reap_timer_deinit() - de-initialize the reap timer 1787 * @soc: data path SoC handle 1788 * 1789 * Return: void 1790 */ 1791 static void dp_reap_timer_deinit(struct dp_soc *soc) 1792 { 1793 dp_monitor_reap_timer_deinit(soc); 1794 } 1795 #else 1796 /* WIN use case */ 1797 static void dp_reap_timer_init(struct dp_soc *soc) 1798 { 1799 /* Configure LMAC rings in Polled mode */ 1800 if (soc->lmac_polled_mode) { 1801 /* 1802 * Timer to reap lmac rings. 1803 */ 1804 qdf_timer_init(soc->osdev, &soc->lmac_reap_timer, 1805 dp_service_lmac_rings, (void *)soc, 1806 QDF_TIMER_TYPE_WAKE_APPS); 1807 soc->lmac_timer_init = 1; 1808 qdf_timer_mod(&soc->lmac_reap_timer, DP_INTR_POLL_TIMER_MS); 1809 } 1810 } 1811 1812 static void dp_reap_timer_deinit(struct dp_soc *soc) 1813 { 1814 if (soc->lmac_timer_init) { 1815 qdf_timer_stop(&soc->lmac_reap_timer); 1816 qdf_timer_free(&soc->lmac_reap_timer); 1817 soc->lmac_timer_init = 0; 1818 } 1819 } 1820 #endif 1821 1822 #ifdef QCA_HOST2FW_RXBUF_RING 1823 /** 1824 * dp_rxdma_ring_alloc() - allocate the RXDMA rings 1825 * @soc: data path SoC handle 1826 * @pdev: Physical device handle 1827 * 1828 * Return: 0 - success, > 0 - failure 1829 */ 1830 static int dp_rxdma_ring_alloc(struct dp_soc *soc, struct dp_pdev *pdev) 1831 { 1832 struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx; 1833 int max_mac_rings; 1834 int i; 1835 int ring_size; 1836 1837 pdev_cfg_ctx = pdev->wlan_cfg_ctx; 1838 max_mac_rings = wlan_cfg_get_num_mac_rings(pdev_cfg_ctx); 1839 ring_size = wlan_cfg_get_rx_dma_buf_ring_size(pdev_cfg_ctx); 1840 1841 for (i = 0; i < max_mac_rings; i++) { 1842 dp_verbose_debug("pdev_id %d mac_id %d", pdev->pdev_id, i); 1843 if (dp_srng_alloc(soc, &pdev->rx_mac_buf_ring[i], 1844 RXDMA_BUF, ring_size, 0)) { 1845 dp_init_err("%pK: failed rx mac ring setup", soc); 1846 return QDF_STATUS_E_FAILURE; 1847 } 1848 } 1849 return QDF_STATUS_SUCCESS; 1850 } 1851 1852 /** 1853 * dp_rxdma_ring_setup() - configure the RXDMA rings 1854 * @soc: data path SoC handle 1855 * @pdev: Physical device handle 1856 * 1857 * Return: 0 - success, > 0 - failure 1858 */ 1859 static int dp_rxdma_ring_setup(struct dp_soc *soc, struct dp_pdev *pdev) 1860 { 1861 struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx; 1862 int max_mac_rings; 1863 int i; 1864 1865 pdev_cfg_ctx = pdev->wlan_cfg_ctx; 1866 max_mac_rings = wlan_cfg_get_num_mac_rings(pdev_cfg_ctx); 1867 1868 for (i = 0; i < max_mac_rings; i++) { 1869 dp_verbose_debug("pdev_id %d mac_id %d", pdev->pdev_id, i); 1870 if (dp_srng_init(soc, &pdev->rx_mac_buf_ring[i], 1871 RXDMA_BUF, 1, i)) { 1872 dp_init_err("%pK: failed rx mac ring setup", soc); 1873 return QDF_STATUS_E_FAILURE; 1874 } 1875 } 1876 return QDF_STATUS_SUCCESS; 1877 } 1878 1879 /** 1880 * dp_rxdma_ring_cleanup() - Deinit the RXDMA rings and reap timer 1881 * @soc: data path SoC handle 1882 * @pdev: Physical device handle 1883 * 1884 * Return: void 1885 */ 1886 static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev) 1887 { 1888 int i; 1889 1890 for (i = 0; i < MAX_RX_MAC_RINGS; i++) 1891 dp_srng_deinit(soc, &pdev->rx_mac_buf_ring[i], RXDMA_BUF, 1); 1892 1893 dp_reap_timer_deinit(soc); 1894 } 1895 1896 /** 1897 * dp_rxdma_ring_free() - Free the RXDMA rings 1898 * @pdev: Physical device handle 1899 * 1900 * Return: void 1901 */ 1902 static void dp_rxdma_ring_free(struct dp_pdev *pdev) 1903 { 1904 int i; 1905 1906 for (i = 0; i < MAX_RX_MAC_RINGS; i++) 1907 dp_srng_free(pdev->soc, &pdev->rx_mac_buf_ring[i]); 1908 } 1909 1910 #else 1911 static int dp_rxdma_ring_alloc(struct dp_soc *soc, struct dp_pdev *pdev) 1912 { 1913 return QDF_STATUS_SUCCESS; 1914 } 1915 1916 static int dp_rxdma_ring_setup(struct dp_soc *soc, struct dp_pdev *pdev) 1917 { 1918 return QDF_STATUS_SUCCESS; 1919 } 1920 1921 static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev) 1922 { 1923 dp_reap_timer_deinit(soc); 1924 } 1925 1926 static void dp_rxdma_ring_free(struct dp_pdev *pdev) 1927 { 1928 } 1929 #endif 1930 1931 #ifdef IPA_OFFLOAD 1932 /** 1933 * dp_setup_ipa_rx_refill_buf_ring - Setup second Rx refill buffer ring 1934 * @soc: data path instance 1935 * @pdev: core txrx pdev context 1936 * 1937 * Return: QDF_STATUS_SUCCESS: success 1938 * QDF_STATUS_E_RESOURCES: Error return 1939 */ 1940 static int dp_setup_ipa_rx_refill_buf_ring(struct dp_soc *soc, 1941 struct dp_pdev *pdev) 1942 { 1943 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1944 int entries; 1945 1946 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) { 1947 soc_cfg_ctx = soc->wlan_cfg_ctx; 1948 entries = 1949 wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); 1950 1951 /* Setup second Rx refill buffer ring */ 1952 if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 1953 entries, 0)) { 1954 dp_init_err("%pK: dp_srng_alloc failed second" 1955 "rx refill ring", soc); 1956 return QDF_STATUS_E_FAILURE; 1957 } 1958 } 1959 1960 return QDF_STATUS_SUCCESS; 1961 } 1962 1963 #ifdef IPA_WDI3_VLAN_SUPPORT 1964 static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 1965 struct dp_pdev *pdev) 1966 { 1967 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 1968 int entries; 1969 1970 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && 1971 wlan_ipa_is_vlan_enabled()) { 1972 soc_cfg_ctx = soc->wlan_cfg_ctx; 1973 entries = 1974 wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); 1975 1976 /* Setup second Rx refill buffer ring */ 1977 if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, 1978 entries, 0)) { 1979 dp_init_err("%pK: alloc failed for 3rd rx refill ring", 1980 soc); 1981 return QDF_STATUS_E_FAILURE; 1982 } 1983 } 1984 1985 return QDF_STATUS_SUCCESS; 1986 } 1987 1988 static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 1989 struct dp_pdev *pdev) 1990 { 1991 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && 1992 wlan_ipa_is_vlan_enabled()) { 1993 if (dp_srng_init(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, 1994 IPA_RX_ALT_REFILL_BUF_RING_IDX, 1995 pdev->pdev_id)) { 1996 dp_init_err("%pK: init failed for 3rd rx refill ring", 1997 soc); 1998 return QDF_STATUS_E_FAILURE; 1999 } 2000 } 2001 2002 return QDF_STATUS_SUCCESS; 2003 } 2004 2005 static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2006 struct dp_pdev *pdev) 2007 { 2008 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && 2009 wlan_ipa_is_vlan_enabled()) 2010 dp_srng_deinit(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, 0); 2011 } 2012 2013 static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2014 struct dp_pdev *pdev) 2015 { 2016 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && 2017 wlan_ipa_is_vlan_enabled()) 2018 dp_srng_free(soc, &pdev->rx_refill_buf_ring3); 2019 } 2020 #else 2021 static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2022 struct dp_pdev *pdev) 2023 { 2024 return QDF_STATUS_SUCCESS; 2025 } 2026 2027 static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2028 struct dp_pdev *pdev) 2029 { 2030 return QDF_STATUS_SUCCESS; 2031 } 2032 2033 static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2034 struct dp_pdev *pdev) 2035 { 2036 } 2037 2038 static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2039 struct dp_pdev *pdev) 2040 { 2041 } 2042 #endif 2043 2044 /** 2045 * dp_deinit_ipa_rx_refill_buf_ring - deinit second Rx refill buffer ring 2046 * @soc: data path instance 2047 * @pdev: core txrx pdev context 2048 * 2049 * Return: void 2050 */ 2051 static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2052 struct dp_pdev *pdev) 2053 { 2054 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) 2055 dp_srng_deinit(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 0); 2056 } 2057 2058 /** 2059 * dp_init_ipa_rx_refill_buf_ring - Init second Rx refill buffer ring 2060 * @soc: data path instance 2061 * @pdev: core txrx pdev context 2062 * 2063 * Return: QDF_STATUS_SUCCESS: success 2064 * QDF_STATUS_E_RESOURCES: Error return 2065 */ 2066 static int dp_init_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2067 struct dp_pdev *pdev) 2068 { 2069 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) { 2070 if (dp_srng_init(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 2071 IPA_RX_REFILL_BUF_RING_IDX, pdev->pdev_id)) { 2072 dp_init_err("%pK: dp_srng_init failed second" 2073 "rx refill ring", soc); 2074 return QDF_STATUS_E_FAILURE; 2075 } 2076 } 2077 2078 if (dp_init_ipa_rx_alt_refill_buf_ring(soc, pdev)) { 2079 dp_deinit_ipa_rx_refill_buf_ring(soc, pdev); 2080 return QDF_STATUS_E_FAILURE; 2081 } 2082 2083 return QDF_STATUS_SUCCESS; 2084 } 2085 2086 /** 2087 * dp_free_ipa_rx_refill_buf_ring - free second Rx refill buffer ring 2088 * @soc: data path instance 2089 * @pdev: core txrx pdev context 2090 * 2091 * Return: void 2092 */ 2093 static void dp_free_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2094 struct dp_pdev *pdev) 2095 { 2096 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) 2097 dp_srng_free(soc, &pdev->rx_refill_buf_ring2); 2098 } 2099 #else 2100 static int dp_setup_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2101 struct dp_pdev *pdev) 2102 { 2103 return QDF_STATUS_SUCCESS; 2104 } 2105 2106 static int dp_init_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2107 struct dp_pdev *pdev) 2108 { 2109 return QDF_STATUS_SUCCESS; 2110 } 2111 2112 static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2113 struct dp_pdev *pdev) 2114 { 2115 } 2116 2117 static void dp_free_ipa_rx_refill_buf_ring(struct dp_soc *soc, 2118 struct dp_pdev *pdev) 2119 { 2120 } 2121 2122 static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2123 struct dp_pdev *pdev) 2124 { 2125 return QDF_STATUS_SUCCESS; 2126 } 2127 2128 static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2129 struct dp_pdev *pdev) 2130 { 2131 } 2132 2133 static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, 2134 struct dp_pdev *pdev) 2135 { 2136 } 2137 #endif 2138 2139 #ifdef WLAN_FEATURE_DP_CFG_EVENT_HISTORY 2140 2141 /** 2142 * dp_soc_cfg_history_attach() - Allocate and attach datapath config events 2143 * history 2144 * @soc: DP soc handle 2145 * 2146 * Return: None 2147 */ 2148 static void dp_soc_cfg_history_attach(struct dp_soc *soc) 2149 { 2150 dp_soc_frag_history_attach(soc, &soc->cfg_event_history, 2151 DP_CFG_EVT_HIST_MAX_SLOTS, 2152 DP_CFG_EVT_HIST_PER_SLOT_MAX, 2153 sizeof(struct dp_cfg_event), 2154 true, DP_CFG_EVENT_HIST_TYPE); 2155 } 2156 2157 /** 2158 * dp_soc_cfg_history_detach() - Detach and free DP config events history 2159 * @soc: DP soc handle 2160 * 2161 * Return: none 2162 */ 2163 static void dp_soc_cfg_history_detach(struct dp_soc *soc) 2164 { 2165 dp_soc_frag_history_detach(soc, &soc->cfg_event_history, 2166 DP_CFG_EVT_HIST_MAX_SLOTS, 2167 true, DP_CFG_EVENT_HIST_TYPE); 2168 } 2169 2170 #else 2171 static void dp_soc_cfg_history_attach(struct dp_soc *soc) 2172 { 2173 } 2174 2175 static void dp_soc_cfg_history_detach(struct dp_soc *soc) 2176 { 2177 } 2178 #endif 2179 2180 #ifdef DP_TX_HW_DESC_HISTORY 2181 /** 2182 * dp_soc_tx_hw_desc_history_attach - Attach TX HW descriptor history 2183 * 2184 * @soc: DP soc handle 2185 * 2186 * Return: None 2187 */ 2188 static void dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc) 2189 { 2190 dp_soc_frag_history_attach(soc, &soc->tx_hw_desc_history, 2191 DP_TX_HW_DESC_HIST_MAX_SLOTS, 2192 DP_TX_HW_DESC_HIST_PER_SLOT_MAX, 2193 sizeof(struct dp_tx_hw_desc_evt), 2194 true, DP_TX_HW_DESC_HIST_TYPE); 2195 } 2196 2197 static void dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc) 2198 { 2199 dp_soc_frag_history_detach(soc, &soc->tx_hw_desc_history, 2200 DP_TX_HW_DESC_HIST_MAX_SLOTS, 2201 true, DP_TX_HW_DESC_HIST_TYPE); 2202 } 2203 2204 #else /* DP_TX_HW_DESC_HISTORY */ 2205 static inline void 2206 dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc) 2207 { 2208 } 2209 2210 static inline void 2211 dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc) 2212 { 2213 } 2214 #endif /* DP_TX_HW_DESC_HISTORY */ 2215 2216 #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY 2217 #ifndef RX_DEFRAG_DO_NOT_REINJECT 2218 /** 2219 * dp_soc_rx_reinject_ring_history_attach - Attach the reo reinject ring 2220 * history. 2221 * @soc: DP soc handle 2222 * 2223 * Return: None 2224 */ 2225 static void dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc) 2226 { 2227 soc->rx_reinject_ring_history = 2228 dp_context_alloc_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE, 2229 sizeof(struct dp_rx_reinject_history)); 2230 if (soc->rx_reinject_ring_history) 2231 qdf_atomic_init(&soc->rx_reinject_ring_history->index); 2232 } 2233 #else /* RX_DEFRAG_DO_NOT_REINJECT */ 2234 static inline void 2235 dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc) 2236 { 2237 } 2238 #endif /* RX_DEFRAG_DO_NOT_REINJECT */ 2239 2240 /** 2241 * dp_soc_rx_history_attach() - Attach the ring history record buffers 2242 * @soc: DP soc structure 2243 * 2244 * This function allocates the memory for recording the rx ring, rx error 2245 * ring and the reinject ring entries. There is no error returned in case 2246 * of allocation failure since the record function checks if the history is 2247 * initialized or not. We do not want to fail the driver load in case of 2248 * failure to allocate memory for debug history. 2249 * 2250 * Return: None 2251 */ 2252 static void dp_soc_rx_history_attach(struct dp_soc *soc) 2253 { 2254 int i; 2255 uint32_t rx_ring_hist_size; 2256 uint32_t rx_refill_ring_hist_size; 2257 2258 rx_ring_hist_size = sizeof(*soc->rx_ring_history[0]); 2259 rx_refill_ring_hist_size = sizeof(*soc->rx_refill_ring_history[0]); 2260 2261 for (i = 0; i < MAX_REO_DEST_RINGS; i++) { 2262 soc->rx_ring_history[i] = dp_context_alloc_mem( 2263 soc, DP_RX_RING_HIST_TYPE, rx_ring_hist_size); 2264 if (soc->rx_ring_history[i]) 2265 qdf_atomic_init(&soc->rx_ring_history[i]->index); 2266 } 2267 2268 soc->rx_err_ring_history = dp_context_alloc_mem( 2269 soc, DP_RX_ERR_RING_HIST_TYPE, rx_ring_hist_size); 2270 if (soc->rx_err_ring_history) 2271 qdf_atomic_init(&soc->rx_err_ring_history->index); 2272 2273 dp_soc_rx_reinject_ring_history_attach(soc); 2274 2275 for (i = 0; i < MAX_PDEV_CNT; i++) { 2276 soc->rx_refill_ring_history[i] = dp_context_alloc_mem( 2277 soc, 2278 DP_RX_REFILL_RING_HIST_TYPE, 2279 rx_refill_ring_hist_size); 2280 2281 if (soc->rx_refill_ring_history[i]) 2282 qdf_atomic_init(&soc->rx_refill_ring_history[i]->index); 2283 } 2284 } 2285 2286 static void dp_soc_rx_history_detach(struct dp_soc *soc) 2287 { 2288 int i; 2289 2290 for (i = 0; i < MAX_REO_DEST_RINGS; i++) 2291 dp_context_free_mem(soc, DP_RX_RING_HIST_TYPE, 2292 soc->rx_ring_history[i]); 2293 2294 dp_context_free_mem(soc, DP_RX_ERR_RING_HIST_TYPE, 2295 soc->rx_err_ring_history); 2296 2297 /* 2298 * No need for a featurized detach since qdf_mem_free takes 2299 * care of NULL pointer. 2300 */ 2301 dp_context_free_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE, 2302 soc->rx_reinject_ring_history); 2303 2304 for (i = 0; i < MAX_PDEV_CNT; i++) 2305 dp_context_free_mem(soc, DP_RX_REFILL_RING_HIST_TYPE, 2306 soc->rx_refill_ring_history[i]); 2307 } 2308 2309 #else 2310 static inline void dp_soc_rx_history_attach(struct dp_soc *soc) 2311 { 2312 } 2313 2314 static inline void dp_soc_rx_history_detach(struct dp_soc *soc) 2315 { 2316 } 2317 #endif 2318 2319 #ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY 2320 /** 2321 * dp_soc_mon_status_ring_history_attach() - Attach the monitor status 2322 * buffer record history. 2323 * @soc: DP soc handle 2324 * 2325 * This function allocates memory to track the event for a monitor 2326 * status buffer, before its parsed and freed. 2327 * 2328 * Return: None 2329 */ 2330 static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc) 2331 { 2332 soc->mon_status_ring_history = dp_context_alloc_mem(soc, 2333 DP_MON_STATUS_BUF_HIST_TYPE, 2334 sizeof(struct dp_mon_status_ring_history)); 2335 if (!soc->mon_status_ring_history) { 2336 dp_err("Failed to alloc memory for mon status ring history"); 2337 return; 2338 } 2339 } 2340 2341 /** 2342 * dp_soc_mon_status_ring_history_detach() - Detach the monitor status buffer 2343 * record history. 2344 * @soc: DP soc handle 2345 * 2346 * Return: None 2347 */ 2348 static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc) 2349 { 2350 dp_context_free_mem(soc, DP_MON_STATUS_BUF_HIST_TYPE, 2351 soc->mon_status_ring_history); 2352 } 2353 #else 2354 static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc) 2355 { 2356 } 2357 2358 static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc) 2359 { 2360 } 2361 #endif 2362 2363 #ifdef WLAN_FEATURE_DP_TX_DESC_HISTORY 2364 /** 2365 * dp_soc_tx_history_attach() - Attach the ring history record buffers 2366 * @soc: DP soc structure 2367 * 2368 * This function allocates the memory for recording the tx tcl ring and 2369 * the tx comp ring entries. There is no error returned in case 2370 * of allocation failure since the record function checks if the history is 2371 * initialized or not. We do not want to fail the driver load in case of 2372 * failure to allocate memory for debug history. 2373 * 2374 * Return: None 2375 */ 2376 static void dp_soc_tx_history_attach(struct dp_soc *soc) 2377 { 2378 dp_soc_frag_history_attach(soc, &soc->tx_tcl_history, 2379 DP_TX_TCL_HIST_MAX_SLOTS, 2380 DP_TX_TCL_HIST_PER_SLOT_MAX, 2381 sizeof(struct dp_tx_desc_event), 2382 true, DP_TX_TCL_HIST_TYPE); 2383 dp_soc_frag_history_attach(soc, &soc->tx_comp_history, 2384 DP_TX_COMP_HIST_MAX_SLOTS, 2385 DP_TX_COMP_HIST_PER_SLOT_MAX, 2386 sizeof(struct dp_tx_desc_event), 2387 true, DP_TX_COMP_HIST_TYPE); 2388 } 2389 2390 /** 2391 * dp_soc_tx_history_detach() - Detach the ring history record buffers 2392 * @soc: DP soc structure 2393 * 2394 * This function frees the memory for recording the tx tcl ring and 2395 * the tx comp ring entries. 2396 * 2397 * Return: None 2398 */ 2399 static void dp_soc_tx_history_detach(struct dp_soc *soc) 2400 { 2401 dp_soc_frag_history_detach(soc, &soc->tx_tcl_history, 2402 DP_TX_TCL_HIST_MAX_SLOTS, 2403 true, DP_TX_TCL_HIST_TYPE); 2404 dp_soc_frag_history_detach(soc, &soc->tx_comp_history, 2405 DP_TX_COMP_HIST_MAX_SLOTS, 2406 true, DP_TX_COMP_HIST_TYPE); 2407 } 2408 2409 #else 2410 static inline void dp_soc_tx_history_attach(struct dp_soc *soc) 2411 { 2412 } 2413 2414 static inline void dp_soc_tx_history_detach(struct dp_soc *soc) 2415 { 2416 } 2417 #endif /* WLAN_FEATURE_DP_TX_DESC_HISTORY */ 2418 2419 #ifdef WLAN_SUPPORT_RX_FLOW_TAG 2420 QDF_STATUS 2421 dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2422 { 2423 struct dp_rx_fst *rx_fst = NULL; 2424 QDF_STATUS ret = QDF_STATUS_SUCCESS; 2425 2426 /* for Lithium the below API is not registered 2427 * hence fst attach happens for each pdev 2428 */ 2429 if (!soc->arch_ops.dp_get_rx_fst) 2430 return dp_rx_fst_attach(soc, pdev); 2431 2432 rx_fst = soc->arch_ops.dp_get_rx_fst(); 2433 2434 /* for BE the FST attach is called only once per 2435 * ML context. if rx_fst is already registered 2436 * increase the ref count and return. 2437 */ 2438 if (rx_fst) { 2439 soc->rx_fst = rx_fst; 2440 pdev->rx_fst = rx_fst; 2441 soc->arch_ops.dp_rx_fst_ref(); 2442 } else { 2443 ret = dp_rx_fst_attach(soc, pdev); 2444 if ((ret != QDF_STATUS_SUCCESS) && 2445 (ret != QDF_STATUS_E_NOSUPPORT)) 2446 return ret; 2447 2448 soc->arch_ops.dp_set_rx_fst(soc->rx_fst); 2449 soc->arch_ops.dp_rx_fst_ref(); 2450 } 2451 return ret; 2452 } 2453 2454 void 2455 dp_rx_fst_detach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2456 { 2457 struct dp_rx_fst *rx_fst = NULL; 2458 2459 /* for Lithium the below API is not registered 2460 * hence fst detach happens for each pdev 2461 */ 2462 if (!soc->arch_ops.dp_get_rx_fst) { 2463 dp_rx_fst_detach(soc, pdev); 2464 return; 2465 } 2466 2467 rx_fst = soc->arch_ops.dp_get_rx_fst(); 2468 2469 /* for BE the FST detach is called only when last 2470 * ref count reaches 1. 2471 */ 2472 if (rx_fst) { 2473 if (soc->arch_ops.dp_rx_fst_deref() == 1) 2474 dp_rx_fst_detach(soc, pdev); 2475 } 2476 pdev->rx_fst = NULL; 2477 } 2478 #elif defined(WLAN_SUPPORT_RX_FISA) 2479 QDF_STATUS 2480 dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2481 { 2482 return dp_rx_fst_attach(soc, pdev); 2483 } 2484 2485 void 2486 dp_rx_fst_detach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2487 { 2488 dp_rx_fst_detach(soc, pdev); 2489 } 2490 #else 2491 QDF_STATUS 2492 dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2493 { 2494 return QDF_STATUS_SUCCESS; 2495 } 2496 2497 void 2498 dp_rx_fst_detach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) 2499 { 2500 } 2501 #endif 2502 2503 /** 2504 * dp_pdev_attach_wifi3() - attach txrx pdev 2505 * @txrx_soc: Datapath SOC handle 2506 * @params: Params for PDEV attach 2507 * 2508 * Return: QDF_STATUS 2509 */ 2510 static inline 2511 QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, 2512 struct cdp_pdev_attach_params *params) 2513 { 2514 qdf_size_t pdev_context_size; 2515 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 2516 struct dp_pdev *pdev = NULL; 2517 uint8_t pdev_id = params->pdev_id; 2518 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 2519 int nss_cfg; 2520 QDF_STATUS ret; 2521 2522 pdev_context_size = 2523 soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_PDEV); 2524 if (pdev_context_size) 2525 pdev = dp_context_alloc_mem(soc, DP_PDEV_TYPE, 2526 pdev_context_size); 2527 2528 if (!pdev) { 2529 dp_init_err("%pK: DP PDEV memory allocation failed", 2530 soc); 2531 goto fail0; 2532 } 2533 wlan_minidump_log(pdev, sizeof(*pdev), soc->ctrl_psoc, 2534 WLAN_MD_DP_PDEV, "dp_pdev"); 2535 2536 soc_cfg_ctx = soc->wlan_cfg_ctx; 2537 pdev->wlan_cfg_ctx = wlan_cfg_pdev_attach(soc->ctrl_psoc); 2538 2539 if (!pdev->wlan_cfg_ctx) { 2540 dp_init_err("%pK: pdev cfg_attach failed", soc); 2541 goto fail1; 2542 } 2543 2544 /* 2545 * set nss pdev config based on soc config 2546 */ 2547 nss_cfg = wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx); 2548 wlan_cfg_set_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx, 2549 (nss_cfg & (1 << pdev_id))); 2550 2551 pdev->soc = soc; 2552 pdev->pdev_id = pdev_id; 2553 soc->pdev_list[pdev_id] = pdev; 2554 2555 pdev->lmac_id = wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, pdev_id); 2556 soc->pdev_count++; 2557 2558 /* Allocate memory for pdev srng rings */ 2559 if (dp_pdev_srng_alloc(pdev)) { 2560 dp_init_err("%pK: dp_pdev_srng_alloc failed", soc); 2561 goto fail2; 2562 } 2563 2564 /* Setup second Rx refill buffer ring */ 2565 if (dp_setup_ipa_rx_refill_buf_ring(soc, pdev)) { 2566 dp_init_err("%pK: dp_srng_alloc failed rxrefill2 ring", 2567 soc); 2568 goto fail3; 2569 } 2570 2571 /* Allocate memory for pdev rxdma rings */ 2572 if (dp_rxdma_ring_alloc(soc, pdev)) { 2573 dp_init_err("%pK: dp_rxdma_ring_alloc failed", soc); 2574 goto fail4; 2575 } 2576 2577 /* Rx specific init */ 2578 if (dp_rx_pdev_desc_pool_alloc(pdev)) { 2579 dp_init_err("%pK: dp_rx_pdev_attach failed", soc); 2580 goto fail4; 2581 } 2582 2583 if (dp_monitor_pdev_attach(pdev)) { 2584 dp_init_err("%pK: dp_monitor_pdev_attach failed", soc); 2585 goto fail5; 2586 } 2587 2588 soc->arch_ops.txrx_pdev_attach(pdev, params); 2589 2590 /* Setup third Rx refill buffer ring */ 2591 if (dp_setup_ipa_rx_alt_refill_buf_ring(soc, pdev)) { 2592 dp_init_err("%pK: dp_srng_alloc failed rxrefill3 ring", 2593 soc); 2594 goto fail6; 2595 } 2596 2597 ret = dp_rx_fst_attach_wrapper(soc, pdev); 2598 if ((ret != QDF_STATUS_SUCCESS) && (ret != QDF_STATUS_E_NOSUPPORT)) { 2599 dp_init_err("%pK: RX FST attach failed: pdev %d err %d", 2600 soc, pdev_id, ret); 2601 goto fail7; 2602 } 2603 2604 return QDF_STATUS_SUCCESS; 2605 2606 fail7: 2607 dp_free_ipa_rx_alt_refill_buf_ring(soc, pdev); 2608 fail6: 2609 dp_monitor_pdev_detach(pdev); 2610 fail5: 2611 dp_rx_pdev_desc_pool_free(pdev); 2612 fail4: 2613 dp_rxdma_ring_free(pdev); 2614 dp_free_ipa_rx_refill_buf_ring(soc, pdev); 2615 fail3: 2616 dp_pdev_srng_free(pdev); 2617 fail2: 2618 wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx); 2619 fail1: 2620 soc->pdev_list[pdev_id] = NULL; 2621 qdf_mem_free(pdev); 2622 fail0: 2623 return QDF_STATUS_E_FAILURE; 2624 } 2625 2626 /** 2627 * dp_pdev_flush_pending_vdevs() - Flush all delete pending vdevs in pdev 2628 * @pdev: Datapath PDEV handle 2629 * 2630 * This is the last chance to flush all pending dp vdevs/peers, 2631 * some peer/vdev leak case like Non-SSR + peer unmap missing 2632 * will be covered here. 2633 * 2634 * Return: None 2635 */ 2636 static void dp_pdev_flush_pending_vdevs(struct dp_pdev *pdev) 2637 { 2638 struct dp_soc *soc = pdev->soc; 2639 struct dp_vdev *vdev_arr[MAX_VDEV_CNT] = {0}; 2640 uint32_t i = 0; 2641 uint32_t num_vdevs = 0; 2642 struct dp_vdev *vdev = NULL; 2643 2644 if (TAILQ_EMPTY(&soc->inactive_vdev_list)) 2645 return; 2646 2647 qdf_spin_lock_bh(&soc->inactive_vdev_list_lock); 2648 TAILQ_FOREACH(vdev, &soc->inactive_vdev_list, 2649 inactive_list_elem) { 2650 if (vdev->pdev != pdev) 2651 continue; 2652 2653 vdev_arr[num_vdevs] = vdev; 2654 num_vdevs++; 2655 /* take reference to free */ 2656 dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CDP); 2657 } 2658 qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock); 2659 2660 for (i = 0; i < num_vdevs; i++) { 2661 dp_vdev_flush_peers((struct cdp_vdev *)vdev_arr[i], 0, 0); 2662 dp_vdev_unref_delete(soc, vdev_arr[i], DP_MOD_ID_CDP); 2663 } 2664 } 2665 2666 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 2667 /** 2668 * dp_vdev_stats_hw_offload_target_config() - Send HTT command to FW 2669 * for enable/disable of HW vdev stats 2670 * @soc: Datapath soc handle 2671 * @pdev_id: INVALID_PDEV_ID for all pdevs or 0,1,2 for individual pdev 2672 * @enable: flag to represent enable/disable of hw vdev stats 2673 * 2674 * Return: none 2675 */ 2676 static void dp_vdev_stats_hw_offload_target_config(struct dp_soc *soc, 2677 uint8_t pdev_id, 2678 bool enable) 2679 { 2680 /* Check SOC level config for HW offload vdev stats support */ 2681 if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) { 2682 dp_debug("%pK: HW vdev offload stats is disabled", soc); 2683 return; 2684 } 2685 2686 /* Send HTT command to FW for enable of stats */ 2687 dp_h2t_hw_vdev_stats_config_send(soc, pdev_id, enable, false, 0); 2688 } 2689 2690 /** 2691 * dp_vdev_stats_hw_offload_target_clear() - Clear HW vdev stats on target 2692 * @soc: Datapath soc handle 2693 * @pdev_id: pdev_id (0,1,2) 2694 * @vdev_id_bitmask: bitmask with vdev_id(s) for which stats are to be 2695 * cleared on HW 2696 * 2697 * Return: none 2698 */ 2699 static 2700 void dp_vdev_stats_hw_offload_target_clear(struct dp_soc *soc, uint8_t pdev_id, 2701 uint64_t vdev_id_bitmask) 2702 { 2703 /* Check SOC level config for HW offload vdev stats support */ 2704 if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) { 2705 dp_debug("%pK: HW vdev offload stats is disabled", soc); 2706 return; 2707 } 2708 2709 /* Send HTT command to FW for reset of stats */ 2710 dp_h2t_hw_vdev_stats_config_send(soc, pdev_id, true, true, 2711 vdev_id_bitmask); 2712 } 2713 #else 2714 static void 2715 dp_vdev_stats_hw_offload_target_config(struct dp_soc *soc, uint8_t pdev_id, 2716 bool enable) 2717 { 2718 } 2719 2720 static 2721 void dp_vdev_stats_hw_offload_target_clear(struct dp_soc *soc, uint8_t pdev_id, 2722 uint64_t vdev_id_bitmask) 2723 { 2724 } 2725 #endif /*QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT */ 2726 2727 /** 2728 * dp_pdev_deinit() - Deinit txrx pdev 2729 * @txrx_pdev: Datapath PDEV handle 2730 * @force: Force deinit 2731 * 2732 * Return: None 2733 */ 2734 static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) 2735 { 2736 struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; 2737 qdf_nbuf_t curr_nbuf, next_nbuf; 2738 2739 if (pdev->pdev_deinit) 2740 return; 2741 2742 dp_tx_me_exit(pdev); 2743 dp_rx_pdev_buffers_free(pdev); 2744 dp_rx_pdev_desc_pool_deinit(pdev); 2745 dp_pdev_bkp_stats_detach(pdev); 2746 qdf_event_destroy(&pdev->fw_peer_stats_event); 2747 qdf_event_destroy(&pdev->fw_stats_event); 2748 qdf_event_destroy(&pdev->fw_obss_stats_event); 2749 if (pdev->sojourn_buf) 2750 qdf_nbuf_free(pdev->sojourn_buf); 2751 2752 dp_pdev_flush_pending_vdevs(pdev); 2753 dp_tx_desc_flush(pdev, NULL, true); 2754 2755 qdf_spinlock_destroy(&pdev->tx_mutex); 2756 qdf_spinlock_destroy(&pdev->vdev_list_lock); 2757 2758 dp_monitor_pdev_deinit(pdev); 2759 2760 dp_pdev_srng_deinit(pdev); 2761 2762 dp_ipa_uc_detach(pdev->soc, pdev); 2763 dp_deinit_ipa_rx_alt_refill_buf_ring(pdev->soc, pdev); 2764 dp_deinit_ipa_rx_refill_buf_ring(pdev->soc, pdev); 2765 dp_rxdma_ring_cleanup(pdev->soc, pdev); 2766 2767 curr_nbuf = pdev->invalid_peer_head_msdu; 2768 while (curr_nbuf) { 2769 next_nbuf = qdf_nbuf_next(curr_nbuf); 2770 dp_rx_nbuf_free(curr_nbuf); 2771 curr_nbuf = next_nbuf; 2772 } 2773 pdev->invalid_peer_head_msdu = NULL; 2774 pdev->invalid_peer_tail_msdu = NULL; 2775 2776 dp_wdi_event_detach(pdev); 2777 pdev->pdev_deinit = 1; 2778 } 2779 2780 /** 2781 * dp_pdev_deinit_wifi3() - Deinit txrx pdev 2782 * @psoc: Datapath psoc handle 2783 * @pdev_id: Id of datapath PDEV handle 2784 * @force: Force deinit 2785 * 2786 * Return: QDF_STATUS 2787 */ 2788 static QDF_STATUS 2789 dp_pdev_deinit_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, 2790 int force) 2791 { 2792 struct dp_pdev *txrx_pdev; 2793 2794 txrx_pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc, 2795 pdev_id); 2796 2797 if (!txrx_pdev) 2798 return QDF_STATUS_E_FAILURE; 2799 2800 dp_pdev_deinit((struct cdp_pdev *)txrx_pdev, force); 2801 2802 return QDF_STATUS_SUCCESS; 2803 } 2804 2805 /** 2806 * dp_pdev_post_attach() - Do post pdev attach after dev_alloc_name 2807 * @txrx_pdev: Datapath PDEV handle 2808 * 2809 * Return: None 2810 */ 2811 static void dp_pdev_post_attach(struct cdp_pdev *txrx_pdev) 2812 { 2813 struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; 2814 2815 dp_monitor_tx_capture_debugfs_init(pdev); 2816 2817 if (dp_pdev_htt_stats_dbgfs_init(pdev)) { 2818 dp_init_err("%pK: Failed to initialize pdev HTT stats debugfs", pdev->soc); 2819 } 2820 } 2821 2822 /** 2823 * dp_pdev_post_attach_wifi3() - attach txrx pdev post 2824 * @soc: Datapath soc handle 2825 * @pdev_id: pdev id of pdev 2826 * 2827 * Return: QDF_STATUS 2828 */ 2829 static int dp_pdev_post_attach_wifi3(struct cdp_soc_t *soc, 2830 uint8_t pdev_id) 2831 { 2832 struct dp_pdev *pdev; 2833 2834 pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 2835 pdev_id); 2836 2837 if (!pdev) { 2838 dp_init_err("%pK: DP PDEV is Null for pdev id %d", 2839 (struct dp_soc *)soc, pdev_id); 2840 return QDF_STATUS_E_FAILURE; 2841 } 2842 2843 dp_pdev_post_attach((struct cdp_pdev *)pdev); 2844 return QDF_STATUS_SUCCESS; 2845 } 2846 2847 /** 2848 * dp_pdev_detach() - Complete rest of pdev detach 2849 * @txrx_pdev: Datapath PDEV handle 2850 * @force: Force deinit 2851 * 2852 * Return: None 2853 */ 2854 static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) 2855 { 2856 struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; 2857 struct dp_soc *soc = pdev->soc; 2858 2859 dp_rx_fst_detach_wrapper(soc, pdev); 2860 dp_pdev_htt_stats_dbgfs_deinit(pdev); 2861 dp_rx_pdev_desc_pool_free(pdev); 2862 dp_monitor_pdev_detach(pdev); 2863 dp_rxdma_ring_free(pdev); 2864 dp_free_ipa_rx_refill_buf_ring(soc, pdev); 2865 dp_free_ipa_rx_alt_refill_buf_ring(soc, pdev); 2866 dp_pdev_srng_free(pdev); 2867 2868 soc->pdev_count--; 2869 soc->pdev_list[pdev->pdev_id] = NULL; 2870 2871 wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx); 2872 wlan_minidump_remove(pdev, sizeof(*pdev), soc->ctrl_psoc, 2873 WLAN_MD_DP_PDEV, "dp_pdev"); 2874 dp_context_free_mem(soc, DP_PDEV_TYPE, pdev); 2875 } 2876 2877 /** 2878 * dp_pdev_detach_wifi3() - detach txrx pdev 2879 * @psoc: Datapath soc handle 2880 * @pdev_id: pdev id of pdev 2881 * @force: Force detach 2882 * 2883 * Return: QDF_STATUS 2884 */ 2885 static QDF_STATUS dp_pdev_detach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, 2886 int force) 2887 { 2888 struct dp_pdev *pdev; 2889 struct dp_soc *soc = (struct dp_soc *)psoc; 2890 2891 pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc, 2892 pdev_id); 2893 2894 if (!pdev) { 2895 dp_init_err("%pK: DP PDEV is Null for pdev id %d", 2896 (struct dp_soc *)psoc, pdev_id); 2897 return QDF_STATUS_E_FAILURE; 2898 } 2899 2900 soc->arch_ops.txrx_pdev_detach(pdev); 2901 2902 dp_pdev_detach((struct cdp_pdev *)pdev, force); 2903 return QDF_STATUS_SUCCESS; 2904 } 2905 2906 void dp_soc_print_inactive_objects(struct dp_soc *soc) 2907 { 2908 struct dp_peer *peer = NULL; 2909 struct dp_peer *tmp_peer = NULL; 2910 struct dp_vdev *vdev = NULL; 2911 struct dp_vdev *tmp_vdev = NULL; 2912 int i = 0; 2913 uint32_t count; 2914 2915 if (TAILQ_EMPTY(&soc->inactive_peer_list) && 2916 TAILQ_EMPTY(&soc->inactive_vdev_list)) 2917 return; 2918 2919 TAILQ_FOREACH_SAFE(peer, &soc->inactive_peer_list, 2920 inactive_list_elem, tmp_peer) { 2921 for (i = 0; i < DP_MOD_ID_MAX; i++) { 2922 count = qdf_atomic_read(&peer->mod_refs[i]); 2923 if (count) 2924 DP_PRINT_STATS("peer %pK Module id %u ==> %u", 2925 peer, i, count); 2926 } 2927 } 2928 2929 TAILQ_FOREACH_SAFE(vdev, &soc->inactive_vdev_list, 2930 inactive_list_elem, tmp_vdev) { 2931 for (i = 0; i < DP_MOD_ID_MAX; i++) { 2932 count = qdf_atomic_read(&vdev->mod_refs[i]); 2933 if (count) 2934 DP_PRINT_STATS("vdev %pK Module id %u ==> %u", 2935 vdev, i, count); 2936 } 2937 } 2938 QDF_BUG(0); 2939 } 2940 2941 /** 2942 * dp_soc_deinit_wifi3() - Deinitialize txrx SOC 2943 * @txrx_soc: Opaque DP SOC handle 2944 * 2945 * Return: None 2946 */ 2947 static void dp_soc_deinit_wifi3(struct cdp_soc_t *txrx_soc) 2948 { 2949 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 2950 2951 soc->arch_ops.txrx_soc_deinit(soc); 2952 } 2953 2954 /** 2955 * dp_soc_detach() - Detach rest of txrx SOC 2956 * @txrx_soc: DP SOC handle, struct cdp_soc_t is first element of struct dp_soc. 2957 * 2958 * Return: None 2959 */ 2960 static void dp_soc_detach(struct cdp_soc_t *txrx_soc) 2961 { 2962 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 2963 2964 soc->arch_ops.txrx_soc_detach(soc); 2965 2966 dp_runtime_deinit(); 2967 2968 dp_sysfs_deinitialize_stats(soc); 2969 dp_soc_swlm_detach(soc); 2970 dp_soc_tx_desc_sw_pools_free(soc); 2971 dp_soc_srng_free(soc); 2972 dp_hw_link_desc_ring_free(soc); 2973 dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID); 2974 wlan_cfg_soc_detach(soc->wlan_cfg_ctx); 2975 dp_soc_tx_hw_desc_history_detach(soc); 2976 dp_soc_tx_history_detach(soc); 2977 dp_soc_mon_status_ring_history_detach(soc); 2978 dp_soc_rx_history_detach(soc); 2979 dp_soc_cfg_history_detach(soc); 2980 2981 if (!dp_monitor_modularized_enable()) { 2982 dp_mon_soc_detach_wrapper(soc); 2983 } 2984 2985 qdf_mem_free(soc->cdp_soc.ops); 2986 qdf_mem_common_free(soc); 2987 } 2988 2989 /** 2990 * dp_soc_detach_wifi3() - Detach txrx SOC 2991 * @txrx_soc: DP SOC handle, struct cdp_soc_t is first element of struct dp_soc. 2992 * 2993 * Return: None 2994 */ 2995 static void dp_soc_detach_wifi3(struct cdp_soc_t *txrx_soc) 2996 { 2997 dp_soc_detach(txrx_soc); 2998 } 2999 3000 #ifdef QCA_HOST2FW_RXBUF_RING 3001 #ifdef IPA_WDI3_VLAN_SUPPORT 3002 static inline 3003 void dp_rxdma_setup_refill_ring3(struct dp_soc *soc, 3004 struct dp_pdev *pdev, 3005 uint8_t idx) 3006 { 3007 if (pdev->rx_refill_buf_ring3.hal_srng) 3008 htt_srng_setup(soc->htt_handle, idx, 3009 pdev->rx_refill_buf_ring3.hal_srng, 3010 RXDMA_BUF); 3011 } 3012 #else 3013 static inline 3014 void dp_rxdma_setup_refill_ring3(struct dp_soc *soc, 3015 struct dp_pdev *pdev, 3016 uint8_t idx) 3017 { } 3018 #endif 3019 3020 /** 3021 * dp_rxdma_ring_config() - configure the RX DMA rings 3022 * @soc: data path SoC handle 3023 * 3024 * This function is used to configure the MAC rings. 3025 * On MCL host provides buffers in Host2FW ring 3026 * FW refills (copies) buffers to the ring and updates 3027 * ring_idx in register 3028 * 3029 * Return: zero on success, non-zero on failure 3030 */ 3031 static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) 3032 { 3033 int i; 3034 QDF_STATUS status = QDF_STATUS_SUCCESS; 3035 3036 for (i = 0; i < MAX_PDEV_CNT; i++) { 3037 struct dp_pdev *pdev = soc->pdev_list[i]; 3038 3039 if (pdev) { 3040 int mac_id; 3041 int max_mac_rings = 3042 wlan_cfg_get_num_mac_rings 3043 (pdev->wlan_cfg_ctx); 3044 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i); 3045 3046 htt_srng_setup(soc->htt_handle, i, 3047 soc->rx_refill_buf_ring[lmac_id] 3048 .hal_srng, 3049 RXDMA_BUF); 3050 3051 if (pdev->rx_refill_buf_ring2.hal_srng) 3052 htt_srng_setup(soc->htt_handle, i, 3053 pdev->rx_refill_buf_ring2 3054 .hal_srng, 3055 RXDMA_BUF); 3056 3057 dp_rxdma_setup_refill_ring3(soc, pdev, i); 3058 3059 dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings); 3060 dp_err("pdev_id %d max_mac_rings %d", 3061 pdev->pdev_id, max_mac_rings); 3062 3063 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 3064 int mac_for_pdev = 3065 dp_get_mac_id_for_pdev(mac_id, 3066 pdev->pdev_id); 3067 /* 3068 * Obtain lmac id from pdev to access the LMAC 3069 * ring in soc context 3070 */ 3071 lmac_id = 3072 dp_get_lmac_id_for_pdev_id(soc, 3073 mac_id, 3074 pdev->pdev_id); 3075 QDF_TRACE(QDF_MODULE_ID_TXRX, 3076 QDF_TRACE_LEVEL_ERROR, 3077 FL("mac_id %d"), mac_for_pdev); 3078 3079 htt_srng_setup(soc->htt_handle, mac_for_pdev, 3080 pdev->rx_mac_buf_ring[mac_id] 3081 .hal_srng, 3082 RXDMA_BUF); 3083 3084 if (!soc->rxdma2sw_rings_not_supported) 3085 dp_htt_setup_rxdma_err_dst_ring(soc, 3086 mac_for_pdev, lmac_id); 3087 3088 /* Configure monitor mode rings */ 3089 status = dp_monitor_htt_srng_setup(soc, pdev, 3090 lmac_id, 3091 mac_for_pdev); 3092 if (status != QDF_STATUS_SUCCESS) { 3093 dp_err("Failed to send htt monitor messages to target"); 3094 return status; 3095 } 3096 3097 } 3098 } 3099 } 3100 3101 dp_reap_timer_init(soc); 3102 return status; 3103 } 3104 #else 3105 /* This is only for WIN */ 3106 static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) 3107 { 3108 int i; 3109 QDF_STATUS status = QDF_STATUS_SUCCESS; 3110 int mac_for_pdev; 3111 int lmac_id; 3112 3113 /* Configure monitor mode rings */ 3114 dp_monitor_soc_htt_srng_setup(soc); 3115 3116 for (i = 0; i < MAX_PDEV_CNT; i++) { 3117 struct dp_pdev *pdev = soc->pdev_list[i]; 3118 3119 if (!pdev) 3120 continue; 3121 3122 mac_for_pdev = i; 3123 lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i); 3124 3125 if (soc->rx_refill_buf_ring[lmac_id].hal_srng) 3126 htt_srng_setup(soc->htt_handle, mac_for_pdev, 3127 soc->rx_refill_buf_ring[lmac_id]. 3128 hal_srng, RXDMA_BUF); 3129 3130 /* Configure monitor mode rings */ 3131 dp_monitor_htt_srng_setup(soc, pdev, 3132 lmac_id, 3133 mac_for_pdev); 3134 if (!soc->rxdma2sw_rings_not_supported) 3135 htt_srng_setup(soc->htt_handle, mac_for_pdev, 3136 soc->rxdma_err_dst_ring[lmac_id].hal_srng, 3137 RXDMA_DST); 3138 } 3139 3140 dp_reap_timer_init(soc); 3141 return status; 3142 } 3143 #endif 3144 3145 /** 3146 * dp_rx_target_fst_config() - configure the RXOLE Flow Search Engine 3147 * 3148 * This function is used to configure the FSE HW block in RX OLE on a 3149 * per pdev basis. Here, we will be programming parameters related to 3150 * the Flow Search Table. 3151 * 3152 * @soc: data path SoC handle 3153 * 3154 * Return: zero on success, non-zero on failure 3155 */ 3156 #ifdef WLAN_SUPPORT_RX_FLOW_TAG 3157 static QDF_STATUS 3158 dp_rx_target_fst_config(struct dp_soc *soc) 3159 { 3160 int i; 3161 QDF_STATUS status = QDF_STATUS_SUCCESS; 3162 3163 for (i = 0; i < MAX_PDEV_CNT; i++) { 3164 struct dp_pdev *pdev = soc->pdev_list[i]; 3165 3166 /* Flow search is not enabled if NSS offload is enabled */ 3167 if (pdev && 3168 !wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { 3169 status = dp_rx_flow_send_fst_fw_setup(pdev->soc, pdev); 3170 if (status != QDF_STATUS_SUCCESS) 3171 break; 3172 } 3173 } 3174 return status; 3175 } 3176 #elif defined(WLAN_SUPPORT_RX_FISA) 3177 /** 3178 * dp_rx_target_fst_config() - Configure RX OLE FSE engine in HW 3179 * @soc: SoC handle 3180 * 3181 * Return: Success 3182 */ 3183 static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) 3184 { 3185 QDF_STATUS status; 3186 struct dp_rx_fst *fst = soc->rx_fst; 3187 3188 /* Check if it is enabled in the INI */ 3189 if (!soc->fisa_enable) { 3190 dp_err("RX FISA feature is disabled"); 3191 return QDF_STATUS_E_NOSUPPORT; 3192 } 3193 3194 status = dp_rx_flow_send_fst_fw_setup(soc, soc->pdev_list[0]); 3195 if (QDF_IS_STATUS_ERROR(status)) { 3196 dp_err("dp_rx_flow_send_fst_fw_setup failed %d", 3197 status); 3198 return status; 3199 } 3200 3201 if (soc->fst_cmem_base) { 3202 soc->fst_in_cmem = true; 3203 dp_rx_fst_update_cmem_params(soc, fst->max_entries, 3204 soc->fst_cmem_base & 0xffffffff, 3205 soc->fst_cmem_base >> 32); 3206 } 3207 return status; 3208 } 3209 3210 #define FISA_MAX_TIMEOUT 0xffffffff 3211 #define FISA_DISABLE_TIMEOUT 0 3212 static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) 3213 { 3214 struct dp_htt_rx_fisa_cfg fisa_config; 3215 3216 fisa_config.pdev_id = 0; 3217 fisa_config.fisa_timeout = FISA_MAX_TIMEOUT; 3218 3219 return dp_htt_rx_fisa_config(soc->pdev_list[0], &fisa_config); 3220 } 3221 3222 #else /* !WLAN_SUPPORT_RX_FISA */ 3223 static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) 3224 { 3225 return QDF_STATUS_SUCCESS; 3226 } 3227 #endif /* !WLAN_SUPPORT_RX_FISA */ 3228 3229 #ifndef WLAN_SUPPORT_RX_FISA 3230 static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) 3231 { 3232 return QDF_STATUS_SUCCESS; 3233 } 3234 3235 static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) 3236 { 3237 return QDF_STATUS_SUCCESS; 3238 } 3239 3240 static void dp_rx_dump_fisa_table(struct dp_soc *soc) 3241 { 3242 } 3243 3244 static void dp_suspend_fse_cache_flush(struct dp_soc *soc) 3245 { 3246 } 3247 3248 static void dp_resume_fse_cache_flush(struct dp_soc *soc) 3249 { 3250 } 3251 #endif /* !WLAN_SUPPORT_RX_FISA */ 3252 3253 #ifndef WLAN_DP_FEATURE_SW_LATENCY_MGR 3254 static inline QDF_STATUS dp_print_swlm_stats(struct dp_soc *soc) 3255 { 3256 return QDF_STATUS_SUCCESS; 3257 } 3258 #endif /* !WLAN_DP_FEATURE_SW_LATENCY_MGR */ 3259 3260 #ifdef WLAN_SUPPORT_PPEDS 3261 /** 3262 * dp_soc_target_ppe_rxole_rxdma_cfg() - Configure the RxOLe and RxDMA for PPE 3263 * @soc: DP Tx/Rx handle 3264 * 3265 * Return: QDF_STATUS 3266 */ 3267 static 3268 QDF_STATUS dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc *soc) 3269 { 3270 struct dp_htt_rxdma_rxole_ppe_config htt_cfg = {0}; 3271 QDF_STATUS status; 3272 3273 /* 3274 * Program RxDMA to override the reo destination indication 3275 * with REO2PPE_DST_IND, when use_ppe is set to 1 in RX_MSDU_END, 3276 * thereby driving the packet to REO2PPE ring. 3277 * If the MSDU is spanning more than 1 buffer, then this 3278 * override is not done. 3279 */ 3280 htt_cfg.override = 1; 3281 htt_cfg.reo_destination_indication = REO2PPE_DST_IND; 3282 htt_cfg.multi_buffer_msdu_override_en = 0; 3283 3284 /* 3285 * Override use_ppe to 0 in RxOLE for the following 3286 * cases. 3287 */ 3288 htt_cfg.intra_bss_override = 1; 3289 htt_cfg.decap_raw_override = 1; 3290 htt_cfg.decap_nwifi_override = 1; 3291 htt_cfg.ip_frag_override = 1; 3292 3293 status = dp_htt_rxdma_rxole_ppe_cfg_set(soc, &htt_cfg); 3294 if (status != QDF_STATUS_SUCCESS) 3295 dp_err("RxOLE and RxDMA PPE config failed %d", status); 3296 3297 return status; 3298 } 3299 3300 #else 3301 static inline 3302 QDF_STATUS dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc *soc) 3303 { 3304 return QDF_STATUS_SUCCESS; 3305 } 3306 3307 #endif /* WLAN_SUPPORT_PPEDS */ 3308 3309 #ifdef DP_UMAC_HW_RESET_SUPPORT 3310 static void dp_register_umac_reset_handlers(struct dp_soc *soc) 3311 { 3312 dp_umac_reset_register_rx_action_callback(soc, 3313 dp_umac_reset_action_trigger_recovery, 3314 UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY); 3315 3316 dp_umac_reset_register_rx_action_callback(soc, 3317 dp_umac_reset_handle_pre_reset, UMAC_RESET_ACTION_DO_PRE_RESET); 3318 3319 dp_umac_reset_register_rx_action_callback(soc, 3320 dp_umac_reset_handle_post_reset, 3321 UMAC_RESET_ACTION_DO_POST_RESET_START); 3322 3323 dp_umac_reset_register_rx_action_callback(soc, 3324 dp_umac_reset_handle_post_reset_complete, 3325 UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE); 3326 3327 } 3328 #else 3329 static void dp_register_umac_reset_handlers(struct dp_soc *soc) 3330 { 3331 } 3332 #endif 3333 /** 3334 * dp_soc_attach_target_wifi3() - SOC initialization in the target 3335 * @cdp_soc: Opaque Datapath SOC handle 3336 * 3337 * Return: zero on success, non-zero on failure 3338 */ 3339 static QDF_STATUS 3340 dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) 3341 { 3342 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 3343 QDF_STATUS status = QDF_STATUS_SUCCESS; 3344 struct hal_reo_params reo_params; 3345 3346 htt_soc_attach_target(soc->htt_handle); 3347 3348 status = dp_soc_target_ppe_rxole_rxdma_cfg(soc); 3349 if (status != QDF_STATUS_SUCCESS) { 3350 dp_err("Failed to send htt RxOLE and RxDMA messages to target"); 3351 return status; 3352 } 3353 3354 status = dp_rxdma_ring_config(soc); 3355 if (status != QDF_STATUS_SUCCESS) { 3356 dp_err("Failed to send htt srng setup messages to target"); 3357 return status; 3358 } 3359 3360 status = soc->arch_ops.dp_rxdma_ring_sel_cfg(soc); 3361 if (status != QDF_STATUS_SUCCESS) { 3362 dp_err("Failed to send htt ring config message to target"); 3363 return status; 3364 } 3365 3366 status = dp_soc_umac_reset_init(cdp_soc); 3367 if (status != QDF_STATUS_SUCCESS && 3368 status != QDF_STATUS_E_NOSUPPORT) { 3369 dp_err("Failed to initialize UMAC reset"); 3370 return status; 3371 } 3372 3373 dp_register_umac_reset_handlers(soc); 3374 3375 status = dp_rx_target_fst_config(soc); 3376 if (status != QDF_STATUS_SUCCESS && 3377 status != QDF_STATUS_E_NOSUPPORT) { 3378 dp_err("Failed to send htt fst setup config message to target"); 3379 return status; 3380 } 3381 3382 if (status == QDF_STATUS_SUCCESS) { 3383 status = dp_rx_fisa_config(soc); 3384 if (status != QDF_STATUS_SUCCESS) { 3385 dp_err("Failed to send htt FISA config message to target"); 3386 return status; 3387 } 3388 } 3389 3390 DP_STATS_INIT(soc); 3391 3392 dp_runtime_init(soc); 3393 3394 /* Enable HW vdev offload stats if feature is supported */ 3395 dp_vdev_stats_hw_offload_target_config(soc, INVALID_PDEV_ID, true); 3396 3397 /* initialize work queue for stats processing */ 3398 qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); 3399 3400 wlan_cfg_soc_update_tgt_params(soc->wlan_cfg_ctx, 3401 soc->ctrl_psoc); 3402 /* Setup HW REO */ 3403 qdf_mem_zero(&reo_params, sizeof(reo_params)); 3404 3405 if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { 3406 /* 3407 * Reo ring remap is not required if both radios 3408 * are offloaded to NSS 3409 */ 3410 3411 if (soc->arch_ops.reo_remap_config(soc, &reo_params.remap0, 3412 &reo_params.remap1, 3413 &reo_params.remap2)) 3414 reo_params.rx_hash_enabled = true; 3415 else 3416 reo_params.rx_hash_enabled = false; 3417 } 3418 3419 /* 3420 * set the fragment destination ring 3421 */ 3422 dp_reo_frag_dst_set(soc, &reo_params.frag_dst_ring); 3423 3424 if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) 3425 reo_params.alt_dst_ind_0 = REO_REMAP_RELEASE; 3426 3427 reo_params.reo_qref = &soc->reo_qref; 3428 hal_reo_setup(soc->hal_soc, &reo_params, 1); 3429 3430 hal_reo_set_err_dst_remap(soc->hal_soc); 3431 3432 soc->features.pn_in_reo_dest = hal_reo_enable_pn_in_dest(soc->hal_soc); 3433 3434 return QDF_STATUS_SUCCESS; 3435 } 3436 3437 /** 3438 * dp_vdev_id_map_tbl_add() - Add vdev into vdev_id table 3439 * @soc: SoC handle 3440 * @vdev: vdev handle 3441 * @vdev_id: vdev_id 3442 * 3443 * Return: None 3444 */ 3445 static void dp_vdev_id_map_tbl_add(struct dp_soc *soc, 3446 struct dp_vdev *vdev, 3447 uint8_t vdev_id) 3448 { 3449 QDF_ASSERT(vdev_id <= MAX_VDEV_CNT); 3450 3451 qdf_spin_lock_bh(&soc->vdev_map_lock); 3452 3453 if (dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CONFIG) != 3454 QDF_STATUS_SUCCESS) { 3455 dp_vdev_info("%pK: unable to get vdev reference at MAP vdev %pK vdev_id %u", 3456 soc, vdev, vdev_id); 3457 qdf_spin_unlock_bh(&soc->vdev_map_lock); 3458 return; 3459 } 3460 3461 if (!soc->vdev_id_map[vdev_id]) 3462 soc->vdev_id_map[vdev_id] = vdev; 3463 else 3464 QDF_ASSERT(0); 3465 3466 qdf_spin_unlock_bh(&soc->vdev_map_lock); 3467 } 3468 3469 /** 3470 * dp_vdev_id_map_tbl_remove() - remove vdev from vdev_id table 3471 * @soc: SoC handle 3472 * @vdev: vdev handle 3473 * 3474 * Return: None 3475 */ 3476 static void dp_vdev_id_map_tbl_remove(struct dp_soc *soc, 3477 struct dp_vdev *vdev) 3478 { 3479 qdf_spin_lock_bh(&soc->vdev_map_lock); 3480 QDF_ASSERT(soc->vdev_id_map[vdev->vdev_id] == vdev); 3481 3482 soc->vdev_id_map[vdev->vdev_id] = NULL; 3483 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG); 3484 qdf_spin_unlock_bh(&soc->vdev_map_lock); 3485 } 3486 3487 /** 3488 * dp_vdev_pdev_list_add() - add vdev into pdev's list 3489 * @soc: soc handle 3490 * @pdev: pdev handle 3491 * @vdev: vdev handle 3492 * 3493 * Return: none 3494 */ 3495 static void dp_vdev_pdev_list_add(struct dp_soc *soc, 3496 struct dp_pdev *pdev, 3497 struct dp_vdev *vdev) 3498 { 3499 qdf_spin_lock_bh(&pdev->vdev_list_lock); 3500 if (dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CONFIG) != 3501 QDF_STATUS_SUCCESS) { 3502 dp_vdev_info("%pK: unable to get vdev reference at MAP vdev %pK", 3503 soc, vdev); 3504 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 3505 return; 3506 } 3507 /* add this vdev into the pdev's list */ 3508 TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); 3509 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 3510 } 3511 3512 /** 3513 * dp_vdev_pdev_list_remove() - remove vdev from pdev's list 3514 * @soc: SoC handle 3515 * @pdev: pdev handle 3516 * @vdev: VDEV handle 3517 * 3518 * Return: none 3519 */ 3520 static void dp_vdev_pdev_list_remove(struct dp_soc *soc, 3521 struct dp_pdev *pdev, 3522 struct dp_vdev *vdev) 3523 { 3524 uint8_t found = 0; 3525 struct dp_vdev *tmpvdev = NULL; 3526 3527 qdf_spin_lock_bh(&pdev->vdev_list_lock); 3528 TAILQ_FOREACH(tmpvdev, &pdev->vdev_list, vdev_list_elem) { 3529 if (tmpvdev == vdev) { 3530 found = 1; 3531 break; 3532 } 3533 } 3534 3535 if (found) { 3536 TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem); 3537 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG); 3538 } else { 3539 dp_vdev_debug("%pK: vdev:%pK not found in pdev:%pK vdevlist:%pK", 3540 soc, vdev, pdev, &pdev->vdev_list); 3541 QDF_ASSERT(0); 3542 } 3543 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 3544 } 3545 3546 #ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT 3547 /** 3548 * dp_vdev_init_rx_eapol() - initializing osif_rx_eapol 3549 * @vdev: Datapath VDEV handle 3550 * 3551 * Return: None 3552 */ 3553 static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev) 3554 { 3555 vdev->osif_rx_eapol = NULL; 3556 } 3557 3558 /** 3559 * dp_vdev_register_rx_eapol() - Register VDEV operations for rx_eapol 3560 * @vdev: DP vdev handle 3561 * @txrx_ops: Tx and Rx operations 3562 * 3563 * Return: None 3564 */ 3565 static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev, 3566 struct ol_txrx_ops *txrx_ops) 3567 { 3568 vdev->osif_rx_eapol = txrx_ops->rx.rx_eapol; 3569 } 3570 #else 3571 static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev) 3572 { 3573 } 3574 3575 static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev, 3576 struct ol_txrx_ops *txrx_ops) 3577 { 3578 } 3579 #endif 3580 3581 #ifdef WLAN_FEATURE_11BE_MLO 3582 static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, 3583 struct cdp_vdev_info *vdev_info) 3584 { 3585 if (vdev_info->mld_mac_addr) 3586 qdf_mem_copy(&vdev->mld_mac_addr.raw[0], 3587 vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE); 3588 } 3589 #else 3590 static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, 3591 struct cdp_vdev_info *vdev_info) 3592 { 3593 3594 } 3595 #endif 3596 3597 #ifdef DP_TRAFFIC_END_INDICATION 3598 /** 3599 * dp_tx_vdev_traffic_end_indication_attach() - Initialize data end indication 3600 * related members in VDEV 3601 * @vdev: DP vdev handle 3602 * 3603 * Return: None 3604 */ 3605 static inline void 3606 dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev *vdev) 3607 { 3608 qdf_nbuf_queue_init(&vdev->end_ind_pkt_q); 3609 } 3610 3611 /** 3612 * dp_tx_vdev_traffic_end_indication_detach() - De-init data end indication 3613 * related members in VDEV 3614 * @vdev: DP vdev handle 3615 * 3616 * Return: None 3617 */ 3618 static inline void 3619 dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev *vdev) 3620 { 3621 qdf_nbuf_t nbuf; 3622 3623 while ((nbuf = qdf_nbuf_queue_remove(&vdev->end_ind_pkt_q)) != NULL) 3624 qdf_nbuf_free(nbuf); 3625 } 3626 #else 3627 static inline void 3628 dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev *vdev) 3629 {} 3630 3631 static inline void 3632 dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev *vdev) 3633 {} 3634 #endif 3635 3636 /** 3637 * dp_vdev_attach_wifi3() - attach txrx vdev 3638 * @cdp_soc: CDP SoC context 3639 * @pdev_id: PDEV ID for vdev creation 3640 * @vdev_info: parameters used for vdev creation 3641 * 3642 * Return: status 3643 */ 3644 static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc, 3645 uint8_t pdev_id, 3646 struct cdp_vdev_info *vdev_info) 3647 { 3648 int i = 0; 3649 qdf_size_t vdev_context_size; 3650 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 3651 struct dp_pdev *pdev = 3652 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 3653 pdev_id); 3654 struct dp_vdev *vdev; 3655 uint8_t *vdev_mac_addr = vdev_info->vdev_mac_addr; 3656 uint8_t vdev_id = vdev_info->vdev_id; 3657 enum wlan_op_mode op_mode = vdev_info->op_mode; 3658 enum wlan_op_subtype subtype = vdev_info->subtype; 3659 uint8_t vdev_stats_id = vdev_info->vdev_stats_id; 3660 3661 vdev_context_size = 3662 soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_VDEV); 3663 vdev = qdf_mem_malloc(vdev_context_size); 3664 3665 if (!pdev) { 3666 dp_init_err("%pK: DP PDEV is Null for pdev id %d", 3667 cdp_soc, pdev_id); 3668 qdf_mem_free(vdev); 3669 goto fail0; 3670 } 3671 3672 if (!vdev) { 3673 dp_init_err("%pK: DP VDEV memory allocation failed", 3674 cdp_soc); 3675 goto fail0; 3676 } 3677 3678 wlan_minidump_log(vdev, sizeof(*vdev), soc->ctrl_psoc, 3679 WLAN_MD_DP_VDEV, "dp_vdev"); 3680 3681 vdev->pdev = pdev; 3682 vdev->vdev_id = vdev_id; 3683 vdev->vdev_stats_id = vdev_stats_id; 3684 vdev->opmode = op_mode; 3685 vdev->subtype = subtype; 3686 vdev->osdev = soc->osdev; 3687 3688 vdev->osif_rx = NULL; 3689 vdev->osif_rsim_rx_decap = NULL; 3690 vdev->osif_get_key = NULL; 3691 vdev->osif_tx_free_ext = NULL; 3692 vdev->osif_vdev = NULL; 3693 3694 vdev->delete.pending = 0; 3695 vdev->safemode = 0; 3696 vdev->drop_unenc = 1; 3697 vdev->sec_type = cdp_sec_type_none; 3698 vdev->multipass_en = false; 3699 vdev->wrap_vdev = false; 3700 dp_vdev_init_rx_eapol(vdev); 3701 qdf_atomic_init(&vdev->ref_cnt); 3702 for (i = 0; i < DP_MOD_ID_MAX; i++) 3703 qdf_atomic_init(&vdev->mod_refs[i]); 3704 3705 /* Take one reference for create*/ 3706 qdf_atomic_inc(&vdev->ref_cnt); 3707 qdf_atomic_inc(&vdev->mod_refs[DP_MOD_ID_CONFIG]); 3708 vdev->num_peers = 0; 3709 #ifdef notyet 3710 vdev->filters_num = 0; 3711 #endif 3712 vdev->lmac_id = pdev->lmac_id; 3713 3714 qdf_mem_copy(&vdev->mac_addr.raw[0], vdev_mac_addr, QDF_MAC_ADDR_SIZE); 3715 3716 dp_vdev_save_mld_addr(vdev, vdev_info); 3717 3718 /* TODO: Initialize default HTT meta data that will be used in 3719 * TCL descriptors for packets transmitted from this VDEV 3720 */ 3721 3722 qdf_spinlock_create(&vdev->peer_list_lock); 3723 TAILQ_INIT(&vdev->peer_list); 3724 dp_peer_multipass_list_init(vdev); 3725 if ((soc->intr_mode == DP_INTR_POLL) && 3726 wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) { 3727 if ((pdev->vdev_count == 0) || 3728 (wlan_op_mode_monitor == vdev->opmode)) 3729 qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); 3730 } else if (dp_soc_get_con_mode(soc) == QDF_GLOBAL_MISSION_MODE && 3731 soc->intr_mode == DP_INTR_MSI && 3732 wlan_op_mode_monitor == vdev->opmode) { 3733 /* Timer to reap status ring in mission mode */ 3734 dp_monitor_vdev_timer_start(soc); 3735 } 3736 3737 dp_vdev_id_map_tbl_add(soc, vdev, vdev_id); 3738 3739 if (wlan_op_mode_monitor == vdev->opmode) { 3740 if (dp_monitor_vdev_attach(vdev) == QDF_STATUS_SUCCESS) { 3741 dp_monitor_pdev_set_mon_vdev(vdev); 3742 return dp_monitor_vdev_set_monitor_mode_buf_rings(pdev); 3743 } 3744 return QDF_STATUS_E_FAILURE; 3745 } 3746 3747 vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); 3748 vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); 3749 vdev->dscp_tid_map_id = 0; 3750 vdev->mcast_enhancement_en = 0; 3751 vdev->igmp_mcast_enhanc_en = 0; 3752 vdev->raw_mode_war = wlan_cfg_get_raw_mode_war(soc->wlan_cfg_ctx); 3753 vdev->prev_tx_enq_tstamp = 0; 3754 vdev->prev_rx_deliver_tstamp = 0; 3755 vdev->skip_sw_tid_classification = DP_TX_HW_DSCP_TID_MAP_VALID; 3756 dp_tx_vdev_traffic_end_indication_attach(vdev); 3757 3758 dp_vdev_pdev_list_add(soc, pdev, vdev); 3759 pdev->vdev_count++; 3760 3761 if (wlan_op_mode_sta != vdev->opmode && 3762 wlan_op_mode_ndi != vdev->opmode) 3763 vdev->ap_bridge_enabled = true; 3764 else 3765 vdev->ap_bridge_enabled = false; 3766 dp_init_info("%pK: wlan_cfg_ap_bridge_enabled %d", 3767 cdp_soc, vdev->ap_bridge_enabled); 3768 3769 dp_tx_vdev_attach(vdev); 3770 3771 dp_monitor_vdev_attach(vdev); 3772 if (!pdev->is_lro_hash_configured) { 3773 if (QDF_IS_STATUS_SUCCESS(dp_lro_hash_setup(soc, pdev))) 3774 pdev->is_lro_hash_configured = true; 3775 else 3776 dp_err("LRO hash setup failure!"); 3777 } 3778 3779 dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_ATTACH, vdev); 3780 dp_info("Created vdev %pK ("QDF_MAC_ADDR_FMT") vdev_id %d", vdev, 3781 QDF_MAC_ADDR_REF(vdev->mac_addr.raw), vdev->vdev_id); 3782 DP_STATS_INIT(vdev); 3783 3784 if (QDF_IS_STATUS_ERROR(soc->arch_ops.txrx_vdev_attach(soc, vdev))) 3785 goto fail0; 3786 3787 if (wlan_op_mode_sta == vdev->opmode) 3788 dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id, 3789 vdev->mac_addr.raw, CDP_LINK_PEER_TYPE); 3790 3791 dp_pdev_update_fast_rx_flag(soc, pdev); 3792 3793 return QDF_STATUS_SUCCESS; 3794 3795 fail0: 3796 return QDF_STATUS_E_FAILURE; 3797 } 3798 3799 #ifndef QCA_HOST_MODE_WIFI_DISABLED 3800 /** 3801 * dp_vdev_fetch_tx_handler() - Fetch Tx handlers 3802 * @vdev: struct dp_vdev * 3803 * @soc: struct dp_soc * 3804 * @ctx: struct ol_txrx_hardtart_ctxt * 3805 */ 3806 static inline void dp_vdev_fetch_tx_handler(struct dp_vdev *vdev, 3807 struct dp_soc *soc, 3808 struct ol_txrx_hardtart_ctxt *ctx) 3809 { 3810 /* Enable vdev_id check only for ap, if flag is enabled */ 3811 if (vdev->mesh_vdev) 3812 ctx->tx = dp_tx_send_mesh; 3813 else if ((wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx)) && 3814 (vdev->opmode == wlan_op_mode_ap)) { 3815 ctx->tx = dp_tx_send_vdev_id_check; 3816 ctx->tx_fast = dp_tx_send_vdev_id_check; 3817 } else { 3818 ctx->tx = dp_tx_send; 3819 ctx->tx_fast = soc->arch_ops.dp_tx_send_fast; 3820 } 3821 3822 /* Avoid check in regular exception Path */ 3823 if ((wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx)) && 3824 (vdev->opmode == wlan_op_mode_ap)) 3825 ctx->tx_exception = dp_tx_send_exception_vdev_id_check; 3826 else 3827 ctx->tx_exception = dp_tx_send_exception; 3828 } 3829 3830 /** 3831 * dp_vdev_register_tx_handler() - Register Tx handler 3832 * @vdev: struct dp_vdev * 3833 * @soc: struct dp_soc * 3834 * @txrx_ops: struct ol_txrx_ops * 3835 */ 3836 static inline void dp_vdev_register_tx_handler(struct dp_vdev *vdev, 3837 struct dp_soc *soc, 3838 struct ol_txrx_ops *txrx_ops) 3839 { 3840 struct ol_txrx_hardtart_ctxt ctx = {0}; 3841 3842 dp_vdev_fetch_tx_handler(vdev, soc, &ctx); 3843 3844 txrx_ops->tx.tx = ctx.tx; 3845 txrx_ops->tx.tx_fast = ctx.tx_fast; 3846 txrx_ops->tx.tx_exception = ctx.tx_exception; 3847 3848 dp_info("Configure tx_vdev_id_chk_handler Feature Flag: %d and mode:%d for vdev_id:%d", 3849 wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx), 3850 vdev->opmode, vdev->vdev_id); 3851 } 3852 #else /* QCA_HOST_MODE_WIFI_DISABLED */ 3853 static inline void dp_vdev_register_tx_handler(struct dp_vdev *vdev, 3854 struct dp_soc *soc, 3855 struct ol_txrx_ops *txrx_ops) 3856 { 3857 } 3858 3859 static inline void dp_vdev_fetch_tx_handler(struct dp_vdev *vdev, 3860 struct dp_soc *soc, 3861 struct ol_txrx_hardtart_ctxt *ctx) 3862 { 3863 } 3864 #endif /* QCA_HOST_MODE_WIFI_DISABLED */ 3865 3866 /** 3867 * dp_vdev_register_wifi3() - Register VDEV operations from osif layer 3868 * @soc_hdl: Datapath soc handle 3869 * @vdev_id: id of Datapath VDEV handle 3870 * @osif_vdev: OSIF vdev handle 3871 * @txrx_ops: Tx and Rx operations 3872 * 3873 * Return: DP VDEV handle on success, NULL on failure 3874 */ 3875 static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl, 3876 uint8_t vdev_id, 3877 ol_osif_vdev_handle osif_vdev, 3878 struct ol_txrx_ops *txrx_ops) 3879 { 3880 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 3881 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 3882 DP_MOD_ID_CDP); 3883 3884 if (!vdev) 3885 return QDF_STATUS_E_FAILURE; 3886 3887 vdev->osif_vdev = osif_vdev; 3888 vdev->osif_rx = txrx_ops->rx.rx; 3889 vdev->osif_rx_stack = txrx_ops->rx.rx_stack; 3890 vdev->osif_rx_flush = txrx_ops->rx.rx_flush; 3891 vdev->osif_gro_flush = txrx_ops->rx.rx_gro_flush; 3892 vdev->osif_rsim_rx_decap = txrx_ops->rx.rsim_rx_decap; 3893 vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx; 3894 vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush; 3895 vdev->osif_get_key = txrx_ops->get_key; 3896 dp_monitor_vdev_register_osif(vdev, txrx_ops); 3897 vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext; 3898 vdev->tx_comp = txrx_ops->tx.tx_comp; 3899 vdev->stats_cb = txrx_ops->rx.stats_rx; 3900 vdev->tx_classify_critical_pkt_cb = 3901 txrx_ops->tx.tx_classify_critical_pkt_cb; 3902 #ifdef notyet 3903 #if ATH_SUPPORT_WAPI 3904 vdev->osif_check_wai = txrx_ops->rx.wai_check; 3905 #endif 3906 #endif 3907 #ifdef UMAC_SUPPORT_PROXY_ARP 3908 vdev->osif_proxy_arp = txrx_ops->proxy_arp; 3909 #endif 3910 vdev->me_convert = txrx_ops->me_convert; 3911 vdev->get_tsf_time = txrx_ops->get_tsf_time; 3912 3913 dp_vdev_register_rx_eapol(vdev, txrx_ops); 3914 3915 dp_vdev_register_tx_handler(vdev, soc, txrx_ops); 3916 3917 dp_init_info("%pK: DP Vdev Register success", soc); 3918 3919 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 3920 return QDF_STATUS_SUCCESS; 3921 } 3922 3923 #ifdef WLAN_FEATURE_11BE_MLO 3924 void dp_peer_delete(struct dp_soc *soc, 3925 struct dp_peer *peer, 3926 void *arg) 3927 { 3928 if (!peer->valid) 3929 return; 3930 3931 dp_peer_delete_wifi3((struct cdp_soc_t *)soc, 3932 peer->vdev->vdev_id, 3933 peer->mac_addr.raw, 0, 3934 peer->peer_type); 3935 } 3936 #else 3937 void dp_peer_delete(struct dp_soc *soc, 3938 struct dp_peer *peer, 3939 void *arg) 3940 { 3941 if (!peer->valid) 3942 return; 3943 3944 dp_peer_delete_wifi3((struct cdp_soc_t *)soc, 3945 peer->vdev->vdev_id, 3946 peer->mac_addr.raw, 0, 3947 CDP_LINK_PEER_TYPE); 3948 } 3949 #endif 3950 3951 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 3952 void dp_mlo_peer_delete(struct dp_soc *soc, struct dp_peer *peer, void *arg) 3953 { 3954 if (!peer->valid) 3955 return; 3956 3957 if (IS_MLO_DP_LINK_PEER(peer)) 3958 dp_peer_delete_wifi3((struct cdp_soc_t *)soc, 3959 peer->vdev->vdev_id, 3960 peer->mac_addr.raw, 0, 3961 CDP_LINK_PEER_TYPE); 3962 } 3963 #else 3964 void dp_mlo_peer_delete(struct dp_soc *soc, struct dp_peer *peer, void *arg) 3965 { 3966 } 3967 #endif 3968 /** 3969 * dp_vdev_flush_peers() - Forcibily Flush peers of vdev 3970 * @vdev_handle: Datapath VDEV handle 3971 * @unmap_only: Flag to indicate "only unmap" 3972 * @mlo_peers_only: true if only MLO peers should be flushed 3973 * 3974 * Return: void 3975 */ 3976 static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, 3977 bool unmap_only, 3978 bool mlo_peers_only) 3979 { 3980 struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; 3981 struct dp_pdev *pdev = vdev->pdev; 3982 struct dp_soc *soc = pdev->soc; 3983 struct dp_peer *peer; 3984 uint32_t i = 0; 3985 3986 3987 if (!unmap_only) { 3988 if (!mlo_peers_only) 3989 dp_vdev_iterate_peer_lock_safe(vdev, 3990 dp_peer_delete, 3991 NULL, 3992 DP_MOD_ID_CDP); 3993 else 3994 dp_vdev_iterate_peer_lock_safe(vdev, 3995 dp_mlo_peer_delete, 3996 NULL, 3997 DP_MOD_ID_CDP); 3998 } 3999 4000 for (i = 0; i < soc->max_peer_id ; i++) { 4001 peer = __dp_peer_get_ref_by_id(soc, i, DP_MOD_ID_CDP); 4002 4003 if (!peer) 4004 continue; 4005 4006 if (peer->vdev != vdev) { 4007 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 4008 continue; 4009 } 4010 4011 if (!mlo_peers_only) { 4012 dp_info("peer: " QDF_MAC_ADDR_FMT " is getting unmap", 4013 QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 4014 dp_rx_peer_unmap_handler(soc, i, 4015 vdev->vdev_id, 4016 peer->mac_addr.raw, 0, 4017 DP_PEER_WDS_COUNT_INVALID); 4018 SET_PEER_REF_CNT_ONE(peer); 4019 } else if (IS_MLO_DP_LINK_PEER(peer) || 4020 IS_MLO_DP_MLD_PEER(peer)) { 4021 dp_info("peer: " QDF_MAC_ADDR_FMT " is getting unmap", 4022 QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 4023 dp_rx_peer_unmap_handler(soc, i, 4024 vdev->vdev_id, 4025 peer->mac_addr.raw, 0, 4026 DP_PEER_WDS_COUNT_INVALID); 4027 SET_PEER_REF_CNT_ONE(peer); 4028 } 4029 4030 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 4031 } 4032 } 4033 4034 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 4035 /** 4036 * dp_txrx_alloc_vdev_stats_id()- Allocate vdev_stats_id 4037 * @soc_hdl: Datapath soc handle 4038 * @vdev_stats_id: Address of vdev_stats_id 4039 * 4040 * Return: QDF_STATUS 4041 */ 4042 static QDF_STATUS dp_txrx_alloc_vdev_stats_id(struct cdp_soc_t *soc_hdl, 4043 uint8_t *vdev_stats_id) 4044 { 4045 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 4046 uint8_t id = 0; 4047 4048 if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) { 4049 *vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 4050 return QDF_STATUS_E_FAILURE; 4051 } 4052 4053 while (id < CDP_MAX_VDEV_STATS_ID) { 4054 if (!qdf_atomic_test_and_set_bit(id, &soc->vdev_stats_id_map)) { 4055 *vdev_stats_id = id; 4056 return QDF_STATUS_SUCCESS; 4057 } 4058 id++; 4059 } 4060 4061 *vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 4062 return QDF_STATUS_E_FAILURE; 4063 } 4064 4065 /** 4066 * dp_txrx_reset_vdev_stats_id() - Reset vdev_stats_id in dp_soc 4067 * @soc_hdl: Datapath soc handle 4068 * @vdev_stats_id: vdev_stats_id to reset in dp_soc 4069 * 4070 * Return: none 4071 */ 4072 static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc_hdl, 4073 uint8_t vdev_stats_id) 4074 { 4075 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 4076 4077 if ((!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) || 4078 (vdev_stats_id >= CDP_MAX_VDEV_STATS_ID)) 4079 return; 4080 4081 qdf_atomic_clear_bit(vdev_stats_id, &soc->vdev_stats_id_map); 4082 } 4083 #else 4084 static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc, 4085 uint8_t vdev_stats_id) 4086 {} 4087 #endif 4088 /** 4089 * dp_vdev_detach_wifi3() - Detach txrx vdev 4090 * @cdp_soc: Datapath soc handle 4091 * @vdev_id: VDEV Id 4092 * @callback: Callback OL_IF on completion of detach 4093 * @cb_context: Callback context 4094 * 4095 */ 4096 static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc, 4097 uint8_t vdev_id, 4098 ol_txrx_vdev_delete_cb callback, 4099 void *cb_context) 4100 { 4101 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 4102 struct dp_pdev *pdev; 4103 struct dp_neighbour_peer *peer = NULL; 4104 struct dp_peer *vap_self_peer = NULL; 4105 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 4106 DP_MOD_ID_CDP); 4107 4108 if (!vdev) 4109 return QDF_STATUS_E_FAILURE; 4110 4111 soc->arch_ops.txrx_vdev_detach(soc, vdev); 4112 4113 pdev = vdev->pdev; 4114 4115 vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev, 4116 DP_MOD_ID_CONFIG); 4117 if (vap_self_peer) { 4118 qdf_spin_lock_bh(&soc->ast_lock); 4119 if (vap_self_peer->self_ast_entry) { 4120 dp_peer_del_ast(soc, vap_self_peer->self_ast_entry); 4121 vap_self_peer->self_ast_entry = NULL; 4122 } 4123 qdf_spin_unlock_bh(&soc->ast_lock); 4124 4125 dp_peer_delete_wifi3((struct cdp_soc_t *)soc, vdev->vdev_id, 4126 vap_self_peer->mac_addr.raw, 0, 4127 CDP_LINK_PEER_TYPE); 4128 dp_peer_unref_delete(vap_self_peer, DP_MOD_ID_CONFIG); 4129 } 4130 4131 /* 4132 * If Target is hung, flush all peers before detaching vdev 4133 * this will free all references held due to missing 4134 * unmap commands from Target 4135 */ 4136 if (!hif_is_target_ready(HIF_GET_SOFTC(soc->hif_handle))) 4137 dp_vdev_flush_peers((struct cdp_vdev *)vdev, false, false); 4138 else if (hif_get_target_status(soc->hif_handle) == TARGET_STATUS_RESET) 4139 dp_vdev_flush_peers((struct cdp_vdev *)vdev, true, false); 4140 4141 /* indicate that the vdev needs to be deleted */ 4142 vdev->delete.pending = 1; 4143 dp_rx_vdev_detach(vdev); 4144 /* 4145 * move it after dp_rx_vdev_detach(), 4146 * as the call back done in dp_rx_vdev_detach() 4147 * still need to get vdev pointer by vdev_id. 4148 */ 4149 dp_vdev_id_map_tbl_remove(soc, vdev); 4150 4151 dp_monitor_neighbour_peer_list_remove(pdev, vdev, peer); 4152 4153 dp_txrx_reset_vdev_stats_id(cdp_soc, vdev->vdev_stats_id); 4154 4155 dp_tx_vdev_multipass_deinit(vdev); 4156 dp_tx_vdev_traffic_end_indication_detach(vdev); 4157 4158 if (vdev->vdev_dp_ext_handle) { 4159 qdf_mem_free(vdev->vdev_dp_ext_handle); 4160 vdev->vdev_dp_ext_handle = NULL; 4161 } 4162 vdev->delete.callback = callback; 4163 vdev->delete.context = cb_context; 4164 4165 if (vdev->opmode != wlan_op_mode_monitor) 4166 dp_vdev_pdev_list_remove(soc, pdev, vdev); 4167 4168 pdev->vdev_count--; 4169 /* release reference taken above for find */ 4170 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4171 4172 qdf_spin_lock_bh(&soc->inactive_vdev_list_lock); 4173 TAILQ_INSERT_TAIL(&soc->inactive_vdev_list, vdev, inactive_list_elem); 4174 qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock); 4175 4176 dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_DETACH, vdev); 4177 dp_info("detach vdev %pK id %d pending refs %d", 4178 vdev, vdev->vdev_id, qdf_atomic_read(&vdev->ref_cnt)); 4179 4180 /* release reference taken at dp_vdev_create */ 4181 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG); 4182 4183 return QDF_STATUS_SUCCESS; 4184 } 4185 4186 #ifdef WLAN_FEATURE_11BE_MLO 4187 /** 4188 * is_dp_peer_can_reuse() - check if the dp_peer match condition to be reused 4189 * @vdev: Target DP vdev handle 4190 * @peer: DP peer handle to be checked 4191 * @peer_mac_addr: Target peer mac address 4192 * @peer_type: Target peer type 4193 * 4194 * Return: true - if match, false - not match 4195 */ 4196 static inline 4197 bool is_dp_peer_can_reuse(struct dp_vdev *vdev, 4198 struct dp_peer *peer, 4199 uint8_t *peer_mac_addr, 4200 enum cdp_peer_type peer_type) 4201 { 4202 if (peer->bss_peer && (peer->vdev == vdev) && 4203 (peer->peer_type == peer_type) && 4204 (qdf_mem_cmp(peer_mac_addr, peer->mac_addr.raw, 4205 QDF_MAC_ADDR_SIZE) == 0)) 4206 return true; 4207 4208 return false; 4209 } 4210 #else 4211 static inline 4212 bool is_dp_peer_can_reuse(struct dp_vdev *vdev, 4213 struct dp_peer *peer, 4214 uint8_t *peer_mac_addr, 4215 enum cdp_peer_type peer_type) 4216 { 4217 if (peer->bss_peer && (peer->vdev == vdev) && 4218 (qdf_mem_cmp(peer_mac_addr, peer->mac_addr.raw, 4219 QDF_MAC_ADDR_SIZE) == 0)) 4220 return true; 4221 4222 return false; 4223 } 4224 #endif 4225 4226 static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev, 4227 uint8_t *peer_mac_addr, 4228 enum cdp_peer_type peer_type) 4229 { 4230 struct dp_peer *peer; 4231 struct dp_soc *soc = vdev->pdev->soc; 4232 4233 qdf_spin_lock_bh(&soc->inactive_peer_list_lock); 4234 TAILQ_FOREACH(peer, &soc->inactive_peer_list, 4235 inactive_list_elem) { 4236 4237 /* reuse bss peer only when vdev matches*/ 4238 if (is_dp_peer_can_reuse(vdev, peer, 4239 peer_mac_addr, peer_type)) { 4240 /* increment ref count for cdp_peer_create*/ 4241 if (dp_peer_get_ref(soc, peer, DP_MOD_ID_CONFIG) == 4242 QDF_STATUS_SUCCESS) { 4243 TAILQ_REMOVE(&soc->inactive_peer_list, peer, 4244 inactive_list_elem); 4245 qdf_spin_unlock_bh 4246 (&soc->inactive_peer_list_lock); 4247 return peer; 4248 } 4249 } 4250 } 4251 4252 qdf_spin_unlock_bh(&soc->inactive_peer_list_lock); 4253 return NULL; 4254 } 4255 4256 #ifdef FEATURE_AST 4257 static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, 4258 struct dp_pdev *pdev, 4259 uint8_t *peer_mac_addr) 4260 { 4261 struct dp_ast_entry *ast_entry; 4262 4263 if (soc->ast_offload_support) 4264 return; 4265 4266 qdf_spin_lock_bh(&soc->ast_lock); 4267 if (soc->ast_override_support) 4268 ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, peer_mac_addr, 4269 pdev->pdev_id); 4270 else 4271 ast_entry = dp_peer_ast_hash_find_soc(soc, peer_mac_addr); 4272 4273 if (ast_entry && ast_entry->next_hop && !ast_entry->delete_in_progress) 4274 dp_peer_del_ast(soc, ast_entry); 4275 4276 qdf_spin_unlock_bh(&soc->ast_lock); 4277 } 4278 #else 4279 static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, 4280 struct dp_pdev *pdev, 4281 uint8_t *peer_mac_addr) 4282 { 4283 } 4284 #endif 4285 4286 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 4287 /** 4288 * dp_peer_hw_txrx_stats_init() - Initialize hw_txrx_stats_en in dp_peer 4289 * @soc: Datapath soc handle 4290 * @txrx_peer: Datapath peer handle 4291 * 4292 * Return: none 4293 */ 4294 static inline 4295 void dp_peer_hw_txrx_stats_init(struct dp_soc *soc, 4296 struct dp_txrx_peer *txrx_peer) 4297 { 4298 txrx_peer->hw_txrx_stats_en = 4299 wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx); 4300 } 4301 #else 4302 static inline 4303 void dp_peer_hw_txrx_stats_init(struct dp_soc *soc, 4304 struct dp_txrx_peer *txrx_peer) 4305 { 4306 txrx_peer->hw_txrx_stats_en = 0; 4307 } 4308 #endif 4309 4310 static QDF_STATUS dp_txrx_peer_detach(struct dp_soc *soc, struct dp_peer *peer) 4311 { 4312 struct dp_txrx_peer *txrx_peer; 4313 struct dp_pdev *pdev; 4314 struct cdp_txrx_peer_params_update params = {0}; 4315 4316 /* dp_txrx_peer exists for mld peer and legacy peer */ 4317 if (peer->txrx_peer) { 4318 txrx_peer = peer->txrx_peer; 4319 peer->txrx_peer = NULL; 4320 pdev = txrx_peer->vdev->pdev; 4321 4322 params.osif_vdev = (void *)peer->vdev->osif_vdev; 4323 params.peer_mac = peer->mac_addr.raw; 4324 4325 dp_wdi_event_handler(WDI_EVENT_PEER_DELETE, soc, 4326 (void *)¶ms, peer->peer_id, 4327 WDI_NO_VAL, pdev->pdev_id); 4328 4329 dp_peer_defrag_rx_tids_deinit(txrx_peer); 4330 /* 4331 * Deallocate the extended stats contenxt 4332 */ 4333 dp_peer_delay_stats_ctx_dealloc(soc, txrx_peer); 4334 dp_peer_rx_bufq_resources_deinit(txrx_peer); 4335 dp_peer_jitter_stats_ctx_dealloc(pdev, txrx_peer); 4336 dp_peer_sawf_stats_ctx_free(soc, txrx_peer); 4337 4338 qdf_mem_free(txrx_peer); 4339 } 4340 4341 return QDF_STATUS_SUCCESS; 4342 } 4343 4344 static inline 4345 uint8_t dp_txrx_peer_calculate_stats_size(struct dp_soc *soc, 4346 struct dp_peer *peer) 4347 { 4348 if ((wlan_cfg_is_peer_link_stats_enabled(soc->wlan_cfg_ctx)) && 4349 IS_MLO_DP_MLD_PEER(peer)) { 4350 return (DP_MAX_MLO_LINKS + 1); 4351 } 4352 return 1; 4353 } 4354 4355 static QDF_STATUS dp_txrx_peer_attach(struct dp_soc *soc, struct dp_peer *peer) 4356 { 4357 struct dp_txrx_peer *txrx_peer; 4358 struct dp_pdev *pdev; 4359 struct cdp_txrx_peer_params_update params = {0}; 4360 uint8_t stats_arr_size = 0; 4361 4362 stats_arr_size = dp_txrx_peer_calculate_stats_size(soc, peer); 4363 4364 txrx_peer = (struct dp_txrx_peer *)qdf_mem_malloc(sizeof(*txrx_peer) + 4365 (stats_arr_size * 4366 sizeof(struct dp_peer_stats))); 4367 4368 if (!txrx_peer) 4369 return QDF_STATUS_E_NOMEM; /* failure */ 4370 4371 txrx_peer->peer_id = HTT_INVALID_PEER; 4372 /* initialize the peer_id */ 4373 txrx_peer->vdev = peer->vdev; 4374 pdev = peer->vdev->pdev; 4375 txrx_peer->stats_arr_size = stats_arr_size; 4376 4377 DP_TXRX_PEER_STATS_INIT(txrx_peer, 4378 (txrx_peer->stats_arr_size * 4379 sizeof(struct dp_peer_stats))); 4380 4381 if (!IS_DP_LEGACY_PEER(peer)) 4382 txrx_peer->is_mld_peer = 1; 4383 4384 dp_wds_ext_peer_init(txrx_peer); 4385 dp_peer_rx_bufq_resources_init(txrx_peer); 4386 dp_peer_hw_txrx_stats_init(soc, txrx_peer); 4387 /* 4388 * Allocate peer extended stats context. Fall through in 4389 * case of failure as its not an implicit requirement to have 4390 * this object for regular statistics updates. 4391 */ 4392 if (dp_peer_delay_stats_ctx_alloc(soc, txrx_peer) != 4393 QDF_STATUS_SUCCESS) 4394 dp_warn("peer delay_stats ctx alloc failed"); 4395 4396 /* 4397 * Alloctate memory for jitter stats. Fall through in 4398 * case of failure as its not an implicit requirement to have 4399 * this object for regular statistics updates. 4400 */ 4401 if (dp_peer_jitter_stats_ctx_alloc(pdev, txrx_peer) != 4402 QDF_STATUS_SUCCESS) 4403 dp_warn("peer jitter_stats ctx alloc failed"); 4404 4405 dp_set_peer_isolation(txrx_peer, false); 4406 4407 dp_peer_defrag_rx_tids_init(txrx_peer); 4408 4409 if (dp_peer_sawf_stats_ctx_alloc(soc, txrx_peer) != QDF_STATUS_SUCCESS) 4410 dp_warn("peer sawf stats alloc failed"); 4411 4412 dp_txrx_peer_attach_add(soc, peer, txrx_peer); 4413 4414 params.peer_mac = peer->mac_addr.raw; 4415 params.osif_vdev = (void *)peer->vdev->osif_vdev; 4416 params.chip_id = dp_mlo_get_chip_id(soc); 4417 params.pdev_id = peer->vdev->pdev->pdev_id; 4418 4419 dp_wdi_event_handler(WDI_EVENT_TXRX_PEER_CREATE, soc, 4420 (void *)¶ms, peer->peer_id, 4421 WDI_NO_VAL, params.pdev_id); 4422 4423 return QDF_STATUS_SUCCESS; 4424 } 4425 4426 static inline 4427 void dp_txrx_peer_stats_clr(struct dp_txrx_peer *txrx_peer) 4428 { 4429 if (!txrx_peer) 4430 return; 4431 4432 txrx_peer->tx_failed = 0; 4433 txrx_peer->comp_pkt.num = 0; 4434 txrx_peer->comp_pkt.bytes = 0; 4435 txrx_peer->to_stack.num = 0; 4436 txrx_peer->to_stack.bytes = 0; 4437 4438 DP_TXRX_PEER_STATS_CLR(txrx_peer, 4439 (txrx_peer->stats_arr_size * 4440 sizeof(struct dp_peer_stats))); 4441 dp_peer_delay_stats_ctx_clr(txrx_peer); 4442 dp_peer_jitter_stats_ctx_clr(txrx_peer); 4443 } 4444 4445 /** 4446 * dp_peer_create_wifi3() - attach txrx peer 4447 * @soc_hdl: Datapath soc handle 4448 * @vdev_id: id of vdev 4449 * @peer_mac_addr: Peer MAC address 4450 * @peer_type: link or MLD peer type 4451 * 4452 * Return: 0 on success, -1 on failure 4453 */ 4454 static QDF_STATUS 4455 dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 4456 uint8_t *peer_mac_addr, enum cdp_peer_type peer_type) 4457 { 4458 struct dp_peer *peer; 4459 int i; 4460 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 4461 struct dp_pdev *pdev; 4462 enum cdp_txrx_ast_entry_type ast_type = CDP_TXRX_AST_TYPE_STATIC; 4463 struct dp_vdev *vdev = NULL; 4464 4465 if (!peer_mac_addr) 4466 return QDF_STATUS_E_FAILURE; 4467 4468 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 4469 4470 if (!vdev) 4471 return QDF_STATUS_E_FAILURE; 4472 4473 pdev = vdev->pdev; 4474 soc = pdev->soc; 4475 4476 /* 4477 * If a peer entry with given MAC address already exists, 4478 * reuse the peer and reset the state of peer. 4479 */ 4480 peer = dp_peer_can_reuse(vdev, peer_mac_addr, peer_type); 4481 4482 if (peer) { 4483 qdf_atomic_init(&peer->is_default_route_set); 4484 dp_peer_cleanup(vdev, peer); 4485 4486 dp_peer_vdev_list_add(soc, vdev, peer); 4487 dp_peer_find_hash_add(soc, peer); 4488 4489 if (dp_peer_rx_tids_create(peer) != QDF_STATUS_SUCCESS) { 4490 dp_alert("RX tid alloc fail for peer %pK (" QDF_MAC_ADDR_FMT ")", 4491 peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 4492 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4493 return QDF_STATUS_E_FAILURE; 4494 } 4495 4496 if (IS_MLO_DP_MLD_PEER(peer)) 4497 dp_mld_peer_init_link_peers_info(peer); 4498 4499 qdf_spin_lock_bh(&soc->ast_lock); 4500 dp_peer_delete_ast_entries(soc, peer); 4501 qdf_spin_unlock_bh(&soc->ast_lock); 4502 4503 if ((vdev->opmode == wlan_op_mode_sta) && 4504 !qdf_mem_cmp(peer_mac_addr, &vdev->mac_addr.raw[0], 4505 QDF_MAC_ADDR_SIZE)) { 4506 ast_type = CDP_TXRX_AST_TYPE_SELF; 4507 } 4508 dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0); 4509 4510 peer->valid = 1; 4511 peer->is_tdls_peer = false; 4512 dp_local_peer_id_alloc(pdev, peer); 4513 4514 qdf_spinlock_create(&peer->peer_info_lock); 4515 4516 DP_STATS_INIT(peer); 4517 4518 /* 4519 * In tx_monitor mode, filter may be set for unassociated peer 4520 * when unassociated peer get associated peer need to 4521 * update tx_cap_enabled flag to support peer filter. 4522 */ 4523 if (!IS_MLO_DP_MLD_PEER(peer)) { 4524 dp_monitor_peer_tx_capture_filter_check(pdev, peer); 4525 dp_monitor_peer_reset_stats(soc, peer); 4526 } 4527 4528 if (peer->txrx_peer) { 4529 dp_peer_rx_bufq_resources_init(peer->txrx_peer); 4530 dp_txrx_peer_stats_clr(peer->txrx_peer); 4531 dp_set_peer_isolation(peer->txrx_peer, false); 4532 dp_wds_ext_peer_init(peer->txrx_peer); 4533 dp_peer_hw_txrx_stats_init(soc, peer->txrx_peer); 4534 } 4535 4536 dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_CREATE, 4537 peer, vdev, 1); 4538 dp_info("vdev %pK Reused peer %pK ("QDF_MAC_ADDR_FMT 4539 ") vdev_ref_cnt " 4540 "%d peer_ref_cnt: %d", 4541 vdev, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw), 4542 qdf_atomic_read(&vdev->ref_cnt), 4543 qdf_atomic_read(&peer->ref_cnt)); 4544 dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT); 4545 4546 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4547 return QDF_STATUS_SUCCESS; 4548 } else { 4549 /* 4550 * When a STA roams from RPTR AP to ROOT AP and vice versa, we 4551 * need to remove the AST entry which was earlier added as a WDS 4552 * entry. 4553 * If an AST entry exists, but no peer entry exists with a given 4554 * MAC addresses, we could deduce it as a WDS entry 4555 */ 4556 dp_peer_ast_handle_roam_del(soc, pdev, peer_mac_addr); 4557 } 4558 4559 #ifdef notyet 4560 peer = (struct dp_peer *)qdf_mempool_alloc(soc->osdev, 4561 soc->mempool_ol_ath_peer); 4562 #else 4563 peer = (struct dp_peer *)qdf_mem_malloc(sizeof(*peer)); 4564 #endif 4565 wlan_minidump_log(peer, 4566 sizeof(*peer), 4567 soc->ctrl_psoc, 4568 WLAN_MD_DP_PEER, "dp_peer"); 4569 if (!peer) { 4570 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4571 return QDF_STATUS_E_FAILURE; /* failure */ 4572 } 4573 4574 qdf_mem_zero(peer, sizeof(struct dp_peer)); 4575 4576 /* store provided params */ 4577 peer->vdev = vdev; 4578 4579 /* initialize the peer_id */ 4580 peer->peer_id = HTT_INVALID_PEER; 4581 4582 qdf_mem_copy( 4583 &peer->mac_addr.raw[0], peer_mac_addr, QDF_MAC_ADDR_SIZE); 4584 4585 DP_PEER_SET_TYPE(peer, peer_type); 4586 if (IS_MLO_DP_MLD_PEER(peer)) { 4587 if (dp_txrx_peer_attach(soc, peer) != 4588 QDF_STATUS_SUCCESS) 4589 goto fail; /* failure */ 4590 4591 dp_mld_peer_init_link_peers_info(peer); 4592 } else if (dp_monitor_peer_attach(soc, peer) != 4593 QDF_STATUS_SUCCESS) 4594 dp_warn("peer monitor ctx alloc failed"); 4595 4596 TAILQ_INIT(&peer->ast_entry_list); 4597 4598 /* get the vdev reference for new peer */ 4599 dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CHILD); 4600 4601 if ((vdev->opmode == wlan_op_mode_sta) && 4602 !qdf_mem_cmp(peer_mac_addr, &vdev->mac_addr.raw[0], 4603 QDF_MAC_ADDR_SIZE)) { 4604 ast_type = CDP_TXRX_AST_TYPE_SELF; 4605 } 4606 qdf_spinlock_create(&peer->peer_state_lock); 4607 dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0); 4608 qdf_spinlock_create(&peer->peer_info_lock); 4609 4610 /* reset the ast index to flowid table */ 4611 dp_peer_reset_flowq_map(peer); 4612 4613 qdf_atomic_init(&peer->ref_cnt); 4614 4615 for (i = 0; i < DP_MOD_ID_MAX; i++) 4616 qdf_atomic_init(&peer->mod_refs[i]); 4617 4618 /* keep one reference for attach */ 4619 qdf_atomic_inc(&peer->ref_cnt); 4620 qdf_atomic_inc(&peer->mod_refs[DP_MOD_ID_CONFIG]); 4621 4622 dp_peer_vdev_list_add(soc, vdev, peer); 4623 4624 /* TODO: See if hash based search is required */ 4625 dp_peer_find_hash_add(soc, peer); 4626 4627 /* Initialize the peer state */ 4628 peer->state = OL_TXRX_PEER_STATE_DISC; 4629 4630 dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_CREATE, 4631 peer, vdev, 0); 4632 dp_info("vdev %pK created peer %pK ("QDF_MAC_ADDR_FMT") vdev_ref_cnt " 4633 "%d peer_ref_cnt: %d", 4634 vdev, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw), 4635 qdf_atomic_read(&vdev->ref_cnt), 4636 qdf_atomic_read(&peer->ref_cnt)); 4637 /* 4638 * For every peer MAp message search and set if bss_peer 4639 */ 4640 if (qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw, 4641 QDF_MAC_ADDR_SIZE) == 0 && 4642 (wlan_op_mode_sta != vdev->opmode)) { 4643 dp_info("vdev bss_peer!!"); 4644 peer->bss_peer = 1; 4645 if (peer->txrx_peer) 4646 peer->txrx_peer->bss_peer = 1; 4647 } 4648 4649 if (wlan_op_mode_sta == vdev->opmode && 4650 qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw, 4651 QDF_MAC_ADDR_SIZE) == 0) { 4652 peer->sta_self_peer = 1; 4653 } 4654 4655 if (dp_peer_rx_tids_create(peer) != QDF_STATUS_SUCCESS) { 4656 dp_alert("RX tid alloc fail for peer %pK (" QDF_MAC_ADDR_FMT ")", 4657 peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 4658 goto fail; 4659 } 4660 4661 peer->valid = 1; 4662 dp_local_peer_id_alloc(pdev, peer); 4663 DP_STATS_INIT(peer); 4664 4665 if (dp_peer_sawf_ctx_alloc(soc, peer) != QDF_STATUS_SUCCESS) 4666 dp_warn("peer sawf context alloc failed"); 4667 4668 dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT); 4669 4670 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4671 4672 return QDF_STATUS_SUCCESS; 4673 fail: 4674 qdf_mem_free(peer); 4675 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 4676 4677 return QDF_STATUS_E_FAILURE; 4678 } 4679 4680 QDF_STATUS dp_peer_legacy_setup(struct dp_soc *soc, struct dp_peer *peer) 4681 { 4682 /* txrx_peer might exist already in peer reuse case */ 4683 if (peer->txrx_peer) 4684 return QDF_STATUS_SUCCESS; 4685 4686 if (dp_txrx_peer_attach(soc, peer) != 4687 QDF_STATUS_SUCCESS) { 4688 dp_err("peer txrx ctx alloc failed"); 4689 return QDF_STATUS_E_FAILURE; 4690 } 4691 4692 return QDF_STATUS_SUCCESS; 4693 } 4694 4695 #ifdef WLAN_FEATURE_11BE_MLO 4696 QDF_STATUS dp_peer_mlo_setup( 4697 struct dp_soc *soc, 4698 struct dp_peer *peer, 4699 uint8_t vdev_id, 4700 struct cdp_peer_setup_info *setup_info) 4701 { 4702 struct dp_peer *mld_peer = NULL; 4703 struct cdp_txrx_peer_params_update params = {0}; 4704 4705 /* Non-MLO connection, do nothing */ 4706 if (!setup_info || !setup_info->mld_peer_mac) 4707 return QDF_STATUS_SUCCESS; 4708 4709 dp_cfg_event_record_peer_setup_evt(soc, DP_CFG_EVENT_MLO_SETUP, 4710 peer, NULL, vdev_id, setup_info); 4711 dp_info("link peer: " QDF_MAC_ADDR_FMT "mld peer: " QDF_MAC_ADDR_FMT 4712 "first_link %d, primary_link %d", 4713 QDF_MAC_ADDR_REF(peer->mac_addr.raw), 4714 QDF_MAC_ADDR_REF(setup_info->mld_peer_mac), 4715 setup_info->is_first_link, 4716 setup_info->is_primary_link); 4717 4718 /* if this is the first link peer */ 4719 if (setup_info->is_first_link) 4720 /* create MLD peer */ 4721 dp_peer_create_wifi3((struct cdp_soc_t *)soc, 4722 vdev_id, 4723 setup_info->mld_peer_mac, 4724 CDP_MLD_PEER_TYPE); 4725 4726 if (peer->vdev->opmode == wlan_op_mode_sta && 4727 setup_info->is_primary_link) { 4728 struct cdp_txrx_peer_params_update params = {0}; 4729 4730 params.chip_id = dp_mlo_get_chip_id(soc); 4731 params.pdev_id = peer->vdev->pdev->pdev_id; 4732 params.osif_vdev = peer->vdev->osif_vdev; 4733 4734 dp_wdi_event_handler( 4735 WDI_EVENT_STA_PRIMARY_UMAC_UPDATE, 4736 soc, 4737 (void *)¶ms, peer->peer_id, 4738 WDI_NO_VAL, params.pdev_id); 4739 } 4740 4741 peer->first_link = setup_info->is_first_link; 4742 peer->primary_link = setup_info->is_primary_link; 4743 mld_peer = dp_mld_peer_find_hash_find(soc, 4744 setup_info->mld_peer_mac, 4745 0, vdev_id, DP_MOD_ID_CDP); 4746 if (mld_peer) { 4747 if (setup_info->is_first_link) { 4748 /* assign rx_tid to mld peer */ 4749 mld_peer->rx_tid = peer->rx_tid; 4750 /* no cdp_peer_setup for MLD peer, 4751 * set it for addba processing 4752 */ 4753 qdf_atomic_set(&mld_peer->is_default_route_set, 1); 4754 } else { 4755 /* free link peer original rx_tids mem */ 4756 dp_peer_rx_tids_destroy(peer); 4757 /* assign mld peer rx_tid to link peer */ 4758 peer->rx_tid = mld_peer->rx_tid; 4759 } 4760 4761 if (setup_info->is_primary_link && 4762 !setup_info->is_first_link) { 4763 struct dp_vdev *prev_vdev; 4764 /* 4765 * if first link is not the primary link, 4766 * then need to change mld_peer->vdev as 4767 * primary link dp_vdev is not same one 4768 * during mld peer creation. 4769 */ 4770 prev_vdev = mld_peer->vdev; 4771 dp_info("Primary link is not the first link. vdev: %pK," 4772 "vdev_id %d vdev_ref_cnt %d", 4773 mld_peer->vdev, vdev_id, 4774 qdf_atomic_read(&mld_peer->vdev->ref_cnt)); 4775 /* release the ref to original dp_vdev */ 4776 dp_vdev_unref_delete(soc, mld_peer->vdev, 4777 DP_MOD_ID_CHILD); 4778 /* 4779 * get the ref to new dp_vdev, 4780 * increase dp_vdev ref_cnt 4781 */ 4782 mld_peer->vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 4783 DP_MOD_ID_CHILD); 4784 mld_peer->txrx_peer->vdev = mld_peer->vdev; 4785 4786 dp_cfg_event_record_mlo_setup_vdev_update_evt( 4787 soc, mld_peer, prev_vdev, 4788 mld_peer->vdev); 4789 4790 params.osif_vdev = (void *)peer->vdev->osif_vdev; 4791 params.peer_mac = mld_peer->mac_addr.raw; 4792 params.chip_id = dp_mlo_get_chip_id(soc); 4793 params.pdev_id = peer->vdev->pdev->pdev_id; 4794 4795 dp_wdi_event_handler( 4796 WDI_EVENT_PEER_PRIMARY_UMAC_UPDATE, 4797 soc, (void *)¶ms, peer->peer_id, 4798 WDI_NO_VAL, params.pdev_id); 4799 } 4800 4801 /* associate mld and link peer */ 4802 dp_link_peer_add_mld_peer(peer, mld_peer); 4803 dp_mld_peer_add_link_peer(mld_peer, peer); 4804 4805 mld_peer->txrx_peer->is_mld_peer = 1; 4806 dp_peer_unref_delete(mld_peer, DP_MOD_ID_CDP); 4807 } else { 4808 peer->mld_peer = NULL; 4809 dp_err("mld peer" QDF_MAC_ADDR_FMT "not found!", 4810 QDF_MAC_ADDR_REF(setup_info->mld_peer_mac)); 4811 return QDF_STATUS_E_FAILURE; 4812 } 4813 4814 return QDF_STATUS_SUCCESS; 4815 } 4816 4817 /** 4818 * dp_mlo_peer_authorize() - authorize MLO peer 4819 * @soc: soc handle 4820 * @peer: pointer to link peer 4821 * 4822 * Return: void 4823 */ 4824 static void dp_mlo_peer_authorize(struct dp_soc *soc, 4825 struct dp_peer *peer) 4826 { 4827 int i; 4828 struct dp_peer *link_peer = NULL; 4829 struct dp_peer *mld_peer = peer->mld_peer; 4830 struct dp_mld_link_peers link_peers_info; 4831 4832 if (!mld_peer) 4833 return; 4834 4835 /* get link peers with reference */ 4836 dp_get_link_peers_ref_from_mld_peer(soc, mld_peer, 4837 &link_peers_info, 4838 DP_MOD_ID_CDP); 4839 4840 for (i = 0; i < link_peers_info.num_links; i++) { 4841 link_peer = link_peers_info.link_peers[i]; 4842 4843 if (!link_peer->authorize) { 4844 dp_release_link_peers_ref(&link_peers_info, 4845 DP_MOD_ID_CDP); 4846 mld_peer->authorize = false; 4847 return; 4848 } 4849 } 4850 4851 /* if we are here all link peers are authorized, 4852 * authorize ml_peer also 4853 */ 4854 mld_peer->authorize = true; 4855 4856 /* release link peers reference */ 4857 dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP); 4858 } 4859 #endif 4860 4861 /** 4862 * dp_peer_setup_wifi3_wrapper() - initialize the peer 4863 * @soc_hdl: soc handle object 4864 * @vdev_id : vdev_id of vdev object 4865 * @peer_mac: Peer's mac address 4866 * @setup_info: peer setup info for MLO 4867 * 4868 * Return: QDF_STATUS 4869 */ 4870 static QDF_STATUS 4871 dp_peer_setup_wifi3_wrapper(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 4872 uint8_t *peer_mac, 4873 struct cdp_peer_setup_info *setup_info) 4874 { 4875 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 4876 4877 return soc->arch_ops.txrx_peer_setup(soc_hdl, vdev_id, 4878 peer_mac, setup_info); 4879 } 4880 4881 /** 4882 * dp_cp_peer_del_resp_handler() - Handle the peer delete response 4883 * @soc_hdl: Datapath SOC handle 4884 * @vdev_id: id of virtual device object 4885 * @mac_addr: Mac address of the peer 4886 * 4887 * Return: QDF_STATUS 4888 */ 4889 static QDF_STATUS dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl, 4890 uint8_t vdev_id, 4891 uint8_t *mac_addr) 4892 { 4893 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 4894 struct dp_ast_entry *ast_entry = NULL; 4895 txrx_ast_free_cb cb = NULL; 4896 void *cookie; 4897 4898 if (soc->ast_offload_support) 4899 return QDF_STATUS_E_INVAL; 4900 4901 qdf_spin_lock_bh(&soc->ast_lock); 4902 4903 ast_entry = 4904 dp_peer_ast_hash_find_by_vdevid(soc, mac_addr, 4905 vdev_id); 4906 4907 /* in case of qwrap we have multiple BSS peers 4908 * with same mac address 4909 * 4910 * AST entry for this mac address will be created 4911 * only for one peer hence it will be NULL here 4912 */ 4913 if ((!ast_entry || !ast_entry->delete_in_progress) || 4914 (ast_entry->peer_id != HTT_INVALID_PEER)) { 4915 qdf_spin_unlock_bh(&soc->ast_lock); 4916 return QDF_STATUS_E_FAILURE; 4917 } 4918 4919 if (ast_entry->is_mapped) 4920 soc->ast_table[ast_entry->ast_idx] = NULL; 4921 4922 DP_STATS_INC(soc, ast.deleted, 1); 4923 dp_peer_ast_hash_remove(soc, ast_entry); 4924 4925 cb = ast_entry->callback; 4926 cookie = ast_entry->cookie; 4927 ast_entry->callback = NULL; 4928 ast_entry->cookie = NULL; 4929 4930 soc->num_ast_entries--; 4931 qdf_spin_unlock_bh(&soc->ast_lock); 4932 4933 if (cb) { 4934 cb(soc->ctrl_psoc, 4935 dp_soc_to_cdp_soc(soc), 4936 cookie, 4937 CDP_TXRX_AST_DELETED); 4938 } 4939 qdf_mem_free(ast_entry); 4940 4941 return QDF_STATUS_SUCCESS; 4942 } 4943 4944 #ifdef WLAN_SUPPORT_MSCS 4945 /** 4946 * dp_record_mscs_params() - Record MSCS parameters sent by the STA in 4947 * the MSCS Request to the AP. 4948 * @soc_hdl: Datapath soc handle 4949 * @peer_mac: STA Mac address 4950 * @vdev_id: ID of the vdev handle 4951 * @mscs_params: Structure having MSCS parameters obtained 4952 * from handshake 4953 * @active: Flag to set MSCS active/inactive 4954 * 4955 * The AP makes a note of these parameters while comparing the MSDUs 4956 * sent by the STA, to send the downlink traffic with correct User 4957 * priority. 4958 * 4959 * Return: QDF_STATUS - Success/Invalid 4960 */ 4961 static QDF_STATUS 4962 dp_record_mscs_params(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, 4963 uint8_t vdev_id, struct cdp_mscs_params *mscs_params, 4964 bool active) 4965 { 4966 struct dp_peer *peer; 4967 struct dp_peer *tgt_peer; 4968 QDF_STATUS status = QDF_STATUS_E_INVAL; 4969 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 4970 4971 peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, 4972 DP_MOD_ID_CDP); 4973 4974 if (!peer) { 4975 dp_err("Peer is NULL!"); 4976 goto fail; 4977 } 4978 4979 tgt_peer = dp_get_tgt_peer_from_peer(peer); 4980 if (!tgt_peer) 4981 goto fail; 4982 4983 if (!active) { 4984 dp_info("MSCS Procedure is terminated"); 4985 tgt_peer->mscs_active = active; 4986 goto fail; 4987 } 4988 4989 if (mscs_params->classifier_type == IEEE80211_TCLAS_MASK_CLA_TYPE_4) { 4990 /* Populate entries inside IPV4 database first */ 4991 tgt_peer->mscs_ipv4_parameter.user_priority_bitmap = 4992 mscs_params->user_pri_bitmap; 4993 tgt_peer->mscs_ipv4_parameter.user_priority_limit = 4994 mscs_params->user_pri_limit; 4995 tgt_peer->mscs_ipv4_parameter.classifier_mask = 4996 mscs_params->classifier_mask; 4997 4998 /* Populate entries inside IPV6 database */ 4999 tgt_peer->mscs_ipv6_parameter.user_priority_bitmap = 5000 mscs_params->user_pri_bitmap; 5001 tgt_peer->mscs_ipv6_parameter.user_priority_limit = 5002 mscs_params->user_pri_limit; 5003 tgt_peer->mscs_ipv6_parameter.classifier_mask = 5004 mscs_params->classifier_mask; 5005 tgt_peer->mscs_active = 1; 5006 dp_info("\n\tMSCS Procedure request based parameters for "QDF_MAC_ADDR_FMT"\n" 5007 "\tClassifier_type = %d\tUser priority bitmap = %x\n" 5008 "\tUser priority limit = %x\tClassifier mask = %x", 5009 QDF_MAC_ADDR_REF(peer_mac), 5010 mscs_params->classifier_type, 5011 tgt_peer->mscs_ipv4_parameter.user_priority_bitmap, 5012 tgt_peer->mscs_ipv4_parameter.user_priority_limit, 5013 tgt_peer->mscs_ipv4_parameter.classifier_mask); 5014 } 5015 5016 status = QDF_STATUS_SUCCESS; 5017 fail: 5018 if (peer) 5019 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5020 return status; 5021 } 5022 #endif 5023 5024 /** 5025 * dp_get_sec_type() - Get the security type 5026 * @soc: soc handle 5027 * @vdev_id: id of dp handle 5028 * @peer_mac: mac of datapath PEER handle 5029 * @sec_idx: Security id (mcast, ucast) 5030 * 5031 * return sec_type: Security type 5032 */ 5033 static int dp_get_sec_type(struct cdp_soc_t *soc, uint8_t vdev_id, 5034 uint8_t *peer_mac, uint8_t sec_idx) 5035 { 5036 int sec_type = 0; 5037 struct dp_peer *peer = 5038 dp_peer_get_tgt_peer_hash_find((struct dp_soc *)soc, 5039 peer_mac, 0, vdev_id, 5040 DP_MOD_ID_CDP); 5041 5042 if (!peer) { 5043 dp_cdp_err("%pK: Peer is NULL!\n", (struct dp_soc *)soc); 5044 return sec_type; 5045 } 5046 5047 if (!peer->txrx_peer) { 5048 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5049 dp_peer_debug("%pK: txrx peer is NULL!\n", soc); 5050 return sec_type; 5051 } 5052 sec_type = peer->txrx_peer->security[sec_idx].sec_type; 5053 5054 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5055 return sec_type; 5056 } 5057 5058 /** 5059 * dp_peer_authorize() - authorize txrx peer 5060 * @soc_hdl: soc handle 5061 * @vdev_id: id of dp handle 5062 * @peer_mac: mac of datapath PEER handle 5063 * @authorize: 5064 * 5065 * Return: QDF_STATUS 5066 * 5067 */ 5068 static QDF_STATUS 5069 dp_peer_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 5070 uint8_t *peer_mac, uint32_t authorize) 5071 { 5072 QDF_STATUS status = QDF_STATUS_SUCCESS; 5073 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 5074 struct dp_peer *peer = dp_peer_get_tgt_peer_hash_find(soc, peer_mac, 5075 0, vdev_id, 5076 DP_MOD_ID_CDP); 5077 5078 if (!peer) { 5079 dp_cdp_debug("%pK: Peer is NULL!\n", soc); 5080 status = QDF_STATUS_E_FAILURE; 5081 } else { 5082 peer->authorize = authorize ? 1 : 0; 5083 if (peer->txrx_peer) 5084 peer->txrx_peer->authorize = peer->authorize; 5085 5086 if (!peer->authorize) 5087 dp_peer_flush_frags(soc_hdl, vdev_id, peer_mac); 5088 5089 dp_mlo_peer_authorize(soc, peer); 5090 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5091 } 5092 5093 return status; 5094 } 5095 5096 /** 5097 * dp_peer_get_authorize() - get peer authorize status 5098 * @soc_hdl: soc handle 5099 * @vdev_id: id of dp handle 5100 * @peer_mac: mac of datapath PEER handle 5101 * 5102 * Return: true is peer is authorized, false otherwise 5103 */ 5104 static bool 5105 dp_peer_get_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 5106 uint8_t *peer_mac) 5107 { 5108 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 5109 bool authorize = false; 5110 struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 5111 0, vdev_id, 5112 DP_MOD_ID_CDP); 5113 5114 if (!peer) { 5115 dp_cdp_debug("%pK: Peer is NULL!\n", soc); 5116 return authorize; 5117 } 5118 5119 authorize = peer->authorize; 5120 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5121 5122 return authorize; 5123 } 5124 5125 void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev, 5126 enum dp_mod_id mod_id) 5127 { 5128 ol_txrx_vdev_delete_cb vdev_delete_cb = NULL; 5129 void *vdev_delete_context = NULL; 5130 uint8_t vdev_id = vdev->vdev_id; 5131 struct dp_pdev *pdev = vdev->pdev; 5132 struct dp_vdev *tmp_vdev = NULL; 5133 uint8_t found = 0; 5134 5135 QDF_ASSERT(qdf_atomic_dec_return(&vdev->mod_refs[mod_id]) >= 0); 5136 5137 /* Return if this is not the last reference*/ 5138 if (!qdf_atomic_dec_and_test(&vdev->ref_cnt)) 5139 return; 5140 5141 /* 5142 * This should be set as last reference need to released 5143 * after cdp_vdev_detach() is called 5144 * 5145 * if this assert is hit there is a ref count issue 5146 */ 5147 QDF_ASSERT(vdev->delete.pending); 5148 5149 vdev_delete_cb = vdev->delete.callback; 5150 vdev_delete_context = vdev->delete.context; 5151 5152 dp_info("deleting vdev object %pK ("QDF_MAC_ADDR_FMT")- its last peer is done", 5153 vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); 5154 5155 if (wlan_op_mode_monitor == vdev->opmode) { 5156 dp_monitor_vdev_delete(soc, vdev); 5157 goto free_vdev; 5158 } 5159 5160 /* all peers are gone, go ahead and delete it */ 5161 dp_tx_flow_pool_unmap_handler(pdev, vdev_id, 5162 FLOW_TYPE_VDEV, vdev_id); 5163 dp_tx_vdev_detach(vdev); 5164 dp_monitor_vdev_detach(vdev); 5165 5166 free_vdev: 5167 qdf_spinlock_destroy(&vdev->peer_list_lock); 5168 5169 qdf_spin_lock_bh(&soc->inactive_vdev_list_lock); 5170 TAILQ_FOREACH(tmp_vdev, &soc->inactive_vdev_list, 5171 inactive_list_elem) { 5172 if (tmp_vdev == vdev) { 5173 found = 1; 5174 break; 5175 } 5176 } 5177 if (found) 5178 TAILQ_REMOVE(&soc->inactive_vdev_list, vdev, 5179 inactive_list_elem); 5180 /* delete this peer from the list */ 5181 qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock); 5182 5183 dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_UNREF_DEL, 5184 vdev); 5185 dp_info("deleting vdev object %pK ("QDF_MAC_ADDR_FMT")", 5186 vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); 5187 wlan_minidump_remove(vdev, sizeof(*vdev), soc->ctrl_psoc, 5188 WLAN_MD_DP_VDEV, "dp_vdev"); 5189 qdf_mem_free(vdev); 5190 vdev = NULL; 5191 5192 if (vdev_delete_cb) 5193 vdev_delete_cb(vdev_delete_context); 5194 } 5195 5196 qdf_export_symbol(dp_vdev_unref_delete); 5197 5198 void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id) 5199 { 5200 struct dp_vdev *vdev = peer->vdev; 5201 struct dp_pdev *pdev = vdev->pdev; 5202 struct dp_soc *soc = pdev->soc; 5203 uint16_t peer_id; 5204 struct dp_peer *tmp_peer; 5205 bool found = false; 5206 5207 if (mod_id > DP_MOD_ID_RX) 5208 QDF_ASSERT(qdf_atomic_dec_return(&peer->mod_refs[mod_id]) >= 0); 5209 5210 /* 5211 * Hold the lock all the way from checking if the peer ref count 5212 * is zero until the peer references are removed from the hash 5213 * table and vdev list (if the peer ref count is zero). 5214 * This protects against a new HL tx operation starting to use the 5215 * peer object just after this function concludes it's done being used. 5216 * Furthermore, the lock needs to be held while checking whether the 5217 * vdev's list of peers is empty, to make sure that list is not modified 5218 * concurrently with the empty check. 5219 */ 5220 if (qdf_atomic_dec_and_test(&peer->ref_cnt)) { 5221 peer_id = peer->peer_id; 5222 5223 /* 5224 * Make sure that the reference to the peer in 5225 * peer object map is removed 5226 */ 5227 QDF_ASSERT(peer_id == HTT_INVALID_PEER); 5228 5229 dp_peer_info("Deleting peer %pK ("QDF_MAC_ADDR_FMT")", peer, 5230 QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 5231 5232 dp_peer_sawf_ctx_free(soc, peer); 5233 5234 wlan_minidump_remove(peer, sizeof(*peer), soc->ctrl_psoc, 5235 WLAN_MD_DP_PEER, "dp_peer"); 5236 5237 qdf_spin_lock_bh(&soc->inactive_peer_list_lock); 5238 TAILQ_FOREACH(tmp_peer, &soc->inactive_peer_list, 5239 inactive_list_elem) { 5240 if (tmp_peer == peer) { 5241 found = 1; 5242 break; 5243 } 5244 } 5245 if (found) 5246 TAILQ_REMOVE(&soc->inactive_peer_list, peer, 5247 inactive_list_elem); 5248 /* delete this peer from the list */ 5249 qdf_spin_unlock_bh(&soc->inactive_peer_list_lock); 5250 DP_AST_ASSERT(TAILQ_EMPTY(&peer->ast_entry_list)); 5251 dp_peer_update_state(soc, peer, DP_PEER_STATE_FREED); 5252 5253 /* cleanup the peer data */ 5254 dp_peer_cleanup(vdev, peer); 5255 5256 if (!IS_MLO_DP_MLD_PEER(peer)) 5257 dp_monitor_peer_detach(soc, peer); 5258 5259 qdf_spinlock_destroy(&peer->peer_state_lock); 5260 5261 dp_txrx_peer_detach(soc, peer); 5262 dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_UNREF_DEL, 5263 peer, vdev, 0); 5264 qdf_mem_free(peer); 5265 5266 /* 5267 * Decrement ref count taken at peer create 5268 */ 5269 dp_peer_info("Deleted peer. Unref vdev %pK, vdev_ref_cnt %d", 5270 vdev, qdf_atomic_read(&vdev->ref_cnt)); 5271 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CHILD); 5272 } 5273 } 5274 5275 qdf_export_symbol(dp_peer_unref_delete); 5276 5277 void dp_txrx_peer_unref_delete(dp_txrx_ref_handle handle, 5278 enum dp_mod_id mod_id) 5279 { 5280 dp_peer_unref_delete((struct dp_peer *)handle, mod_id); 5281 } 5282 5283 qdf_export_symbol(dp_txrx_peer_unref_delete); 5284 5285 /** 5286 * dp_peer_delete_wifi3() - Delete txrx peer 5287 * @soc_hdl: soc handle 5288 * @vdev_id: id of dp handle 5289 * @peer_mac: mac of datapath PEER handle 5290 * @bitmap: bitmap indicating special handling of request. 5291 * @peer_type: peer type (link or MLD) 5292 * 5293 */ 5294 static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, 5295 uint8_t vdev_id, 5296 uint8_t *peer_mac, uint32_t bitmap, 5297 enum cdp_peer_type peer_type) 5298 { 5299 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5300 struct dp_peer *peer; 5301 struct cdp_peer_info peer_info = { 0 }; 5302 struct dp_vdev *vdev = NULL; 5303 5304 DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, 5305 false, peer_type); 5306 peer = dp_peer_hash_find_wrapper(soc, &peer_info, DP_MOD_ID_CDP); 5307 5308 /* Peer can be null for monitor vap mac address */ 5309 if (!peer) { 5310 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 5311 "%s: Invalid peer\n", __func__); 5312 return QDF_STATUS_E_FAILURE; 5313 } 5314 5315 if (!peer->valid) { 5316 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5317 dp_err("Invalid peer: "QDF_MAC_ADDR_FMT, 5318 QDF_MAC_ADDR_REF(peer_mac)); 5319 return QDF_STATUS_E_ALREADY; 5320 } 5321 5322 vdev = peer->vdev; 5323 5324 if (!vdev) { 5325 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5326 return QDF_STATUS_E_FAILURE; 5327 } 5328 5329 peer->valid = 0; 5330 5331 dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_DELETE, peer, 5332 vdev, 0); 5333 dp_init_info("%pK: peer %pK (" QDF_MAC_ADDR_FMT ") pending-refs %d", 5334 soc, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw), 5335 qdf_atomic_read(&peer->ref_cnt)); 5336 5337 dp_peer_rx_reo_shared_qaddr_delete(soc, peer); 5338 5339 dp_local_peer_id_free(peer->vdev->pdev, peer); 5340 5341 /* Drop all rx packets before deleting peer */ 5342 dp_clear_peer_internal(soc, peer); 5343 5344 qdf_spinlock_destroy(&peer->peer_info_lock); 5345 dp_peer_multipass_list_remove(peer); 5346 5347 /* remove the reference to the peer from the hash table */ 5348 dp_peer_find_hash_remove(soc, peer); 5349 5350 dp_peer_vdev_list_remove(soc, vdev, peer); 5351 5352 dp_peer_mlo_delete(peer); 5353 5354 qdf_spin_lock_bh(&soc->inactive_peer_list_lock); 5355 TAILQ_INSERT_TAIL(&soc->inactive_peer_list, peer, 5356 inactive_list_elem); 5357 qdf_spin_unlock_bh(&soc->inactive_peer_list_lock); 5358 5359 /* 5360 * Remove the reference added during peer_attach. 5361 * The peer will still be left allocated until the 5362 * PEER_UNMAP message arrives to remove the other 5363 * reference, added by the PEER_MAP message. 5364 */ 5365 dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG); 5366 /* 5367 * Remove the reference taken above 5368 */ 5369 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5370 5371 return QDF_STATUS_SUCCESS; 5372 } 5373 5374 #ifdef DP_RX_UDP_OVER_PEER_ROAM 5375 static QDF_STATUS dp_update_roaming_peer_wifi3(struct cdp_soc_t *soc_hdl, 5376 uint8_t vdev_id, 5377 uint8_t *peer_mac, 5378 uint32_t auth_status) 5379 { 5380 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5381 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 5382 DP_MOD_ID_CDP); 5383 if (!vdev) 5384 return QDF_STATUS_E_FAILURE; 5385 5386 vdev->roaming_peer_status = auth_status; 5387 qdf_mem_copy(vdev->roaming_peer_mac.raw, peer_mac, 5388 QDF_MAC_ADDR_SIZE); 5389 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5390 5391 return QDF_STATUS_SUCCESS; 5392 } 5393 #endif 5394 /** 5395 * dp_get_vdev_mac_addr_wifi3() - Detach txrx peer 5396 * @soc_hdl: Datapath soc handle 5397 * @vdev_id: virtual interface id 5398 * 5399 * Return: MAC address on success, NULL on failure. 5400 * 5401 */ 5402 static uint8_t *dp_get_vdev_mac_addr_wifi3(struct cdp_soc_t *soc_hdl, 5403 uint8_t vdev_id) 5404 { 5405 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5406 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 5407 DP_MOD_ID_CDP); 5408 uint8_t *mac = NULL; 5409 5410 if (!vdev) 5411 return NULL; 5412 5413 mac = vdev->mac_addr.raw; 5414 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5415 5416 return mac; 5417 } 5418 5419 /** 5420 * dp_vdev_set_wds() - Enable per packet stats 5421 * @soc_hdl: DP soc handle 5422 * @vdev_id: id of DP VDEV handle 5423 * @val: value 5424 * 5425 * Return: none 5426 */ 5427 static int dp_vdev_set_wds(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 5428 uint32_t val) 5429 { 5430 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5431 struct dp_vdev *vdev = 5432 dp_vdev_get_ref_by_id((struct dp_soc *)soc, vdev_id, 5433 DP_MOD_ID_CDP); 5434 5435 if (!vdev) 5436 return QDF_STATUS_E_FAILURE; 5437 5438 vdev->wds_enabled = val; 5439 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5440 5441 return QDF_STATUS_SUCCESS; 5442 } 5443 5444 static int dp_get_opmode(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) 5445 { 5446 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5447 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 5448 DP_MOD_ID_CDP); 5449 int opmode; 5450 5451 if (!vdev) { 5452 dp_err_rl("vdev for id %d is NULL", vdev_id); 5453 return -EINVAL; 5454 } 5455 opmode = vdev->opmode; 5456 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5457 5458 return opmode; 5459 } 5460 5461 /** 5462 * dp_get_os_rx_handles_from_vdev_wifi3() - Get os rx handles for a vdev 5463 * @soc_hdl: ol_txrx_soc_handle handle 5464 * @vdev_id: vdev id for which os rx handles are needed 5465 * @stack_fn_p: pointer to stack function pointer 5466 * @osif_vdev_p: pointer to ol_osif_vdev_handle 5467 * 5468 * Return: void 5469 */ 5470 static 5471 void dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_soc_t *soc_hdl, 5472 uint8_t vdev_id, 5473 ol_txrx_rx_fp *stack_fn_p, 5474 ol_osif_vdev_handle *osif_vdev_p) 5475 { 5476 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5477 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 5478 DP_MOD_ID_CDP); 5479 5480 if (qdf_unlikely(!vdev)) { 5481 *stack_fn_p = NULL; 5482 *osif_vdev_p = NULL; 5483 return; 5484 } 5485 *stack_fn_p = vdev->osif_rx_stack; 5486 *osif_vdev_p = vdev->osif_vdev; 5487 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5488 } 5489 5490 /** 5491 * dp_get_ctrl_pdev_from_vdev_wifi3() - Get control pdev of vdev 5492 * @soc_hdl: datapath soc handle 5493 * @vdev_id: virtual device/interface id 5494 * 5495 * Return: Handle to control pdev 5496 */ 5497 static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3( 5498 struct cdp_soc_t *soc_hdl, 5499 uint8_t vdev_id) 5500 { 5501 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5502 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 5503 DP_MOD_ID_CDP); 5504 struct dp_pdev *pdev; 5505 5506 if (!vdev) 5507 return NULL; 5508 5509 pdev = vdev->pdev; 5510 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5511 return pdev ? (struct cdp_cfg *)pdev->wlan_cfg_ctx : NULL; 5512 } 5513 5514 int32_t dp_get_tx_pending(struct cdp_pdev *pdev_handle) 5515 { 5516 struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; 5517 5518 return qdf_atomic_read(&pdev->num_tx_outstanding); 5519 } 5520 5521 /** 5522 * dp_get_peer_mac_from_peer_id() - get peer mac 5523 * @soc: CDP SoC handle 5524 * @peer_id: Peer ID 5525 * @peer_mac: MAC addr of PEER 5526 * 5527 * Return: QDF_STATUS 5528 */ 5529 static QDF_STATUS dp_get_peer_mac_from_peer_id(struct cdp_soc_t *soc, 5530 uint32_t peer_id, 5531 uint8_t *peer_mac) 5532 { 5533 struct dp_peer *peer; 5534 5535 if (soc && peer_mac) { 5536 peer = dp_peer_get_ref_by_id((struct dp_soc *)soc, 5537 (uint16_t)peer_id, 5538 DP_MOD_ID_CDP); 5539 if (peer) { 5540 qdf_mem_copy(peer_mac, peer->mac_addr.raw, 5541 QDF_MAC_ADDR_SIZE); 5542 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 5543 return QDF_STATUS_SUCCESS; 5544 } 5545 } 5546 5547 return QDF_STATUS_E_FAILURE; 5548 } 5549 5550 #ifdef MESH_MODE_SUPPORT 5551 static 5552 void dp_vdev_set_mesh_mode(struct cdp_vdev *vdev_hdl, uint32_t val) 5553 { 5554 struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; 5555 5556 dp_cdp_info("%pK: val %d", vdev->pdev->soc, val); 5557 vdev->mesh_vdev = val; 5558 if (val) 5559 vdev->skip_sw_tid_classification |= 5560 DP_TX_MESH_ENABLED; 5561 else 5562 vdev->skip_sw_tid_classification &= 5563 ~DP_TX_MESH_ENABLED; 5564 } 5565 5566 /** 5567 * dp_vdev_set_mesh_rx_filter() - to set the mesh rx filter 5568 * @vdev_hdl: virtual device object 5569 * @val: value to be set 5570 * 5571 * Return: void 5572 */ 5573 static 5574 void dp_vdev_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val) 5575 { 5576 struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; 5577 5578 dp_cdp_info("%pK: val %d", vdev->pdev->soc, val); 5579 vdev->mesh_rx_filter = val; 5580 } 5581 #endif 5582 5583 /** 5584 * dp_vdev_set_hlos_tid_override() - to set hlos tid override 5585 * @vdev: virtual device object 5586 * @val: value to be set 5587 * 5588 * Return: void 5589 */ 5590 static 5591 void dp_vdev_set_hlos_tid_override(struct dp_vdev *vdev, uint32_t val) 5592 { 5593 dp_cdp_info("%pK: val %d", vdev->pdev->soc, val); 5594 if (val) 5595 vdev->skip_sw_tid_classification |= 5596 DP_TXRX_HLOS_TID_OVERRIDE_ENABLED; 5597 else 5598 vdev->skip_sw_tid_classification &= 5599 ~DP_TXRX_HLOS_TID_OVERRIDE_ENABLED; 5600 } 5601 5602 /** 5603 * dp_vdev_get_hlos_tid_override() - to get hlos tid override flag 5604 * @vdev_hdl: virtual device object 5605 * 5606 * Return: 1 if this flag is set 5607 */ 5608 static 5609 uint8_t dp_vdev_get_hlos_tid_override(struct cdp_vdev *vdev_hdl) 5610 { 5611 struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; 5612 5613 return !!(vdev->skip_sw_tid_classification & 5614 DP_TXRX_HLOS_TID_OVERRIDE_ENABLED); 5615 } 5616 5617 #ifdef VDEV_PEER_PROTOCOL_COUNT 5618 static void dp_enable_vdev_peer_protocol_count(struct cdp_soc_t *soc_hdl, 5619 int8_t vdev_id, 5620 bool enable) 5621 { 5622 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5623 struct dp_vdev *vdev; 5624 5625 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 5626 if (!vdev) 5627 return; 5628 5629 dp_info("enable %d vdev_id %d", enable, vdev_id); 5630 vdev->peer_protocol_count_track = enable; 5631 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5632 } 5633 5634 static void dp_enable_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc_hdl, 5635 int8_t vdev_id, 5636 int drop_mask) 5637 { 5638 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5639 struct dp_vdev *vdev; 5640 5641 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 5642 if (!vdev) 5643 return; 5644 5645 dp_info("drop_mask %d vdev_id %d", drop_mask, vdev_id); 5646 vdev->peer_protocol_count_dropmask = drop_mask; 5647 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5648 } 5649 5650 static int dp_is_vdev_peer_protocol_count_enabled(struct cdp_soc_t *soc_hdl, 5651 int8_t vdev_id) 5652 { 5653 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5654 struct dp_vdev *vdev; 5655 int peer_protocol_count_track; 5656 5657 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 5658 if (!vdev) 5659 return 0; 5660 5661 dp_info("enable %d vdev_id %d", vdev->peer_protocol_count_track, 5662 vdev_id); 5663 peer_protocol_count_track = 5664 vdev->peer_protocol_count_track; 5665 5666 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5667 return peer_protocol_count_track; 5668 } 5669 5670 static int dp_get_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc_hdl, 5671 int8_t vdev_id) 5672 { 5673 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5674 struct dp_vdev *vdev; 5675 int peer_protocol_count_dropmask; 5676 5677 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 5678 if (!vdev) 5679 return 0; 5680 5681 dp_info("drop_mask %d vdev_id %d", vdev->peer_protocol_count_dropmask, 5682 vdev_id); 5683 peer_protocol_count_dropmask = 5684 vdev->peer_protocol_count_dropmask; 5685 5686 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5687 return peer_protocol_count_dropmask; 5688 } 5689 5690 #endif 5691 5692 bool dp_check_pdev_exists(struct dp_soc *soc, struct dp_pdev *data) 5693 { 5694 uint8_t pdev_count; 5695 5696 for (pdev_count = 0; pdev_count < MAX_PDEV_CNT; pdev_count++) { 5697 if (soc->pdev_list[pdev_count] && 5698 soc->pdev_list[pdev_count] == data) 5699 return true; 5700 } 5701 return false; 5702 } 5703 5704 void dp_aggregate_vdev_stats(struct dp_vdev *vdev, 5705 struct cdp_vdev_stats *vdev_stats) 5706 { 5707 5708 if (!vdev || !vdev->pdev) 5709 return; 5710 5711 dp_update_vdev_ingress_stats(vdev); 5712 5713 qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); 5714 5715 dp_vdev_iterate_peer(vdev, dp_update_vdev_stats, vdev_stats, 5716 DP_MOD_ID_GENERIC_STATS); 5717 5718 dp_update_vdev_rate_stats(vdev_stats, &vdev->stats); 5719 5720 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 5721 dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc, 5722 vdev_stats, vdev->vdev_id, 5723 UPDATE_VDEV_STATS, vdev->pdev->pdev_id); 5724 #endif 5725 } 5726 5727 void dp_aggregate_pdev_stats(struct dp_pdev *pdev) 5728 { 5729 struct dp_vdev *vdev = NULL; 5730 struct dp_soc *soc; 5731 struct cdp_vdev_stats *vdev_stats = 5732 qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats)); 5733 5734 if (!vdev_stats) { 5735 dp_cdp_err("%pK: DP alloc failure - unable to get alloc vdev stats", 5736 pdev->soc); 5737 return; 5738 } 5739 5740 soc = pdev->soc; 5741 5742 qdf_mem_zero(&pdev->stats.tx, sizeof(pdev->stats.tx)); 5743 qdf_mem_zero(&pdev->stats.rx, sizeof(pdev->stats.rx)); 5744 qdf_mem_zero(&pdev->stats.tx_i, sizeof(pdev->stats.tx_i)); 5745 qdf_mem_zero(&pdev->stats.rx_i, sizeof(pdev->stats.rx_i)); 5746 5747 if (dp_monitor_is_enable_mcopy_mode(pdev)) 5748 dp_monitor_invalid_peer_update_pdev_stats(soc, pdev); 5749 5750 qdf_spin_lock_bh(&pdev->vdev_list_lock); 5751 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 5752 5753 dp_aggregate_vdev_stats(vdev, vdev_stats); 5754 dp_update_pdev_stats(pdev, vdev_stats); 5755 dp_update_pdev_ingress_stats(pdev, vdev); 5756 } 5757 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 5758 qdf_mem_free(vdev_stats); 5759 5760 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 5761 dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, &pdev->stats, 5762 pdev->pdev_id, UPDATE_PDEV_STATS, pdev->pdev_id); 5763 #endif 5764 } 5765 5766 /** 5767 * dp_vdev_getstats() - get vdev packet level stats 5768 * @vdev_handle: Datapath VDEV handle 5769 * @stats: cdp network device stats structure 5770 * 5771 * Return: QDF_STATUS 5772 */ 5773 static QDF_STATUS dp_vdev_getstats(struct cdp_vdev *vdev_handle, 5774 struct cdp_dev_stats *stats) 5775 { 5776 struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; 5777 struct dp_pdev *pdev; 5778 struct dp_soc *soc; 5779 struct cdp_vdev_stats *vdev_stats; 5780 5781 if (!vdev) 5782 return QDF_STATUS_E_FAILURE; 5783 5784 pdev = vdev->pdev; 5785 if (!pdev) 5786 return QDF_STATUS_E_FAILURE; 5787 5788 soc = pdev->soc; 5789 5790 vdev_stats = qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats)); 5791 5792 if (!vdev_stats) { 5793 dp_err("%pK: DP alloc failure - unable to get alloc vdev stats", 5794 soc); 5795 return QDF_STATUS_E_FAILURE; 5796 } 5797 5798 dp_aggregate_vdev_stats(vdev, vdev_stats); 5799 5800 stats->tx_packets = vdev_stats->tx.comp_pkt.num; 5801 stats->tx_bytes = vdev_stats->tx.comp_pkt.bytes; 5802 5803 stats->tx_errors = vdev_stats->tx.tx_failed; 5804 stats->tx_dropped = vdev_stats->tx_i.dropped.dropped_pkt.num + 5805 vdev_stats->tx_i.sg.dropped_host.num + 5806 vdev_stats->tx_i.mcast_en.dropped_map_error + 5807 vdev_stats->tx_i.mcast_en.dropped_self_mac + 5808 vdev_stats->tx_i.mcast_en.dropped_send_fail + 5809 vdev_stats->tx.nawds_mcast_drop; 5810 5811 if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) { 5812 stats->rx_packets = vdev_stats->rx.to_stack.num; 5813 stats->rx_bytes = vdev_stats->rx.to_stack.bytes; 5814 } else { 5815 stats->rx_packets = vdev_stats->rx_i.reo_rcvd_pkt.num + 5816 vdev_stats->rx_i.null_q_desc_pkt.num + 5817 vdev_stats->rx_i.routed_eapol_pkt.num; 5818 stats->rx_bytes = vdev_stats->rx_i.reo_rcvd_pkt.bytes + 5819 vdev_stats->rx_i.null_q_desc_pkt.bytes + 5820 vdev_stats->rx_i.routed_eapol_pkt.bytes; 5821 } 5822 5823 stats->rx_errors = vdev_stats->rx.err.mic_err + 5824 vdev_stats->rx.err.decrypt_err + 5825 vdev_stats->rx.err.fcserr + 5826 vdev_stats->rx.err.pn_err + 5827 vdev_stats->rx.err.oor_err + 5828 vdev_stats->rx.err.jump_2k_err + 5829 vdev_stats->rx.err.rxdma_wifi_parse_err; 5830 5831 stats->rx_dropped = vdev_stats->rx.mec_drop.num + 5832 vdev_stats->rx.multipass_rx_pkt_drop + 5833 vdev_stats->rx.peer_unauth_rx_pkt_drop + 5834 vdev_stats->rx.policy_check_drop + 5835 vdev_stats->rx.nawds_mcast_drop + 5836 vdev_stats->rx.mcast_3addr_drop + 5837 vdev_stats->rx.ppeds_drop.num; 5838 5839 qdf_mem_free(vdev_stats); 5840 5841 return QDF_STATUS_SUCCESS; 5842 } 5843 5844 /** 5845 * dp_pdev_getstats() - get pdev packet level stats 5846 * @pdev_handle: Datapath PDEV handle 5847 * @stats: cdp network device stats structure 5848 * 5849 * Return: QDF_STATUS 5850 */ 5851 static void dp_pdev_getstats(struct cdp_pdev *pdev_handle, 5852 struct cdp_dev_stats *stats) 5853 { 5854 struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; 5855 5856 dp_aggregate_pdev_stats(pdev); 5857 5858 stats->tx_packets = pdev->stats.tx.comp_pkt.num; 5859 stats->tx_bytes = pdev->stats.tx.comp_pkt.bytes; 5860 5861 stats->tx_errors = pdev->stats.tx.tx_failed; 5862 stats->tx_dropped = pdev->stats.tx_i.dropped.dropped_pkt.num + 5863 pdev->stats.tx_i.sg.dropped_host.num + 5864 pdev->stats.tx_i.mcast_en.dropped_map_error + 5865 pdev->stats.tx_i.mcast_en.dropped_self_mac + 5866 pdev->stats.tx_i.mcast_en.dropped_send_fail + 5867 pdev->stats.tx.nawds_mcast_drop + 5868 pdev->stats.tso_stats.dropped_host.num; 5869 5870 if (!wlan_cfg_get_vdev_stats_hw_offload_config(pdev->soc->wlan_cfg_ctx)) { 5871 stats->rx_packets = pdev->stats.rx.to_stack.num; 5872 stats->rx_bytes = pdev->stats.rx.to_stack.bytes; 5873 } else { 5874 stats->rx_packets = pdev->stats.rx_i.reo_rcvd_pkt.num + 5875 pdev->stats.rx_i.null_q_desc_pkt.num + 5876 pdev->stats.rx_i.routed_eapol_pkt.num; 5877 stats->rx_bytes = pdev->stats.rx_i.reo_rcvd_pkt.bytes + 5878 pdev->stats.rx_i.null_q_desc_pkt.bytes + 5879 pdev->stats.rx_i.routed_eapol_pkt.bytes; 5880 } 5881 5882 stats->rx_errors = pdev->stats.err.ip_csum_err + 5883 pdev->stats.err.tcp_udp_csum_err + 5884 pdev->stats.rx.err.mic_err + 5885 pdev->stats.rx.err.decrypt_err + 5886 pdev->stats.rx.err.fcserr + 5887 pdev->stats.rx.err.pn_err + 5888 pdev->stats.rx.err.oor_err + 5889 pdev->stats.rx.err.jump_2k_err + 5890 pdev->stats.rx.err.rxdma_wifi_parse_err; 5891 stats->rx_dropped = pdev->stats.dropped.msdu_not_done + 5892 pdev->stats.dropped.mec + 5893 pdev->stats.dropped.mesh_filter + 5894 pdev->stats.dropped.wifi_parse + 5895 pdev->stats.dropped.mon_rx_drop + 5896 pdev->stats.dropped.mon_radiotap_update_err + 5897 pdev->stats.rx.mec_drop.num + 5898 pdev->stats.rx.ppeds_drop.num + 5899 pdev->stats.rx.multipass_rx_pkt_drop + 5900 pdev->stats.rx.peer_unauth_rx_pkt_drop + 5901 pdev->stats.rx.policy_check_drop + 5902 pdev->stats.rx.nawds_mcast_drop + 5903 pdev->stats.rx.mcast_3addr_drop; 5904 } 5905 5906 /** 5907 * dp_get_device_stats() - get interface level packet stats 5908 * @soc_hdl: soc handle 5909 * @id: vdev_id or pdev_id based on type 5910 * @stats: cdp network device stats structure 5911 * @type: device type pdev/vdev 5912 * 5913 * Return: QDF_STATUS 5914 */ 5915 static QDF_STATUS dp_get_device_stats(struct cdp_soc_t *soc_hdl, uint8_t id, 5916 struct cdp_dev_stats *stats, 5917 uint8_t type) 5918 { 5919 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 5920 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5921 struct dp_vdev *vdev; 5922 5923 switch (type) { 5924 case UPDATE_VDEV_STATS: 5925 vdev = dp_vdev_get_ref_by_id(soc, id, DP_MOD_ID_CDP); 5926 5927 if (vdev) { 5928 status = dp_vdev_getstats((struct cdp_vdev *)vdev, 5929 stats); 5930 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 5931 } 5932 return status; 5933 case UPDATE_PDEV_STATS: 5934 { 5935 struct dp_pdev *pdev = 5936 dp_get_pdev_from_soc_pdev_id_wifi3( 5937 (struct dp_soc *)soc, 5938 id); 5939 if (pdev) { 5940 dp_pdev_getstats((struct cdp_pdev *)pdev, 5941 stats); 5942 return QDF_STATUS_SUCCESS; 5943 } 5944 } 5945 break; 5946 default: 5947 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 5948 "apstats cannot be updated for this input " 5949 "type %d", type); 5950 break; 5951 } 5952 5953 return QDF_STATUS_E_FAILURE; 5954 } 5955 5956 const 5957 char *dp_srng_get_str_from_hal_ring_type(enum hal_ring_type ring_type) 5958 { 5959 switch (ring_type) { 5960 case REO_DST: 5961 return "Reo_dst"; 5962 case REO_EXCEPTION: 5963 return "Reo_exception"; 5964 case REO_CMD: 5965 return "Reo_cmd"; 5966 case REO_REINJECT: 5967 return "Reo_reinject"; 5968 case REO_STATUS: 5969 return "Reo_status"; 5970 case WBM2SW_RELEASE: 5971 return "wbm2sw_release"; 5972 case TCL_DATA: 5973 return "tcl_data"; 5974 case TCL_CMD_CREDIT: 5975 return "tcl_cmd_credit"; 5976 case TCL_STATUS: 5977 return "tcl_status"; 5978 case SW2WBM_RELEASE: 5979 return "sw2wbm_release"; 5980 case RXDMA_BUF: 5981 return "Rxdma_buf"; 5982 case RXDMA_DST: 5983 return "Rxdma_dst"; 5984 case RXDMA_MONITOR_BUF: 5985 return "Rxdma_monitor_buf"; 5986 case RXDMA_MONITOR_DESC: 5987 return "Rxdma_monitor_desc"; 5988 case RXDMA_MONITOR_STATUS: 5989 return "Rxdma_monitor_status"; 5990 case RXDMA_MONITOR_DST: 5991 return "Rxdma_monitor_destination"; 5992 case WBM_IDLE_LINK: 5993 return "WBM_hw_idle_link"; 5994 case PPE2TCL: 5995 return "PPE2TCL"; 5996 case REO2PPE: 5997 return "REO2PPE"; 5998 case TX_MONITOR_DST: 5999 return "tx_monitor_destination"; 6000 case TX_MONITOR_BUF: 6001 return "tx_monitor_buf"; 6002 default: 6003 dp_err("Invalid ring type"); 6004 break; 6005 } 6006 return "Invalid"; 6007 } 6008 6009 void dp_print_napi_stats(struct dp_soc *soc) 6010 { 6011 hif_print_napi_stats(soc->hif_handle); 6012 } 6013 6014 /** 6015 * dp_txrx_host_peer_stats_clr() - Reinitialize the txrx peer stats 6016 * @soc: Datapath soc 6017 * @peer: Datatpath peer 6018 * @arg: argument to iter function 6019 * 6020 * Return: QDF_STATUS 6021 */ 6022 static inline void 6023 dp_txrx_host_peer_stats_clr(struct dp_soc *soc, 6024 struct dp_peer *peer, 6025 void *arg) 6026 { 6027 struct dp_txrx_peer *txrx_peer = NULL; 6028 struct dp_peer *tgt_peer = NULL; 6029 struct cdp_interface_peer_stats peer_stats_intf; 6030 6031 qdf_mem_zero(&peer_stats_intf, sizeof(struct cdp_interface_peer_stats)); 6032 6033 DP_STATS_CLR(peer); 6034 /* Clear monitor peer stats */ 6035 dp_monitor_peer_reset_stats(soc, peer); 6036 6037 /* Clear MLD peer stats only when link peer is primary */ 6038 if (dp_peer_is_primary_link_peer(peer)) { 6039 tgt_peer = dp_get_tgt_peer_from_peer(peer); 6040 if (tgt_peer) { 6041 DP_STATS_CLR(tgt_peer); 6042 txrx_peer = tgt_peer->txrx_peer; 6043 dp_txrx_peer_stats_clr(txrx_peer); 6044 } 6045 } 6046 6047 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 6048 dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, peer->vdev->pdev->soc, 6049 &peer_stats_intf, peer->peer_id, 6050 UPDATE_PEER_STATS, peer->vdev->pdev->pdev_id); 6051 #endif 6052 } 6053 6054 #ifdef WLAN_DP_SRNG_USAGE_WM_TRACKING 6055 static inline void dp_srng_clear_ring_usage_wm_stats(struct dp_soc *soc) 6056 { 6057 int ring; 6058 6059 for (ring = 0; ring < soc->num_reo_dest_rings; ring++) 6060 hal_srng_clear_ring_usage_wm_locked(soc->hal_soc, 6061 soc->reo_dest_ring[ring].hal_srng); 6062 } 6063 #else 6064 static inline void dp_srng_clear_ring_usage_wm_stats(struct dp_soc *soc) 6065 { 6066 } 6067 #endif 6068 6069 /** 6070 * dp_txrx_host_stats_clr() - Reinitialize the txrx stats 6071 * @vdev: DP_VDEV handle 6072 * @soc: DP_SOC handle 6073 * 6074 * Return: QDF_STATUS 6075 */ 6076 static inline QDF_STATUS 6077 dp_txrx_host_stats_clr(struct dp_vdev *vdev, struct dp_soc *soc) 6078 { 6079 if (!vdev || !vdev->pdev) 6080 return QDF_STATUS_E_FAILURE; 6081 6082 /* 6083 * if NSS offload is enabled, then send message 6084 * to NSS FW to clear the stats. Once NSS FW clears the statistics 6085 * then clear host statistics. 6086 */ 6087 if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) { 6088 if (soc->cdp_soc.ol_ops->nss_stats_clr) 6089 soc->cdp_soc.ol_ops->nss_stats_clr(soc->ctrl_psoc, 6090 vdev->vdev_id); 6091 } 6092 6093 dp_vdev_stats_hw_offload_target_clear(soc, vdev->pdev->pdev_id, 6094 (1 << vdev->vdev_id)); 6095 6096 DP_STATS_CLR(vdev->pdev); 6097 DP_STATS_CLR(vdev->pdev->soc); 6098 DP_STATS_CLR(vdev); 6099 6100 hif_clear_napi_stats(vdev->pdev->soc->hif_handle); 6101 6102 dp_vdev_iterate_peer(vdev, dp_txrx_host_peer_stats_clr, NULL, 6103 DP_MOD_ID_GENERIC_STATS); 6104 6105 dp_srng_clear_ring_usage_wm_stats(soc); 6106 6107 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 6108 dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc, 6109 &vdev->stats, vdev->vdev_id, 6110 UPDATE_VDEV_STATS, vdev->pdev->pdev_id); 6111 #endif 6112 return QDF_STATUS_SUCCESS; 6113 } 6114 6115 /** 6116 * dp_get_peer_calibr_stats()- Get peer calibrated stats 6117 * @peer: Datapath peer 6118 * @peer_stats: buffer for peer stats 6119 * 6120 * Return: none 6121 */ 6122 static inline 6123 void dp_get_peer_calibr_stats(struct dp_peer *peer, 6124 struct cdp_peer_stats *peer_stats) 6125 { 6126 struct dp_peer *tgt_peer; 6127 6128 tgt_peer = dp_get_tgt_peer_from_peer(peer); 6129 if (!tgt_peer) 6130 return; 6131 6132 peer_stats->tx.last_per = tgt_peer->stats.tx.last_per; 6133 peer_stats->tx.tx_bytes_success_last = 6134 tgt_peer->stats.tx.tx_bytes_success_last; 6135 peer_stats->tx.tx_data_success_last = 6136 tgt_peer->stats.tx.tx_data_success_last; 6137 peer_stats->tx.tx_byte_rate = tgt_peer->stats.tx.tx_byte_rate; 6138 peer_stats->tx.tx_data_rate = tgt_peer->stats.tx.tx_data_rate; 6139 peer_stats->tx.tx_data_ucast_last = 6140 tgt_peer->stats.tx.tx_data_ucast_last; 6141 peer_stats->tx.tx_data_ucast_rate = 6142 tgt_peer->stats.tx.tx_data_ucast_rate; 6143 peer_stats->tx.inactive_time = tgt_peer->stats.tx.inactive_time; 6144 peer_stats->rx.rx_bytes_success_last = 6145 tgt_peer->stats.rx.rx_bytes_success_last; 6146 peer_stats->rx.rx_data_success_last = 6147 tgt_peer->stats.rx.rx_data_success_last; 6148 peer_stats->rx.rx_byte_rate = tgt_peer->stats.rx.rx_byte_rate; 6149 peer_stats->rx.rx_data_rate = tgt_peer->stats.rx.rx_data_rate; 6150 } 6151 6152 /** 6153 * dp_get_peer_basic_stats()- Get peer basic stats 6154 * @peer: Datapath peer 6155 * @peer_stats: buffer for peer stats 6156 * 6157 * Return: none 6158 */ 6159 static inline 6160 void dp_get_peer_basic_stats(struct dp_peer *peer, 6161 struct cdp_peer_stats *peer_stats) 6162 { 6163 struct dp_txrx_peer *txrx_peer; 6164 6165 txrx_peer = dp_get_txrx_peer(peer); 6166 if (!txrx_peer) 6167 return; 6168 6169 peer_stats->tx.comp_pkt.num += txrx_peer->comp_pkt.num; 6170 peer_stats->tx.comp_pkt.bytes += txrx_peer->comp_pkt.bytes; 6171 peer_stats->tx.tx_failed += txrx_peer->tx_failed; 6172 peer_stats->rx.to_stack.num += txrx_peer->to_stack.num; 6173 peer_stats->rx.to_stack.bytes += txrx_peer->to_stack.bytes; 6174 } 6175 6176 #ifdef QCA_ENHANCED_STATS_SUPPORT 6177 /** 6178 * dp_get_peer_per_pkt_stats()- Get peer per pkt stats 6179 * @peer: Datapath peer 6180 * @peer_stats: buffer for peer stats 6181 * 6182 * Return: none 6183 */ 6184 static inline 6185 void dp_get_peer_per_pkt_stats(struct dp_peer *peer, 6186 struct cdp_peer_stats *peer_stats) 6187 { 6188 struct dp_txrx_peer *txrx_peer; 6189 struct dp_peer_per_pkt_stats *per_pkt_stats; 6190 uint8_t inx = 0, link_id = 0; 6191 struct dp_pdev *pdev; 6192 struct dp_soc *soc; 6193 uint8_t stats_arr_size; 6194 6195 txrx_peer = dp_get_txrx_peer(peer); 6196 pdev = peer->vdev->pdev; 6197 6198 if (!txrx_peer) 6199 return; 6200 6201 if (!IS_MLO_DP_LINK_PEER(peer)) { 6202 stats_arr_size = txrx_peer->stats_arr_size; 6203 for (inx = 0; inx < stats_arr_size; inx++) { 6204 per_pkt_stats = &txrx_peer->stats[inx].per_pkt_stats; 6205 DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats); 6206 } 6207 } else { 6208 soc = pdev->soc; 6209 link_id = dp_get_peer_hw_link_id(soc, pdev); 6210 per_pkt_stats = 6211 &txrx_peer->stats[link_id].per_pkt_stats; 6212 DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats); 6213 } 6214 } 6215 6216 #ifdef WLAN_FEATURE_11BE_MLO 6217 /** 6218 * dp_get_peer_extd_stats()- Get peer extd stats 6219 * @peer: Datapath peer 6220 * @peer_stats: buffer for peer stats 6221 * 6222 * Return: none 6223 */ 6224 static inline 6225 void dp_get_peer_extd_stats(struct dp_peer *peer, 6226 struct cdp_peer_stats *peer_stats) 6227 { 6228 struct dp_soc *soc = peer->vdev->pdev->soc; 6229 6230 if (IS_MLO_DP_MLD_PEER(peer)) { 6231 uint8_t i; 6232 struct dp_peer *link_peer; 6233 struct dp_soc *link_peer_soc; 6234 struct dp_mld_link_peers link_peers_info; 6235 6236 dp_get_link_peers_ref_from_mld_peer(soc, peer, 6237 &link_peers_info, 6238 DP_MOD_ID_CDP); 6239 for (i = 0; i < link_peers_info.num_links; i++) { 6240 link_peer = link_peers_info.link_peers[i]; 6241 link_peer_soc = link_peer->vdev->pdev->soc; 6242 dp_monitor_peer_get_stats(link_peer_soc, link_peer, 6243 peer_stats, 6244 UPDATE_PEER_STATS); 6245 } 6246 dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP); 6247 } else { 6248 dp_monitor_peer_get_stats(soc, peer, peer_stats, 6249 UPDATE_PEER_STATS); 6250 } 6251 } 6252 #else 6253 static inline 6254 void dp_get_peer_extd_stats(struct dp_peer *peer, 6255 struct cdp_peer_stats *peer_stats) 6256 { 6257 struct dp_soc *soc = peer->vdev->pdev->soc; 6258 6259 dp_monitor_peer_get_stats(soc, peer, peer_stats, UPDATE_PEER_STATS); 6260 } 6261 #endif 6262 #else 6263 static inline 6264 void dp_get_peer_per_pkt_stats(struct dp_peer *peer, 6265 struct cdp_peer_stats *peer_stats) 6266 { 6267 struct dp_txrx_peer *txrx_peer; 6268 struct dp_peer_per_pkt_stats *per_pkt_stats; 6269 6270 txrx_peer = dp_get_txrx_peer(peer); 6271 if (!txrx_peer) 6272 return; 6273 6274 per_pkt_stats = &txrx_peer->stats[0].per_pkt_stats; 6275 DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats); 6276 } 6277 6278 static inline 6279 void dp_get_peer_extd_stats(struct dp_peer *peer, 6280 struct cdp_peer_stats *peer_stats) 6281 { 6282 struct dp_txrx_peer *txrx_peer; 6283 struct dp_peer_extd_stats *extd_stats; 6284 6285 txrx_peer = dp_get_txrx_peer(peer); 6286 if (qdf_unlikely(!txrx_peer)) { 6287 dp_err_rl("txrx_peer NULL"); 6288 return; 6289 } 6290 6291 extd_stats = &txrx_peer->stats[0].extd_stats; 6292 DP_UPDATE_EXTD_STATS(peer_stats, extd_stats); 6293 } 6294 #endif 6295 6296 /** 6297 * dp_get_peer_tx_per()- Get peer packet error ratio 6298 * @peer_stats: buffer for peer stats 6299 * 6300 * Return: none 6301 */ 6302 static inline 6303 void dp_get_peer_tx_per(struct cdp_peer_stats *peer_stats) 6304 { 6305 if (peer_stats->tx.tx_success.num + peer_stats->tx.retries > 0) 6306 peer_stats->tx.per = (peer_stats->tx.retries * 100) / 6307 (peer_stats->tx.tx_success.num + 6308 peer_stats->tx.retries); 6309 else 6310 peer_stats->tx.per = 0; 6311 } 6312 6313 void dp_get_peer_stats(struct dp_peer *peer, struct cdp_peer_stats *peer_stats) 6314 { 6315 dp_get_peer_calibr_stats(peer, peer_stats); 6316 6317 dp_get_peer_basic_stats(peer, peer_stats); 6318 6319 dp_get_peer_per_pkt_stats(peer, peer_stats); 6320 6321 dp_get_peer_extd_stats(peer, peer_stats); 6322 6323 dp_get_peer_tx_per(peer_stats); 6324 } 6325 6326 /** 6327 * dp_get_host_peer_stats()- function to print peer stats 6328 * @soc: dp_soc handle 6329 * @mac_addr: mac address of the peer 6330 * 6331 * Return: QDF_STATUS 6332 */ 6333 static QDF_STATUS 6334 dp_get_host_peer_stats(struct cdp_soc_t *soc, uint8_t *mac_addr) 6335 { 6336 struct dp_peer *peer = NULL; 6337 struct cdp_peer_stats *peer_stats = NULL; 6338 struct cdp_peer_info peer_info = { 0 }; 6339 6340 if (!mac_addr) { 6341 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 6342 "%s: NULL peer mac addr\n", __func__); 6343 return QDF_STATUS_E_FAILURE; 6344 } 6345 6346 DP_PEER_INFO_PARAMS_INIT(&peer_info, DP_VDEV_ALL, mac_addr, false, 6347 CDP_WILD_PEER_TYPE); 6348 6349 peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info, 6350 DP_MOD_ID_CDP); 6351 if (!peer) { 6352 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 6353 "%s: Invalid peer\n", __func__); 6354 return QDF_STATUS_E_FAILURE; 6355 } 6356 6357 peer_stats = qdf_mem_malloc(sizeof(struct cdp_peer_stats)); 6358 if (!peer_stats) { 6359 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 6360 "%s: Memory allocation failed for cdp_peer_stats\n", 6361 __func__); 6362 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 6363 return QDF_STATUS_E_NOMEM; 6364 } 6365 6366 qdf_mem_zero(peer_stats, sizeof(struct cdp_peer_stats)); 6367 6368 dp_get_peer_stats(peer, peer_stats); 6369 dp_print_peer_stats(peer, peer_stats); 6370 6371 dp_peer_rxtid_stats(dp_get_tgt_peer_from_peer(peer), 6372 dp_rx_tid_stats_cb, NULL); 6373 6374 qdf_mem_free(peer_stats); 6375 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 6376 6377 return QDF_STATUS_SUCCESS; 6378 } 6379 6380 /** 6381 * dp_txrx_stats_help() - Helper function for Txrx_Stats 6382 * 6383 * Return: None 6384 */ 6385 static void dp_txrx_stats_help(void) 6386 { 6387 dp_info("Command: iwpriv wlan0 txrx_stats <stats_option> <mac_id>"); 6388 dp_info("stats_option:"); 6389 dp_info(" 1 -- HTT Tx Statistics"); 6390 dp_info(" 2 -- HTT Rx Statistics"); 6391 dp_info(" 3 -- HTT Tx HW Queue Statistics"); 6392 dp_info(" 4 -- HTT Tx HW Sched Statistics"); 6393 dp_info(" 5 -- HTT Error Statistics"); 6394 dp_info(" 6 -- HTT TQM Statistics"); 6395 dp_info(" 7 -- HTT TQM CMDQ Statistics"); 6396 dp_info(" 8 -- HTT TX_DE_CMN Statistics"); 6397 dp_info(" 9 -- HTT Tx Rate Statistics"); 6398 dp_info(" 10 -- HTT Rx Rate Statistics"); 6399 dp_info(" 11 -- HTT Peer Statistics"); 6400 dp_info(" 12 -- HTT Tx SelfGen Statistics"); 6401 dp_info(" 13 -- HTT Tx MU HWQ Statistics"); 6402 dp_info(" 14 -- HTT RING_IF_INFO Statistics"); 6403 dp_info(" 15 -- HTT SRNG Statistics"); 6404 dp_info(" 16 -- HTT SFM Info Statistics"); 6405 dp_info(" 17 -- HTT PDEV_TX_MU_MIMO_SCHED INFO Statistics"); 6406 dp_info(" 18 -- HTT Peer List Details"); 6407 dp_info(" 20 -- Clear Host Statistics"); 6408 dp_info(" 21 -- Host Rx Rate Statistics"); 6409 dp_info(" 22 -- Host Tx Rate Statistics"); 6410 dp_info(" 23 -- Host Tx Statistics"); 6411 dp_info(" 24 -- Host Rx Statistics"); 6412 dp_info(" 25 -- Host AST Statistics"); 6413 dp_info(" 26 -- Host SRNG PTR Statistics"); 6414 dp_info(" 27 -- Host Mon Statistics"); 6415 dp_info(" 28 -- Host REO Queue Statistics"); 6416 dp_info(" 29 -- Host Soc cfg param Statistics"); 6417 dp_info(" 30 -- Host pdev cfg param Statistics"); 6418 dp_info(" 31 -- Host NAPI stats"); 6419 dp_info(" 32 -- Host Interrupt stats"); 6420 dp_info(" 33 -- Host FISA stats"); 6421 dp_info(" 34 -- Host Register Work stats"); 6422 dp_info(" 35 -- HW REO Queue stats"); 6423 dp_info(" 36 -- Host WBM IDLE link desc ring HP/TP"); 6424 dp_info(" 37 -- Host SRNG usage watermark stats"); 6425 } 6426 6427 #ifdef DP_UMAC_HW_RESET_SUPPORT 6428 /** 6429 * dp_umac_rst_skel_enable_update() - Update skel dbg flag for umac reset 6430 * @soc: dp soc handle 6431 * @en: ebable/disable 6432 * 6433 * Return: void 6434 */ 6435 static void dp_umac_rst_skel_enable_update(struct dp_soc *soc, bool en) 6436 { 6437 soc->umac_reset_ctx.skel_enable = en; 6438 dp_cdp_debug("UMAC HW reset debug skeleton code enabled :%u", 6439 soc->umac_reset_ctx.skel_enable); 6440 } 6441 6442 /** 6443 * dp_umac_rst_skel_enable_get() - Get skel dbg flag for umac reset 6444 * @soc: dp soc handle 6445 * 6446 * Return: enable/disable flag 6447 */ 6448 static bool dp_umac_rst_skel_enable_get(struct dp_soc *soc) 6449 { 6450 return soc->umac_reset_ctx.skel_enable; 6451 } 6452 #else 6453 static void dp_umac_rst_skel_enable_update(struct dp_soc *soc, bool en) 6454 { 6455 } 6456 6457 static bool dp_umac_rst_skel_enable_get(struct dp_soc *soc) 6458 { 6459 return false; 6460 } 6461 #endif 6462 6463 /** 6464 * dp_print_host_stats()- Function to print the stats aggregated at host 6465 * @vdev: DP_VDEV handle 6466 * @req: host stats type 6467 * @soc: dp soc handler 6468 * 6469 * Return: 0 on success, print error message in case of failure 6470 */ 6471 static int 6472 dp_print_host_stats(struct dp_vdev *vdev, 6473 struct cdp_txrx_stats_req *req, 6474 struct dp_soc *soc) 6475 { 6476 struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; 6477 enum cdp_host_txrx_stats type = 6478 dp_stats_mapping_table[req->stats][STATS_HOST]; 6479 6480 dp_aggregate_pdev_stats(pdev); 6481 6482 switch (type) { 6483 case TXRX_CLEAR_STATS: 6484 dp_txrx_host_stats_clr(vdev, soc); 6485 break; 6486 case TXRX_RX_RATE_STATS: 6487 dp_print_rx_rates(vdev); 6488 break; 6489 case TXRX_TX_RATE_STATS: 6490 dp_print_tx_rates(vdev); 6491 break; 6492 case TXRX_TX_HOST_STATS: 6493 dp_print_pdev_tx_stats(pdev); 6494 dp_print_soc_tx_stats(pdev->soc); 6495 dp_print_global_desc_count(); 6496 break; 6497 case TXRX_RX_HOST_STATS: 6498 dp_print_pdev_rx_stats(pdev); 6499 dp_print_soc_rx_stats(pdev->soc); 6500 break; 6501 case TXRX_AST_STATS: 6502 dp_print_ast_stats(pdev->soc); 6503 dp_print_mec_stats(pdev->soc); 6504 dp_print_peer_table(vdev); 6505 break; 6506 case TXRX_SRNG_PTR_STATS: 6507 dp_print_ring_stats(pdev); 6508 break; 6509 case TXRX_RX_MON_STATS: 6510 dp_monitor_print_pdev_rx_mon_stats(pdev); 6511 break; 6512 case TXRX_REO_QUEUE_STATS: 6513 dp_get_host_peer_stats((struct cdp_soc_t *)pdev->soc, 6514 req->peer_addr); 6515 break; 6516 case TXRX_SOC_CFG_PARAMS: 6517 dp_print_soc_cfg_params(pdev->soc); 6518 break; 6519 case TXRX_PDEV_CFG_PARAMS: 6520 dp_print_pdev_cfg_params(pdev); 6521 break; 6522 case TXRX_NAPI_STATS: 6523 dp_print_napi_stats(pdev->soc); 6524 break; 6525 case TXRX_SOC_INTERRUPT_STATS: 6526 dp_print_soc_interrupt_stats(pdev->soc); 6527 break; 6528 case TXRX_SOC_FSE_STATS: 6529 dp_rx_dump_fisa_table(pdev->soc); 6530 break; 6531 case TXRX_HAL_REG_WRITE_STATS: 6532 hal_dump_reg_write_stats(pdev->soc->hal_soc); 6533 hal_dump_reg_write_srng_stats(pdev->soc->hal_soc); 6534 break; 6535 case TXRX_SOC_REO_HW_DESC_DUMP: 6536 dp_get_rx_reo_queue_info((struct cdp_soc_t *)pdev->soc, 6537 vdev->vdev_id); 6538 break; 6539 case TXRX_SOC_WBM_IDLE_HPTP_DUMP: 6540 dp_dump_wbm_idle_hptp(pdev->soc, pdev); 6541 break; 6542 case TXRX_SRNG_USAGE_WM_STATS: 6543 /* Dump usage watermark stats for all SRNGs */ 6544 dp_dump_srng_high_wm_stats(soc, 0xFF); 6545 break; 6546 default: 6547 dp_info("Wrong Input For TxRx Host Stats"); 6548 dp_txrx_stats_help(); 6549 break; 6550 } 6551 return 0; 6552 } 6553 6554 /** 6555 * dp_pdev_tid_stats_ingress_inc() - increment ingress_stack counter 6556 * @pdev: pdev handle 6557 * @val: increase in value 6558 * 6559 * Return: void 6560 */ 6561 static void 6562 dp_pdev_tid_stats_ingress_inc(struct dp_pdev *pdev, uint32_t val) 6563 { 6564 pdev->stats.tid_stats.ingress_stack += val; 6565 } 6566 6567 /** 6568 * dp_pdev_tid_stats_osif_drop() - increment osif_drop counter 6569 * @pdev: pdev handle 6570 * @val: increase in value 6571 * 6572 * Return: void 6573 */ 6574 static void 6575 dp_pdev_tid_stats_osif_drop(struct dp_pdev *pdev, uint32_t val) 6576 { 6577 pdev->stats.tid_stats.osif_drop += val; 6578 } 6579 6580 /** 6581 * dp_get_fw_peer_stats()- function to print peer stats 6582 * @soc: soc handle 6583 * @pdev_id: id of the pdev handle 6584 * @mac_addr: mac address of the peer 6585 * @cap: Type of htt stats requested 6586 * @is_wait: if set, wait on completion from firmware response 6587 * 6588 * Currently Supporting only MAC ID based requests Only 6589 * 1: HTT_PEER_STATS_REQ_MODE_NO_QUERY 6590 * 2: HTT_PEER_STATS_REQ_MODE_QUERY_TQM 6591 * 3: HTT_PEER_STATS_REQ_MODE_FLUSH_TQM 6592 * 6593 * Return: QDF_STATUS 6594 */ 6595 static QDF_STATUS 6596 dp_get_fw_peer_stats(struct cdp_soc_t *soc, uint8_t pdev_id, 6597 uint8_t *mac_addr, 6598 uint32_t cap, uint32_t is_wait) 6599 { 6600 int i; 6601 uint32_t config_param0 = 0; 6602 uint32_t config_param1 = 0; 6603 uint32_t config_param2 = 0; 6604 uint32_t config_param3 = 0; 6605 struct dp_pdev *pdev = 6606 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 6607 pdev_id); 6608 6609 if (!pdev) 6610 return QDF_STATUS_E_FAILURE; 6611 6612 HTT_DBG_EXT_STATS_PEER_INFO_IS_MAC_ADDR_SET(config_param0, 1); 6613 config_param0 |= (1 << (cap + 1)); 6614 6615 for (i = 0; i < HTT_PEER_STATS_MAX_TLV; i++) { 6616 config_param1 |= (1 << i); 6617 } 6618 6619 config_param2 |= (mac_addr[0] & 0x000000ff); 6620 config_param2 |= ((mac_addr[1] << 8) & 0x0000ff00); 6621 config_param2 |= ((mac_addr[2] << 16) & 0x00ff0000); 6622 config_param2 |= ((mac_addr[3] << 24) & 0xff000000); 6623 6624 config_param3 |= (mac_addr[4] & 0x000000ff); 6625 config_param3 |= ((mac_addr[5] << 8) & 0x0000ff00); 6626 6627 if (is_wait) { 6628 qdf_event_reset(&pdev->fw_peer_stats_event); 6629 dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, 6630 config_param0, config_param1, 6631 config_param2, config_param3, 6632 0, DBG_STATS_COOKIE_DP_STATS, 0); 6633 qdf_wait_single_event(&pdev->fw_peer_stats_event, 6634 DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC); 6635 } else { 6636 dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, 6637 config_param0, config_param1, 6638 config_param2, config_param3, 6639 0, DBG_STATS_COOKIE_DEFAULT, 0); 6640 } 6641 6642 return QDF_STATUS_SUCCESS; 6643 6644 } 6645 6646 /* This struct definition will be removed from here 6647 * once it get added in FW headers*/ 6648 struct httstats_cmd_req { 6649 uint32_t config_param0; 6650 uint32_t config_param1; 6651 uint32_t config_param2; 6652 uint32_t config_param3; 6653 int cookie; 6654 u_int8_t stats_id; 6655 }; 6656 6657 /** 6658 * dp_get_htt_stats: function to process the httstas request 6659 * @soc: DP soc handle 6660 * @pdev_id: id of pdev handle 6661 * @data: pointer to request data 6662 * @data_len: length for request data 6663 * 6664 * Return: QDF_STATUS 6665 */ 6666 static QDF_STATUS 6667 dp_get_htt_stats(struct cdp_soc_t *soc, uint8_t pdev_id, void *data, 6668 uint32_t data_len) 6669 { 6670 struct httstats_cmd_req *req = (struct httstats_cmd_req *)data; 6671 struct dp_pdev *pdev = 6672 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 6673 pdev_id); 6674 6675 if (!pdev) 6676 return QDF_STATUS_E_FAILURE; 6677 6678 QDF_ASSERT(data_len == sizeof(struct httstats_cmd_req)); 6679 dp_h2t_ext_stats_msg_send(pdev, req->stats_id, 6680 req->config_param0, req->config_param1, 6681 req->config_param2, req->config_param3, 6682 req->cookie, DBG_STATS_COOKIE_DEFAULT, 0); 6683 6684 return QDF_STATUS_SUCCESS; 6685 } 6686 6687 /** 6688 * dp_set_pdev_tidmap_prty_wifi3() - update tidmap priority in pdev 6689 * @pdev: DP_PDEV handle 6690 * @prio: tidmap priority value passed by the user 6691 * 6692 * Return: QDF_STATUS_SUCCESS on success 6693 */ 6694 static QDF_STATUS dp_set_pdev_tidmap_prty_wifi3(struct dp_pdev *pdev, 6695 uint8_t prio) 6696 { 6697 struct dp_soc *soc = pdev->soc; 6698 6699 soc->tidmap_prty = prio; 6700 6701 hal_tx_set_tidmap_prty(soc->hal_soc, prio); 6702 return QDF_STATUS_SUCCESS; 6703 } 6704 6705 /** 6706 * dp_get_peer_param: function to get parameters in peer 6707 * @cdp_soc: DP soc handle 6708 * @vdev_id: id of vdev handle 6709 * @peer_mac: peer mac address 6710 * @param: parameter type to be set 6711 * @val: address of buffer 6712 * 6713 * Return: val 6714 */ 6715 static QDF_STATUS dp_get_peer_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, 6716 uint8_t *peer_mac, 6717 enum cdp_peer_param_type param, 6718 cdp_config_param_type *val) 6719 { 6720 return QDF_STATUS_SUCCESS; 6721 } 6722 6723 /** 6724 * dp_set_peer_param: function to set parameters in peer 6725 * @cdp_soc: DP soc handle 6726 * @vdev_id: id of vdev handle 6727 * @peer_mac: peer mac address 6728 * @param: parameter type to be set 6729 * @val: value of parameter to be set 6730 * 6731 * Return: 0 for success. nonzero for failure. 6732 */ 6733 static QDF_STATUS dp_set_peer_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, 6734 uint8_t *peer_mac, 6735 enum cdp_peer_param_type param, 6736 cdp_config_param_type val) 6737 { 6738 struct dp_peer *peer = 6739 dp_peer_get_tgt_peer_hash_find((struct dp_soc *)cdp_soc, 6740 peer_mac, 0, vdev_id, 6741 DP_MOD_ID_CDP); 6742 struct dp_txrx_peer *txrx_peer; 6743 6744 if (!peer) 6745 return QDF_STATUS_E_FAILURE; 6746 6747 txrx_peer = peer->txrx_peer; 6748 if (!txrx_peer) { 6749 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 6750 return QDF_STATUS_E_FAILURE; 6751 } 6752 6753 switch (param) { 6754 case CDP_CONFIG_NAWDS: 6755 txrx_peer->nawds_enabled = val.cdp_peer_param_nawds; 6756 break; 6757 case CDP_CONFIG_ISOLATION: 6758 dp_set_peer_isolation(txrx_peer, val.cdp_peer_param_isolation); 6759 break; 6760 case CDP_CONFIG_IN_TWT: 6761 txrx_peer->in_twt = !!(val.cdp_peer_param_in_twt); 6762 break; 6763 default: 6764 break; 6765 } 6766 6767 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 6768 6769 return QDF_STATUS_SUCCESS; 6770 } 6771 6772 /** 6773 * dp_get_pdev_param() - function to get parameters from pdev 6774 * @cdp_soc: DP soc handle 6775 * @pdev_id: id of pdev handle 6776 * @param: parameter type to be get 6777 * @val: buffer for value 6778 * 6779 * Return: status 6780 */ 6781 static QDF_STATUS dp_get_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, 6782 enum cdp_pdev_param_type param, 6783 cdp_config_param_type *val) 6784 { 6785 struct cdp_pdev *pdev = (struct cdp_pdev *) 6786 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, 6787 pdev_id); 6788 if (!pdev) 6789 return QDF_STATUS_E_FAILURE; 6790 6791 switch (param) { 6792 case CDP_CONFIG_VOW: 6793 val->cdp_pdev_param_cfg_vow = 6794 ((struct dp_pdev *)pdev)->delay_stats_flag; 6795 break; 6796 case CDP_TX_PENDING: 6797 val->cdp_pdev_param_tx_pending = dp_get_tx_pending(pdev); 6798 break; 6799 case CDP_FILTER_MCAST_DATA: 6800 val->cdp_pdev_param_fltr_mcast = 6801 dp_monitor_pdev_get_filter_mcast_data(pdev); 6802 break; 6803 case CDP_FILTER_NO_DATA: 6804 val->cdp_pdev_param_fltr_none = 6805 dp_monitor_pdev_get_filter_non_data(pdev); 6806 break; 6807 case CDP_FILTER_UCAST_DATA: 6808 val->cdp_pdev_param_fltr_ucast = 6809 dp_monitor_pdev_get_filter_ucast_data(pdev); 6810 break; 6811 case CDP_MONITOR_CHANNEL: 6812 val->cdp_pdev_param_monitor_chan = 6813 dp_monitor_get_chan_num((struct dp_pdev *)pdev); 6814 break; 6815 case CDP_MONITOR_FREQUENCY: 6816 val->cdp_pdev_param_mon_freq = 6817 dp_monitor_get_chan_freq((struct dp_pdev *)pdev); 6818 break; 6819 default: 6820 return QDF_STATUS_E_FAILURE; 6821 } 6822 6823 return QDF_STATUS_SUCCESS; 6824 } 6825 6826 /** 6827 * dp_set_pdev_param() - function to set parameters in pdev 6828 * @cdp_soc: DP soc handle 6829 * @pdev_id: id of pdev handle 6830 * @param: parameter type to be set 6831 * @val: value of parameter to be set 6832 * 6833 * Return: 0 for success. nonzero for failure. 6834 */ 6835 static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, 6836 enum cdp_pdev_param_type param, 6837 cdp_config_param_type val) 6838 { 6839 int target_type; 6840 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 6841 struct dp_pdev *pdev = 6842 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, 6843 pdev_id); 6844 enum reg_wifi_band chan_band; 6845 6846 if (!pdev) 6847 return QDF_STATUS_E_FAILURE; 6848 6849 target_type = hal_get_target_type(soc->hal_soc); 6850 switch (target_type) { 6851 case TARGET_TYPE_QCA6750: 6852 case TARGET_TYPE_WCN6450: 6853 pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC0_LMAC_ID; 6854 pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID; 6855 pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID; 6856 break; 6857 case TARGET_TYPE_KIWI: 6858 case TARGET_TYPE_MANGO: 6859 case TARGET_TYPE_PEACH: 6860 pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC0_LMAC_ID; 6861 pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID; 6862 pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID; 6863 break; 6864 default: 6865 pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC1_LMAC_ID; 6866 pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID; 6867 pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID; 6868 break; 6869 } 6870 6871 switch (param) { 6872 case CDP_CONFIG_TX_CAPTURE: 6873 return dp_monitor_config_debug_sniffer(pdev, 6874 val.cdp_pdev_param_tx_capture); 6875 case CDP_CONFIG_DEBUG_SNIFFER: 6876 return dp_monitor_config_debug_sniffer(pdev, 6877 val.cdp_pdev_param_dbg_snf); 6878 case CDP_CONFIG_BPR_ENABLE: 6879 return dp_monitor_set_bpr_enable(pdev, 6880 val.cdp_pdev_param_bpr_enable); 6881 case CDP_CONFIG_PRIMARY_RADIO: 6882 pdev->is_primary = val.cdp_pdev_param_primary_radio; 6883 break; 6884 case CDP_CONFIG_CAPTURE_LATENCY: 6885 pdev->latency_capture_enable = val.cdp_pdev_param_cptr_latcy; 6886 break; 6887 case CDP_INGRESS_STATS: 6888 dp_pdev_tid_stats_ingress_inc(pdev, 6889 val.cdp_pdev_param_ingrs_stats); 6890 break; 6891 case CDP_OSIF_DROP: 6892 dp_pdev_tid_stats_osif_drop(pdev, 6893 val.cdp_pdev_param_osif_drop); 6894 break; 6895 case CDP_CONFIG_ENH_RX_CAPTURE: 6896 return dp_monitor_config_enh_rx_capture(pdev, 6897 val.cdp_pdev_param_en_rx_cap); 6898 case CDP_CONFIG_ENH_TX_CAPTURE: 6899 return dp_monitor_config_enh_tx_capture(pdev, 6900 val.cdp_pdev_param_en_tx_cap); 6901 case CDP_CONFIG_HMMC_TID_OVERRIDE: 6902 pdev->hmmc_tid_override_en = val.cdp_pdev_param_hmmc_tid_ovrd; 6903 break; 6904 case CDP_CONFIG_HMMC_TID_VALUE: 6905 pdev->hmmc_tid = val.cdp_pdev_param_hmmc_tid; 6906 break; 6907 case CDP_CHAN_NOISE_FLOOR: 6908 pdev->chan_noise_floor = val.cdp_pdev_param_chn_noise_flr; 6909 break; 6910 case CDP_TIDMAP_PRTY: 6911 dp_set_pdev_tidmap_prty_wifi3(pdev, 6912 val.cdp_pdev_param_tidmap_prty); 6913 break; 6914 case CDP_FILTER_NEIGH_PEERS: 6915 dp_monitor_set_filter_neigh_peers(pdev, 6916 val.cdp_pdev_param_fltr_neigh_peers); 6917 break; 6918 case CDP_MONITOR_CHANNEL: 6919 dp_monitor_set_chan_num(pdev, val.cdp_pdev_param_monitor_chan); 6920 break; 6921 case CDP_MONITOR_FREQUENCY: 6922 chan_band = wlan_reg_freq_to_band(val.cdp_pdev_param_mon_freq); 6923 dp_monitor_set_chan_freq(pdev, val.cdp_pdev_param_mon_freq); 6924 dp_monitor_set_chan_band(pdev, chan_band); 6925 break; 6926 case CDP_CONFIG_BSS_COLOR: 6927 dp_monitor_set_bsscolor(pdev, val.cdp_pdev_param_bss_color); 6928 break; 6929 case CDP_SET_ATF_STATS_ENABLE: 6930 dp_monitor_set_atf_stats_enable(pdev, 6931 val.cdp_pdev_param_atf_stats_enable); 6932 break; 6933 case CDP_CONFIG_SPECIAL_VAP: 6934 dp_monitor_pdev_config_scan_spcl_vap(pdev, 6935 val.cdp_pdev_param_config_special_vap); 6936 dp_monitor_vdev_set_monitor_mode_buf_rings(pdev); 6937 break; 6938 case CDP_RESET_SCAN_SPCL_VAP_STATS_ENABLE: 6939 dp_monitor_pdev_reset_scan_spcl_vap_stats_enable(pdev, 6940 val.cdp_pdev_param_reset_scan_spcl_vap_stats_enable); 6941 break; 6942 case CDP_CONFIG_ENHANCED_STATS_ENABLE: 6943 pdev->enhanced_stats_en = val.cdp_pdev_param_enhanced_stats_enable; 6944 break; 6945 case CDP_ISOLATION: 6946 pdev->isolation = val.cdp_pdev_param_isolation; 6947 break; 6948 case CDP_CONFIG_UNDECODED_METADATA_CAPTURE_ENABLE: 6949 return dp_monitor_config_undecoded_metadata_capture(pdev, 6950 val.cdp_pdev_param_undecoded_metadata_enable); 6951 break; 6952 default: 6953 return QDF_STATUS_E_INVAL; 6954 } 6955 return QDF_STATUS_SUCCESS; 6956 } 6957 6958 #ifdef QCA_UNDECODED_METADATA_SUPPORT 6959 static 6960 QDF_STATUS dp_set_pdev_phyrx_error_mask(struct cdp_soc_t *cdp_soc, 6961 uint8_t pdev_id, uint32_t mask, 6962 uint32_t mask_cont) 6963 { 6964 struct dp_pdev *pdev = 6965 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, 6966 pdev_id); 6967 6968 if (!pdev) 6969 return QDF_STATUS_E_FAILURE; 6970 6971 return dp_monitor_config_undecoded_metadata_phyrx_error_mask(pdev, 6972 mask, mask_cont); 6973 } 6974 6975 static 6976 QDF_STATUS dp_get_pdev_phyrx_error_mask(struct cdp_soc_t *cdp_soc, 6977 uint8_t pdev_id, uint32_t *mask, 6978 uint32_t *mask_cont) 6979 { 6980 struct dp_pdev *pdev = 6981 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, 6982 pdev_id); 6983 6984 if (!pdev) 6985 return QDF_STATUS_E_FAILURE; 6986 6987 return dp_monitor_get_undecoded_metadata_phyrx_error_mask(pdev, 6988 mask, mask_cont); 6989 } 6990 #endif 6991 6992 #ifdef QCA_PEER_EXT_STATS 6993 static void dp_rx_update_peer_delay_stats(struct dp_soc *soc, 6994 qdf_nbuf_t nbuf) 6995 { 6996 struct dp_peer *peer = NULL; 6997 uint16_t peer_id, ring_id; 6998 uint8_t tid = qdf_nbuf_get_tid_val(nbuf); 6999 struct dp_peer_delay_stats *delay_stats = NULL; 7000 7001 peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf); 7002 if (peer_id > soc->max_peer_id) 7003 return; 7004 7005 peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_CDP); 7006 if (qdf_unlikely(!peer)) 7007 return; 7008 7009 if (qdf_unlikely(!peer->txrx_peer)) { 7010 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7011 return; 7012 } 7013 7014 if (qdf_likely(peer->txrx_peer->delay_stats)) { 7015 delay_stats = peer->txrx_peer->delay_stats; 7016 ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); 7017 dp_rx_compute_tid_delay(&delay_stats->delay_tid_stats[tid][ring_id], 7018 nbuf); 7019 } 7020 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7021 } 7022 #else 7023 static inline void dp_rx_update_peer_delay_stats(struct dp_soc *soc, 7024 qdf_nbuf_t nbuf) 7025 { 7026 } 7027 #endif 7028 7029 /** 7030 * dp_calculate_delay_stats() - function to get rx delay stats 7031 * @cdp_soc: DP soc handle 7032 * @vdev_id: id of DP vdev handle 7033 * @nbuf: skb 7034 * 7035 * Return: QDF_STATUS 7036 */ 7037 static QDF_STATUS 7038 dp_calculate_delay_stats(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, 7039 qdf_nbuf_t nbuf) 7040 { 7041 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 7042 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 7043 DP_MOD_ID_CDP); 7044 7045 if (!vdev) 7046 return QDF_STATUS_SUCCESS; 7047 7048 if (vdev->pdev->delay_stats_flag) 7049 dp_rx_compute_delay(vdev, nbuf); 7050 else 7051 dp_rx_update_peer_delay_stats(soc, nbuf); 7052 7053 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7054 return QDF_STATUS_SUCCESS; 7055 } 7056 7057 /** 7058 * dp_get_vdev_param() - function to get parameters from vdev 7059 * @cdp_soc: DP soc handle 7060 * @vdev_id: id of DP vdev handle 7061 * @param: parameter type to get value 7062 * @val: buffer address 7063 * 7064 * Return: status 7065 */ 7066 static QDF_STATUS dp_get_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, 7067 enum cdp_vdev_param_type param, 7068 cdp_config_param_type *val) 7069 { 7070 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 7071 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 7072 DP_MOD_ID_CDP); 7073 7074 if (!vdev) 7075 return QDF_STATUS_E_FAILURE; 7076 7077 switch (param) { 7078 case CDP_ENABLE_WDS: 7079 val->cdp_vdev_param_wds = vdev->wds_enabled; 7080 break; 7081 case CDP_ENABLE_MEC: 7082 val->cdp_vdev_param_mec = vdev->mec_enabled; 7083 break; 7084 case CDP_ENABLE_DA_WAR: 7085 val->cdp_vdev_param_da_war = vdev->pdev->soc->da_war_enabled; 7086 break; 7087 case CDP_ENABLE_IGMP_MCAST_EN: 7088 val->cdp_vdev_param_igmp_mcast_en = vdev->igmp_mcast_enhanc_en; 7089 break; 7090 case CDP_ENABLE_MCAST_EN: 7091 val->cdp_vdev_param_mcast_en = vdev->mcast_enhancement_en; 7092 break; 7093 case CDP_ENABLE_HLOS_TID_OVERRIDE: 7094 val->cdp_vdev_param_hlos_tid_override = 7095 dp_vdev_get_hlos_tid_override((struct cdp_vdev *)vdev); 7096 break; 7097 case CDP_ENABLE_PEER_AUTHORIZE: 7098 val->cdp_vdev_param_peer_authorize = 7099 vdev->peer_authorize; 7100 break; 7101 case CDP_TX_ENCAP_TYPE: 7102 val->cdp_vdev_param_tx_encap = vdev->tx_encap_type; 7103 break; 7104 case CDP_ENABLE_CIPHER: 7105 val->cdp_vdev_param_cipher_en = vdev->sec_type; 7106 break; 7107 #ifdef WLAN_SUPPORT_MESH_LATENCY 7108 case CDP_ENABLE_PEER_TID_LATENCY: 7109 val->cdp_vdev_param_peer_tid_latency_enable = 7110 vdev->peer_tid_latency_enabled; 7111 break; 7112 case CDP_SET_VAP_MESH_TID: 7113 val->cdp_vdev_param_mesh_tid = 7114 vdev->mesh_tid_latency_config.latency_tid; 7115 break; 7116 #endif 7117 case CDP_DROP_3ADDR_MCAST: 7118 val->cdp_drop_3addr_mcast = vdev->drop_3addr_mcast; 7119 break; 7120 case CDP_SET_MCAST_VDEV: 7121 soc->arch_ops.txrx_get_vdev_mcast_param(soc, vdev, val); 7122 break; 7123 #ifdef QCA_SUPPORT_WDS_EXTENDED 7124 case CDP_DROP_TX_MCAST: 7125 val->cdp_drop_tx_mcast = vdev->drop_tx_mcast; 7126 break; 7127 #endif 7128 7129 #ifdef MESH_MODE_SUPPORT 7130 case CDP_MESH_RX_FILTER: 7131 val->cdp_vdev_param_mesh_rx_filter = vdev->mesh_rx_filter; 7132 break; 7133 case CDP_MESH_MODE: 7134 val->cdp_vdev_param_mesh_mode = vdev->mesh_vdev; 7135 break; 7136 #endif 7137 case CDP_ENABLE_NAWDS: 7138 val->cdp_vdev_param_nawds = vdev->nawds_enabled; 7139 break; 7140 7141 case CDP_ENABLE_WRAP: 7142 val->cdp_vdev_param_wrap = vdev->wrap_vdev; 7143 break; 7144 7145 #ifdef DP_TRAFFIC_END_INDICATION 7146 case CDP_ENABLE_TRAFFIC_END_INDICATION: 7147 val->cdp_vdev_param_traffic_end_ind = vdev->traffic_end_ind_en; 7148 break; 7149 #endif 7150 7151 default: 7152 dp_cdp_err("%pK: param value %d is wrong", 7153 soc, param); 7154 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7155 return QDF_STATUS_E_FAILURE; 7156 } 7157 7158 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7159 return QDF_STATUS_SUCCESS; 7160 } 7161 7162 /** 7163 * dp_set_vdev_param() - function to set parameters in vdev 7164 * @cdp_soc: DP soc handle 7165 * @vdev_id: id of DP vdev handle 7166 * @param: parameter type to get value 7167 * @val: value 7168 * 7169 * Return: QDF_STATUS 7170 */ 7171 static QDF_STATUS 7172 dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, 7173 enum cdp_vdev_param_type param, cdp_config_param_type val) 7174 { 7175 struct dp_soc *dsoc = (struct dp_soc *)cdp_soc; 7176 struct dp_vdev *vdev = 7177 dp_vdev_get_ref_by_id(dsoc, vdev_id, DP_MOD_ID_CDP); 7178 uint32_t var = 0; 7179 7180 if (!vdev) 7181 return QDF_STATUS_E_FAILURE; 7182 7183 switch (param) { 7184 case CDP_ENABLE_WDS: 7185 dp_cdp_err("%pK: wds_enable %d for vdev(%pK) id(%d)\n", 7186 dsoc, val.cdp_vdev_param_wds, vdev, vdev->vdev_id); 7187 vdev->wds_enabled = val.cdp_vdev_param_wds; 7188 break; 7189 case CDP_ENABLE_MEC: 7190 dp_cdp_err("%pK: mec_enable %d for vdev(%pK) id(%d)\n", 7191 dsoc, val.cdp_vdev_param_mec, vdev, vdev->vdev_id); 7192 vdev->mec_enabled = val.cdp_vdev_param_mec; 7193 break; 7194 case CDP_ENABLE_DA_WAR: 7195 dp_cdp_err("%pK: da_war_enable %d for vdev(%pK) id(%d)\n", 7196 dsoc, val.cdp_vdev_param_da_war, vdev, vdev->vdev_id); 7197 vdev->pdev->soc->da_war_enabled = val.cdp_vdev_param_da_war; 7198 dp_wds_flush_ast_table_wifi3(((struct cdp_soc_t *) 7199 vdev->pdev->soc)); 7200 break; 7201 case CDP_ENABLE_NAWDS: 7202 vdev->nawds_enabled = val.cdp_vdev_param_nawds; 7203 break; 7204 case CDP_ENABLE_MCAST_EN: 7205 vdev->mcast_enhancement_en = val.cdp_vdev_param_mcast_en; 7206 break; 7207 case CDP_ENABLE_IGMP_MCAST_EN: 7208 vdev->igmp_mcast_enhanc_en = val.cdp_vdev_param_igmp_mcast_en; 7209 break; 7210 case CDP_ENABLE_PROXYSTA: 7211 vdev->proxysta_vdev = val.cdp_vdev_param_proxysta; 7212 break; 7213 case CDP_UPDATE_TDLS_FLAGS: 7214 vdev->tdls_link_connected = val.cdp_vdev_param_tdls_flags; 7215 break; 7216 case CDP_CFG_WDS_AGING_TIMER: 7217 var = val.cdp_vdev_param_aging_tmr; 7218 if (!var) 7219 qdf_timer_stop(&vdev->pdev->soc->ast_aging_timer); 7220 else if (var != vdev->wds_aging_timer_val) 7221 qdf_timer_mod(&vdev->pdev->soc->ast_aging_timer, var); 7222 7223 vdev->wds_aging_timer_val = var; 7224 break; 7225 case CDP_ENABLE_AP_BRIDGE: 7226 if (wlan_op_mode_sta != vdev->opmode) 7227 vdev->ap_bridge_enabled = val.cdp_vdev_param_ap_brdg_en; 7228 else 7229 vdev->ap_bridge_enabled = false; 7230 break; 7231 case CDP_ENABLE_CIPHER: 7232 vdev->sec_type = val.cdp_vdev_param_cipher_en; 7233 break; 7234 case CDP_ENABLE_QWRAP_ISOLATION: 7235 vdev->isolation_vdev = val.cdp_vdev_param_qwrap_isolation; 7236 break; 7237 case CDP_UPDATE_MULTIPASS: 7238 vdev->multipass_en = val.cdp_vdev_param_update_multipass; 7239 break; 7240 case CDP_TX_ENCAP_TYPE: 7241 vdev->tx_encap_type = val.cdp_vdev_param_tx_encap; 7242 break; 7243 case CDP_RX_DECAP_TYPE: 7244 vdev->rx_decap_type = val.cdp_vdev_param_rx_decap; 7245 break; 7246 case CDP_TID_VDEV_PRTY: 7247 vdev->tidmap_prty = val.cdp_vdev_param_tidmap_prty; 7248 break; 7249 case CDP_TIDMAP_TBL_ID: 7250 vdev->tidmap_tbl_id = val.cdp_vdev_param_tidmap_tbl_id; 7251 break; 7252 #ifdef MESH_MODE_SUPPORT 7253 case CDP_MESH_RX_FILTER: 7254 dp_vdev_set_mesh_rx_filter((struct cdp_vdev *)vdev, 7255 val.cdp_vdev_param_mesh_rx_filter); 7256 break; 7257 case CDP_MESH_MODE: 7258 dp_vdev_set_mesh_mode((struct cdp_vdev *)vdev, 7259 val.cdp_vdev_param_mesh_mode); 7260 break; 7261 #endif 7262 case CDP_ENABLE_HLOS_TID_OVERRIDE: 7263 dp_info("vdev_id %d enable hlod tid override %d", vdev_id, 7264 val.cdp_vdev_param_hlos_tid_override); 7265 dp_vdev_set_hlos_tid_override(vdev, 7266 val.cdp_vdev_param_hlos_tid_override); 7267 break; 7268 #ifdef QCA_SUPPORT_WDS_EXTENDED 7269 case CDP_CFG_WDS_EXT: 7270 if (vdev->opmode == wlan_op_mode_ap) 7271 vdev->wds_ext_enabled = val.cdp_vdev_param_wds_ext; 7272 break; 7273 case CDP_DROP_TX_MCAST: 7274 dp_info("vdev_id %d drop tx mcast :%d", vdev_id, 7275 val.cdp_drop_tx_mcast); 7276 vdev->drop_tx_mcast = val.cdp_drop_tx_mcast; 7277 break; 7278 #endif 7279 case CDP_ENABLE_PEER_AUTHORIZE: 7280 vdev->peer_authorize = val.cdp_vdev_param_peer_authorize; 7281 break; 7282 #ifdef WLAN_SUPPORT_MESH_LATENCY 7283 case CDP_ENABLE_PEER_TID_LATENCY: 7284 dp_info("vdev_id %d enable peer tid latency %d", vdev_id, 7285 val.cdp_vdev_param_peer_tid_latency_enable); 7286 vdev->peer_tid_latency_enabled = 7287 val.cdp_vdev_param_peer_tid_latency_enable; 7288 break; 7289 case CDP_SET_VAP_MESH_TID: 7290 dp_info("vdev_id %d enable peer tid latency %d", vdev_id, 7291 val.cdp_vdev_param_mesh_tid); 7292 vdev->mesh_tid_latency_config.latency_tid 7293 = val.cdp_vdev_param_mesh_tid; 7294 break; 7295 #endif 7296 #ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE 7297 case CDP_SKIP_BAR_UPDATE_AP: 7298 dp_info("vdev_id %d skip BAR update: %u", vdev_id, 7299 val.cdp_skip_bar_update); 7300 vdev->skip_bar_update = val.cdp_skip_bar_update; 7301 vdev->skip_bar_update_last_ts = 0; 7302 break; 7303 #endif 7304 case CDP_DROP_3ADDR_MCAST: 7305 dp_info("vdev_id %d drop 3 addr mcast :%d", vdev_id, 7306 val.cdp_drop_3addr_mcast); 7307 vdev->drop_3addr_mcast = val.cdp_drop_3addr_mcast; 7308 break; 7309 case CDP_ENABLE_WRAP: 7310 vdev->wrap_vdev = val.cdp_vdev_param_wrap; 7311 break; 7312 #ifdef DP_TRAFFIC_END_INDICATION 7313 case CDP_ENABLE_TRAFFIC_END_INDICATION: 7314 vdev->traffic_end_ind_en = val.cdp_vdev_param_traffic_end_ind; 7315 break; 7316 #endif 7317 #ifdef FEATURE_DIRECT_LINK 7318 case CDP_VDEV_TX_TO_FW: 7319 dp_info("vdev_id %d to_fw :%d", vdev_id, val.cdp_vdev_tx_to_fw); 7320 vdev->to_fw = val.cdp_vdev_tx_to_fw; 7321 break; 7322 #endif 7323 default: 7324 break; 7325 } 7326 7327 dp_tx_vdev_update_search_flags((struct dp_vdev *)vdev); 7328 dsoc->arch_ops.txrx_set_vdev_param(dsoc, vdev, param, val); 7329 7330 /* Update PDEV flags as VDEV flags are updated */ 7331 dp_pdev_update_fast_rx_flag(dsoc, vdev->pdev); 7332 dp_vdev_unref_delete(dsoc, vdev, DP_MOD_ID_CDP); 7333 7334 return QDF_STATUS_SUCCESS; 7335 } 7336 7337 /** 7338 * dp_set_psoc_param: function to set parameters in psoc 7339 * @cdp_soc: DP soc handle 7340 * @param: parameter type to be set 7341 * @val: value of parameter to be set 7342 * 7343 * Return: QDF_STATUS 7344 */ 7345 static QDF_STATUS 7346 dp_set_psoc_param(struct cdp_soc_t *cdp_soc, 7347 enum cdp_psoc_param_type param, cdp_config_param_type val) 7348 { 7349 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 7350 struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = soc->wlan_cfg_ctx; 7351 7352 switch (param) { 7353 case CDP_ENABLE_RATE_STATS: 7354 soc->peerstats_enabled = val.cdp_psoc_param_en_rate_stats; 7355 break; 7356 case CDP_SET_NSS_CFG: 7357 wlan_cfg_set_dp_soc_nss_cfg(wlan_cfg_ctx, 7358 val.cdp_psoc_param_en_nss_cfg); 7359 /* 7360 * TODO: masked out based on the per offloaded radio 7361 */ 7362 switch (val.cdp_psoc_param_en_nss_cfg) { 7363 case dp_nss_cfg_default: 7364 break; 7365 case dp_nss_cfg_first_radio: 7366 /* 7367 * This configuration is valid for single band radio which 7368 * is also NSS offload. 7369 */ 7370 case dp_nss_cfg_dbdc: 7371 case dp_nss_cfg_dbtc: 7372 wlan_cfg_set_num_tx_desc_pool(wlan_cfg_ctx, 0); 7373 wlan_cfg_set_num_tx_ext_desc_pool(wlan_cfg_ctx, 0); 7374 wlan_cfg_set_num_tx_desc(wlan_cfg_ctx, 0); 7375 wlan_cfg_set_num_tx_ext_desc(wlan_cfg_ctx, 0); 7376 break; 7377 default: 7378 dp_cdp_err("%pK: Invalid offload config %d", 7379 soc, val.cdp_psoc_param_en_nss_cfg); 7380 } 7381 7382 dp_cdp_err("%pK: nss-wifi<0> nss config is enabled" 7383 , soc); 7384 break; 7385 case CDP_SET_PREFERRED_HW_MODE: 7386 soc->preferred_hw_mode = val.cdp_psoc_param_preferred_hw_mode; 7387 break; 7388 case CDP_IPA_ENABLE: 7389 soc->wlan_cfg_ctx->ipa_enabled = val.cdp_ipa_enabled; 7390 break; 7391 case CDP_CFG_VDEV_STATS_HW_OFFLOAD: 7392 wlan_cfg_set_vdev_stats_hw_offload_config(wlan_cfg_ctx, 7393 val.cdp_psoc_param_vdev_stats_hw_offload); 7394 break; 7395 case CDP_SAWF_ENABLE: 7396 wlan_cfg_set_sawf_config(wlan_cfg_ctx, val.cdp_sawf_enabled); 7397 break; 7398 case CDP_UMAC_RST_SKEL_ENABLE: 7399 dp_umac_rst_skel_enable_update(soc, val.cdp_umac_rst_skel); 7400 break; 7401 case CDP_UMAC_RESET_STATS: 7402 dp_umac_reset_stats_print(soc); 7403 break; 7404 case CDP_SAWF_STATS: 7405 wlan_cfg_set_sawf_stats_config(wlan_cfg_ctx, 7406 val.cdp_sawf_stats); 7407 break; 7408 default: 7409 break; 7410 } 7411 7412 return QDF_STATUS_SUCCESS; 7413 } 7414 7415 /** 7416 * dp_get_psoc_param: function to get parameters in soc 7417 * @cdp_soc: DP soc handle 7418 * @param: parameter type to be set 7419 * @val: address of buffer 7420 * 7421 * Return: status 7422 */ 7423 static QDF_STATUS dp_get_psoc_param(struct cdp_soc_t *cdp_soc, 7424 enum cdp_psoc_param_type param, 7425 cdp_config_param_type *val) 7426 { 7427 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 7428 7429 if (!soc) 7430 return QDF_STATUS_E_FAILURE; 7431 7432 switch (param) { 7433 case CDP_CFG_PEER_EXT_STATS: 7434 val->cdp_psoc_param_pext_stats = 7435 wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx); 7436 break; 7437 case CDP_CFG_VDEV_STATS_HW_OFFLOAD: 7438 val->cdp_psoc_param_vdev_stats_hw_offload = 7439 wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx); 7440 break; 7441 case CDP_UMAC_RST_SKEL_ENABLE: 7442 val->cdp_umac_rst_skel = dp_umac_rst_skel_enable_get(soc); 7443 break; 7444 default: 7445 dp_warn("Invalid param"); 7446 break; 7447 } 7448 7449 return QDF_STATUS_SUCCESS; 7450 } 7451 7452 /** 7453 * dp_set_vdev_dscp_tid_map_wifi3() - Update Map ID selected for particular vdev 7454 * @cdp_soc: CDP SOC handle 7455 * @vdev_id: id of DP_VDEV handle 7456 * @map_id:ID of map that needs to be updated 7457 * 7458 * Return: QDF_STATUS 7459 */ 7460 static QDF_STATUS dp_set_vdev_dscp_tid_map_wifi3(ol_txrx_soc_handle cdp_soc, 7461 uint8_t vdev_id, 7462 uint8_t map_id) 7463 { 7464 cdp_config_param_type val; 7465 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 7466 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 7467 DP_MOD_ID_CDP); 7468 if (vdev) { 7469 vdev->dscp_tid_map_id = map_id; 7470 val.cdp_vdev_param_dscp_tid_map_id = map_id; 7471 soc->arch_ops.txrx_set_vdev_param(soc, 7472 vdev, 7473 CDP_UPDATE_DSCP_TO_TID_MAP, 7474 val); 7475 /* Update flag for transmit tid classification */ 7476 if (vdev->dscp_tid_map_id < soc->num_hw_dscp_tid_map) 7477 vdev->skip_sw_tid_classification |= 7478 DP_TX_HW_DSCP_TID_MAP_VALID; 7479 else 7480 vdev->skip_sw_tid_classification &= 7481 ~DP_TX_HW_DSCP_TID_MAP_VALID; 7482 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7483 return QDF_STATUS_SUCCESS; 7484 } 7485 7486 return QDF_STATUS_E_FAILURE; 7487 } 7488 7489 #ifdef DP_RATETABLE_SUPPORT 7490 static int dp_txrx_get_ratekbps(int preamb, int mcs, 7491 int htflag, int gintval) 7492 { 7493 uint32_t rix; 7494 uint16_t ratecode; 7495 enum cdp_punctured_modes punc_mode = NO_PUNCTURE; 7496 7497 return dp_getrateindex((uint32_t)gintval, (uint16_t)mcs, 1, 7498 (uint8_t)preamb, 1, punc_mode, 7499 &rix, &ratecode); 7500 } 7501 #else 7502 static int dp_txrx_get_ratekbps(int preamb, int mcs, 7503 int htflag, int gintval) 7504 { 7505 return 0; 7506 } 7507 #endif 7508 7509 /** 7510 * dp_txrx_get_pdev_stats() - Returns cdp_pdev_stats 7511 * @soc: DP soc handle 7512 * @pdev_id: id of DP pdev handle 7513 * @pdev_stats: buffer to copy to 7514 * 7515 * Return: status success/failure 7516 */ 7517 static QDF_STATUS 7518 dp_txrx_get_pdev_stats(struct cdp_soc_t *soc, uint8_t pdev_id, 7519 struct cdp_pdev_stats *pdev_stats) 7520 { 7521 struct dp_pdev *pdev = 7522 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 7523 pdev_id); 7524 if (!pdev) 7525 return QDF_STATUS_E_FAILURE; 7526 7527 dp_aggregate_pdev_stats(pdev); 7528 7529 qdf_mem_copy(pdev_stats, &pdev->stats, sizeof(struct cdp_pdev_stats)); 7530 return QDF_STATUS_SUCCESS; 7531 } 7532 7533 /** 7534 * dp_txrx_update_vdev_me_stats() - Update vdev ME stats sent from CDP 7535 * @vdev: DP vdev handle 7536 * @buf: buffer containing specific stats structure 7537 * 7538 * Return: void 7539 */ 7540 static void dp_txrx_update_vdev_me_stats(struct dp_vdev *vdev, 7541 void *buf) 7542 { 7543 struct cdp_tx_ingress_stats *host_stats = NULL; 7544 7545 if (!buf) { 7546 dp_cdp_err("%pK: Invalid host stats buf", vdev->pdev->soc); 7547 return; 7548 } 7549 host_stats = (struct cdp_tx_ingress_stats *)buf; 7550 7551 DP_STATS_INC_PKT(vdev, tx_i.mcast_en.mcast_pkt, 7552 host_stats->mcast_en.mcast_pkt.num, 7553 host_stats->mcast_en.mcast_pkt.bytes); 7554 DP_STATS_INC(vdev, tx_i.mcast_en.dropped_map_error, 7555 host_stats->mcast_en.dropped_map_error); 7556 DP_STATS_INC(vdev, tx_i.mcast_en.dropped_self_mac, 7557 host_stats->mcast_en.dropped_self_mac); 7558 DP_STATS_INC(vdev, tx_i.mcast_en.dropped_send_fail, 7559 host_stats->mcast_en.dropped_send_fail); 7560 DP_STATS_INC(vdev, tx_i.mcast_en.ucast, 7561 host_stats->mcast_en.ucast); 7562 DP_STATS_INC(vdev, tx_i.mcast_en.fail_seg_alloc, 7563 host_stats->mcast_en.fail_seg_alloc); 7564 DP_STATS_INC(vdev, tx_i.mcast_en.clone_fail, 7565 host_stats->mcast_en.clone_fail); 7566 } 7567 7568 /** 7569 * dp_txrx_update_vdev_igmp_me_stats() - Update vdev IGMP ME stats sent from CDP 7570 * @vdev: DP vdev handle 7571 * @buf: buffer containing specific stats structure 7572 * 7573 * Return: void 7574 */ 7575 static void dp_txrx_update_vdev_igmp_me_stats(struct dp_vdev *vdev, 7576 void *buf) 7577 { 7578 struct cdp_tx_ingress_stats *host_stats = NULL; 7579 7580 if (!buf) { 7581 dp_cdp_err("%pK: Invalid host stats buf", vdev->pdev->soc); 7582 return; 7583 } 7584 host_stats = (struct cdp_tx_ingress_stats *)buf; 7585 7586 DP_STATS_INC(vdev, tx_i.igmp_mcast_en.igmp_rcvd, 7587 host_stats->igmp_mcast_en.igmp_rcvd); 7588 DP_STATS_INC(vdev, tx_i.igmp_mcast_en.igmp_ucast_converted, 7589 host_stats->igmp_mcast_en.igmp_ucast_converted); 7590 } 7591 7592 /** 7593 * dp_txrx_update_vdev_host_stats() - Update stats sent through CDP 7594 * @soc_hdl: DP soc handle 7595 * @vdev_id: id of DP vdev handle 7596 * @buf: buffer containing specific stats structure 7597 * @stats_id: stats type 7598 * 7599 * Return: QDF_STATUS 7600 */ 7601 static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc_hdl, 7602 uint8_t vdev_id, 7603 void *buf, 7604 uint16_t stats_id) 7605 { 7606 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 7607 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 7608 DP_MOD_ID_CDP); 7609 7610 if (!vdev) { 7611 dp_cdp_err("%pK: Invalid vdev handle", soc); 7612 return QDF_STATUS_E_FAILURE; 7613 } 7614 7615 switch (stats_id) { 7616 case DP_VDEV_STATS_PKT_CNT_ONLY: 7617 break; 7618 case DP_VDEV_STATS_TX_ME: 7619 dp_txrx_update_vdev_me_stats(vdev, buf); 7620 dp_txrx_update_vdev_igmp_me_stats(vdev, buf); 7621 break; 7622 default: 7623 qdf_info("Invalid stats_id %d", stats_id); 7624 break; 7625 } 7626 7627 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7628 return QDF_STATUS_SUCCESS; 7629 } 7630 7631 /** 7632 * dp_txrx_get_peer_stats() - will return cdp_peer_stats 7633 * @soc: soc handle 7634 * @vdev_id: id of vdev handle 7635 * @peer_mac: mac of DP_PEER handle 7636 * @peer_stats: buffer to copy to 7637 * 7638 * Return: status success/failure 7639 */ 7640 static QDF_STATUS 7641 dp_txrx_get_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id, 7642 uint8_t *peer_mac, struct cdp_peer_stats *peer_stats) 7643 { 7644 struct dp_peer *peer = NULL; 7645 struct cdp_peer_info peer_info = { 0 }; 7646 7647 DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false, 7648 CDP_WILD_PEER_TYPE); 7649 7650 peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info, 7651 DP_MOD_ID_CDP); 7652 7653 qdf_mem_zero(peer_stats, sizeof(struct cdp_peer_stats)); 7654 7655 if (!peer) 7656 return QDF_STATUS_E_FAILURE; 7657 7658 dp_get_peer_stats(peer, peer_stats); 7659 7660 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7661 7662 return QDF_STATUS_SUCCESS; 7663 } 7664 7665 /** 7666 * dp_txrx_get_peer_stats_param() - will return specified cdp_peer_stats 7667 * @soc: soc handle 7668 * @vdev_id: vdev_id of vdev object 7669 * @peer_mac: mac address of the peer 7670 * @type: enum of required stats 7671 * @buf: buffer to hold the value 7672 * 7673 * Return: status success/failure 7674 */ 7675 static QDF_STATUS 7676 dp_txrx_get_peer_stats_param(struct cdp_soc_t *soc, uint8_t vdev_id, 7677 uint8_t *peer_mac, enum cdp_peer_stats_type type, 7678 cdp_peer_stats_param_t *buf) 7679 { 7680 QDF_STATUS ret; 7681 struct dp_peer *peer = NULL; 7682 struct cdp_peer_info peer_info = { 0 }; 7683 7684 DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false, 7685 CDP_WILD_PEER_TYPE); 7686 7687 peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info, 7688 DP_MOD_ID_CDP); 7689 7690 if (!peer) { 7691 dp_peer_err("%pK: Invalid Peer for Mac " QDF_MAC_ADDR_FMT, 7692 soc, QDF_MAC_ADDR_REF(peer_mac)); 7693 return QDF_STATUS_E_FAILURE; 7694 } 7695 7696 if (type >= cdp_peer_per_pkt_stats_min && 7697 type < cdp_peer_per_pkt_stats_max) { 7698 ret = dp_txrx_get_peer_per_pkt_stats_param(peer, type, buf); 7699 } else if (type >= cdp_peer_extd_stats_min && 7700 type < cdp_peer_extd_stats_max) { 7701 ret = dp_txrx_get_peer_extd_stats_param(peer, type, buf); 7702 } else { 7703 dp_err("%pK: Invalid stat type requested", soc); 7704 ret = QDF_STATUS_E_FAILURE; 7705 } 7706 7707 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7708 7709 return ret; 7710 } 7711 7712 /** 7713 * dp_txrx_reset_peer_stats() - reset cdp_peer_stats for particular peer 7714 * @soc_hdl: soc handle 7715 * @vdev_id: id of vdev handle 7716 * @peer_mac: mac of DP_PEER handle 7717 * 7718 * Return: QDF_STATUS 7719 */ 7720 #ifdef WLAN_FEATURE_11BE_MLO 7721 static QDF_STATUS 7722 dp_txrx_reset_peer_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 7723 uint8_t *peer_mac) 7724 { 7725 QDF_STATUS status = QDF_STATUS_SUCCESS; 7726 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 7727 struct dp_peer *peer = 7728 dp_peer_get_tgt_peer_hash_find(soc, peer_mac, 0, 7729 vdev_id, DP_MOD_ID_CDP); 7730 7731 if (!peer) 7732 return QDF_STATUS_E_FAILURE; 7733 7734 DP_STATS_CLR(peer); 7735 dp_txrx_peer_stats_clr(peer->txrx_peer); 7736 7737 if (IS_MLO_DP_MLD_PEER(peer)) { 7738 uint8_t i; 7739 struct dp_peer *link_peer; 7740 struct dp_soc *link_peer_soc; 7741 struct dp_mld_link_peers link_peers_info; 7742 7743 dp_get_link_peers_ref_from_mld_peer(soc, peer, 7744 &link_peers_info, 7745 DP_MOD_ID_CDP); 7746 for (i = 0; i < link_peers_info.num_links; i++) { 7747 link_peer = link_peers_info.link_peers[i]; 7748 link_peer_soc = link_peer->vdev->pdev->soc; 7749 7750 DP_STATS_CLR(link_peer); 7751 dp_monitor_peer_reset_stats(link_peer_soc, link_peer); 7752 } 7753 7754 dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP); 7755 } else { 7756 dp_monitor_peer_reset_stats(soc, peer); 7757 } 7758 7759 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7760 7761 return status; 7762 } 7763 #else 7764 static QDF_STATUS 7765 dp_txrx_reset_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id, 7766 uint8_t *peer_mac) 7767 { 7768 QDF_STATUS status = QDF_STATUS_SUCCESS; 7769 struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, 7770 peer_mac, 0, vdev_id, 7771 DP_MOD_ID_CDP); 7772 7773 if (!peer) 7774 return QDF_STATUS_E_FAILURE; 7775 7776 DP_STATS_CLR(peer); 7777 dp_txrx_peer_stats_clr(peer->txrx_peer); 7778 dp_monitor_peer_reset_stats((struct dp_soc *)soc, peer); 7779 7780 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 7781 7782 return status; 7783 } 7784 #endif 7785 7786 /** 7787 * dp_txrx_get_vdev_stats() - Update buffer with cdp_vdev_stats 7788 * @soc_hdl: CDP SoC handle 7789 * @vdev_id: vdev Id 7790 * @buf: buffer for vdev stats 7791 * @is_aggregate: are aggregate stats being collected 7792 * 7793 * Return: int 7794 */ 7795 static int dp_txrx_get_vdev_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 7796 void *buf, bool is_aggregate) 7797 { 7798 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 7799 struct cdp_vdev_stats *vdev_stats; 7800 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 7801 DP_MOD_ID_CDP); 7802 7803 if (!vdev) 7804 return 1; 7805 7806 vdev_stats = (struct cdp_vdev_stats *)buf; 7807 7808 if (is_aggregate) { 7809 dp_aggregate_vdev_stats(vdev, buf); 7810 } else { 7811 qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); 7812 } 7813 7814 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 7815 return 0; 7816 } 7817 7818 /** 7819 * dp_get_total_per() - get total per 7820 * @soc: DP soc handle 7821 * @pdev_id: id of DP_PDEV handle 7822 * 7823 * Return: % error rate using retries per packet and success packets 7824 */ 7825 static int dp_get_total_per(struct cdp_soc_t *soc, uint8_t pdev_id) 7826 { 7827 struct dp_pdev *pdev = 7828 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 7829 pdev_id); 7830 7831 if (!pdev) 7832 return 0; 7833 7834 dp_aggregate_pdev_stats(pdev); 7835 if ((pdev->stats.tx.tx_success.num + pdev->stats.tx.retries) == 0) 7836 return 0; 7837 return ((pdev->stats.tx.retries * 100) / 7838 ((pdev->stats.tx.tx_success.num) + (pdev->stats.tx.retries))); 7839 } 7840 7841 /** 7842 * dp_txrx_stats_publish() - publish pdev stats into a buffer 7843 * @soc: DP soc handle 7844 * @pdev_id: id of DP_PDEV handle 7845 * @buf: to hold pdev_stats 7846 * 7847 * Return: int 7848 */ 7849 static int 7850 dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id, 7851 struct cdp_stats_extd *buf) 7852 { 7853 struct cdp_txrx_stats_req req = {0,}; 7854 QDF_STATUS status; 7855 struct dp_pdev *pdev = 7856 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 7857 pdev_id); 7858 7859 if (!pdev) 7860 return TXRX_STATS_LEVEL_OFF; 7861 7862 if (pdev->pending_fw_stats_response) 7863 return TXRX_STATS_LEVEL_OFF; 7864 7865 dp_aggregate_pdev_stats(pdev); 7866 7867 pdev->pending_fw_stats_response = true; 7868 req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_TX; 7869 req.cookie_val = DBG_STATS_COOKIE_DP_STATS; 7870 pdev->fw_stats_tlv_bitmap_rcvd = 0; 7871 qdf_event_reset(&pdev->fw_stats_event); 7872 dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0, 7873 req.param1, req.param2, req.param3, 0, 7874 req.cookie_val, 0); 7875 7876 req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_RX; 7877 req.cookie_val = DBG_STATS_COOKIE_DP_STATS; 7878 dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0, 7879 req.param1, req.param2, req.param3, 0, 7880 req.cookie_val, 0); 7881 7882 status = 7883 qdf_wait_single_event(&pdev->fw_stats_event, DP_MAX_SLEEP_TIME); 7884 7885 if (status != QDF_STATUS_SUCCESS) { 7886 if (status == QDF_STATUS_E_TIMEOUT) 7887 qdf_debug("TIMEOUT_OCCURS"); 7888 pdev->pending_fw_stats_response = false; 7889 return TXRX_STATS_LEVEL_OFF; 7890 } 7891 qdf_mem_copy(buf, &pdev->stats, sizeof(struct cdp_pdev_stats)); 7892 pdev->pending_fw_stats_response = false; 7893 7894 return TXRX_STATS_LEVEL; 7895 } 7896 7897 /** 7898 * dp_get_obss_stats() - Get Pdev OBSS stats from Fw 7899 * @soc: DP soc handle 7900 * @pdev_id: id of DP_PDEV handle 7901 * @buf: to hold pdev obss stats 7902 * @req: Pointer to CDP TxRx stats 7903 * 7904 * Return: status 7905 */ 7906 static QDF_STATUS 7907 dp_get_obss_stats(struct cdp_soc_t *soc, uint8_t pdev_id, 7908 struct cdp_pdev_obss_pd_stats_tlv *buf, 7909 struct cdp_txrx_stats_req *req) 7910 { 7911 QDF_STATUS status; 7912 struct dp_pdev *pdev = 7913 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 7914 pdev_id); 7915 7916 if (!pdev) 7917 return QDF_STATUS_E_INVAL; 7918 7919 if (pdev->pending_fw_obss_stats_response) 7920 return QDF_STATUS_E_AGAIN; 7921 7922 pdev->pending_fw_obss_stats_response = true; 7923 req->stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS; 7924 req->cookie_val = DBG_STATS_COOKIE_HTT_OBSS; 7925 qdf_event_reset(&pdev->fw_obss_stats_event); 7926 status = dp_h2t_ext_stats_msg_send(pdev, req->stats, req->param0, 7927 req->param1, req->param2, 7928 req->param3, 0, req->cookie_val, 7929 req->mac_id); 7930 if (QDF_IS_STATUS_ERROR(status)) { 7931 pdev->pending_fw_obss_stats_response = false; 7932 return status; 7933 } 7934 status = 7935 qdf_wait_single_event(&pdev->fw_obss_stats_event, 7936 DP_MAX_SLEEP_TIME); 7937 7938 if (status != QDF_STATUS_SUCCESS) { 7939 if (status == QDF_STATUS_E_TIMEOUT) 7940 qdf_debug("TIMEOUT_OCCURS"); 7941 pdev->pending_fw_obss_stats_response = false; 7942 return QDF_STATUS_E_TIMEOUT; 7943 } 7944 qdf_mem_copy(buf, &pdev->stats.htt_tx_pdev_stats.obss_pd_stats_tlv, 7945 sizeof(struct cdp_pdev_obss_pd_stats_tlv)); 7946 pdev->pending_fw_obss_stats_response = false; 7947 return status; 7948 } 7949 7950 /** 7951 * dp_clear_pdev_obss_pd_stats() - Clear pdev obss stats 7952 * @soc: DP soc handle 7953 * @pdev_id: id of DP_PDEV handle 7954 * @req: Pointer to CDP TxRx stats request mac_id will be 7955 * pre-filled and should not be overwritten 7956 * 7957 * Return: status 7958 */ 7959 static QDF_STATUS 7960 dp_clear_pdev_obss_pd_stats(struct cdp_soc_t *soc, uint8_t pdev_id, 7961 struct cdp_txrx_stats_req *req) 7962 { 7963 struct dp_pdev *pdev = 7964 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 7965 pdev_id); 7966 uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT; 7967 7968 if (!pdev) 7969 return QDF_STATUS_E_INVAL; 7970 7971 /* 7972 * For HTT_DBG_EXT_STATS_RESET command, FW need to config 7973 * from param0 to param3 according to below rule: 7974 * 7975 * PARAM: 7976 * - config_param0 : start_offset (stats type) 7977 * - config_param1 : stats bmask from start offset 7978 * - config_param2 : stats bmask from start offset + 32 7979 * - config_param3 : stats bmask from start offset + 64 7980 */ 7981 req->stats = (enum cdp_stats)HTT_DBG_EXT_STATS_RESET; 7982 req->param0 = HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS; 7983 req->param1 = 0x00000001; 7984 7985 return dp_h2t_ext_stats_msg_send(pdev, req->stats, req->param0, 7986 req->param1, req->param2, req->param3, 0, 7987 cookie_val, req->mac_id); 7988 } 7989 7990 /** 7991 * dp_set_pdev_dscp_tid_map_wifi3() - update dscp tid map in pdev 7992 * @soc_handle: soc handle 7993 * @pdev_id: id of DP_PDEV handle 7994 * @map_id: ID of map that needs to be updated 7995 * @tos: index value in map 7996 * @tid: tid value passed by the user 7997 * 7998 * Return: QDF_STATUS 7999 */ 8000 static QDF_STATUS 8001 dp_set_pdev_dscp_tid_map_wifi3(struct cdp_soc_t *soc_handle, 8002 uint8_t pdev_id, 8003 uint8_t map_id, 8004 uint8_t tos, uint8_t tid) 8005 { 8006 uint8_t dscp; 8007 struct dp_soc *soc = (struct dp_soc *)soc_handle; 8008 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 8009 8010 if (!pdev) 8011 return QDF_STATUS_E_FAILURE; 8012 8013 dscp = (tos >> DP_IP_DSCP_SHIFT) & DP_IP_DSCP_MASK; 8014 pdev->dscp_tid_map[map_id][dscp] = tid; 8015 8016 if (map_id < soc->num_hw_dscp_tid_map) 8017 hal_tx_update_dscp_tid(soc->hal_soc, tid, 8018 map_id, dscp); 8019 else 8020 return QDF_STATUS_E_FAILURE; 8021 8022 return QDF_STATUS_SUCCESS; 8023 } 8024 8025 #ifdef WLAN_SYSFS_DP_STATS 8026 /** 8027 * dp_sysfs_event_trigger() - Trigger event to wait for firmware 8028 * stats request response. 8029 * @soc: soc handle 8030 * @cookie_val: cookie value 8031 * 8032 * Return: QDF_STATUS 8033 */ 8034 static QDF_STATUS 8035 dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val) 8036 { 8037 QDF_STATUS status = QDF_STATUS_SUCCESS; 8038 /* wait for firmware response for sysfs stats request */ 8039 if (cookie_val == DBG_SYSFS_STATS_COOKIE) { 8040 if (!soc) { 8041 dp_cdp_err("soc is NULL"); 8042 return QDF_STATUS_E_FAILURE; 8043 } 8044 /* wait for event completion */ 8045 status = qdf_wait_single_event(&soc->sysfs_config->sysfs_txrx_fw_request_done, 8046 WLAN_SYSFS_STAT_REQ_WAIT_MS); 8047 if (status == QDF_STATUS_SUCCESS) 8048 dp_cdp_info("sysfs_txrx_fw_request_done event completed"); 8049 else if (status == QDF_STATUS_E_TIMEOUT) 8050 dp_cdp_warn("sysfs_txrx_fw_request_done event expired"); 8051 else 8052 dp_cdp_warn("sysfs_txrx_fw_request_done event error code %d", status); 8053 } 8054 8055 return status; 8056 } 8057 #else /* WLAN_SYSFS_DP_STATS */ 8058 static QDF_STATUS 8059 dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val) 8060 { 8061 return QDF_STATUS_SUCCESS; 8062 } 8063 #endif /* WLAN_SYSFS_DP_STATS */ 8064 8065 /** 8066 * dp_fw_stats_process() - Process TXRX FW stats request. 8067 * @vdev: DP VDEV handle 8068 * @req: stats request 8069 * 8070 * Return: QDF_STATUS 8071 */ 8072 static QDF_STATUS 8073 dp_fw_stats_process(struct dp_vdev *vdev, 8074 struct cdp_txrx_stats_req *req) 8075 { 8076 struct dp_pdev *pdev = NULL; 8077 struct dp_soc *soc = NULL; 8078 uint32_t stats = req->stats; 8079 uint8_t mac_id = req->mac_id; 8080 uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT; 8081 8082 if (!vdev) { 8083 DP_TRACE(NONE, "VDEV not found"); 8084 return QDF_STATUS_E_FAILURE; 8085 } 8086 8087 pdev = vdev->pdev; 8088 if (!pdev) { 8089 DP_TRACE(NONE, "PDEV not found"); 8090 return QDF_STATUS_E_FAILURE; 8091 } 8092 8093 soc = pdev->soc; 8094 if (!soc) { 8095 DP_TRACE(NONE, "soc not found"); 8096 return QDF_STATUS_E_FAILURE; 8097 } 8098 8099 /* In case request is from host sysfs for displaying stats on console */ 8100 if (req->cookie_val == DBG_SYSFS_STATS_COOKIE) 8101 cookie_val = DBG_SYSFS_STATS_COOKIE; 8102 8103 /* 8104 * For HTT_DBG_EXT_STATS_RESET command, FW need to config 8105 * from param0 to param3 according to below rule: 8106 * 8107 * PARAM: 8108 * - config_param0 : start_offset (stats type) 8109 * - config_param1 : stats bmask from start offset 8110 * - config_param2 : stats bmask from start offset + 32 8111 * - config_param3 : stats bmask from start offset + 64 8112 */ 8113 if (req->stats == CDP_TXRX_STATS_0) { 8114 req->param0 = HTT_DBG_EXT_STATS_PDEV_TX; 8115 req->param1 = 0xFFFFFFFF; 8116 req->param2 = 0xFFFFFFFF; 8117 req->param3 = 0xFFFFFFFF; 8118 } else if (req->stats == (uint8_t)HTT_DBG_EXT_STATS_PDEV_TX_MU) { 8119 req->param0 = HTT_DBG_EXT_STATS_SET_VDEV_MASK(vdev->vdev_id); 8120 } 8121 8122 if (req->stats == (uint8_t)HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT) { 8123 dp_h2t_ext_stats_msg_send(pdev, 8124 HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, 8125 req->param0, req->param1, req->param2, 8126 req->param3, 0, cookie_val, 8127 mac_id); 8128 } else { 8129 dp_h2t_ext_stats_msg_send(pdev, stats, req->param0, 8130 req->param1, req->param2, req->param3, 8131 0, cookie_val, mac_id); 8132 } 8133 8134 dp_sysfs_event_trigger(soc, cookie_val); 8135 8136 return QDF_STATUS_SUCCESS; 8137 } 8138 8139 /** 8140 * dp_txrx_stats_request - function to map to firmware and host stats 8141 * @soc_handle: soc handle 8142 * @vdev_id: virtual device ID 8143 * @req: stats request 8144 * 8145 * Return: QDF_STATUS 8146 */ 8147 static 8148 QDF_STATUS dp_txrx_stats_request(struct cdp_soc_t *soc_handle, 8149 uint8_t vdev_id, 8150 struct cdp_txrx_stats_req *req) 8151 { 8152 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_handle); 8153 int host_stats; 8154 int fw_stats; 8155 enum cdp_stats stats; 8156 int num_stats; 8157 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 8158 DP_MOD_ID_CDP); 8159 QDF_STATUS status = QDF_STATUS_E_INVAL; 8160 8161 if (!vdev || !req) { 8162 dp_cdp_err("%pK: Invalid vdev/req instance", soc); 8163 status = QDF_STATUS_E_INVAL; 8164 goto fail0; 8165 } 8166 8167 if (req->mac_id >= WLAN_CFG_MAC_PER_TARGET) { 8168 dp_err("Invalid mac id request"); 8169 status = QDF_STATUS_E_INVAL; 8170 goto fail0; 8171 } 8172 8173 stats = req->stats; 8174 if (stats >= CDP_TXRX_MAX_STATS) { 8175 status = QDF_STATUS_E_INVAL; 8176 goto fail0; 8177 } 8178 8179 /* 8180 * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available 8181 * has to be updated if new FW HTT stats added 8182 */ 8183 if (stats > CDP_TXRX_STATS_HTT_MAX) 8184 stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX; 8185 8186 num_stats = QDF_ARRAY_SIZE(dp_stats_mapping_table); 8187 8188 if (stats >= num_stats) { 8189 dp_cdp_err("%pK : Invalid stats option: %d", soc, stats); 8190 status = QDF_STATUS_E_INVAL; 8191 goto fail0; 8192 } 8193 8194 req->stats = stats; 8195 fw_stats = dp_stats_mapping_table[stats][STATS_FW]; 8196 host_stats = dp_stats_mapping_table[stats][STATS_HOST]; 8197 8198 dp_info("stats: %u fw_stats_type: %d host_stats: %d", 8199 stats, fw_stats, host_stats); 8200 8201 if (fw_stats != TXRX_FW_STATS_INVALID) { 8202 /* update request with FW stats type */ 8203 req->stats = fw_stats; 8204 status = dp_fw_stats_process(vdev, req); 8205 } else if ((host_stats != TXRX_HOST_STATS_INVALID) && 8206 (host_stats <= TXRX_HOST_STATS_MAX)) 8207 status = dp_print_host_stats(vdev, req, soc); 8208 else 8209 dp_cdp_info("%pK: Wrong Input for TxRx Stats", soc); 8210 fail0: 8211 if (vdev) 8212 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8213 return status; 8214 } 8215 8216 /** 8217 * dp_soc_notify_asserted_soc() - API to notify asserted soc info 8218 * @psoc: CDP soc handle 8219 * 8220 * Return: QDF_STATUS 8221 */ 8222 static QDF_STATUS dp_soc_notify_asserted_soc(struct cdp_soc_t *psoc) 8223 { 8224 struct dp_soc *soc = (struct dp_soc *)psoc; 8225 8226 if (!soc) { 8227 dp_cdp_err("%pK: soc is NULL", soc); 8228 return QDF_STATUS_E_INVAL; 8229 } 8230 8231 return dp_umac_reset_notify_asserted_soc(soc); 8232 } 8233 8234 /** 8235 * dp_txrx_dump_stats() - Dump statistics 8236 * @psoc: CDP soc handle 8237 * @value: Statistics option 8238 * @level: verbosity level 8239 */ 8240 static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value, 8241 enum qdf_stats_verbosity_level level) 8242 { 8243 struct dp_soc *soc = 8244 (struct dp_soc *)psoc; 8245 QDF_STATUS status = QDF_STATUS_SUCCESS; 8246 8247 if (!soc) { 8248 dp_cdp_err("%pK: soc is NULL", soc); 8249 return QDF_STATUS_E_INVAL; 8250 } 8251 8252 switch (value) { 8253 case CDP_TXRX_PATH_STATS: 8254 dp_txrx_path_stats(soc); 8255 dp_print_soc_interrupt_stats(soc); 8256 hal_dump_reg_write_stats(soc->hal_soc); 8257 dp_pdev_print_tx_delay_stats(soc); 8258 /* Dump usage watermark stats for core TX/RX SRNGs */ 8259 dp_dump_srng_high_wm_stats(soc, (1 << REO_DST)); 8260 dp_print_fisa_stats(soc); 8261 break; 8262 8263 case CDP_RX_RING_STATS: 8264 dp_print_per_ring_stats(soc); 8265 break; 8266 8267 case CDP_TXRX_TSO_STATS: 8268 dp_print_tso_stats(soc, level); 8269 break; 8270 8271 case CDP_DUMP_TX_FLOW_POOL_INFO: 8272 if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH) 8273 cdp_dump_flow_pool_info((struct cdp_soc_t *)soc); 8274 else 8275 dp_tx_dump_flow_pool_info_compact(soc); 8276 break; 8277 8278 case CDP_DP_NAPI_STATS: 8279 dp_print_napi_stats(soc); 8280 break; 8281 8282 case CDP_TXRX_DESC_STATS: 8283 /* TODO: NOT IMPLEMENTED */ 8284 break; 8285 8286 case CDP_DP_RX_FISA_STATS: 8287 dp_rx_dump_fisa_stats(soc); 8288 break; 8289 8290 case CDP_DP_SWLM_STATS: 8291 dp_print_swlm_stats(soc); 8292 break; 8293 8294 case CDP_DP_TX_HW_LATENCY_STATS: 8295 dp_pdev_print_tx_delay_stats(soc); 8296 break; 8297 8298 default: 8299 status = QDF_STATUS_E_INVAL; 8300 break; 8301 } 8302 8303 return status; 8304 8305 } 8306 8307 #ifdef WLAN_SYSFS_DP_STATS 8308 static 8309 void dp_sysfs_get_stat_type(struct dp_soc *soc, uint32_t *mac_id, 8310 uint32_t *stat_type) 8311 { 8312 qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock); 8313 *stat_type = soc->sysfs_config->stat_type_requested; 8314 *mac_id = soc->sysfs_config->mac_id; 8315 8316 qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock); 8317 } 8318 8319 static 8320 void dp_sysfs_update_config_buf_params(struct dp_soc *soc, 8321 uint32_t curr_len, 8322 uint32_t max_buf_len, 8323 char *buf) 8324 { 8325 qdf_spinlock_acquire(&soc->sysfs_config->sysfs_write_user_buffer); 8326 /* set sysfs_config parameters */ 8327 soc->sysfs_config->buf = buf; 8328 soc->sysfs_config->curr_buffer_length = curr_len; 8329 soc->sysfs_config->max_buffer_length = max_buf_len; 8330 qdf_spinlock_release(&soc->sysfs_config->sysfs_write_user_buffer); 8331 } 8332 8333 static 8334 QDF_STATUS dp_sysfs_fill_stats(ol_txrx_soc_handle soc_hdl, 8335 char *buf, uint32_t buf_size) 8336 { 8337 uint32_t mac_id = 0; 8338 uint32_t stat_type = 0; 8339 uint32_t fw_stats = 0; 8340 uint32_t host_stats = 0; 8341 enum cdp_stats stats; 8342 struct cdp_txrx_stats_req req; 8343 uint32_t num_stats; 8344 struct dp_soc *soc = NULL; 8345 8346 if (!soc_hdl) { 8347 dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); 8348 return QDF_STATUS_E_INVAL; 8349 } 8350 8351 soc = cdp_soc_t_to_dp_soc(soc_hdl); 8352 8353 if (!soc) { 8354 dp_cdp_err("%pK: soc is NULL", soc); 8355 return QDF_STATUS_E_INVAL; 8356 } 8357 8358 dp_sysfs_get_stat_type(soc, &mac_id, &stat_type); 8359 8360 stats = stat_type; 8361 if (stats >= CDP_TXRX_MAX_STATS) { 8362 dp_cdp_info("sysfs stat type requested is invalid"); 8363 return QDF_STATUS_E_INVAL; 8364 } 8365 /* 8366 * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available 8367 * has to be updated if new FW HTT stats added 8368 */ 8369 if (stats > CDP_TXRX_MAX_STATS) 8370 stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX; 8371 8372 num_stats = QDF_ARRAY_SIZE(dp_stats_mapping_table); 8373 8374 if (stats >= num_stats) { 8375 dp_cdp_err("%pK : Invalid stats option: %d, max num stats: %d", 8376 soc, stats, num_stats); 8377 return QDF_STATUS_E_INVAL; 8378 } 8379 8380 /* build request */ 8381 fw_stats = dp_stats_mapping_table[stats][STATS_FW]; 8382 host_stats = dp_stats_mapping_table[stats][STATS_HOST]; 8383 8384 req.stats = stat_type; 8385 req.mac_id = mac_id; 8386 /* request stats to be printed */ 8387 qdf_mutex_acquire(&soc->sysfs_config->sysfs_read_lock); 8388 8389 if (fw_stats != TXRX_FW_STATS_INVALID) { 8390 /* update request with FW stats type */ 8391 req.cookie_val = DBG_SYSFS_STATS_COOKIE; 8392 } else if ((host_stats != TXRX_HOST_STATS_INVALID) && 8393 (host_stats <= TXRX_HOST_STATS_MAX)) { 8394 req.cookie_val = DBG_STATS_COOKIE_DEFAULT; 8395 soc->sysfs_config->process_id = qdf_get_current_pid(); 8396 soc->sysfs_config->printing_mode = PRINTING_MODE_ENABLED; 8397 } 8398 8399 dp_sysfs_update_config_buf_params(soc, 0, buf_size, buf); 8400 8401 dp_txrx_stats_request(soc_hdl, mac_id, &req); 8402 soc->sysfs_config->process_id = 0; 8403 soc->sysfs_config->printing_mode = PRINTING_MODE_DISABLED; 8404 8405 dp_sysfs_update_config_buf_params(soc, 0, 0, NULL); 8406 8407 qdf_mutex_release(&soc->sysfs_config->sysfs_read_lock); 8408 return QDF_STATUS_SUCCESS; 8409 } 8410 8411 static 8412 QDF_STATUS dp_sysfs_set_stat_type(ol_txrx_soc_handle soc_hdl, 8413 uint32_t stat_type, uint32_t mac_id) 8414 { 8415 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8416 8417 if (!soc_hdl) { 8418 dp_cdp_err("%pK: soc is NULL", soc); 8419 return QDF_STATUS_E_INVAL; 8420 } 8421 8422 qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock); 8423 8424 soc->sysfs_config->stat_type_requested = stat_type; 8425 soc->sysfs_config->mac_id = mac_id; 8426 8427 qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock); 8428 8429 return QDF_STATUS_SUCCESS; 8430 } 8431 8432 static 8433 QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl) 8434 { 8435 struct dp_soc *soc; 8436 QDF_STATUS status; 8437 8438 if (!soc_hdl) { 8439 dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); 8440 return QDF_STATUS_E_INVAL; 8441 } 8442 8443 soc = soc_hdl; 8444 8445 soc->sysfs_config = qdf_mem_malloc(sizeof(struct sysfs_stats_config)); 8446 if (!soc->sysfs_config) { 8447 dp_cdp_err("failed to allocate memory for sysfs_config no memory"); 8448 return QDF_STATUS_E_NOMEM; 8449 } 8450 8451 status = qdf_event_create(&soc->sysfs_config->sysfs_txrx_fw_request_done); 8452 /* create event for fw stats request from sysfs */ 8453 if (status != QDF_STATUS_SUCCESS) { 8454 dp_cdp_err("failed to create event sysfs_txrx_fw_request_done"); 8455 qdf_mem_free(soc->sysfs_config); 8456 soc->sysfs_config = NULL; 8457 return QDF_STATUS_E_FAILURE; 8458 } 8459 8460 qdf_spinlock_create(&soc->sysfs_config->rw_stats_lock); 8461 qdf_mutex_create(&soc->sysfs_config->sysfs_read_lock); 8462 qdf_spinlock_create(&soc->sysfs_config->sysfs_write_user_buffer); 8463 8464 return QDF_STATUS_SUCCESS; 8465 } 8466 8467 static 8468 QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl) 8469 { 8470 struct dp_soc *soc; 8471 QDF_STATUS status; 8472 8473 if (!soc_hdl) { 8474 dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); 8475 return QDF_STATUS_E_INVAL; 8476 } 8477 8478 soc = soc_hdl; 8479 if (!soc->sysfs_config) { 8480 dp_cdp_err("soc->sysfs_config is NULL"); 8481 return QDF_STATUS_E_FAILURE; 8482 } 8483 8484 status = qdf_event_destroy(&soc->sysfs_config->sysfs_txrx_fw_request_done); 8485 if (status != QDF_STATUS_SUCCESS) 8486 dp_cdp_err("Failed to destroy event sysfs_txrx_fw_request_done"); 8487 8488 qdf_mutex_destroy(&soc->sysfs_config->sysfs_read_lock); 8489 qdf_spinlock_destroy(&soc->sysfs_config->rw_stats_lock); 8490 qdf_spinlock_destroy(&soc->sysfs_config->sysfs_write_user_buffer); 8491 8492 qdf_mem_free(soc->sysfs_config); 8493 8494 return QDF_STATUS_SUCCESS; 8495 } 8496 8497 #else /* WLAN_SYSFS_DP_STATS */ 8498 8499 static 8500 QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl) 8501 { 8502 return QDF_STATUS_SUCCESS; 8503 } 8504 8505 static 8506 QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl) 8507 { 8508 return QDF_STATUS_SUCCESS; 8509 } 8510 #endif /* WLAN_SYSFS_DP_STATS */ 8511 8512 /** 8513 * dp_txrx_clear_dump_stats() - clear dumpStats 8514 * @soc_hdl: soc handle 8515 * @pdev_id: pdev ID 8516 * @value: stats option 8517 * 8518 * Return: 0 - Success, non-zero - failure 8519 */ 8520 static 8521 QDF_STATUS dp_txrx_clear_dump_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 8522 uint8_t value) 8523 { 8524 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8525 QDF_STATUS status = QDF_STATUS_SUCCESS; 8526 8527 if (!soc) { 8528 dp_err("soc is NULL"); 8529 return QDF_STATUS_E_INVAL; 8530 } 8531 8532 switch (value) { 8533 case CDP_TXRX_TSO_STATS: 8534 dp_txrx_clear_tso_stats(soc); 8535 break; 8536 8537 case CDP_DP_TX_HW_LATENCY_STATS: 8538 dp_pdev_clear_tx_delay_stats(soc); 8539 break; 8540 8541 default: 8542 status = QDF_STATUS_E_INVAL; 8543 break; 8544 } 8545 8546 return status; 8547 } 8548 8549 #ifdef QCA_LL_TX_FLOW_CONTROL_V2 8550 /** 8551 * dp_update_flow_control_parameters() - API to store datapath 8552 * config parameters 8553 * @soc: soc handle 8554 * @params: ini parameter handle 8555 * 8556 * Return: void 8557 */ 8558 static inline 8559 void dp_update_flow_control_parameters(struct dp_soc *soc, 8560 struct cdp_config_params *params) 8561 { 8562 soc->wlan_cfg_ctx->tx_flow_stop_queue_threshold = 8563 params->tx_flow_stop_queue_threshold; 8564 soc->wlan_cfg_ctx->tx_flow_start_queue_offset = 8565 params->tx_flow_start_queue_offset; 8566 } 8567 #else 8568 static inline 8569 void dp_update_flow_control_parameters(struct dp_soc *soc, 8570 struct cdp_config_params *params) 8571 { 8572 } 8573 #endif 8574 8575 #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT 8576 /* Max packet limit for TX Comp packet loop (dp_tx_comp_handler) */ 8577 #define DP_TX_COMP_LOOP_PKT_LIMIT_MAX 1024 8578 8579 /* Max packet limit for RX REAP Loop (dp_rx_process) */ 8580 #define DP_RX_REAP_LOOP_PKT_LIMIT_MAX 1024 8581 8582 static 8583 void dp_update_rx_soft_irq_limit_params(struct dp_soc *soc, 8584 struct cdp_config_params *params) 8585 { 8586 soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit = 8587 params->tx_comp_loop_pkt_limit; 8588 8589 if (params->tx_comp_loop_pkt_limit < DP_TX_COMP_LOOP_PKT_LIMIT_MAX) 8590 soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check = true; 8591 else 8592 soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check = false; 8593 8594 soc->wlan_cfg_ctx->rx_reap_loop_pkt_limit = 8595 params->rx_reap_loop_pkt_limit; 8596 8597 if (params->rx_reap_loop_pkt_limit < DP_RX_REAP_LOOP_PKT_LIMIT_MAX) 8598 soc->wlan_cfg_ctx->rx_enable_eol_data_check = true; 8599 else 8600 soc->wlan_cfg_ctx->rx_enable_eol_data_check = false; 8601 8602 soc->wlan_cfg_ctx->rx_hp_oos_update_limit = 8603 params->rx_hp_oos_update_limit; 8604 8605 dp_info("tx_comp_loop_pkt_limit %u tx_comp_enable_eol_data_check %u rx_reap_loop_pkt_limit %u rx_enable_eol_data_check %u rx_hp_oos_update_limit %u", 8606 soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit, 8607 soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check, 8608 soc->wlan_cfg_ctx->rx_reap_loop_pkt_limit, 8609 soc->wlan_cfg_ctx->rx_enable_eol_data_check, 8610 soc->wlan_cfg_ctx->rx_hp_oos_update_limit); 8611 } 8612 8613 #else 8614 static inline 8615 void dp_update_rx_soft_irq_limit_params(struct dp_soc *soc, 8616 struct cdp_config_params *params) 8617 { } 8618 8619 #endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */ 8620 8621 /** 8622 * dp_update_config_parameters() - API to store datapath 8623 * config parameters 8624 * @psoc: soc handle 8625 * @params: ini parameter handle 8626 * 8627 * Return: status 8628 */ 8629 static 8630 QDF_STATUS dp_update_config_parameters(struct cdp_soc *psoc, 8631 struct cdp_config_params *params) 8632 { 8633 struct dp_soc *soc = (struct dp_soc *)psoc; 8634 8635 if (!(soc)) { 8636 dp_cdp_err("%pK: Invalid handle", soc); 8637 return QDF_STATUS_E_INVAL; 8638 } 8639 8640 soc->wlan_cfg_ctx->tso_enabled = params->tso_enable; 8641 soc->wlan_cfg_ctx->lro_enabled = params->lro_enable; 8642 soc->wlan_cfg_ctx->rx_hash = params->flow_steering_enable; 8643 soc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload = 8644 params->p2p_tcp_udp_checksumoffload; 8645 soc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload = 8646 params->nan_tcp_udp_checksumoffload; 8647 soc->wlan_cfg_ctx->tcp_udp_checksumoffload = 8648 params->tcp_udp_checksumoffload; 8649 soc->wlan_cfg_ctx->napi_enabled = params->napi_enable; 8650 soc->wlan_cfg_ctx->ipa_enabled = params->ipa_enable; 8651 soc->wlan_cfg_ctx->gro_enabled = params->gro_enable; 8652 8653 dp_update_rx_soft_irq_limit_params(soc, params); 8654 dp_update_flow_control_parameters(soc, params); 8655 8656 return QDF_STATUS_SUCCESS; 8657 } 8658 8659 static struct cdp_wds_ops dp_ops_wds = { 8660 .vdev_set_wds = dp_vdev_set_wds, 8661 #ifdef WDS_VENDOR_EXTENSION 8662 .txrx_set_wds_rx_policy = dp_txrx_set_wds_rx_policy, 8663 .txrx_wds_peer_tx_policy_update = dp_txrx_peer_wds_tx_policy_update, 8664 #endif 8665 }; 8666 8667 /** 8668 * dp_txrx_data_tx_cb_set() - set the callback for non standard tx 8669 * @soc_hdl: datapath soc handle 8670 * @vdev_id: virtual interface id 8671 * @callback: callback function 8672 * @ctxt: callback context 8673 * 8674 */ 8675 static void 8676 dp_txrx_data_tx_cb_set(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 8677 ol_txrx_data_tx_cb callback, void *ctxt) 8678 { 8679 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8680 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 8681 DP_MOD_ID_CDP); 8682 8683 if (!vdev) 8684 return; 8685 8686 vdev->tx_non_std_data_callback.func = callback; 8687 vdev->tx_non_std_data_callback.ctxt = ctxt; 8688 8689 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8690 } 8691 8692 /** 8693 * dp_pdev_get_dp_txrx_handle() - get dp handle from pdev 8694 * @soc: datapath soc handle 8695 * @pdev_id: id of datapath pdev handle 8696 * 8697 * Return: opaque pointer to dp txrx handle 8698 */ 8699 static void *dp_pdev_get_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id) 8700 { 8701 struct dp_pdev *pdev = 8702 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 8703 pdev_id); 8704 if (qdf_unlikely(!pdev)) 8705 return NULL; 8706 8707 return pdev->dp_txrx_handle; 8708 } 8709 8710 /** 8711 * dp_pdev_set_dp_txrx_handle() - set dp handle in pdev 8712 * @soc: datapath soc handle 8713 * @pdev_id: id of datapath pdev handle 8714 * @dp_txrx_hdl: opaque pointer for dp_txrx_handle 8715 * 8716 * Return: void 8717 */ 8718 static void 8719 dp_pdev_set_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id, 8720 void *dp_txrx_hdl) 8721 { 8722 struct dp_pdev *pdev = 8723 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 8724 pdev_id); 8725 8726 if (!pdev) 8727 return; 8728 8729 pdev->dp_txrx_handle = dp_txrx_hdl; 8730 } 8731 8732 /** 8733 * dp_vdev_get_dp_ext_handle() - get dp handle from vdev 8734 * @soc_hdl: datapath soc handle 8735 * @vdev_id: vdev id 8736 * 8737 * Return: opaque pointer to dp txrx handle 8738 */ 8739 static void *dp_vdev_get_dp_ext_handle(ol_txrx_soc_handle soc_hdl, 8740 uint8_t vdev_id) 8741 { 8742 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8743 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 8744 DP_MOD_ID_CDP); 8745 void *dp_ext_handle; 8746 8747 if (!vdev) 8748 return NULL; 8749 dp_ext_handle = vdev->vdev_dp_ext_handle; 8750 8751 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8752 return dp_ext_handle; 8753 } 8754 8755 /** 8756 * dp_vdev_set_dp_ext_handle() - set dp handle in vdev 8757 * @soc_hdl: datapath soc handle 8758 * @vdev_id: vdev id 8759 * @size: size of advance dp handle 8760 * 8761 * Return: QDF_STATUS 8762 */ 8763 static QDF_STATUS 8764 dp_vdev_set_dp_ext_handle(ol_txrx_soc_handle soc_hdl, uint8_t vdev_id, 8765 uint16_t size) 8766 { 8767 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8768 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 8769 DP_MOD_ID_CDP); 8770 void *dp_ext_handle; 8771 8772 if (!vdev) 8773 return QDF_STATUS_E_FAILURE; 8774 8775 dp_ext_handle = qdf_mem_malloc(size); 8776 8777 if (!dp_ext_handle) { 8778 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8779 return QDF_STATUS_E_FAILURE; 8780 } 8781 8782 vdev->vdev_dp_ext_handle = dp_ext_handle; 8783 8784 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8785 return QDF_STATUS_SUCCESS; 8786 } 8787 8788 /** 8789 * dp_vdev_inform_ll_conn() - Inform vdev to add/delete a latency critical 8790 * connection for this vdev 8791 * @soc_hdl: CDP soc handle 8792 * @vdev_id: vdev ID 8793 * @action: Add/Delete action 8794 * 8795 * Return: QDF_STATUS. 8796 */ 8797 static QDF_STATUS 8798 dp_vdev_inform_ll_conn(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 8799 enum vdev_ll_conn_actions action) 8800 { 8801 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8802 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 8803 DP_MOD_ID_CDP); 8804 8805 if (!vdev) { 8806 dp_err("LL connection action for invalid vdev %d", vdev_id); 8807 return QDF_STATUS_E_FAILURE; 8808 } 8809 8810 switch (action) { 8811 case CDP_VDEV_LL_CONN_ADD: 8812 vdev->num_latency_critical_conn++; 8813 break; 8814 8815 case CDP_VDEV_LL_CONN_DEL: 8816 vdev->num_latency_critical_conn--; 8817 break; 8818 8819 default: 8820 dp_err("LL connection action invalid %d", action); 8821 break; 8822 } 8823 8824 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 8825 return QDF_STATUS_SUCCESS; 8826 } 8827 8828 #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR 8829 /** 8830 * dp_soc_set_swlm_enable() - Enable/Disable SWLM if initialized. 8831 * @soc_hdl: CDP Soc handle 8832 * @value: Enable/Disable value 8833 * 8834 * Return: QDF_STATUS 8835 */ 8836 static QDF_STATUS dp_soc_set_swlm_enable(struct cdp_soc_t *soc_hdl, 8837 uint8_t value) 8838 { 8839 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8840 8841 if (!soc->swlm.is_init) { 8842 dp_err("SWLM is not initialized"); 8843 return QDF_STATUS_E_FAILURE; 8844 } 8845 8846 soc->swlm.is_enabled = !!value; 8847 8848 return QDF_STATUS_SUCCESS; 8849 } 8850 8851 /** 8852 * dp_soc_is_swlm_enabled() - Check if SWLM is enabled. 8853 * @soc_hdl: CDP Soc handle 8854 * 8855 * Return: QDF_STATUS 8856 */ 8857 static uint8_t dp_soc_is_swlm_enabled(struct cdp_soc_t *soc_hdl) 8858 { 8859 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 8860 8861 return soc->swlm.is_enabled; 8862 } 8863 #endif 8864 8865 /** 8866 * dp_soc_get_dp_txrx_handle() - get context for external-dp from dp soc 8867 * @soc_handle: datapath soc handle 8868 * 8869 * Return: opaque pointer to external dp (non-core DP) 8870 */ 8871 static void *dp_soc_get_dp_txrx_handle(struct cdp_soc *soc_handle) 8872 { 8873 struct dp_soc *soc = (struct dp_soc *)soc_handle; 8874 8875 return soc->external_txrx_handle; 8876 } 8877 8878 /** 8879 * dp_soc_set_dp_txrx_handle() - set external dp handle in soc 8880 * @soc_handle: datapath soc handle 8881 * @txrx_handle: opaque pointer to external dp (non-core DP) 8882 * 8883 * Return: void 8884 */ 8885 static void 8886 dp_soc_set_dp_txrx_handle(struct cdp_soc *soc_handle, void *txrx_handle) 8887 { 8888 struct dp_soc *soc = (struct dp_soc *)soc_handle; 8889 8890 soc->external_txrx_handle = txrx_handle; 8891 } 8892 8893 /** 8894 * dp_soc_map_pdev_to_lmac() - Save pdev_id to lmac_id mapping 8895 * @soc_hdl: datapath soc handle 8896 * @pdev_id: id of the datapath pdev handle 8897 * @lmac_id: lmac id 8898 * 8899 * Return: QDF_STATUS 8900 */ 8901 static QDF_STATUS 8902 dp_soc_map_pdev_to_lmac 8903 (struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 8904 uint32_t lmac_id) 8905 { 8906 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 8907 8908 wlan_cfg_set_hw_mac_idx(soc->wlan_cfg_ctx, 8909 pdev_id, 8910 lmac_id); 8911 8912 /*Set host PDEV ID for lmac_id*/ 8913 wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx, 8914 pdev_id, 8915 lmac_id); 8916 8917 return QDF_STATUS_SUCCESS; 8918 } 8919 8920 /** 8921 * dp_soc_handle_pdev_mode_change() - Update pdev to lmac mapping 8922 * @soc_hdl: datapath soc handle 8923 * @pdev_id: id of the datapath pdev handle 8924 * @lmac_id: lmac id 8925 * 8926 * In the event of a dynamic mode change, update the pdev to lmac mapping 8927 * 8928 * Return: QDF_STATUS 8929 */ 8930 static QDF_STATUS 8931 dp_soc_handle_pdev_mode_change 8932 (struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 8933 uint32_t lmac_id) 8934 { 8935 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 8936 struct dp_vdev *vdev = NULL; 8937 uint8_t hw_pdev_id, mac_id; 8938 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, 8939 pdev_id); 8940 int nss_config = wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx); 8941 8942 if (qdf_unlikely(!pdev)) 8943 return QDF_STATUS_E_FAILURE; 8944 8945 pdev->lmac_id = lmac_id; 8946 pdev->target_pdev_id = 8947 dp_calculate_target_pdev_id_from_host_pdev_id(soc, pdev_id); 8948 dp_info(" mode change %d %d\n", pdev->pdev_id, pdev->lmac_id); 8949 8950 /*Set host PDEV ID for lmac_id*/ 8951 wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx, 8952 pdev->pdev_id, 8953 lmac_id); 8954 8955 hw_pdev_id = 8956 dp_get_target_pdev_id_for_host_pdev_id(soc, 8957 pdev->pdev_id); 8958 8959 /* 8960 * When NSS offload is enabled, send pdev_id->lmac_id 8961 * and pdev_id to hw_pdev_id to NSS FW 8962 */ 8963 if (nss_config) { 8964 mac_id = pdev->lmac_id; 8965 if (soc->cdp_soc.ol_ops->pdev_update_lmac_n_target_pdev_id) 8966 soc->cdp_soc.ol_ops-> 8967 pdev_update_lmac_n_target_pdev_id( 8968 soc->ctrl_psoc, 8969 &pdev_id, &mac_id, &hw_pdev_id); 8970 } 8971 8972 qdf_spin_lock_bh(&pdev->vdev_list_lock); 8973 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 8974 DP_TX_TCL_METADATA_PDEV_ID_SET(vdev->htt_tcl_metadata, 8975 hw_pdev_id); 8976 vdev->lmac_id = pdev->lmac_id; 8977 } 8978 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 8979 8980 return QDF_STATUS_SUCCESS; 8981 } 8982 8983 /** 8984 * dp_soc_set_pdev_status_down() - set pdev down/up status 8985 * @soc: datapath soc handle 8986 * @pdev_id: id of datapath pdev handle 8987 * @is_pdev_down: pdev down/up status 8988 * 8989 * Return: QDF_STATUS 8990 */ 8991 static QDF_STATUS 8992 dp_soc_set_pdev_status_down(struct cdp_soc_t *soc, uint8_t pdev_id, 8993 bool is_pdev_down) 8994 { 8995 struct dp_pdev *pdev = 8996 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 8997 pdev_id); 8998 if (!pdev) 8999 return QDF_STATUS_E_FAILURE; 9000 9001 pdev->is_pdev_down = is_pdev_down; 9002 return QDF_STATUS_SUCCESS; 9003 } 9004 9005 /** 9006 * dp_get_cfg_capabilities() - get dp capabilities 9007 * @soc_handle: datapath soc handle 9008 * @dp_caps: enum for dp capabilities 9009 * 9010 * Return: bool to determine if dp caps is enabled 9011 */ 9012 static bool 9013 dp_get_cfg_capabilities(struct cdp_soc_t *soc_handle, 9014 enum cdp_capabilities dp_caps) 9015 { 9016 struct dp_soc *soc = (struct dp_soc *)soc_handle; 9017 9018 return wlan_cfg_get_dp_caps(soc->wlan_cfg_ctx, dp_caps); 9019 } 9020 9021 #ifdef FEATURE_AST 9022 static QDF_STATUS 9023 dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 9024 uint8_t *peer_mac) 9025 { 9026 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9027 QDF_STATUS status = QDF_STATUS_SUCCESS; 9028 struct dp_peer *peer = 9029 dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, 9030 DP_MOD_ID_CDP); 9031 9032 /* Peer can be null for monitor vap mac address */ 9033 if (!peer) { 9034 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, 9035 "%s: Invalid peer\n", __func__); 9036 return QDF_STATUS_E_FAILURE; 9037 } 9038 9039 dp_peer_update_state(soc, peer, DP_PEER_STATE_LOGICAL_DELETE); 9040 9041 qdf_spin_lock_bh(&soc->ast_lock); 9042 dp_peer_send_wds_disconnect(soc, peer); 9043 dp_peer_delete_ast_entries(soc, peer); 9044 qdf_spin_unlock_bh(&soc->ast_lock); 9045 9046 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 9047 return status; 9048 } 9049 #endif 9050 9051 #ifndef WLAN_SUPPORT_RX_TAG_STATISTICS 9052 /** 9053 * dp_dump_pdev_rx_protocol_tag_stats - dump the number of packets tagged for 9054 * given protocol type (RX_PROTOCOL_TAG_ALL indicates for all protocol) 9055 * @soc: cdp_soc handle 9056 * @pdev_id: id of cdp_pdev handle 9057 * @protocol_type: protocol type for which stats should be displayed 9058 * 9059 * Return: none 9060 */ 9061 static inline void 9062 dp_dump_pdev_rx_protocol_tag_stats(struct cdp_soc_t *soc, uint8_t pdev_id, 9063 uint16_t protocol_type) 9064 { 9065 } 9066 #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ 9067 9068 #ifndef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG 9069 /** 9070 * dp_update_pdev_rx_protocol_tag() - Add/remove a protocol tag that should be 9071 * applied to the desired protocol type packets 9072 * @soc: soc handle 9073 * @pdev_id: id of cdp_pdev handle 9074 * @enable_rx_protocol_tag: bitmask that indicates what protocol types 9075 * are enabled for tagging. zero indicates disable feature, non-zero indicates 9076 * enable feature 9077 * @protocol_type: new protocol type for which the tag is being added 9078 * @tag: user configured tag for the new protocol 9079 * 9080 * Return: Success 9081 */ 9082 static inline QDF_STATUS 9083 dp_update_pdev_rx_protocol_tag(struct cdp_soc_t *soc, uint8_t pdev_id, 9084 uint32_t enable_rx_protocol_tag, 9085 uint16_t protocol_type, 9086 uint16_t tag) 9087 { 9088 return QDF_STATUS_SUCCESS; 9089 } 9090 #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ 9091 9092 #ifndef WLAN_SUPPORT_RX_FLOW_TAG 9093 /** 9094 * dp_set_rx_flow_tag() - add/delete a flow 9095 * @cdp_soc: CDP soc handle 9096 * @pdev_id: id of cdp_pdev handle 9097 * @flow_info: flow tuple that is to be added to/deleted from flow search table 9098 * 9099 * Return: Success 9100 */ 9101 static inline QDF_STATUS 9102 dp_set_rx_flow_tag(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, 9103 struct cdp_rx_flow_info *flow_info) 9104 { 9105 return QDF_STATUS_SUCCESS; 9106 } 9107 /** 9108 * dp_dump_rx_flow_tag_stats() - dump the number of packets tagged for 9109 * given flow 5-tuple 9110 * @cdp_soc: soc handle 9111 * @pdev_id: id of cdp_pdev handle 9112 * @flow_info: flow 5-tuple for which stats should be displayed 9113 * 9114 * Return: Success 9115 */ 9116 static inline QDF_STATUS 9117 dp_dump_rx_flow_tag_stats(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, 9118 struct cdp_rx_flow_info *flow_info) 9119 { 9120 return QDF_STATUS_SUCCESS; 9121 } 9122 #endif /* WLAN_SUPPORT_RX_FLOW_TAG */ 9123 9124 static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t *soc_hdl, 9125 uint32_t max_peers, 9126 uint32_t max_ast_index, 9127 uint8_t peer_map_unmap_versions) 9128 { 9129 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9130 QDF_STATUS status; 9131 9132 soc->max_peers = max_peers; 9133 9134 wlan_cfg_set_max_ast_idx(soc->wlan_cfg_ctx, max_ast_index); 9135 9136 status = soc->arch_ops.txrx_peer_map_attach(soc); 9137 if (!QDF_IS_STATUS_SUCCESS(status)) { 9138 dp_err("failure in allocating peer tables"); 9139 return QDF_STATUS_E_FAILURE; 9140 } 9141 9142 dp_info("max_peers %u, calculated max_peers %u max_ast_index: %u\n", 9143 max_peers, soc->max_peer_id, max_ast_index); 9144 9145 status = dp_peer_find_attach(soc); 9146 if (!QDF_IS_STATUS_SUCCESS(status)) { 9147 dp_err("Peer find attach failure"); 9148 goto fail; 9149 } 9150 9151 soc->peer_map_unmap_versions = peer_map_unmap_versions; 9152 soc->peer_map_attach_success = TRUE; 9153 9154 return QDF_STATUS_SUCCESS; 9155 fail: 9156 soc->arch_ops.txrx_peer_map_detach(soc); 9157 9158 return status; 9159 } 9160 9161 static QDF_STATUS dp_soc_set_param(struct cdp_soc_t *soc_hdl, 9162 enum cdp_soc_param_t param, 9163 uint32_t value) 9164 { 9165 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9166 9167 switch (param) { 9168 case DP_SOC_PARAM_MSDU_EXCEPTION_DESC: 9169 soc->num_msdu_exception_desc = value; 9170 dp_info("num_msdu exception_desc %u", 9171 value); 9172 break; 9173 case DP_SOC_PARAM_CMEM_FSE_SUPPORT: 9174 if (wlan_cfg_is_fst_in_cmem_enabled(soc->wlan_cfg_ctx)) 9175 soc->fst_in_cmem = !!value; 9176 dp_info("FW supports CMEM FSE %u", value); 9177 break; 9178 case DP_SOC_PARAM_MAX_AST_AGEOUT: 9179 soc->max_ast_ageout_count = value; 9180 dp_info("Max ast ageout count %u", soc->max_ast_ageout_count); 9181 break; 9182 case DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT: 9183 soc->eapol_over_control_port = value; 9184 dp_info("Eapol over control_port:%d", 9185 soc->eapol_over_control_port); 9186 break; 9187 case DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT: 9188 soc->multi_peer_grp_cmd_supported = value; 9189 dp_info("Multi Peer group command support:%d", 9190 soc->multi_peer_grp_cmd_supported); 9191 break; 9192 case DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT: 9193 soc->features.rssi_dbm_conv_support = value; 9194 dp_info("Rssi dbm conversion support:%u", 9195 soc->features.rssi_dbm_conv_support); 9196 break; 9197 case DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT: 9198 soc->features.umac_hw_reset_support = value; 9199 dp_info("UMAC HW reset support :%u", 9200 soc->features.umac_hw_reset_support); 9201 break; 9202 default: 9203 dp_info("not handled param %d ", param); 9204 break; 9205 } 9206 9207 return QDF_STATUS_SUCCESS; 9208 } 9209 9210 static void dp_soc_set_rate_stats_ctx(struct cdp_soc_t *soc_handle, 9211 void *stats_ctx) 9212 { 9213 struct dp_soc *soc = (struct dp_soc *)soc_handle; 9214 9215 soc->rate_stats_ctx = (struct cdp_soc_rate_stats_ctx *)stats_ctx; 9216 } 9217 9218 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 9219 /** 9220 * dp_peer_flush_rate_stats_req() - Flush peer rate stats 9221 * @soc: Datapath SOC handle 9222 * @peer: Datapath peer 9223 * @arg: argument to iter function 9224 * 9225 * Return: QDF_STATUS 9226 */ 9227 static void 9228 dp_peer_flush_rate_stats_req(struct dp_soc *soc, struct dp_peer *peer, 9229 void *arg) 9230 { 9231 /* Skip self peer */ 9232 if (!qdf_mem_cmp(peer->mac_addr.raw, peer->vdev->mac_addr.raw, 9233 QDF_MAC_ADDR_SIZE)) 9234 return; 9235 9236 dp_wdi_event_handler( 9237 WDI_EVENT_FLUSH_RATE_STATS_REQ, 9238 soc, dp_monitor_peer_get_peerstats_ctx(soc, peer), 9239 peer->peer_id, 9240 WDI_NO_VAL, peer->vdev->pdev->pdev_id); 9241 } 9242 9243 /** 9244 * dp_flush_rate_stats_req() - Flush peer rate stats in pdev 9245 * @soc_hdl: Datapath SOC handle 9246 * @pdev_id: pdev_id 9247 * 9248 * Return: QDF_STATUS 9249 */ 9250 static QDF_STATUS dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, 9251 uint8_t pdev_id) 9252 { 9253 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9254 struct dp_pdev *pdev = 9255 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 9256 pdev_id); 9257 if (!pdev) 9258 return QDF_STATUS_E_FAILURE; 9259 9260 dp_pdev_iterate_peer(pdev, dp_peer_flush_rate_stats_req, NULL, 9261 DP_MOD_ID_CDP); 9262 9263 return QDF_STATUS_SUCCESS; 9264 } 9265 #else 9266 static inline QDF_STATUS 9267 dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, 9268 uint8_t pdev_id) 9269 { 9270 return QDF_STATUS_SUCCESS; 9271 } 9272 #endif 9273 9274 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 9275 #ifdef WLAN_FEATURE_11BE_MLO 9276 /** 9277 * dp_get_peer_extd_rate_link_stats() - function to get peer 9278 * extended rate and link stats 9279 * @soc_hdl: dp soc handler 9280 * @mac_addr: mac address of peer 9281 * 9282 * Return: QDF_STATUS 9283 */ 9284 static QDF_STATUS 9285 dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr) 9286 { 9287 uint8_t i; 9288 struct dp_peer *link_peer; 9289 struct dp_soc *link_peer_soc; 9290 struct dp_mld_link_peers link_peers_info; 9291 struct dp_peer *peer = NULL; 9292 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9293 struct cdp_peer_info peer_info = { 0 }; 9294 9295 if (!mac_addr) { 9296 dp_err("NULL peer mac addr\n"); 9297 return QDF_STATUS_E_FAILURE; 9298 } 9299 9300 DP_PEER_INFO_PARAMS_INIT(&peer_info, DP_VDEV_ALL, mac_addr, false, 9301 CDP_WILD_PEER_TYPE); 9302 9303 peer = dp_peer_hash_find_wrapper(soc, &peer_info, DP_MOD_ID_CDP); 9304 if (!peer) { 9305 dp_err("Invalid peer\n"); 9306 return QDF_STATUS_E_FAILURE; 9307 } 9308 9309 if (IS_MLO_DP_MLD_PEER(peer)) { 9310 dp_get_link_peers_ref_from_mld_peer(soc, peer, 9311 &link_peers_info, 9312 DP_MOD_ID_CDP); 9313 for (i = 0; i < link_peers_info.num_links; i++) { 9314 link_peer = link_peers_info.link_peers[i]; 9315 link_peer_soc = link_peer->vdev->pdev->soc; 9316 dp_wdi_event_handler(WDI_EVENT_FLUSH_RATE_STATS_REQ, 9317 link_peer_soc, 9318 dp_monitor_peer_get_peerstats_ctx 9319 (link_peer_soc, link_peer), 9320 link_peer->peer_id, 9321 WDI_NO_VAL, 9322 link_peer->vdev->pdev->pdev_id); 9323 } 9324 dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP); 9325 } else { 9326 dp_wdi_event_handler( 9327 WDI_EVENT_FLUSH_RATE_STATS_REQ, soc, 9328 dp_monitor_peer_get_peerstats_ctx(soc, peer), 9329 peer->peer_id, 9330 WDI_NO_VAL, peer->vdev->pdev->pdev_id); 9331 } 9332 9333 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 9334 return QDF_STATUS_SUCCESS; 9335 } 9336 #else 9337 static QDF_STATUS 9338 dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr) 9339 { 9340 struct dp_peer *peer = NULL; 9341 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9342 9343 if (!mac_addr) { 9344 dp_err("NULL peer mac addr\n"); 9345 return QDF_STATUS_E_FAILURE; 9346 } 9347 9348 peer = dp_peer_find_hash_find(soc, mac_addr, 0, 9349 DP_VDEV_ALL, DP_MOD_ID_CDP); 9350 if (!peer) { 9351 dp_err("Invalid peer\n"); 9352 return QDF_STATUS_E_FAILURE; 9353 } 9354 9355 dp_wdi_event_handler( 9356 WDI_EVENT_FLUSH_RATE_STATS_REQ, soc, 9357 dp_monitor_peer_get_peerstats_ctx(soc, peer), 9358 peer->peer_id, 9359 WDI_NO_VAL, peer->vdev->pdev->pdev_id); 9360 9361 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 9362 return QDF_STATUS_SUCCESS; 9363 } 9364 #endif 9365 #else 9366 static inline QDF_STATUS 9367 dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr) 9368 { 9369 return QDF_STATUS_SUCCESS; 9370 } 9371 #endif 9372 9373 static void *dp_peer_get_peerstats_ctx(struct cdp_soc_t *soc_hdl, 9374 uint8_t vdev_id, 9375 uint8_t *mac_addr) 9376 { 9377 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 9378 struct dp_peer *peer; 9379 void *peerstats_ctx = NULL; 9380 9381 if (mac_addr) { 9382 peer = dp_peer_find_hash_find(soc, mac_addr, 9383 0, vdev_id, 9384 DP_MOD_ID_CDP); 9385 if (!peer) 9386 return NULL; 9387 9388 if (!IS_MLO_DP_MLD_PEER(peer)) 9389 peerstats_ctx = dp_monitor_peer_get_peerstats_ctx(soc, 9390 peer); 9391 9392 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 9393 } 9394 9395 return peerstats_ctx; 9396 } 9397 9398 #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE 9399 static QDF_STATUS dp_peer_flush_rate_stats(struct cdp_soc_t *soc, 9400 uint8_t pdev_id, 9401 void *buf) 9402 { 9403 dp_wdi_event_handler(WDI_EVENT_PEER_FLUSH_RATE_STATS, 9404 (struct dp_soc *)soc, buf, HTT_INVALID_PEER, 9405 WDI_NO_VAL, pdev_id); 9406 return QDF_STATUS_SUCCESS; 9407 } 9408 #else 9409 static inline QDF_STATUS 9410 dp_peer_flush_rate_stats(struct cdp_soc_t *soc, 9411 uint8_t pdev_id, 9412 void *buf) 9413 { 9414 return QDF_STATUS_SUCCESS; 9415 } 9416 #endif 9417 9418 static void *dp_soc_get_rate_stats_ctx(struct cdp_soc_t *soc_handle) 9419 { 9420 struct dp_soc *soc = (struct dp_soc *)soc_handle; 9421 9422 return soc->rate_stats_ctx; 9423 } 9424 9425 /** 9426 * dp_get_cfg() - get dp cfg 9427 * @soc: cdp soc handle 9428 * @cfg: cfg enum 9429 * 9430 * Return: cfg value 9431 */ 9432 static uint32_t dp_get_cfg(struct cdp_soc_t *soc, enum cdp_dp_cfg cfg) 9433 { 9434 struct dp_soc *dpsoc = (struct dp_soc *)soc; 9435 uint32_t value = 0; 9436 9437 switch (cfg) { 9438 case cfg_dp_enable_data_stall: 9439 value = dpsoc->wlan_cfg_ctx->enable_data_stall_detection; 9440 break; 9441 case cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload: 9442 value = dpsoc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload; 9443 break; 9444 case cfg_dp_enable_nan_ip_tcp_udp_checksum_offload: 9445 value = dpsoc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload; 9446 break; 9447 case cfg_dp_enable_ip_tcp_udp_checksum_offload: 9448 value = dpsoc->wlan_cfg_ctx->tcp_udp_checksumoffload; 9449 break; 9450 case cfg_dp_disable_legacy_mode_csum_offload: 9451 value = dpsoc->wlan_cfg_ctx-> 9452 legacy_mode_checksumoffload_disable; 9453 break; 9454 case cfg_dp_tso_enable: 9455 value = dpsoc->wlan_cfg_ctx->tso_enabled; 9456 break; 9457 case cfg_dp_lro_enable: 9458 value = dpsoc->wlan_cfg_ctx->lro_enabled; 9459 break; 9460 case cfg_dp_gro_enable: 9461 value = dpsoc->wlan_cfg_ctx->gro_enabled; 9462 break; 9463 case cfg_dp_tc_based_dyn_gro_enable: 9464 value = dpsoc->wlan_cfg_ctx->tc_based_dynamic_gro; 9465 break; 9466 case cfg_dp_tc_ingress_prio: 9467 value = dpsoc->wlan_cfg_ctx->tc_ingress_prio; 9468 break; 9469 case cfg_dp_sg_enable: 9470 value = dpsoc->wlan_cfg_ctx->sg_enabled; 9471 break; 9472 case cfg_dp_tx_flow_start_queue_offset: 9473 value = dpsoc->wlan_cfg_ctx->tx_flow_start_queue_offset; 9474 break; 9475 case cfg_dp_tx_flow_stop_queue_threshold: 9476 value = dpsoc->wlan_cfg_ctx->tx_flow_stop_queue_threshold; 9477 break; 9478 case cfg_dp_disable_intra_bss_fwd: 9479 value = dpsoc->wlan_cfg_ctx->disable_intra_bss_fwd; 9480 break; 9481 case cfg_dp_pktlog_buffer_size: 9482 value = dpsoc->wlan_cfg_ctx->pktlog_buffer_size; 9483 break; 9484 case cfg_dp_wow_check_rx_pending: 9485 value = dpsoc->wlan_cfg_ctx->wow_check_rx_pending_enable; 9486 break; 9487 default: 9488 value = 0; 9489 } 9490 9491 return value; 9492 } 9493 9494 #ifdef PEER_FLOW_CONTROL 9495 /** 9496 * dp_tx_flow_ctrl_configure_pdev() - Configure flow control params 9497 * @soc_handle: datapath soc handle 9498 * @pdev_id: id of datapath pdev handle 9499 * @param: ol ath params 9500 * @value: value of the flag 9501 * @buff: Buffer to be passed 9502 * 9503 * Implemented this function same as legacy function. In legacy code, single 9504 * function is used to display stats and update pdev params. 9505 * 9506 * Return: 0 for success. nonzero for failure. 9507 */ 9508 static uint32_t dp_tx_flow_ctrl_configure_pdev(struct cdp_soc_t *soc_handle, 9509 uint8_t pdev_id, 9510 enum _dp_param_t param, 9511 uint32_t value, void *buff) 9512 { 9513 struct dp_soc *soc = (struct dp_soc *)soc_handle; 9514 struct dp_pdev *pdev = 9515 dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, 9516 pdev_id); 9517 9518 if (qdf_unlikely(!pdev)) 9519 return 1; 9520 9521 soc = pdev->soc; 9522 if (!soc) 9523 return 1; 9524 9525 switch (param) { 9526 #ifdef QCA_ENH_V3_STATS_SUPPORT 9527 case DP_PARAM_VIDEO_DELAY_STATS_FC: 9528 if (value) 9529 pdev->delay_stats_flag = true; 9530 else 9531 pdev->delay_stats_flag = false; 9532 break; 9533 case DP_PARAM_VIDEO_STATS_FC: 9534 qdf_print("------- TID Stats ------\n"); 9535 dp_pdev_print_tid_stats(pdev); 9536 qdf_print("------ Delay Stats ------\n"); 9537 dp_pdev_print_delay_stats(pdev); 9538 qdf_print("------ Rx Error Stats ------\n"); 9539 dp_pdev_print_rx_error_stats(pdev); 9540 break; 9541 #endif 9542 case DP_PARAM_TOTAL_Q_SIZE: 9543 { 9544 uint32_t tx_min, tx_max; 9545 9546 tx_min = wlan_cfg_get_min_tx_desc(soc->wlan_cfg_ctx); 9547 tx_max = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); 9548 9549 if (!buff) { 9550 if ((value >= tx_min) && (value <= tx_max)) { 9551 pdev->num_tx_allowed = value; 9552 } else { 9553 dp_tx_info("%pK: Failed to update num_tx_allowed, Q_min = %d Q_max = %d", 9554 soc, tx_min, tx_max); 9555 break; 9556 } 9557 } else { 9558 *(int *)buff = pdev->num_tx_allowed; 9559 } 9560 } 9561 break; 9562 default: 9563 dp_tx_info("%pK: not handled param %d ", soc, param); 9564 break; 9565 } 9566 9567 return 0; 9568 } 9569 #endif 9570 9571 #ifdef DP_UMAC_HW_RESET_SUPPORT 9572 /** 9573 * dp_reset_interrupt_ring_masks() - Reset rx interrupt masks 9574 * @soc: dp soc handle 9575 * 9576 * Return: void 9577 */ 9578 static void dp_reset_interrupt_ring_masks(struct dp_soc *soc) 9579 { 9580 struct dp_intr_bkp *intr_bkp; 9581 struct dp_intr *intr_ctx; 9582 int num_ctxt = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); 9583 int i; 9584 9585 intr_bkp = 9586 (struct dp_intr_bkp *)qdf_mem_malloc_atomic(sizeof(struct dp_intr_bkp) * 9587 num_ctxt); 9588 9589 qdf_assert_always(intr_bkp); 9590 9591 soc->umac_reset_ctx.intr_ctx_bkp = intr_bkp; 9592 for (i = 0; i < num_ctxt; i++) { 9593 intr_ctx = &soc->intr_ctx[i]; 9594 9595 intr_bkp->tx_ring_mask = intr_ctx->tx_ring_mask; 9596 intr_bkp->rx_ring_mask = intr_ctx->rx_ring_mask; 9597 intr_bkp->rx_mon_ring_mask = intr_ctx->rx_mon_ring_mask; 9598 intr_bkp->rx_err_ring_mask = intr_ctx->rx_err_ring_mask; 9599 intr_bkp->rx_wbm_rel_ring_mask = intr_ctx->rx_wbm_rel_ring_mask; 9600 intr_bkp->reo_status_ring_mask = intr_ctx->reo_status_ring_mask; 9601 intr_bkp->rxdma2host_ring_mask = intr_ctx->rxdma2host_ring_mask; 9602 intr_bkp->host2rxdma_ring_mask = intr_ctx->host2rxdma_ring_mask; 9603 intr_bkp->host2rxdma_mon_ring_mask = 9604 intr_ctx->host2rxdma_mon_ring_mask; 9605 intr_bkp->tx_mon_ring_mask = intr_ctx->tx_mon_ring_mask; 9606 9607 intr_ctx->tx_ring_mask = 0; 9608 intr_ctx->rx_ring_mask = 0; 9609 intr_ctx->rx_mon_ring_mask = 0; 9610 intr_ctx->rx_err_ring_mask = 0; 9611 intr_ctx->rx_wbm_rel_ring_mask = 0; 9612 intr_ctx->reo_status_ring_mask = 0; 9613 intr_ctx->rxdma2host_ring_mask = 0; 9614 intr_ctx->host2rxdma_ring_mask = 0; 9615 intr_ctx->host2rxdma_mon_ring_mask = 0; 9616 intr_ctx->tx_mon_ring_mask = 0; 9617 9618 intr_bkp++; 9619 } 9620 } 9621 9622 /** 9623 * dp_restore_interrupt_ring_masks() - Restore rx interrupt masks 9624 * @soc: dp soc handle 9625 * 9626 * Return: void 9627 */ 9628 static void dp_restore_interrupt_ring_masks(struct dp_soc *soc) 9629 { 9630 struct dp_intr_bkp *intr_bkp = soc->umac_reset_ctx.intr_ctx_bkp; 9631 struct dp_intr_bkp *intr_bkp_base = intr_bkp; 9632 struct dp_intr *intr_ctx; 9633 int num_ctxt = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); 9634 int i; 9635 9636 if (!intr_bkp) 9637 return; 9638 9639 for (i = 0; i < num_ctxt; i++) { 9640 intr_ctx = &soc->intr_ctx[i]; 9641 9642 intr_ctx->tx_ring_mask = intr_bkp->tx_ring_mask; 9643 intr_ctx->rx_ring_mask = intr_bkp->rx_ring_mask; 9644 intr_ctx->rx_mon_ring_mask = intr_bkp->rx_mon_ring_mask; 9645 intr_ctx->rx_err_ring_mask = intr_bkp->rx_err_ring_mask; 9646 intr_ctx->rx_wbm_rel_ring_mask = intr_bkp->rx_wbm_rel_ring_mask; 9647 intr_ctx->reo_status_ring_mask = intr_bkp->reo_status_ring_mask; 9648 intr_ctx->rxdma2host_ring_mask = intr_bkp->rxdma2host_ring_mask; 9649 intr_ctx->host2rxdma_ring_mask = intr_bkp->host2rxdma_ring_mask; 9650 intr_ctx->host2rxdma_mon_ring_mask = 9651 intr_bkp->host2rxdma_mon_ring_mask; 9652 intr_ctx->tx_mon_ring_mask = intr_bkp->tx_mon_ring_mask; 9653 9654 intr_bkp++; 9655 } 9656 9657 qdf_mem_free(intr_bkp_base); 9658 soc->umac_reset_ctx.intr_ctx_bkp = NULL; 9659 } 9660 9661 /** 9662 * dp_resume_tx_hardstart() - Restore the old Tx hardstart functions 9663 * @soc: dp soc handle 9664 * 9665 * Return: void 9666 */ 9667 static void dp_resume_tx_hardstart(struct dp_soc *soc) 9668 { 9669 struct dp_vdev *vdev; 9670 struct ol_txrx_hardtart_ctxt ctxt = {0}; 9671 struct cdp_ctrl_objmgr_psoc *psoc = soc->ctrl_psoc; 9672 int i; 9673 9674 for (i = 0; i < MAX_PDEV_CNT; i++) { 9675 struct dp_pdev *pdev = soc->pdev_list[i]; 9676 9677 if (!pdev) 9678 continue; 9679 9680 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 9681 uint8_t vdev_id = vdev->vdev_id; 9682 9683 dp_vdev_fetch_tx_handler(vdev, soc, &ctxt); 9684 soc->cdp_soc.ol_ops->dp_update_tx_hardstart(psoc, 9685 vdev_id, 9686 &ctxt); 9687 } 9688 } 9689 } 9690 9691 /** 9692 * dp_pause_tx_hardstart() - Register Tx hardstart functions to drop packets 9693 * @soc: dp soc handle 9694 * 9695 * Return: void 9696 */ 9697 static void dp_pause_tx_hardstart(struct dp_soc *soc) 9698 { 9699 struct dp_vdev *vdev; 9700 struct ol_txrx_hardtart_ctxt ctxt; 9701 struct cdp_ctrl_objmgr_psoc *psoc = soc->ctrl_psoc; 9702 int i; 9703 9704 ctxt.tx = &dp_tx_drop; 9705 ctxt.tx_fast = &dp_tx_drop; 9706 ctxt.tx_exception = &dp_tx_exc_drop; 9707 9708 for (i = 0; i < MAX_PDEV_CNT; i++) { 9709 struct dp_pdev *pdev = soc->pdev_list[i]; 9710 9711 if (!pdev) 9712 continue; 9713 9714 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 9715 uint8_t vdev_id = vdev->vdev_id; 9716 9717 soc->cdp_soc.ol_ops->dp_update_tx_hardstart(psoc, 9718 vdev_id, 9719 &ctxt); 9720 } 9721 } 9722 } 9723 9724 /** 9725 * dp_unregister_notify_umac_pre_reset_fw_callback() - unregister notify_fw_cb 9726 * @soc: dp soc handle 9727 * 9728 * Return: void 9729 */ 9730 static inline 9731 void dp_unregister_notify_umac_pre_reset_fw_callback(struct dp_soc *soc) 9732 { 9733 soc->notify_fw_callback = NULL; 9734 } 9735 9736 /** 9737 * dp_check_n_notify_umac_prereset_done() - Send pre reset done to firmware 9738 * @soc: dp soc handle 9739 * 9740 * Return: void 9741 */ 9742 static inline 9743 void dp_check_n_notify_umac_prereset_done(struct dp_soc *soc) 9744 { 9745 /* Some Cpu(s) is processing the umac rings*/ 9746 if (soc->service_rings_running) 9747 return; 9748 9749 /* Notify the firmware that Umac pre reset is complete */ 9750 dp_umac_reset_notify_action_completion(soc, 9751 UMAC_RESET_ACTION_DO_PRE_RESET); 9752 9753 /* Unregister the callback */ 9754 dp_unregister_notify_umac_pre_reset_fw_callback(soc); 9755 } 9756 9757 /** 9758 * dp_register_notify_umac_pre_reset_fw_callback() - register notify_fw_cb 9759 * @soc: dp soc handle 9760 * 9761 * Return: void 9762 */ 9763 static inline 9764 void dp_register_notify_umac_pre_reset_fw_callback(struct dp_soc *soc) 9765 { 9766 soc->notify_fw_callback = dp_check_n_notify_umac_prereset_done; 9767 } 9768 9769 #ifdef DP_UMAC_HW_HARD_RESET 9770 /** 9771 * dp_set_umac_regs() - Reinitialize host umac registers 9772 * @soc: dp soc handle 9773 * 9774 * Return: void 9775 */ 9776 static void dp_set_umac_regs(struct dp_soc *soc) 9777 { 9778 int i; 9779 struct hal_reo_params reo_params; 9780 9781 qdf_mem_zero(&reo_params, sizeof(reo_params)); 9782 9783 if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { 9784 if (soc->arch_ops.reo_remap_config(soc, &reo_params.remap0, 9785 &reo_params.remap1, 9786 &reo_params.remap2)) 9787 reo_params.rx_hash_enabled = true; 9788 else 9789 reo_params.rx_hash_enabled = false; 9790 } 9791 9792 reo_params.reo_qref = &soc->reo_qref; 9793 hal_reo_setup(soc->hal_soc, &reo_params, 0); 9794 9795 soc->arch_ops.dp_cc_reg_cfg_init(soc, true); 9796 9797 for (i = 0; i < PCP_TID_MAP_MAX; i++) 9798 hal_tx_update_pcp_tid_map(soc->hal_soc, soc->pcp_tid_map[i], i); 9799 9800 for (i = 0; i < MAX_PDEV_CNT; i++) { 9801 struct dp_vdev *vdev = NULL; 9802 struct dp_pdev *pdev = soc->pdev_list[i]; 9803 9804 if (!pdev) 9805 continue; 9806 9807 for (i = 0; i < soc->num_hw_dscp_tid_map; i++) 9808 hal_tx_set_dscp_tid_map(soc->hal_soc, 9809 pdev->dscp_tid_map[i], i); 9810 9811 TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { 9812 soc->arch_ops.dp_bank_reconfig(soc, vdev); 9813 soc->arch_ops.dp_reconfig_tx_vdev_mcast_ctrl(soc, 9814 vdev); 9815 } 9816 } 9817 } 9818 #else 9819 static void dp_set_umac_regs(struct dp_soc *soc) 9820 { 9821 } 9822 #endif 9823 9824 /** 9825 * dp_reinit_rings() - Reinitialize host managed rings 9826 * @soc: dp soc handle 9827 * 9828 * Return: QDF_STATUS 9829 */ 9830 static void dp_reinit_rings(struct dp_soc *soc) 9831 { 9832 unsigned long end; 9833 9834 dp_soc_srng_deinit(soc); 9835 dp_hw_link_desc_ring_deinit(soc); 9836 9837 /* Busy wait for 2 ms to make sure the rings are in idle state 9838 * before we enable them again 9839 */ 9840 end = jiffies + msecs_to_jiffies(2); 9841 while (time_before(jiffies, end)) 9842 ; 9843 9844 dp_hw_link_desc_ring_init(soc); 9845 dp_link_desc_ring_replenish(soc, WLAN_INVALID_PDEV_ID); 9846 dp_soc_srng_init(soc); 9847 } 9848 9849 /** 9850 * dp_umac_reset_action_trigger_recovery() - Handle FW Umac recovery trigger 9851 * @soc: dp soc handle 9852 * 9853 * Return: QDF_STATUS 9854 */ 9855 static QDF_STATUS dp_umac_reset_action_trigger_recovery(struct dp_soc *soc) 9856 { 9857 enum umac_reset_action action = UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY; 9858 9859 return dp_umac_reset_notify_action_completion(soc, action); 9860 } 9861 9862 #ifdef WLAN_SUPPORT_PPEDS 9863 /** 9864 * dp_umac_reset_service_handle_n_notify_done() 9865 * Handle Umac pre reset for direct switch 9866 * @soc: dp soc handle 9867 * 9868 * Return: QDF_STATUS 9869 */ 9870 static QDF_STATUS dp_umac_reset_service_handle_n_notify_done(struct dp_soc *soc) 9871 { 9872 if (!soc->arch_ops.txrx_soc_ppeds_enabled_check || 9873 !soc->arch_ops.txrx_soc_ppeds_service_status_update || 9874 !soc->arch_ops.txrx_soc_ppeds_interrupt_stop) 9875 goto non_ppeds; 9876 9877 /* 9878 * Check if ppeds is enabled on SoC. 9879 */ 9880 if (!soc->arch_ops.txrx_soc_ppeds_enabled_check(soc)) 9881 goto non_ppeds; 9882 9883 /* 9884 * Start the UMAC pre reset done service. 9885 */ 9886 soc->arch_ops.txrx_soc_ppeds_service_status_update(soc, true); 9887 9888 dp_register_notify_umac_pre_reset_fw_callback(soc); 9889 9890 soc->arch_ops.txrx_soc_ppeds_interrupt_stop(soc); 9891 9892 dp_soc_ppeds_stop((struct cdp_soc_t *)soc); 9893 9894 /* 9895 * UMAC pre reset service complete 9896 */ 9897 soc->arch_ops.txrx_soc_ppeds_service_status_update(soc, false); 9898 9899 soc->umac_reset_ctx.nbuf_list = NULL; 9900 return QDF_STATUS_SUCCESS; 9901 9902 non_ppeds: 9903 dp_register_notify_umac_pre_reset_fw_callback(soc); 9904 dp_check_n_notify_umac_prereset_done(soc); 9905 soc->umac_reset_ctx.nbuf_list = NULL; 9906 return QDF_STATUS_SUCCESS; 9907 } 9908 9909 static inline void dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc *soc, 9910 qdf_nbuf_t *nbuf_list) 9911 { 9912 if (!soc->arch_ops.txrx_soc_ppeds_enabled_check || 9913 !soc->arch_ops.txrx_soc_ppeds_txdesc_pool_reset) 9914 return; 9915 9916 /* 9917 * Deinit of PPEDS Tx desc rings. 9918 */ 9919 if (soc->arch_ops.txrx_soc_ppeds_enabled_check(soc)) 9920 soc->arch_ops.txrx_soc_ppeds_txdesc_pool_reset(soc, nbuf_list); 9921 } 9922 9923 static inline void dp_umac_reset_ppeds_start(struct dp_soc *soc) 9924 { 9925 if (!soc->arch_ops.txrx_soc_ppeds_enabled_check || 9926 !soc->arch_ops.txrx_soc_ppeds_start || 9927 !soc->arch_ops.txrx_soc_ppeds_interrupt_start) 9928 return; 9929 9930 /* 9931 * Start PPEDS node and enable interrupt. 9932 */ 9933 if (soc->arch_ops.txrx_soc_ppeds_enabled_check(soc)) { 9934 soc->arch_ops.txrx_soc_ppeds_start(soc); 9935 soc->arch_ops.txrx_soc_ppeds_interrupt_start(soc); 9936 } 9937 } 9938 #else 9939 static QDF_STATUS dp_umac_reset_service_handle_n_notify_done(struct dp_soc *soc) 9940 { 9941 dp_register_notify_umac_pre_reset_fw_callback(soc); 9942 dp_check_n_notify_umac_prereset_done(soc); 9943 soc->umac_reset_ctx.nbuf_list = NULL; 9944 return QDF_STATUS_SUCCESS; 9945 } 9946 9947 static inline void dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc *soc, 9948 qdf_nbuf_t *nbuf_list) 9949 { 9950 } 9951 9952 static inline void dp_umac_reset_ppeds_start(struct dp_soc *soc) 9953 { 9954 } 9955 #endif 9956 9957 /** 9958 * dp_umac_reset_handle_pre_reset() - Handle Umac prereset interrupt from FW 9959 * @soc: dp soc handle 9960 * 9961 * Return: QDF_STATUS 9962 */ 9963 static QDF_STATUS dp_umac_reset_handle_pre_reset(struct dp_soc *soc) 9964 { 9965 dp_reset_interrupt_ring_masks(soc); 9966 9967 dp_pause_tx_hardstart(soc); 9968 dp_pause_reo_send_cmd(soc); 9969 dp_umac_reset_service_handle_n_notify_done(soc); 9970 return QDF_STATUS_SUCCESS; 9971 } 9972 9973 /** 9974 * dp_umac_reset_handle_post_reset() - Handle Umac postreset interrupt from FW 9975 * @soc: dp soc handle 9976 * 9977 * Return: QDF_STATUS 9978 */ 9979 static QDF_STATUS dp_umac_reset_handle_post_reset(struct dp_soc *soc) 9980 { 9981 if (!soc->umac_reset_ctx.skel_enable) { 9982 qdf_nbuf_t *nbuf_list = &soc->umac_reset_ctx.nbuf_list; 9983 9984 dp_set_umac_regs(soc); 9985 9986 dp_reinit_rings(soc); 9987 9988 dp_rx_desc_reuse(soc, nbuf_list); 9989 9990 dp_cleanup_reo_cmd_module(soc); 9991 9992 dp_umac_reset_ppeds_txdesc_pool_reset(soc, nbuf_list); 9993 9994 dp_tx_desc_pool_cleanup(soc, nbuf_list); 9995 9996 dp_reset_tid_q_setup(soc); 9997 } 9998 9999 return dp_umac_reset_notify_action_completion(soc, 10000 UMAC_RESET_ACTION_DO_POST_RESET_START); 10001 } 10002 10003 /** 10004 * dp_umac_reset_handle_post_reset_complete() - Handle Umac postreset_complete 10005 * interrupt from FW 10006 * @soc: dp soc handle 10007 * 10008 * Return: QDF_STATUS 10009 */ 10010 static QDF_STATUS dp_umac_reset_handle_post_reset_complete(struct dp_soc *soc) 10011 { 10012 QDF_STATUS status; 10013 qdf_nbuf_t nbuf_list = soc->umac_reset_ctx.nbuf_list; 10014 10015 soc->umac_reset_ctx.nbuf_list = NULL; 10016 10017 dp_resume_reo_send_cmd(soc); 10018 10019 dp_umac_reset_ppeds_start(soc); 10020 10021 dp_restore_interrupt_ring_masks(soc); 10022 10023 dp_resume_tx_hardstart(soc); 10024 10025 status = dp_umac_reset_notify_action_completion(soc, 10026 UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE); 10027 10028 while (nbuf_list) { 10029 qdf_nbuf_t nbuf = nbuf_list->next; 10030 10031 qdf_nbuf_free(nbuf_list); 10032 nbuf_list = nbuf; 10033 } 10034 10035 dp_umac_reset_info("Umac reset done on soc %pK\n trigger start : %u us " 10036 "trigger done : %u us prereset : %u us\n" 10037 "postreset : %u us \n postreset complete: %u us \n", 10038 soc, 10039 soc->umac_reset_ctx.ts.trigger_done - 10040 soc->umac_reset_ctx.ts.trigger_start, 10041 soc->umac_reset_ctx.ts.pre_reset_done - 10042 soc->umac_reset_ctx.ts.pre_reset_start, 10043 soc->umac_reset_ctx.ts.post_reset_done - 10044 soc->umac_reset_ctx.ts.post_reset_start, 10045 soc->umac_reset_ctx.ts.post_reset_complete_done - 10046 soc->umac_reset_ctx.ts.post_reset_complete_start); 10047 10048 return status; 10049 } 10050 #endif 10051 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 10052 static void 10053 dp_set_pkt_capture_mode(struct cdp_soc_t *soc_handle, bool val) 10054 { 10055 struct dp_soc *soc = (struct dp_soc *)soc_handle; 10056 10057 soc->wlan_cfg_ctx->pkt_capture_mode = val; 10058 } 10059 #endif 10060 10061 #ifdef HW_TX_DELAY_STATS_ENABLE 10062 /** 10063 * dp_enable_disable_vdev_tx_delay_stats() - Start/Stop tx delay stats capture 10064 * @soc_hdl: DP soc handle 10065 * @vdev_id: vdev id 10066 * @value: value 10067 * 10068 * Return: None 10069 */ 10070 static void 10071 dp_enable_disable_vdev_tx_delay_stats(struct cdp_soc_t *soc_hdl, 10072 uint8_t vdev_id, 10073 uint8_t value) 10074 { 10075 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10076 struct dp_vdev *vdev = NULL; 10077 10078 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 10079 if (!vdev) 10080 return; 10081 10082 vdev->hw_tx_delay_stats_enabled = value; 10083 10084 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 10085 } 10086 10087 /** 10088 * dp_check_vdev_tx_delay_stats_enabled() - check the feature is enabled or not 10089 * @soc_hdl: DP soc handle 10090 * @vdev_id: vdev id 10091 * 10092 * Return: 1 if enabled, 0 if disabled 10093 */ 10094 static uint8_t 10095 dp_check_vdev_tx_delay_stats_enabled(struct cdp_soc_t *soc_hdl, 10096 uint8_t vdev_id) 10097 { 10098 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10099 struct dp_vdev *vdev; 10100 uint8_t ret_val = 0; 10101 10102 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 10103 if (!vdev) 10104 return ret_val; 10105 10106 ret_val = vdev->hw_tx_delay_stats_enabled; 10107 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 10108 10109 return ret_val; 10110 } 10111 #endif 10112 10113 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 10114 static void 10115 dp_recovery_vdev_flush_peers(struct cdp_soc_t *cdp_soc, 10116 uint8_t vdev_id, 10117 bool mlo_peers_only) 10118 { 10119 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 10120 struct dp_vdev *vdev; 10121 10122 vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP); 10123 10124 if (!vdev) 10125 return; 10126 10127 dp_vdev_flush_peers((struct cdp_vdev *)vdev, false, mlo_peers_only); 10128 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 10129 } 10130 #endif 10131 #ifdef QCA_GET_TSF_VIA_REG 10132 /** 10133 * dp_get_tsf_time() - get tsf time 10134 * @soc_hdl: Datapath soc handle 10135 * @tsf_id: TSF identifier 10136 * @mac_id: mac_id 10137 * @tsf: pointer to update tsf value 10138 * @tsf_sync_soc_time: pointer to update tsf sync time 10139 * 10140 * Return: None. 10141 */ 10142 static inline void 10143 dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id, 10144 uint64_t *tsf, uint64_t *tsf_sync_soc_time) 10145 { 10146 hal_get_tsf_time(((struct dp_soc *)soc_hdl)->hal_soc, tsf_id, mac_id, 10147 tsf, tsf_sync_soc_time); 10148 } 10149 #else 10150 static inline void 10151 dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id, 10152 uint64_t *tsf, uint64_t *tsf_sync_soc_time) 10153 { 10154 } 10155 #endif 10156 10157 /** 10158 * dp_get_tsf2_scratch_reg() - get tsf2 offset from the scratch register 10159 * @soc_hdl: Datapath soc handle 10160 * @mac_id: mac_id 10161 * @value: pointer to update tsf2 offset value 10162 * 10163 * Return: None. 10164 */ 10165 static inline void 10166 dp_get_tsf2_scratch_reg(struct cdp_soc_t *soc_hdl, uint8_t mac_id, 10167 uint64_t *value) 10168 { 10169 hal_get_tsf2_offset(((struct dp_soc *)soc_hdl)->hal_soc, mac_id, value); 10170 } 10171 10172 /** 10173 * dp_get_tqm_scratch_reg() - get tqm offset from the scratch register 10174 * @soc_hdl: Datapath soc handle 10175 * @value: pointer to update tqm offset value 10176 * 10177 * Return: None. 10178 */ 10179 static inline void 10180 dp_get_tqm_scratch_reg(struct cdp_soc_t *soc_hdl, uint64_t *value) 10181 { 10182 hal_get_tqm_offset(((struct dp_soc *)soc_hdl)->hal_soc, value); 10183 } 10184 10185 /** 10186 * dp_set_tx_pause() - Pause or resume tx path 10187 * @soc_hdl: Datapath soc handle 10188 * @flag: set or clear is_tx_pause 10189 * 10190 * Return: None. 10191 */ 10192 static inline 10193 void dp_set_tx_pause(struct cdp_soc_t *soc_hdl, bool flag) 10194 { 10195 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10196 10197 soc->is_tx_pause = flag; 10198 } 10199 10200 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 10201 /** 10202 * dp_evaluate_update_tx_ilp_config() - Evaluate and update DP TX 10203 * ILP configuration 10204 * @soc_hdl: CDP SOC handle 10205 * @num_msdu_idx_map: Number of HTT msdu index to qtype map in array 10206 * @msdu_idx_map_arr: Pointer to HTT msdu index to qtype map array 10207 * 10208 * This function will check: (a) TX ILP INI configuration, 10209 * (b) index 3 value in array same as HTT_MSDU_QTYPE_LATENCY_TOLERANT, 10210 * only if both (a) and (b) condition is met, then TX ILP feature is 10211 * considered to be enabled. 10212 * 10213 * Return: Final updated TX ILP enable result in dp_soc, 10214 * true is enabled, false is not 10215 */ 10216 static 10217 bool dp_evaluate_update_tx_ilp_config(struct cdp_soc_t *soc_hdl, 10218 uint8_t num_msdu_idx_map, 10219 uint8_t *msdu_idx_map_arr) 10220 { 10221 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10222 bool enable_tx_ilp = false; 10223 10224 /** 10225 * Check INI configuration firstly, if it's disabled, 10226 * then keep feature disabled. 10227 */ 10228 if (!wlan_cfg_get_tx_ilp_inspect_config(soc->wlan_cfg_ctx)) { 10229 dp_info("TX ILP INI is disabled already"); 10230 goto update_tx_ilp; 10231 } 10232 10233 /* Check if the msdu index to qtype map table is valid */ 10234 if (num_msdu_idx_map != HTT_MSDUQ_MAX_INDEX || !msdu_idx_map_arr) { 10235 dp_info("Invalid msdu_idx qtype map num: 0x%x, arr_addr %pK", 10236 num_msdu_idx_map, msdu_idx_map_arr); 10237 goto update_tx_ilp; 10238 } 10239 10240 dp_info("msdu_idx_map_arr idx 0x%x value 0x%x", 10241 HTT_MSDUQ_INDEX_CUSTOM_PRIO_1, 10242 msdu_idx_map_arr[HTT_MSDUQ_INDEX_CUSTOM_PRIO_1]); 10243 10244 if (HTT_MSDU_QTYPE_USER_SPECIFIED == 10245 msdu_idx_map_arr[HTT_MSDUQ_INDEX_CUSTOM_PRIO_1]) 10246 enable_tx_ilp = true; 10247 10248 update_tx_ilp: 10249 soc->tx_ilp_enable = enable_tx_ilp; 10250 dp_info("configure tx ilp enable %d", soc->tx_ilp_enable); 10251 10252 return soc->tx_ilp_enable; 10253 } 10254 #endif 10255 10256 static struct cdp_cmn_ops dp_ops_cmn = { 10257 .txrx_soc_attach_target = dp_soc_attach_target_wifi3, 10258 .txrx_vdev_attach = dp_vdev_attach_wifi3, 10259 .txrx_vdev_detach = dp_vdev_detach_wifi3, 10260 .txrx_pdev_attach = dp_pdev_attach_wifi3, 10261 .txrx_pdev_post_attach = dp_pdev_post_attach_wifi3, 10262 .txrx_pdev_detach = dp_pdev_detach_wifi3, 10263 .txrx_pdev_deinit = dp_pdev_deinit_wifi3, 10264 .txrx_peer_create = dp_peer_create_wifi3, 10265 .txrx_peer_setup = dp_peer_setup_wifi3_wrapper, 10266 #ifdef FEATURE_AST 10267 .txrx_peer_teardown = dp_peer_teardown_wifi3, 10268 #else 10269 .txrx_peer_teardown = NULL, 10270 #endif 10271 .txrx_peer_add_ast = dp_peer_add_ast_wifi3, 10272 .txrx_peer_update_ast = dp_peer_update_ast_wifi3, 10273 .txrx_peer_get_ast_info_by_soc = dp_peer_get_ast_info_by_soc_wifi3, 10274 .txrx_peer_get_ast_info_by_pdev = 10275 dp_peer_get_ast_info_by_pdevid_wifi3, 10276 .txrx_peer_ast_delete_by_soc = 10277 dp_peer_ast_entry_del_by_soc, 10278 .txrx_peer_ast_delete_by_pdev = 10279 dp_peer_ast_entry_del_by_pdev, 10280 .txrx_peer_HMWDS_ast_delete = dp_peer_HMWDS_ast_entry_del, 10281 .txrx_peer_delete = dp_peer_delete_wifi3, 10282 #ifdef DP_RX_UDP_OVER_PEER_ROAM 10283 .txrx_update_roaming_peer = dp_update_roaming_peer_wifi3, 10284 #endif 10285 .txrx_vdev_register = dp_vdev_register_wifi3, 10286 .txrx_soc_detach = dp_soc_detach_wifi3, 10287 .txrx_soc_deinit = dp_soc_deinit_wifi3, 10288 .txrx_soc_init = dp_soc_init_wifi3, 10289 #ifndef QCA_HOST_MODE_WIFI_DISABLED 10290 .txrx_tso_soc_attach = dp_tso_soc_attach, 10291 .txrx_tso_soc_detach = dp_tso_soc_detach, 10292 .tx_send = dp_tx_send, 10293 .tx_send_exc = dp_tx_send_exception, 10294 #endif 10295 .set_tx_pause = dp_set_tx_pause, 10296 .txrx_pdev_init = dp_pdev_init_wifi3, 10297 .txrx_get_vdev_mac_addr = dp_get_vdev_mac_addr_wifi3, 10298 .txrx_get_ctrl_pdev_from_vdev = dp_get_ctrl_pdev_from_vdev_wifi3, 10299 .txrx_ath_getstats = dp_get_device_stats, 10300 #ifndef WLAN_SOFTUMAC_SUPPORT 10301 .addba_requestprocess = dp_addba_requestprocess_wifi3, 10302 .addba_responsesetup = dp_addba_responsesetup_wifi3, 10303 .addba_resp_tx_completion = dp_addba_resp_tx_completion_wifi3, 10304 .delba_process = dp_delba_process_wifi3, 10305 .set_addba_response = dp_set_addba_response, 10306 .flush_cache_rx_queue = NULL, 10307 .tid_update_ba_win_size = dp_rx_tid_update_ba_win_size, 10308 #endif 10309 /* TODO: get API's for dscp-tid need to be added*/ 10310 .set_vdev_dscp_tid_map = dp_set_vdev_dscp_tid_map_wifi3, 10311 .set_pdev_dscp_tid_map = dp_set_pdev_dscp_tid_map_wifi3, 10312 .txrx_get_total_per = dp_get_total_per, 10313 .txrx_stats_request = dp_txrx_stats_request, 10314 .txrx_get_peer_mac_from_peer_id = dp_get_peer_mac_from_peer_id, 10315 .display_stats = dp_txrx_dump_stats, 10316 .notify_asserted_soc = dp_soc_notify_asserted_soc, 10317 .txrx_intr_attach = dp_soc_interrupt_attach_wrapper, 10318 .txrx_intr_detach = dp_soc_interrupt_detach, 10319 .txrx_ppeds_stop = dp_soc_ppeds_stop, 10320 .set_key_sec_type = dp_set_key_sec_type_wifi3, 10321 .update_config_parameters = dp_update_config_parameters, 10322 /* TODO: Add other functions */ 10323 .txrx_data_tx_cb_set = dp_txrx_data_tx_cb_set, 10324 .get_dp_txrx_handle = dp_pdev_get_dp_txrx_handle, 10325 .set_dp_txrx_handle = dp_pdev_set_dp_txrx_handle, 10326 .get_vdev_dp_ext_txrx_handle = dp_vdev_get_dp_ext_handle, 10327 .set_vdev_dp_ext_txrx_handle = dp_vdev_set_dp_ext_handle, 10328 .get_soc_dp_txrx_handle = dp_soc_get_dp_txrx_handle, 10329 .set_soc_dp_txrx_handle = dp_soc_set_dp_txrx_handle, 10330 .map_pdev_to_lmac = dp_soc_map_pdev_to_lmac, 10331 .handle_mode_change = dp_soc_handle_pdev_mode_change, 10332 .set_pdev_status_down = dp_soc_set_pdev_status_down, 10333 .txrx_peer_reset_ast = dp_wds_reset_ast_wifi3, 10334 .txrx_peer_reset_ast_table = dp_wds_reset_ast_table_wifi3, 10335 .txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3, 10336 .txrx_peer_map_attach = dp_peer_map_attach_wifi3, 10337 .set_soc_param = dp_soc_set_param, 10338 .txrx_get_os_rx_handles_from_vdev = 10339 dp_get_os_rx_handles_from_vdev_wifi3, 10340 #ifndef WLAN_SOFTUMAC_SUPPORT 10341 .set_pn_check = dp_set_pn_check_wifi3, 10342 .txrx_set_ba_aging_timeout = dp_set_ba_aging_timeout, 10343 .txrx_get_ba_aging_timeout = dp_get_ba_aging_timeout, 10344 .delba_tx_completion = dp_delba_tx_completion_wifi3, 10345 .set_pdev_pcp_tid_map = dp_set_pdev_pcp_tid_map_wifi3, 10346 .set_vdev_pcp_tid_map = dp_set_vdev_pcp_tid_map_wifi3, 10347 #endif 10348 .get_dp_capabilities = dp_get_cfg_capabilities, 10349 .txrx_get_cfg = dp_get_cfg, 10350 .set_rate_stats_ctx = dp_soc_set_rate_stats_ctx, 10351 .get_rate_stats_ctx = dp_soc_get_rate_stats_ctx, 10352 .txrx_peer_flush_rate_stats = dp_peer_flush_rate_stats, 10353 .txrx_flush_rate_stats_request = dp_flush_rate_stats_req, 10354 .txrx_peer_get_peerstats_ctx = dp_peer_get_peerstats_ctx, 10355 10356 .txrx_cp_peer_del_response = dp_cp_peer_del_resp_handler, 10357 #ifdef QCA_MULTIPASS_SUPPORT 10358 .set_vlan_groupkey = dp_set_vlan_groupkey, 10359 #endif 10360 .get_peer_mac_list = dp_get_peer_mac_list, 10361 .get_peer_id = dp_get_peer_id, 10362 #ifdef QCA_SUPPORT_WDS_EXTENDED 10363 .set_wds_ext_peer_rx = dp_wds_ext_set_peer_rx, 10364 .get_wds_ext_peer_osif_handle = dp_wds_ext_get_peer_osif_handle, 10365 #endif /* QCA_SUPPORT_WDS_EXTENDED */ 10366 10367 #if defined(FEATURE_RUNTIME_PM) || defined(DP_POWER_SAVE) 10368 .txrx_drain = dp_drain_txrx, 10369 #endif 10370 #if defined(FEATURE_RUNTIME_PM) 10371 .set_rtpm_tput_policy = dp_set_rtpm_tput_policy_requirement, 10372 #endif 10373 #ifdef WLAN_SYSFS_DP_STATS 10374 .txrx_sysfs_fill_stats = dp_sysfs_fill_stats, 10375 .txrx_sysfs_set_stat_type = dp_sysfs_set_stat_type, 10376 #endif /* WLAN_SYSFS_DP_STATS */ 10377 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 10378 .set_pkt_capture_mode = dp_set_pkt_capture_mode, 10379 #endif 10380 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 10381 .txrx_recovery_vdev_flush_peers = dp_recovery_vdev_flush_peers, 10382 #endif 10383 .txrx_umac_reset_deinit = dp_soc_umac_reset_deinit, 10384 .txrx_umac_reset_init = dp_soc_umac_reset_init, 10385 .txrx_get_tsf_time = dp_get_tsf_time, 10386 .txrx_get_tsf2_offset = dp_get_tsf2_scratch_reg, 10387 .txrx_get_tqm_offset = dp_get_tqm_scratch_reg, 10388 }; 10389 10390 static struct cdp_ctrl_ops dp_ops_ctrl = { 10391 .txrx_peer_authorize = dp_peer_authorize, 10392 .txrx_peer_get_authorize = dp_peer_get_authorize, 10393 #ifdef VDEV_PEER_PROTOCOL_COUNT 10394 .txrx_enable_peer_protocol_count = dp_enable_vdev_peer_protocol_count, 10395 .txrx_set_peer_protocol_drop_mask = 10396 dp_enable_vdev_peer_protocol_drop_mask, 10397 .txrx_is_peer_protocol_count_enabled = 10398 dp_is_vdev_peer_protocol_count_enabled, 10399 .txrx_get_peer_protocol_drop_mask = dp_get_vdev_peer_protocol_drop_mask, 10400 #endif 10401 .txrx_set_vdev_param = dp_set_vdev_param, 10402 .txrx_set_psoc_param = dp_set_psoc_param, 10403 .txrx_get_psoc_param = dp_get_psoc_param, 10404 #ifndef WLAN_SOFTUMAC_SUPPORT 10405 .txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest, 10406 .txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest, 10407 #endif 10408 .txrx_get_sec_type = dp_get_sec_type, 10409 .txrx_wdi_event_sub = dp_wdi_event_sub, 10410 .txrx_wdi_event_unsub = dp_wdi_event_unsub, 10411 .txrx_set_pdev_param = dp_set_pdev_param, 10412 .txrx_get_pdev_param = dp_get_pdev_param, 10413 .txrx_set_peer_param = dp_set_peer_param, 10414 .txrx_get_peer_param = dp_get_peer_param, 10415 #ifdef VDEV_PEER_PROTOCOL_COUNT 10416 .txrx_peer_protocol_cnt = dp_peer_stats_update_protocol_cnt, 10417 #endif 10418 #ifdef WLAN_SUPPORT_MSCS 10419 .txrx_record_mscs_params = dp_record_mscs_params, 10420 #endif 10421 .set_key = dp_set_michael_key, 10422 .txrx_get_vdev_param = dp_get_vdev_param, 10423 .calculate_delay_stats = dp_calculate_delay_stats, 10424 #ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG 10425 .txrx_update_pdev_rx_protocol_tag = dp_update_pdev_rx_protocol_tag, 10426 #ifdef WLAN_SUPPORT_RX_TAG_STATISTICS 10427 .txrx_dump_pdev_rx_protocol_tag_stats = 10428 dp_dump_pdev_rx_protocol_tag_stats, 10429 #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ 10430 #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ 10431 #ifdef WLAN_SUPPORT_RX_FLOW_TAG 10432 .txrx_set_rx_flow_tag = dp_set_rx_flow_tag, 10433 .txrx_dump_rx_flow_tag_stats = dp_dump_rx_flow_tag_stats, 10434 #endif /* WLAN_SUPPORT_RX_FLOW_TAG */ 10435 #ifdef QCA_MULTIPASS_SUPPORT 10436 .txrx_peer_set_vlan_id = dp_peer_set_vlan_id, 10437 #endif /*QCA_MULTIPASS_SUPPORT*/ 10438 #if defined(WLAN_FEATURE_TSF_UPLINK_DELAY) || defined(WLAN_CONFIG_TX_DELAY) 10439 .txrx_set_delta_tsf = dp_set_delta_tsf, 10440 #endif 10441 #ifdef WLAN_FEATURE_TSF_UPLINK_DELAY 10442 .txrx_set_tsf_ul_delay_report = dp_set_tsf_ul_delay_report, 10443 .txrx_get_uplink_delay = dp_get_uplink_delay, 10444 #endif 10445 #ifdef QCA_UNDECODED_METADATA_SUPPORT 10446 .txrx_set_pdev_phyrx_error_mask = dp_set_pdev_phyrx_error_mask, 10447 .txrx_get_pdev_phyrx_error_mask = dp_get_pdev_phyrx_error_mask, 10448 #endif 10449 .txrx_peer_flush_frags = dp_peer_flush_frags, 10450 }; 10451 10452 static struct cdp_me_ops dp_ops_me = { 10453 #ifndef QCA_HOST_MODE_WIFI_DISABLED 10454 #ifdef ATH_SUPPORT_IQUE 10455 .tx_me_alloc_descriptor = dp_tx_me_alloc_descriptor, 10456 .tx_me_free_descriptor = dp_tx_me_free_descriptor, 10457 .tx_me_convert_ucast = dp_tx_me_send_convert_ucast, 10458 #endif 10459 #endif 10460 }; 10461 10462 static struct cdp_host_stats_ops dp_ops_host_stats = { 10463 .txrx_per_peer_stats = dp_get_host_peer_stats, 10464 .get_fw_peer_stats = dp_get_fw_peer_stats, 10465 .get_htt_stats = dp_get_htt_stats, 10466 .txrx_stats_publish = dp_txrx_stats_publish, 10467 .txrx_get_vdev_stats = dp_txrx_get_vdev_stats, 10468 .txrx_get_peer_stats = dp_txrx_get_peer_stats, 10469 .txrx_get_soc_stats = dp_txrx_get_soc_stats, 10470 .txrx_get_peer_stats_param = dp_txrx_get_peer_stats_param, 10471 .txrx_reset_peer_stats = dp_txrx_reset_peer_stats, 10472 .txrx_get_pdev_stats = dp_txrx_get_pdev_stats, 10473 #if defined(IPA_OFFLOAD) && defined(QCA_ENHANCED_STATS_SUPPORT) 10474 .txrx_get_peer_stats = dp_ipa_txrx_get_peer_stats, 10475 .txrx_get_vdev_stats = dp_ipa_txrx_get_vdev_stats, 10476 .txrx_get_pdev_stats = dp_ipa_txrx_get_pdev_stats, 10477 #endif 10478 .txrx_get_ratekbps = dp_txrx_get_ratekbps, 10479 .txrx_update_vdev_stats = dp_txrx_update_vdev_host_stats, 10480 .txrx_get_peer_delay_stats = dp_txrx_get_peer_delay_stats, 10481 .txrx_get_peer_jitter_stats = dp_txrx_get_peer_jitter_stats, 10482 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 10483 .txrx_alloc_vdev_stats_id = dp_txrx_alloc_vdev_stats_id, 10484 .txrx_reset_vdev_stats_id = dp_txrx_reset_vdev_stats_id, 10485 #endif 10486 #ifdef WLAN_TX_PKT_CAPTURE_ENH 10487 .get_peer_tx_capture_stats = dp_peer_get_tx_capture_stats, 10488 .get_pdev_tx_capture_stats = dp_pdev_get_tx_capture_stats, 10489 #endif /* WLAN_TX_PKT_CAPTURE_ENH */ 10490 #ifdef HW_TX_DELAY_STATS_ENABLE 10491 .enable_disable_vdev_tx_delay_stats = 10492 dp_enable_disable_vdev_tx_delay_stats, 10493 .is_tx_delay_stats_enabled = dp_check_vdev_tx_delay_stats_enabled, 10494 #endif 10495 .txrx_get_pdev_tid_stats = dp_pdev_get_tid_stats, 10496 #ifdef WLAN_CONFIG_TELEMETRY_AGENT 10497 .txrx_pdev_telemetry_stats = dp_get_pdev_telemetry_stats, 10498 .txrx_peer_telemetry_stats = dp_get_peer_telemetry_stats, 10499 .txrx_pdev_deter_stats = dp_get_pdev_deter_stats, 10500 .txrx_peer_deter_stats = dp_get_peer_deter_stats, 10501 .txrx_update_pdev_chan_util_stats = dp_update_pdev_chan_util_stats, 10502 #endif 10503 .txrx_get_peer_extd_rate_link_stats = 10504 dp_get_peer_extd_rate_link_stats, 10505 .get_pdev_obss_stats = dp_get_obss_stats, 10506 .clear_pdev_obss_pd_stats = dp_clear_pdev_obss_pd_stats, 10507 /* TODO */ 10508 }; 10509 10510 static struct cdp_raw_ops dp_ops_raw = { 10511 /* TODO */ 10512 }; 10513 10514 #ifdef PEER_FLOW_CONTROL 10515 static struct cdp_pflow_ops dp_ops_pflow = { 10516 dp_tx_flow_ctrl_configure_pdev, 10517 }; 10518 #endif 10519 10520 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 10521 static struct cdp_cfr_ops dp_ops_cfr = { 10522 .txrx_get_cfr_rcc = dp_get_cfr_rcc, 10523 .txrx_set_cfr_rcc = dp_set_cfr_rcc, 10524 .txrx_get_cfr_dbg_stats = dp_get_cfr_dbg_stats, 10525 .txrx_clear_cfr_dbg_stats = dp_clear_cfr_dbg_stats, 10526 }; 10527 #endif 10528 10529 #ifdef WLAN_SUPPORT_MSCS 10530 static struct cdp_mscs_ops dp_ops_mscs = { 10531 .mscs_peer_lookup_n_get_priority = dp_mscs_peer_lookup_n_get_priority, 10532 }; 10533 #endif 10534 10535 #ifdef WLAN_SUPPORT_MESH_LATENCY 10536 static struct cdp_mesh_latency_ops dp_ops_mesh_latency = { 10537 .mesh_latency_update_peer_parameter = 10538 dp_mesh_latency_update_peer_parameter, 10539 }; 10540 #endif 10541 10542 #ifdef WLAN_SUPPORT_SCS 10543 static struct cdp_scs_ops dp_ops_scs = { 10544 .scs_peer_lookup_n_rule_match = dp_scs_peer_lookup_n_rule_match, 10545 }; 10546 #endif 10547 10548 #ifdef CONFIG_SAWF_DEF_QUEUES 10549 static struct cdp_sawf_ops dp_ops_sawf = { 10550 .sawf_def_queues_map_req = dp_sawf_def_queues_map_req, 10551 .sawf_def_queues_unmap_req = dp_sawf_def_queues_unmap_req, 10552 .sawf_def_queues_get_map_report = 10553 dp_sawf_def_queues_get_map_report, 10554 #ifdef CONFIG_SAWF_STATS 10555 .sawf_get_peer_msduq_info = dp_sawf_get_peer_msduq_info, 10556 .txrx_get_peer_sawf_delay_stats = dp_sawf_get_peer_delay_stats, 10557 .txrx_get_peer_sawf_tx_stats = dp_sawf_get_peer_tx_stats, 10558 .sawf_mpdu_stats_req = dp_sawf_mpdu_stats_req, 10559 .sawf_mpdu_details_stats_req = dp_sawf_mpdu_details_stats_req, 10560 .txrx_sawf_set_mov_avg_params = dp_sawf_set_mov_avg_params, 10561 .txrx_sawf_set_sla_params = dp_sawf_set_sla_params, 10562 .txrx_sawf_init_telemtery_params = dp_sawf_init_telemetry_params, 10563 .telemetry_get_throughput_stats = dp_sawf_get_tx_stats, 10564 .telemetry_get_mpdu_stats = dp_sawf_get_mpdu_sched_stats, 10565 .telemetry_get_drop_stats = dp_sawf_get_drop_stats, 10566 .peer_config_ul = dp_sawf_peer_config_ul, 10567 .swaf_peer_is_sla_configured = dp_swaf_peer_is_sla_configured, 10568 #endif 10569 }; 10570 #endif 10571 10572 #ifdef DP_TX_TRACKING 10573 10574 #define DP_TX_COMP_MAX_LATENCY_MS 60000 10575 /** 10576 * dp_tx_comp_delay_check() - calculate time latency for tx completion per pkt 10577 * @tx_desc: tx descriptor 10578 * 10579 * Calculate time latency for tx completion per pkt and trigger self recovery 10580 * when the delay is more than threshold value. 10581 * 10582 * Return: True if delay is more than threshold 10583 */ 10584 static bool dp_tx_comp_delay_check(struct dp_tx_desc_s *tx_desc) 10585 { 10586 uint64_t time_latency, timestamp_tick = tx_desc->timestamp_tick; 10587 qdf_ktime_t current_time = qdf_ktime_real_get(); 10588 qdf_ktime_t timestamp = tx_desc->timestamp; 10589 10590 if (dp_tx_pkt_tracepoints_enabled()) { 10591 if (!timestamp) 10592 return false; 10593 10594 time_latency = qdf_ktime_to_ms(current_time) - 10595 qdf_ktime_to_ms(timestamp); 10596 if (time_latency >= DP_TX_COMP_MAX_LATENCY_MS) { 10597 dp_err_rl("enqueued: %llu ms, current : %llu ms", 10598 timestamp, current_time); 10599 return true; 10600 } 10601 } else { 10602 if (!timestamp_tick) 10603 return false; 10604 10605 current_time = qdf_system_ticks(); 10606 time_latency = qdf_system_ticks_to_msecs(current_time - 10607 timestamp_tick); 10608 if (time_latency >= DP_TX_COMP_MAX_LATENCY_MS) { 10609 dp_err_rl("enqueued: %u ms, current : %u ms", 10610 qdf_system_ticks_to_msecs(timestamp_tick), 10611 qdf_system_ticks_to_msecs(current_time)); 10612 return true; 10613 } 10614 } 10615 10616 return false; 10617 } 10618 10619 void dp_find_missing_tx_comp(struct dp_soc *soc) 10620 { 10621 uint8_t i; 10622 uint32_t j; 10623 uint32_t num_desc, page_id, offset; 10624 uint16_t num_desc_per_page; 10625 struct dp_tx_desc_s *tx_desc = NULL; 10626 struct dp_tx_desc_pool_s *tx_desc_pool = NULL; 10627 10628 for (i = 0; i < MAX_TXDESC_POOLS; i++) { 10629 tx_desc_pool = &soc->tx_desc[i]; 10630 if (!(tx_desc_pool->pool_size) || 10631 IS_TX_DESC_POOL_STATUS_INACTIVE(tx_desc_pool) || 10632 !(tx_desc_pool->desc_pages.cacheable_pages)) 10633 continue; 10634 10635 num_desc = tx_desc_pool->pool_size; 10636 num_desc_per_page = 10637 tx_desc_pool->desc_pages.num_element_per_page; 10638 for (j = 0; j < num_desc; j++) { 10639 page_id = j / num_desc_per_page; 10640 offset = j % num_desc_per_page; 10641 10642 if (qdf_unlikely(!(tx_desc_pool-> 10643 desc_pages.cacheable_pages))) 10644 break; 10645 10646 tx_desc = dp_tx_desc_find(soc, i, page_id, offset); 10647 if (tx_desc->magic == DP_TX_MAGIC_PATTERN_FREE) { 10648 continue; 10649 } else if (tx_desc->magic == 10650 DP_TX_MAGIC_PATTERN_INUSE) { 10651 if (dp_tx_comp_delay_check(tx_desc)) { 10652 dp_err_rl("Tx completion not rcvd for id: %u", 10653 tx_desc->id); 10654 if (tx_desc->vdev_id == DP_INVALID_VDEV_ID) { 10655 tx_desc->flags |= DP_TX_DESC_FLAG_FLUSH; 10656 dp_err_rl("Freed tx_desc %u", 10657 tx_desc->id); 10658 dp_tx_comp_free_buf(soc, 10659 tx_desc, 10660 false); 10661 dp_tx_desc_release(tx_desc, i); 10662 DP_STATS_INC(soc, 10663 tx.tx_comp_force_freed, 1); 10664 } 10665 } 10666 } else { 10667 dp_err_rl("tx desc %u corrupted, flags: 0x%x", 10668 tx_desc->id, tx_desc->flags); 10669 } 10670 } 10671 } 10672 } 10673 #else 10674 inline void dp_find_missing_tx_comp(struct dp_soc *soc) 10675 { 10676 } 10677 #endif 10678 10679 #ifdef FEATURE_RUNTIME_PM 10680 /** 10681 * dp_runtime_suspend() - ensure DP is ready to runtime suspend 10682 * @soc_hdl: Datapath soc handle 10683 * @pdev_id: id of data path pdev handle 10684 * 10685 * DP is ready to runtime suspend if there are no pending TX packets. 10686 * 10687 * Return: QDF_STATUS 10688 */ 10689 static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 10690 { 10691 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10692 struct dp_pdev *pdev; 10693 int32_t tx_pending; 10694 10695 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10696 if (!pdev) { 10697 dp_err("pdev is NULL"); 10698 return QDF_STATUS_E_INVAL; 10699 } 10700 10701 /* Abort if there are any pending TX packets */ 10702 tx_pending = dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)); 10703 if (tx_pending) { 10704 dp_info_rl("%pK: Abort suspend due to pending TX packets %d", 10705 soc, tx_pending); 10706 dp_find_missing_tx_comp(soc); 10707 /* perform a force flush if tx is pending */ 10708 soc->arch_ops.dp_update_ring_hptp(soc, true); 10709 qdf_atomic_set(&soc->tx_pending_rtpm, 0); 10710 10711 return QDF_STATUS_E_AGAIN; 10712 } 10713 10714 if (dp_runtime_get_refcount(soc)) { 10715 dp_init_info("refcount: %d", dp_runtime_get_refcount(soc)); 10716 10717 return QDF_STATUS_E_AGAIN; 10718 } 10719 10720 if (soc->intr_mode == DP_INTR_POLL) 10721 qdf_timer_stop(&soc->int_timer); 10722 10723 dp_rx_fst_update_pm_suspend_status(soc, true); 10724 10725 return QDF_STATUS_SUCCESS; 10726 } 10727 10728 #define DP_FLUSH_WAIT_CNT 10 10729 #define DP_RUNTIME_SUSPEND_WAIT_MS 10 10730 /** 10731 * dp_runtime_resume() - ensure DP is ready to runtime resume 10732 * @soc_hdl: Datapath soc handle 10733 * @pdev_id: id of data path pdev handle 10734 * 10735 * Resume DP for runtime PM. 10736 * 10737 * Return: QDF_STATUS 10738 */ 10739 static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 10740 { 10741 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10742 int suspend_wait = 0; 10743 10744 if (soc->intr_mode == DP_INTR_POLL) 10745 qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); 10746 10747 /* 10748 * Wait until dp runtime refcount becomes zero or time out, then flush 10749 * pending tx for runtime suspend. 10750 */ 10751 while (dp_runtime_get_refcount(soc) && 10752 suspend_wait < DP_FLUSH_WAIT_CNT) { 10753 qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS); 10754 suspend_wait++; 10755 } 10756 10757 soc->arch_ops.dp_update_ring_hptp(soc, false); 10758 qdf_atomic_set(&soc->tx_pending_rtpm, 0); 10759 10760 dp_rx_fst_update_pm_suspend_status(soc, false); 10761 10762 return QDF_STATUS_SUCCESS; 10763 } 10764 #endif /* FEATURE_RUNTIME_PM */ 10765 10766 /** 10767 * dp_tx_get_success_ack_stats() - get tx success completion count 10768 * @soc_hdl: Datapath soc handle 10769 * @vdev_id: vdev identifier 10770 * 10771 * Return: tx success ack count 10772 */ 10773 static uint32_t dp_tx_get_success_ack_stats(struct cdp_soc_t *soc_hdl, 10774 uint8_t vdev_id) 10775 { 10776 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10777 struct cdp_vdev_stats *vdev_stats = NULL; 10778 uint32_t tx_success; 10779 struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id, 10780 DP_MOD_ID_CDP); 10781 10782 if (!vdev) { 10783 dp_cdp_err("%pK: Invalid vdev id %d", soc, vdev_id); 10784 return 0; 10785 } 10786 10787 vdev_stats = qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats)); 10788 if (!vdev_stats) { 10789 dp_cdp_err("%pK: DP alloc failure - unable to get alloc vdev stats", soc); 10790 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 10791 return 0; 10792 } 10793 10794 dp_aggregate_vdev_stats(vdev, vdev_stats); 10795 10796 tx_success = vdev_stats->tx.tx_success.num; 10797 qdf_mem_free(vdev_stats); 10798 10799 dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); 10800 return tx_success; 10801 } 10802 10803 #ifdef WLAN_SUPPORT_DATA_STALL 10804 /** 10805 * dp_register_data_stall_detect_cb() - register data stall callback 10806 * @soc_hdl: Datapath soc handle 10807 * @pdev_id: id of data path pdev handle 10808 * @data_stall_detect_callback: data stall callback function 10809 * 10810 * Return: QDF_STATUS Enumeration 10811 */ 10812 static 10813 QDF_STATUS dp_register_data_stall_detect_cb( 10814 struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 10815 data_stall_detect_cb data_stall_detect_callback) 10816 { 10817 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10818 struct dp_pdev *pdev; 10819 10820 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10821 if (!pdev) { 10822 dp_err("pdev NULL!"); 10823 return QDF_STATUS_E_INVAL; 10824 } 10825 10826 pdev->data_stall_detect_callback = data_stall_detect_callback; 10827 return QDF_STATUS_SUCCESS; 10828 } 10829 10830 /** 10831 * dp_deregister_data_stall_detect_cb() - de-register data stall callback 10832 * @soc_hdl: Datapath soc handle 10833 * @pdev_id: id of data path pdev handle 10834 * @data_stall_detect_callback: data stall callback function 10835 * 10836 * Return: QDF_STATUS Enumeration 10837 */ 10838 static 10839 QDF_STATUS dp_deregister_data_stall_detect_cb( 10840 struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 10841 data_stall_detect_cb data_stall_detect_callback) 10842 { 10843 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10844 struct dp_pdev *pdev; 10845 10846 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10847 if (!pdev) { 10848 dp_err("pdev NULL!"); 10849 return QDF_STATUS_E_INVAL; 10850 } 10851 10852 pdev->data_stall_detect_callback = NULL; 10853 return QDF_STATUS_SUCCESS; 10854 } 10855 10856 /** 10857 * dp_txrx_post_data_stall_event() - post data stall event 10858 * @soc_hdl: Datapath soc handle 10859 * @indicator: Module triggering data stall 10860 * @data_stall_type: data stall event type 10861 * @pdev_id: pdev id 10862 * @vdev_id_bitmap: vdev id bitmap 10863 * @recovery_type: data stall recovery type 10864 * 10865 * Return: None 10866 */ 10867 static void 10868 dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl, 10869 enum data_stall_log_event_indicator indicator, 10870 enum data_stall_log_event_type data_stall_type, 10871 uint32_t pdev_id, uint32_t vdev_id_bitmap, 10872 enum data_stall_log_recovery_type recovery_type) 10873 { 10874 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10875 struct data_stall_event_info data_stall_info; 10876 struct dp_pdev *pdev; 10877 10878 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10879 if (!pdev) { 10880 dp_err("pdev NULL!"); 10881 return; 10882 } 10883 10884 if (!pdev->data_stall_detect_callback) { 10885 dp_err("data stall cb not registered!"); 10886 return; 10887 } 10888 10889 dp_info("data_stall_type: %x pdev_id: %d", 10890 data_stall_type, pdev_id); 10891 10892 data_stall_info.indicator = indicator; 10893 data_stall_info.data_stall_type = data_stall_type; 10894 data_stall_info.vdev_id_bitmap = vdev_id_bitmap; 10895 data_stall_info.pdev_id = pdev_id; 10896 data_stall_info.recovery_type = recovery_type; 10897 10898 pdev->data_stall_detect_callback(&data_stall_info); 10899 } 10900 #endif /* WLAN_SUPPORT_DATA_STALL */ 10901 10902 #ifdef WLAN_FEATURE_STATS_EXT 10903 /** 10904 * dp_txrx_ext_stats_request() - request dp txrx extended stats request 10905 * @soc_hdl: soc handle 10906 * @pdev_id: pdev id 10907 * @req: stats request 10908 * 10909 * Return: QDF_STATUS 10910 */ 10911 static QDF_STATUS 10912 dp_txrx_ext_stats_request(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 10913 struct cdp_txrx_ext_stats *req) 10914 { 10915 struct dp_soc *soc = (struct dp_soc *)soc_hdl; 10916 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10917 int i = 0; 10918 int tcl_ring_full = 0; 10919 10920 if (!pdev) { 10921 dp_err("pdev is null"); 10922 return QDF_STATUS_E_INVAL; 10923 } 10924 10925 dp_aggregate_pdev_stats(pdev); 10926 10927 for(i = 0 ; i < MAX_TCL_DATA_RINGS; i++) 10928 tcl_ring_full += soc->stats.tx.tcl_ring_full[i]; 10929 10930 req->tx_msdu_enqueue = pdev->stats.tx_i.processed.num; 10931 req->tx_msdu_overflow = tcl_ring_full; 10932 /* Error rate at LMAC */ 10933 req->rx_mpdu_received = soc->ext_stats.rx_mpdu_received + 10934 pdev->stats.err.fw_reported_rxdma_error; 10935 /* only count error source from RXDMA */ 10936 req->rx_mpdu_error = pdev->stats.err.fw_reported_rxdma_error; 10937 10938 /* Error rate at above the MAC */ 10939 req->rx_mpdu_delivered = soc->ext_stats.rx_mpdu_received; 10940 req->rx_mpdu_missed = pdev->stats.err.reo_error; 10941 10942 dp_info("ext stats: tx_msdu_enq = %u, tx_msdu_overflow = %u, " 10943 "rx_mpdu_receive = %u, rx_mpdu_delivered = %u, " 10944 "rx_mpdu_missed = %u, rx_mpdu_error = %u", 10945 req->tx_msdu_enqueue, 10946 req->tx_msdu_overflow, 10947 req->rx_mpdu_received, 10948 req->rx_mpdu_delivered, 10949 req->rx_mpdu_missed, 10950 req->rx_mpdu_error); 10951 10952 return QDF_STATUS_SUCCESS; 10953 } 10954 10955 #endif /* WLAN_FEATURE_STATS_EXT */ 10956 10957 #ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET 10958 /** 10959 * dp_mark_first_wakeup_packet() - set flag to indicate that 10960 * fw is compatible for marking first packet after wow wakeup 10961 * @soc_hdl: Datapath soc handle 10962 * @pdev_id: id of data path pdev handle 10963 * @value: 1 for enabled/ 0 for disabled 10964 * 10965 * Return: None 10966 */ 10967 static void dp_mark_first_wakeup_packet(struct cdp_soc_t *soc_hdl, 10968 uint8_t pdev_id, uint8_t value) 10969 { 10970 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 10971 struct dp_pdev *pdev; 10972 10973 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 10974 if (!pdev) { 10975 dp_err("pdev is NULL"); 10976 return; 10977 } 10978 10979 pdev->is_first_wakeup_packet = value; 10980 } 10981 #endif 10982 10983 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 10984 /** 10985 * dp_set_peer_txq_flush_config() - Set the peer txq flush configuration 10986 * @soc_hdl: Opaque handle to the DP soc object 10987 * @vdev_id: VDEV identifier 10988 * @mac: MAC address of the peer 10989 * @ac: access category mask 10990 * @tid: TID mask 10991 * @policy: Flush policy 10992 * 10993 * Return: 0 on success, errno on failure 10994 */ 10995 static int dp_set_peer_txq_flush_config(struct cdp_soc_t *soc_hdl, 10996 uint8_t vdev_id, uint8_t *mac, 10997 uint8_t ac, uint32_t tid, 10998 enum cdp_peer_txq_flush_policy policy) 10999 { 11000 struct dp_soc *soc; 11001 11002 if (!soc_hdl) { 11003 dp_err("soc is null"); 11004 return -EINVAL; 11005 } 11006 soc = cdp_soc_t_to_dp_soc(soc_hdl); 11007 return target_if_peer_txq_flush_config(soc->ctrl_psoc, vdev_id, 11008 mac, ac, tid, policy); 11009 } 11010 #endif 11011 11012 #ifdef CONNECTIVITY_PKTLOG 11013 /** 11014 * dp_register_packetdump_callback() - registers 11015 * tx data packet, tx mgmt. packet and rx data packet 11016 * dump callback handler. 11017 * 11018 * @soc_hdl: Datapath soc handle 11019 * @pdev_id: id of data path pdev handle 11020 * @dp_tx_packetdump_cb: tx packetdump cb 11021 * @dp_rx_packetdump_cb: rx packetdump cb 11022 * 11023 * This function is used to register tx data pkt, tx mgmt. 11024 * pkt and rx data pkt dump callback 11025 * 11026 * Return: None 11027 * 11028 */ 11029 static inline 11030 void dp_register_packetdump_callback(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 11031 ol_txrx_pktdump_cb dp_tx_packetdump_cb, 11032 ol_txrx_pktdump_cb dp_rx_packetdump_cb) 11033 { 11034 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11035 struct dp_pdev *pdev; 11036 11037 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11038 if (!pdev) { 11039 dp_err("pdev is NULL!"); 11040 return; 11041 } 11042 11043 pdev->dp_tx_packetdump_cb = dp_tx_packetdump_cb; 11044 pdev->dp_rx_packetdump_cb = dp_rx_packetdump_cb; 11045 } 11046 11047 /** 11048 * dp_deregister_packetdump_callback() - deregidters 11049 * tx data packet, tx mgmt. packet and rx data packet 11050 * dump callback handler 11051 * @soc_hdl: Datapath soc handle 11052 * @pdev_id: id of data path pdev handle 11053 * 11054 * This function is used to deregidter tx data pkt., 11055 * tx mgmt. pkt and rx data pkt. dump callback 11056 * 11057 * Return: None 11058 * 11059 */ 11060 static inline 11061 void dp_deregister_packetdump_callback(struct cdp_soc_t *soc_hdl, 11062 uint8_t pdev_id) 11063 { 11064 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11065 struct dp_pdev *pdev; 11066 11067 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11068 if (!pdev) { 11069 dp_err("pdev is NULL!"); 11070 return; 11071 } 11072 11073 pdev->dp_tx_packetdump_cb = NULL; 11074 pdev->dp_rx_packetdump_cb = NULL; 11075 } 11076 #endif 11077 11078 #ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER 11079 /** 11080 * dp_set_bus_vote_lvl_high() - Take a vote on bus bandwidth from dp 11081 * @soc_hdl: Datapath soc handle 11082 * @high: whether the bus bw is high or not 11083 * 11084 * Return: void 11085 */ 11086 static void 11087 dp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl, bool high) 11088 { 11089 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11090 11091 soc->high_throughput = high; 11092 } 11093 11094 /** 11095 * dp_get_bus_vote_lvl_high() - get bus bandwidth vote to dp 11096 * @soc_hdl: Datapath soc handle 11097 * 11098 * Return: bool 11099 */ 11100 static bool 11101 dp_get_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl) 11102 { 11103 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11104 11105 return soc->high_throughput; 11106 } 11107 #endif 11108 11109 #ifdef DP_PEER_EXTENDED_API 11110 static struct cdp_misc_ops dp_ops_misc = { 11111 #ifdef FEATURE_WLAN_TDLS 11112 .tx_non_std = dp_tx_non_std, 11113 #endif /* FEATURE_WLAN_TDLS */ 11114 .get_opmode = dp_get_opmode, 11115 #ifdef FEATURE_RUNTIME_PM 11116 .runtime_suspend = dp_runtime_suspend, 11117 .runtime_resume = dp_runtime_resume, 11118 #endif /* FEATURE_RUNTIME_PM */ 11119 .get_num_rx_contexts = dp_get_num_rx_contexts, 11120 .get_tx_ack_stats = dp_tx_get_success_ack_stats, 11121 #ifdef WLAN_SUPPORT_DATA_STALL 11122 .txrx_data_stall_cb_register = dp_register_data_stall_detect_cb, 11123 .txrx_data_stall_cb_deregister = dp_deregister_data_stall_detect_cb, 11124 .txrx_post_data_stall_event = dp_txrx_post_data_stall_event, 11125 #endif 11126 11127 #ifdef WLAN_FEATURE_STATS_EXT 11128 .txrx_ext_stats_request = dp_txrx_ext_stats_request, 11129 #ifndef WLAN_SOFTUMAC_SUPPORT 11130 .request_rx_hw_stats = dp_request_rx_hw_stats, 11131 .reset_rx_hw_ext_stats = dp_reset_rx_hw_ext_stats, 11132 #endif 11133 #endif /* WLAN_FEATURE_STATS_EXT */ 11134 .vdev_inform_ll_conn = dp_vdev_inform_ll_conn, 11135 #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR 11136 .set_swlm_enable = dp_soc_set_swlm_enable, 11137 .is_swlm_enabled = dp_soc_is_swlm_enabled, 11138 #endif 11139 .display_txrx_hw_info = dp_display_srng_info, 11140 #ifndef WLAN_SOFTUMAC_SUPPORT 11141 .get_tx_rings_grp_bitmap = dp_get_tx_rings_grp_bitmap, 11142 #endif 11143 #ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET 11144 .mark_first_wakeup_packet = dp_mark_first_wakeup_packet, 11145 #endif 11146 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF 11147 .set_peer_txq_flush_config = dp_set_peer_txq_flush_config, 11148 #endif 11149 #ifdef CONNECTIVITY_PKTLOG 11150 .register_pktdump_cb = dp_register_packetdump_callback, 11151 .unregister_pktdump_cb = dp_deregister_packetdump_callback, 11152 #endif 11153 #ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER 11154 .set_bus_vote_lvl_high = dp_set_bus_vote_lvl_high, 11155 .get_bus_vote_lvl_high = dp_get_bus_vote_lvl_high, 11156 #endif 11157 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 11158 .evaluate_update_tx_ilp_cfg = dp_evaluate_update_tx_ilp_config, 11159 #endif 11160 }; 11161 #endif 11162 11163 #ifdef DP_FLOW_CTL 11164 static struct cdp_flowctl_ops dp_ops_flowctl = { 11165 /* WIFI 3.0 DP implement as required. */ 11166 #ifdef QCA_LL_TX_FLOW_CONTROL_V2 11167 #ifndef WLAN_SOFTUMAC_SUPPORT 11168 .flow_pool_map_handler = dp_tx_flow_pool_map, 11169 .flow_pool_unmap_handler = dp_tx_flow_pool_unmap, 11170 #endif /*WLAN_SOFTUMAC_SUPPORT */ 11171 .register_pause_cb = dp_txrx_register_pause_cb, 11172 .dump_flow_pool_info = dp_tx_dump_flow_pool_info, 11173 .tx_desc_thresh_reached = dp_tx_desc_thresh_reached, 11174 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ 11175 }; 11176 11177 static struct cdp_lflowctl_ops dp_ops_l_flowctl = { 11178 /* WIFI 3.0 DP NOT IMPLEMENTED YET */ 11179 }; 11180 #endif 11181 11182 #ifdef IPA_OFFLOAD 11183 static struct cdp_ipa_ops dp_ops_ipa = { 11184 .ipa_get_resource = dp_ipa_get_resource, 11185 .ipa_set_doorbell_paddr = dp_ipa_set_doorbell_paddr, 11186 .ipa_iounmap_doorbell_vaddr = dp_ipa_iounmap_doorbell_vaddr, 11187 .ipa_op_response = dp_ipa_op_response, 11188 .ipa_register_op_cb = dp_ipa_register_op_cb, 11189 .ipa_deregister_op_cb = dp_ipa_deregister_op_cb, 11190 .ipa_get_stat = dp_ipa_get_stat, 11191 .ipa_tx_data_frame = dp_tx_send_ipa_data_frame, 11192 .ipa_enable_autonomy = dp_ipa_enable_autonomy, 11193 .ipa_disable_autonomy = dp_ipa_disable_autonomy, 11194 .ipa_setup = dp_ipa_setup, 11195 .ipa_cleanup = dp_ipa_cleanup, 11196 .ipa_setup_iface = dp_ipa_setup_iface, 11197 .ipa_cleanup_iface = dp_ipa_cleanup_iface, 11198 .ipa_enable_pipes = dp_ipa_enable_pipes, 11199 .ipa_disable_pipes = dp_ipa_disable_pipes, 11200 .ipa_set_perf_level = dp_ipa_set_perf_level, 11201 .ipa_rx_intrabss_fwd = dp_ipa_rx_intrabss_fwd, 11202 .ipa_tx_buf_smmu_mapping = dp_ipa_tx_buf_smmu_mapping, 11203 .ipa_tx_buf_smmu_unmapping = dp_ipa_tx_buf_smmu_unmapping, 11204 #ifdef QCA_ENHANCED_STATS_SUPPORT 11205 .ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats, 11206 #endif 11207 #ifdef IPA_OPT_WIFI_DP 11208 .ipa_rx_super_rule_setup = dp_ipa_rx_super_rule_setup, 11209 .ipa_pcie_link_up = dp_ipa_pcie_link_up, 11210 .ipa_pcie_link_down = dp_ipa_pcie_link_down, 11211 #endif 11212 #ifdef IPA_WDS_EASYMESH_FEATURE 11213 .ipa_ast_create = dp_ipa_ast_create, 11214 #endif 11215 .ipa_get_wdi_version = dp_ipa_get_wdi_version, 11216 }; 11217 #endif 11218 11219 #ifdef DP_POWER_SAVE 11220 static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 11221 { 11222 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11223 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11224 int timeout = SUSPEND_DRAIN_WAIT; 11225 int drain_wait_delay = 50; /* 50 ms */ 11226 int32_t tx_pending; 11227 11228 if (qdf_unlikely(!pdev)) { 11229 dp_err("pdev is NULL"); 11230 return QDF_STATUS_E_INVAL; 11231 } 11232 11233 /* Abort if there are any pending TX packets */ 11234 while ((tx_pending = dp_get_tx_pending((struct cdp_pdev *)pdev))) { 11235 qdf_sleep(drain_wait_delay); 11236 if (timeout <= 0) { 11237 dp_info("TX frames are pending %d, abort suspend", 11238 tx_pending); 11239 dp_find_missing_tx_comp(soc); 11240 return QDF_STATUS_E_TIMEOUT; 11241 } 11242 timeout = timeout - drain_wait_delay; 11243 } 11244 11245 if (soc->intr_mode == DP_INTR_POLL) 11246 qdf_timer_stop(&soc->int_timer); 11247 11248 /* Stop monitor reap timer and reap any pending frames in ring */ 11249 dp_monitor_reap_timer_suspend(soc); 11250 11251 dp_suspend_fse_cache_flush(soc); 11252 dp_rx_fst_update_pm_suspend_status(soc, true); 11253 11254 return QDF_STATUS_SUCCESS; 11255 } 11256 11257 static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 11258 { 11259 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11260 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11261 11262 if (qdf_unlikely(!pdev)) { 11263 dp_err("pdev is NULL"); 11264 return QDF_STATUS_E_INVAL; 11265 } 11266 11267 if (soc->intr_mode == DP_INTR_POLL) 11268 qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); 11269 11270 /* Start monitor reap timer */ 11271 dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_ANY); 11272 11273 dp_resume_fse_cache_flush(soc); 11274 11275 soc->arch_ops.dp_update_ring_hptp(soc, false); 11276 11277 dp_rx_fst_update_pm_suspend_status(soc, false); 11278 11279 dp_rx_fst_requeue_wq(soc); 11280 11281 return QDF_STATUS_SUCCESS; 11282 } 11283 11284 /** 11285 * dp_process_wow_ack_rsp() - process wow ack response 11286 * @soc_hdl: datapath soc handle 11287 * @pdev_id: data path pdev handle id 11288 * 11289 * Return: none 11290 */ 11291 static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 11292 { 11293 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11294 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11295 11296 if (qdf_unlikely(!pdev)) { 11297 dp_err("pdev is NULL"); 11298 return; 11299 } 11300 11301 /* 11302 * As part of wow enable FW disables the mon status ring and in wow ack 11303 * response from FW reap mon status ring to make sure no packets pending 11304 * in the ring. 11305 */ 11306 dp_monitor_reap_timer_suspend(soc); 11307 } 11308 11309 /** 11310 * dp_process_target_suspend_req() - process target suspend request 11311 * @soc_hdl: datapath soc handle 11312 * @pdev_id: data path pdev handle id 11313 * 11314 * Return: none 11315 */ 11316 static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl, 11317 uint8_t pdev_id) 11318 { 11319 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11320 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11321 11322 if (qdf_unlikely(!pdev)) { 11323 dp_err("pdev is NULL"); 11324 return; 11325 } 11326 11327 /* Stop monitor reap timer and reap any pending frames in ring */ 11328 dp_monitor_reap_timer_suspend(soc); 11329 } 11330 11331 static struct cdp_bus_ops dp_ops_bus = { 11332 .bus_suspend = dp_bus_suspend, 11333 .bus_resume = dp_bus_resume, 11334 .process_wow_ack_rsp = dp_process_wow_ack_rsp, 11335 .process_target_suspend_req = dp_process_target_suspend_req 11336 }; 11337 #endif 11338 11339 #ifdef DP_FLOW_CTL 11340 static struct cdp_throttle_ops dp_ops_throttle = { 11341 /* WIFI 3.0 DP NOT IMPLEMENTED YET */ 11342 }; 11343 11344 static struct cdp_cfg_ops dp_ops_cfg = { 11345 /* WIFI 3.0 DP NOT IMPLEMENTED YET */ 11346 }; 11347 #endif 11348 11349 #ifdef DP_PEER_EXTENDED_API 11350 static struct cdp_ocb_ops dp_ops_ocb = { 11351 /* WIFI 3.0 DP NOT IMPLEMENTED YET */ 11352 }; 11353 11354 static struct cdp_mob_stats_ops dp_ops_mob_stats = { 11355 .clear_stats = dp_txrx_clear_dump_stats, 11356 }; 11357 11358 static struct cdp_peer_ops dp_ops_peer = { 11359 .register_peer = dp_register_peer, 11360 .clear_peer = dp_clear_peer, 11361 .find_peer_exist = dp_find_peer_exist, 11362 .find_peer_exist_on_vdev = dp_find_peer_exist_on_vdev, 11363 .find_peer_exist_on_other_vdev = dp_find_peer_exist_on_other_vdev, 11364 .peer_state_update = dp_peer_state_update, 11365 .get_vdevid = dp_get_vdevid, 11366 .get_vdev_by_peer_addr = dp_get_vdev_by_peer_addr, 11367 .peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr, 11368 .get_peer_state = dp_get_peer_state, 11369 .peer_flush_frags = dp_peer_flush_frags, 11370 .set_peer_as_tdls_peer = dp_set_peer_as_tdls_peer, 11371 }; 11372 #endif 11373 11374 static void dp_soc_txrx_ops_attach(struct dp_soc *soc) 11375 { 11376 soc->cdp_soc.ops->cmn_drv_ops = &dp_ops_cmn; 11377 soc->cdp_soc.ops->ctrl_ops = &dp_ops_ctrl; 11378 soc->cdp_soc.ops->me_ops = &dp_ops_me; 11379 soc->cdp_soc.ops->host_stats_ops = &dp_ops_host_stats; 11380 soc->cdp_soc.ops->wds_ops = &dp_ops_wds; 11381 soc->cdp_soc.ops->raw_ops = &dp_ops_raw; 11382 #ifdef PEER_FLOW_CONTROL 11383 soc->cdp_soc.ops->pflow_ops = &dp_ops_pflow; 11384 #endif /* PEER_FLOW_CONTROL */ 11385 #ifdef DP_PEER_EXTENDED_API 11386 soc->cdp_soc.ops->misc_ops = &dp_ops_misc; 11387 soc->cdp_soc.ops->ocb_ops = &dp_ops_ocb; 11388 soc->cdp_soc.ops->peer_ops = &dp_ops_peer; 11389 soc->cdp_soc.ops->mob_stats_ops = &dp_ops_mob_stats; 11390 #endif 11391 #ifdef DP_FLOW_CTL 11392 soc->cdp_soc.ops->cfg_ops = &dp_ops_cfg; 11393 soc->cdp_soc.ops->flowctl_ops = &dp_ops_flowctl; 11394 soc->cdp_soc.ops->l_flowctl_ops = &dp_ops_l_flowctl; 11395 soc->cdp_soc.ops->throttle_ops = &dp_ops_throttle; 11396 #endif 11397 #ifdef IPA_OFFLOAD 11398 soc->cdp_soc.ops->ipa_ops = &dp_ops_ipa; 11399 #endif 11400 #ifdef DP_POWER_SAVE 11401 soc->cdp_soc.ops->bus_ops = &dp_ops_bus; 11402 #endif 11403 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 11404 soc->cdp_soc.ops->cfr_ops = &dp_ops_cfr; 11405 #endif 11406 #ifdef WLAN_SUPPORT_MSCS 11407 soc->cdp_soc.ops->mscs_ops = &dp_ops_mscs; 11408 #endif 11409 #ifdef WLAN_SUPPORT_MESH_LATENCY 11410 soc->cdp_soc.ops->mesh_latency_ops = &dp_ops_mesh_latency; 11411 #endif 11412 #ifdef CONFIG_SAWF_DEF_QUEUES 11413 soc->cdp_soc.ops->sawf_ops = &dp_ops_sawf; 11414 #endif 11415 #ifdef WLAN_SUPPORT_SCS 11416 soc->cdp_soc.ops->scs_ops = &dp_ops_scs; 11417 #endif 11418 }; 11419 11420 #if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \ 11421 defined(QCA_WIFI_QCA5018) || defined(QCA_WIFI_QCA9574) || \ 11422 defined(QCA_WIFI_QCA5332) 11423 /** 11424 * dp_soc_attach_wifi3() - Attach txrx SOC 11425 * @ctrl_psoc: Opaque SOC handle from control plane 11426 * @params: SOC attach params 11427 * 11428 * Return: DP SOC handle on success, NULL on failure 11429 */ 11430 struct cdp_soc_t * 11431 dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, 11432 struct cdp_soc_attach_params *params) 11433 { 11434 struct dp_soc *dp_soc = NULL; 11435 11436 dp_soc = dp_soc_attach(ctrl_psoc, params); 11437 11438 return dp_soc_to_cdp_soc_t(dp_soc); 11439 } 11440 11441 static inline void dp_soc_set_def_pdev(struct dp_soc *soc) 11442 { 11443 int lmac_id; 11444 11445 for (lmac_id = 0; lmac_id < MAX_NUM_LMAC_HW; lmac_id++) { 11446 /*Set default host PDEV ID for lmac_id*/ 11447 wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx, 11448 INVALID_PDEV_ID, lmac_id); 11449 } 11450 } 11451 11452 static uint32_t 11453 dp_get_link_desc_id_start(uint16_t arch_id) 11454 { 11455 switch (arch_id) { 11456 case CDP_ARCH_TYPE_LI: 11457 case CDP_ARCH_TYPE_RH: 11458 return LINK_DESC_ID_START_21_BITS_COOKIE; 11459 case CDP_ARCH_TYPE_BE: 11460 return LINK_DESC_ID_START_20_BITS_COOKIE; 11461 default: 11462 dp_err("unknown arch_id 0x%x", arch_id); 11463 QDF_BUG(0); 11464 return LINK_DESC_ID_START_21_BITS_COOKIE; 11465 } 11466 } 11467 11468 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP 11469 static inline 11470 void dp_soc_init_tx_ilp(struct dp_soc *soc) 11471 { 11472 soc->tx_ilp_enable = false; 11473 } 11474 #else 11475 static inline 11476 void dp_soc_init_tx_ilp(struct dp_soc *soc) 11477 { 11478 } 11479 #endif 11480 11481 /** 11482 * dp_soc_attach() - Attach txrx SOC 11483 * @ctrl_psoc: Opaque SOC handle from control plane 11484 * @params: SOC attach params 11485 * 11486 * Return: DP SOC handle on success, NULL on failure 11487 */ 11488 static struct dp_soc * 11489 dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, 11490 struct cdp_soc_attach_params *params) 11491 { 11492 struct dp_soc *soc = NULL; 11493 uint16_t arch_id; 11494 struct hif_opaque_softc *hif_handle = params->hif_handle; 11495 qdf_device_t qdf_osdev = params->qdf_osdev; 11496 struct ol_if_ops *ol_ops = params->ol_ops; 11497 uint16_t device_id = params->device_id; 11498 11499 if (!hif_handle) { 11500 dp_err("HIF handle is NULL"); 11501 goto fail0; 11502 } 11503 arch_id = cdp_get_arch_type_from_devid(device_id); 11504 soc = qdf_mem_common_alloc(dp_get_soc_context_size(device_id)); 11505 if (!soc) { 11506 dp_err("DP SOC memory allocation failed"); 11507 goto fail0; 11508 } 11509 11510 dp_info("soc memory allocated %pK", soc); 11511 soc->hif_handle = hif_handle; 11512 soc->hal_soc = hif_get_hal_handle(soc->hif_handle); 11513 if (!soc->hal_soc) 11514 goto fail1; 11515 11516 hif_get_cmem_info(soc->hif_handle, 11517 &soc->cmem_base, 11518 &soc->cmem_total_size); 11519 soc->cmem_avail_size = soc->cmem_total_size; 11520 soc->device_id = device_id; 11521 soc->cdp_soc.ops = 11522 (struct cdp_ops *)qdf_mem_malloc(sizeof(struct cdp_ops)); 11523 if (!soc->cdp_soc.ops) 11524 goto fail1; 11525 11526 dp_soc_txrx_ops_attach(soc); 11527 soc->cdp_soc.ol_ops = ol_ops; 11528 soc->ctrl_psoc = ctrl_psoc; 11529 soc->osdev = qdf_osdev; 11530 soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS; 11531 dp_soc_init_tx_ilp(soc); 11532 hal_rx_get_tlv_size(soc->hal_soc, &soc->rx_pkt_tlv_size, 11533 &soc->rx_mon_pkt_tlv_size); 11534 soc->idle_link_bm_id = hal_get_idle_link_bm_id(soc->hal_soc, 11535 params->mlo_chip_id); 11536 soc->features.dmac_cmn_src_rxbuf_ring_enabled = 11537 hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc); 11538 soc->arch_id = arch_id; 11539 soc->link_desc_id_start = 11540 dp_get_link_desc_id_start(soc->arch_id); 11541 dp_configure_arch_ops(soc); 11542 11543 /* Reset wbm sg list and flags */ 11544 dp_rx_wbm_sg_list_reset(soc); 11545 11546 dp_soc_cfg_history_attach(soc); 11547 dp_soc_tx_hw_desc_history_attach(soc); 11548 dp_soc_rx_history_attach(soc); 11549 dp_soc_mon_status_ring_history_attach(soc); 11550 dp_soc_tx_history_attach(soc); 11551 wlan_set_srng_cfg(&soc->wlan_srng_cfg); 11552 soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); 11553 if (!soc->wlan_cfg_ctx) { 11554 dp_err("wlan_cfg_ctx failed\n"); 11555 goto fail2; 11556 } 11557 11558 soc->arch_ops.soc_cfg_attach(soc); 11559 11560 if (dp_hw_link_desc_pool_banks_alloc(soc, WLAN_INVALID_PDEV_ID)) { 11561 dp_err("failed to allocate link desc pool banks"); 11562 goto fail3; 11563 } 11564 11565 if (dp_hw_link_desc_ring_alloc(soc)) { 11566 dp_err("failed to allocate link_desc_ring"); 11567 goto fail4; 11568 } 11569 11570 if (!QDF_IS_STATUS_SUCCESS(soc->arch_ops.txrx_soc_attach(soc, 11571 params))) { 11572 dp_err("unable to do target specific attach"); 11573 goto fail5; 11574 } 11575 11576 if (dp_soc_srng_alloc(soc)) { 11577 dp_err("failed to allocate soc srng rings"); 11578 goto fail6; 11579 } 11580 11581 if (dp_soc_tx_desc_sw_pools_alloc(soc)) { 11582 dp_err("dp_soc_tx_desc_sw_pools_alloc failed"); 11583 goto fail7; 11584 } 11585 11586 if (!dp_monitor_modularized_enable()) { 11587 if (dp_mon_soc_attach_wrapper(soc)) { 11588 dp_err("failed to attach monitor"); 11589 goto fail8; 11590 } 11591 } 11592 11593 if (hal_reo_shared_qaddr_setup((hal_soc_handle_t)soc->hal_soc, 11594 &soc->reo_qref) 11595 != QDF_STATUS_SUCCESS) { 11596 dp_err("unable to setup reo shared qaddr"); 11597 goto fail9; 11598 } 11599 11600 if (dp_sysfs_initialize_stats(soc) != QDF_STATUS_SUCCESS) { 11601 dp_err("failed to initialize dp stats sysfs file"); 11602 dp_sysfs_deinitialize_stats(soc); 11603 } 11604 11605 dp_soc_swlm_attach(soc); 11606 dp_soc_set_interrupt_mode(soc); 11607 dp_soc_set_def_pdev(soc); 11608 11609 dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u", 11610 qdf_dma_mem_stats_read(), 11611 qdf_heap_mem_stats_read(), 11612 qdf_skb_total_mem_stats_read()); 11613 11614 return soc; 11615 fail9: 11616 if (!dp_monitor_modularized_enable()) 11617 dp_mon_soc_detach_wrapper(soc); 11618 fail8: 11619 dp_soc_tx_desc_sw_pools_free(soc); 11620 fail7: 11621 dp_soc_srng_free(soc); 11622 fail6: 11623 soc->arch_ops.txrx_soc_detach(soc); 11624 fail5: 11625 dp_hw_link_desc_ring_free(soc); 11626 fail4: 11627 dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID); 11628 fail3: 11629 wlan_cfg_soc_detach(soc->wlan_cfg_ctx); 11630 fail2: 11631 qdf_mem_free(soc->cdp_soc.ops); 11632 fail1: 11633 qdf_mem_common_free(soc); 11634 fail0: 11635 return NULL; 11636 } 11637 11638 void *dp_soc_init_wifi3(struct cdp_soc_t *cdp_soc, 11639 struct cdp_ctrl_objmgr_psoc *ctrl_psoc, 11640 struct hif_opaque_softc *hif_handle, 11641 HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, 11642 struct ol_if_ops *ol_ops, uint16_t device_id) 11643 { 11644 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 11645 11646 return soc->arch_ops.txrx_soc_init(soc, htc_handle, hif_handle); 11647 } 11648 11649 #endif 11650 11651 void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id) 11652 { 11653 if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) 11654 return (mac_id < MAX_PDEV_CNT) ? soc->pdev_list[mac_id] : NULL; 11655 11656 /* Typically for MCL as there only 1 PDEV*/ 11657 return soc->pdev_list[0]; 11658 } 11659 11660 void dp_update_num_mac_rings_for_dbs(struct dp_soc *soc, 11661 int *max_mac_rings) 11662 { 11663 bool dbs_enable = false; 11664 11665 if (soc->cdp_soc.ol_ops->is_hw_dbs_capable) 11666 dbs_enable = soc->cdp_soc.ol_ops-> 11667 is_hw_dbs_capable((void *)soc->ctrl_psoc); 11668 11669 *max_mac_rings = dbs_enable ? (*max_mac_rings) : 1; 11670 dp_info("dbs_enable %d, max_mac_rings %d", 11671 dbs_enable, *max_mac_rings); 11672 } 11673 11674 qdf_export_symbol(dp_update_num_mac_rings_for_dbs); 11675 11676 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 11677 /** 11678 * dp_get_cfr_rcc() - get cfr rcc config 11679 * @soc_hdl: Datapath soc handle 11680 * @pdev_id: id of objmgr pdev 11681 * 11682 * Return: true/false based on cfr mode setting 11683 */ 11684 static 11685 bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) 11686 { 11687 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11688 struct dp_pdev *pdev = NULL; 11689 11690 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11691 if (!pdev) { 11692 dp_err("pdev is NULL"); 11693 return false; 11694 } 11695 11696 return pdev->cfr_rcc_mode; 11697 } 11698 11699 /** 11700 * dp_set_cfr_rcc() - enable/disable cfr rcc config 11701 * @soc_hdl: Datapath soc handle 11702 * @pdev_id: id of objmgr pdev 11703 * @enable: Enable/Disable cfr rcc mode 11704 * 11705 * Return: none 11706 */ 11707 static 11708 void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable) 11709 { 11710 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11711 struct dp_pdev *pdev = NULL; 11712 11713 pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11714 if (!pdev) { 11715 dp_err("pdev is NULL"); 11716 return; 11717 } 11718 11719 pdev->cfr_rcc_mode = enable; 11720 } 11721 11722 /** 11723 * dp_get_cfr_dbg_stats - Get the debug statistics for CFR 11724 * @soc_hdl: Datapath soc handle 11725 * @pdev_id: id of data path pdev handle 11726 * @cfr_rcc_stats: CFR RCC debug statistics buffer 11727 * 11728 * Return: none 11729 */ 11730 static inline void 11731 dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, 11732 struct cdp_cfr_rcc_stats *cfr_rcc_stats) 11733 { 11734 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11735 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11736 11737 if (!pdev) { 11738 dp_err("Invalid pdev"); 11739 return; 11740 } 11741 11742 qdf_mem_copy(cfr_rcc_stats, &pdev->stats.rcc, 11743 sizeof(struct cdp_cfr_rcc_stats)); 11744 } 11745 11746 /** 11747 * dp_clear_cfr_dbg_stats - Clear debug statistics for CFR 11748 * @soc_hdl: Datapath soc handle 11749 * @pdev_id: id of data path pdev handle 11750 * 11751 * Return: none 11752 */ 11753 static void dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, 11754 uint8_t pdev_id) 11755 { 11756 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 11757 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 11758 11759 if (!pdev) { 11760 dp_err("dp pdev is NULL"); 11761 return; 11762 } 11763 11764 qdf_mem_zero(&pdev->stats.rcc, sizeof(pdev->stats.rcc)); 11765 } 11766 #endif 11767 11768 /** 11769 * dp_bucket_index() - Return index from array 11770 * 11771 * @delay: delay measured 11772 * @array: array used to index corresponding delay 11773 * @delay_in_us: flag to indicate whether the delay in ms or us 11774 * 11775 * Return: index 11776 */ 11777 static uint8_t 11778 dp_bucket_index(uint32_t delay, uint16_t *array, bool delay_in_us) 11779 { 11780 uint8_t i = CDP_DELAY_BUCKET_0; 11781 uint32_t thr_low, thr_high; 11782 11783 for (; i < CDP_DELAY_BUCKET_MAX - 1; i++) { 11784 thr_low = array[i]; 11785 thr_high = array[i + 1]; 11786 11787 if (delay_in_us) { 11788 thr_low = thr_low * USEC_PER_MSEC; 11789 thr_high = thr_high * USEC_PER_MSEC; 11790 } 11791 if (delay >= thr_low && delay <= thr_high) 11792 return i; 11793 } 11794 return (CDP_DELAY_BUCKET_MAX - 1); 11795 } 11796 11797 #ifdef HW_TX_DELAY_STATS_ENABLE 11798 /* 11799 * cdp_fw_to_hw_delay_range 11800 * Fw to hw delay ranges in milliseconds 11801 */ 11802 static uint16_t cdp_fw_to_hw_delay[CDP_DELAY_BUCKET_MAX] = { 11803 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 250, 500}; 11804 #else 11805 static uint16_t cdp_fw_to_hw_delay[CDP_DELAY_BUCKET_MAX] = { 11806 0, 2, 4, 6, 8, 10, 20, 30, 40, 50, 100, 250, 500}; 11807 #endif 11808 11809 /* 11810 * cdp_sw_enq_delay_range 11811 * Software enqueue delay ranges in milliseconds 11812 */ 11813 static uint16_t cdp_sw_enq_delay[CDP_DELAY_BUCKET_MAX] = { 11814 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 11815 11816 /* 11817 * cdp_intfrm_delay_range 11818 * Interframe delay ranges in milliseconds 11819 */ 11820 static uint16_t cdp_intfrm_delay[CDP_DELAY_BUCKET_MAX] = { 11821 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60}; 11822 11823 /** 11824 * dp_fill_delay_buckets() - Fill delay statistics bucket for each 11825 * type of delay 11826 * @tstats: tid tx stats 11827 * @rstats: tid rx stats 11828 * @delay: delay in ms 11829 * @tid: tid value 11830 * @mode: type of tx delay mode 11831 * @ring_id: ring number 11832 * @delay_in_us: flag to indicate whether the delay in ms or us 11833 * 11834 * Return: pointer to cdp_delay_stats structure 11835 */ 11836 static struct cdp_delay_stats * 11837 dp_fill_delay_buckets(struct cdp_tid_tx_stats *tstats, 11838 struct cdp_tid_rx_stats *rstats, uint32_t delay, 11839 uint8_t tid, uint8_t mode, uint8_t ring_id, 11840 bool delay_in_us) 11841 { 11842 uint8_t delay_index = 0; 11843 struct cdp_delay_stats *stats = NULL; 11844 11845 /* 11846 * Update delay stats in proper bucket 11847 */ 11848 switch (mode) { 11849 /* Software Enqueue delay ranges */ 11850 case CDP_DELAY_STATS_SW_ENQ: 11851 if (!tstats) 11852 break; 11853 11854 delay_index = dp_bucket_index(delay, cdp_sw_enq_delay, 11855 delay_in_us); 11856 tstats->swq_delay.delay_bucket[delay_index]++; 11857 stats = &tstats->swq_delay; 11858 break; 11859 11860 /* Tx Completion delay ranges */ 11861 case CDP_DELAY_STATS_FW_HW_TRANSMIT: 11862 if (!tstats) 11863 break; 11864 11865 delay_index = dp_bucket_index(delay, cdp_fw_to_hw_delay, 11866 delay_in_us); 11867 tstats->hwtx_delay.delay_bucket[delay_index]++; 11868 stats = &tstats->hwtx_delay; 11869 break; 11870 11871 /* Interframe tx delay ranges */ 11872 case CDP_DELAY_STATS_TX_INTERFRAME: 11873 if (!tstats) 11874 break; 11875 11876 delay_index = dp_bucket_index(delay, cdp_intfrm_delay, 11877 delay_in_us); 11878 tstats->intfrm_delay.delay_bucket[delay_index]++; 11879 stats = &tstats->intfrm_delay; 11880 break; 11881 11882 /* Interframe rx delay ranges */ 11883 case CDP_DELAY_STATS_RX_INTERFRAME: 11884 if (!rstats) 11885 break; 11886 11887 delay_index = dp_bucket_index(delay, cdp_intfrm_delay, 11888 delay_in_us); 11889 rstats->intfrm_delay.delay_bucket[delay_index]++; 11890 stats = &rstats->intfrm_delay; 11891 break; 11892 11893 /* Ring reap to indication to network stack */ 11894 case CDP_DELAY_STATS_REAP_STACK: 11895 if (!rstats) 11896 break; 11897 11898 delay_index = dp_bucket_index(delay, cdp_intfrm_delay, 11899 delay_in_us); 11900 rstats->to_stack_delay.delay_bucket[delay_index]++; 11901 stats = &rstats->to_stack_delay; 11902 break; 11903 default: 11904 dp_debug("Incorrect delay mode: %d", mode); 11905 } 11906 11907 return stats; 11908 } 11909 11910 void dp_update_delay_stats(struct cdp_tid_tx_stats *tstats, 11911 struct cdp_tid_rx_stats *rstats, uint32_t delay, 11912 uint8_t tid, uint8_t mode, uint8_t ring_id, 11913 bool delay_in_us) 11914 { 11915 struct cdp_delay_stats *dstats = NULL; 11916 11917 /* 11918 * Delay ranges are different for different delay modes 11919 * Get the correct index to update delay bucket 11920 */ 11921 dstats = dp_fill_delay_buckets(tstats, rstats, delay, tid, mode, 11922 ring_id, delay_in_us); 11923 if (qdf_unlikely(!dstats)) 11924 return; 11925 11926 if (delay != 0) { 11927 /* 11928 * Compute minimum,average and maximum 11929 * delay 11930 */ 11931 if (delay < dstats->min_delay) 11932 dstats->min_delay = delay; 11933 11934 if (delay > dstats->max_delay) 11935 dstats->max_delay = delay; 11936 11937 /* 11938 * Average over delay measured till now 11939 */ 11940 if (!dstats->avg_delay) 11941 dstats->avg_delay = delay; 11942 else 11943 dstats->avg_delay = ((delay + dstats->avg_delay) >> 1); 11944 } 11945 } 11946 11947 uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, 11948 u_int8_t newmac[][QDF_MAC_ADDR_SIZE], 11949 u_int16_t mac_cnt, bool limit) 11950 { 11951 struct dp_soc *dp_soc = (struct dp_soc *)soc; 11952 struct dp_vdev *vdev = 11953 dp_vdev_get_ref_by_id(dp_soc, vdev_id, DP_MOD_ID_CDP); 11954 struct dp_peer *peer; 11955 uint16_t new_mac_cnt = 0; 11956 11957 if (!vdev) 11958 return new_mac_cnt; 11959 11960 if (limit && (vdev->num_peers > mac_cnt)) 11961 return 0; 11962 11963 qdf_spin_lock_bh(&vdev->peer_list_lock); 11964 TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { 11965 if (peer->bss_peer) 11966 continue; 11967 if (new_mac_cnt < mac_cnt) { 11968 WLAN_ADDR_COPY(newmac[new_mac_cnt], peer->mac_addr.raw); 11969 new_mac_cnt++; 11970 } 11971 } 11972 qdf_spin_unlock_bh(&vdev->peer_list_lock); 11973 dp_vdev_unref_delete(dp_soc, vdev, DP_MOD_ID_CDP); 11974 return new_mac_cnt; 11975 } 11976 11977 uint16_t dp_get_peer_id(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *mac) 11978 { 11979 struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, 11980 mac, 0, vdev_id, 11981 DP_MOD_ID_CDP); 11982 uint16_t peer_id = HTT_INVALID_PEER; 11983 11984 if (!peer) { 11985 dp_cdp_debug("%pK: Peer is NULL!\n", (struct dp_soc *)soc); 11986 return peer_id; 11987 } 11988 11989 peer_id = peer->peer_id; 11990 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 11991 return peer_id; 11992 } 11993 11994 #ifdef QCA_SUPPORT_WDS_EXTENDED 11995 QDF_STATUS dp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc, 11996 uint8_t vdev_id, 11997 uint8_t *mac, 11998 ol_txrx_rx_fp rx, 11999 ol_osif_peer_handle osif_peer) 12000 { 12001 struct dp_txrx_peer *txrx_peer = NULL; 12002 struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, 12003 mac, 0, vdev_id, 12004 DP_MOD_ID_CDP); 12005 QDF_STATUS status = QDF_STATUS_E_INVAL; 12006 12007 if (!peer) { 12008 dp_cdp_debug("%pK: Peer is NULL!\n", (struct dp_soc *)soc); 12009 return status; 12010 } 12011 12012 txrx_peer = dp_get_txrx_peer(peer); 12013 if (!txrx_peer) { 12014 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 12015 return status; 12016 } 12017 12018 if (rx) { 12019 if (txrx_peer->osif_rx) { 12020 status = QDF_STATUS_E_ALREADY; 12021 } else { 12022 txrx_peer->osif_rx = rx; 12023 status = QDF_STATUS_SUCCESS; 12024 } 12025 } else { 12026 if (txrx_peer->osif_rx) { 12027 txrx_peer->osif_rx = NULL; 12028 status = QDF_STATUS_SUCCESS; 12029 } else { 12030 status = QDF_STATUS_E_ALREADY; 12031 } 12032 } 12033 12034 txrx_peer->wds_ext.osif_peer = osif_peer; 12035 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 12036 12037 return status; 12038 } 12039 12040 QDF_STATUS dp_wds_ext_get_peer_osif_handle( 12041 ol_txrx_soc_handle soc, 12042 uint8_t vdev_id, 12043 uint8_t *mac, 12044 ol_osif_peer_handle *osif_peer) 12045 { 12046 struct dp_soc *dp_soc = (struct dp_soc *)soc; 12047 struct dp_txrx_peer *txrx_peer = NULL; 12048 struct dp_peer *peer = dp_peer_find_hash_find(dp_soc, 12049 mac, 0, vdev_id, 12050 DP_MOD_ID_CDP); 12051 12052 if (!peer) { 12053 dp_cdp_debug("%pK: Peer is NULL!\n", dp_soc); 12054 return QDF_STATUS_E_INVAL; 12055 } 12056 12057 txrx_peer = dp_get_txrx_peer(peer); 12058 if (!txrx_peer) { 12059 dp_cdp_debug("%pK: TXRX Peer is NULL!\n", dp_soc); 12060 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 12061 return QDF_STATUS_E_INVAL; 12062 } 12063 12064 *osif_peer = txrx_peer->wds_ext.osif_peer; 12065 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 12066 12067 return QDF_STATUS_SUCCESS; 12068 } 12069 #endif /* QCA_SUPPORT_WDS_EXTENDED */ 12070 12071 /** 12072 * dp_pdev_srng_deinit() - de-initialize all pdev srng ring including 12073 * monitor rings 12074 * @pdev: Datapath pdev handle 12075 * 12076 */ 12077 static void dp_pdev_srng_deinit(struct dp_pdev *pdev) 12078 { 12079 struct dp_soc *soc = pdev->soc; 12080 uint8_t i; 12081 12082 if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) 12083 dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], 12084 RXDMA_BUF, 12085 pdev->lmac_id); 12086 12087 if (!soc->rxdma2sw_rings_not_supported) { 12088 for (i = 0; 12089 i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) { 12090 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, 12091 pdev->pdev_id); 12092 12093 wlan_minidump_remove(soc->rxdma_err_dst_ring[lmac_id]. 12094 base_vaddr_unaligned, 12095 soc->rxdma_err_dst_ring[lmac_id]. 12096 alloc_size, 12097 soc->ctrl_psoc, 12098 WLAN_MD_DP_SRNG_RXDMA_ERR_DST, 12099 "rxdma_err_dst"); 12100 dp_srng_deinit(soc, &soc->rxdma_err_dst_ring[lmac_id], 12101 RXDMA_DST, lmac_id); 12102 } 12103 } 12104 12105 12106 } 12107 12108 /** 12109 * dp_pdev_srng_init() - initialize all pdev srng rings including 12110 * monitor rings 12111 * @pdev: Datapath pdev handle 12112 * 12113 * Return: QDF_STATUS_SUCCESS on success 12114 * QDF_STATUS_E_NOMEM on failure 12115 */ 12116 static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev) 12117 { 12118 struct dp_soc *soc = pdev->soc; 12119 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 12120 uint32_t i; 12121 12122 soc_cfg_ctx = soc->wlan_cfg_ctx; 12123 12124 if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 12125 if (dp_srng_init(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], 12126 RXDMA_BUF, 0, pdev->lmac_id)) { 12127 dp_init_err("%pK: dp_srng_init failed rx refill ring", 12128 soc); 12129 goto fail1; 12130 } 12131 } 12132 12133 /* LMAC RxDMA to SW Rings configuration */ 12134 if (!wlan_cfg_per_pdev_lmac_ring(soc_cfg_ctx)) 12135 /* Only valid for MCL */ 12136 pdev = soc->pdev_list[0]; 12137 12138 if (!soc->rxdma2sw_rings_not_supported) { 12139 for (i = 0; 12140 i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) { 12141 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, 12142 pdev->pdev_id); 12143 struct dp_srng *srng = 12144 &soc->rxdma_err_dst_ring[lmac_id]; 12145 12146 if (srng->hal_srng) 12147 continue; 12148 12149 if (dp_srng_init(soc, srng, RXDMA_DST, 0, lmac_id)) { 12150 dp_init_err("%pK:" RNG_ERR "rxdma_err_dst_ring", 12151 soc); 12152 goto fail1; 12153 } 12154 wlan_minidump_log(soc->rxdma_err_dst_ring[lmac_id]. 12155 base_vaddr_unaligned, 12156 soc->rxdma_err_dst_ring[lmac_id]. 12157 alloc_size, 12158 soc->ctrl_psoc, 12159 WLAN_MD_DP_SRNG_RXDMA_ERR_DST, 12160 "rxdma_err_dst"); 12161 } 12162 } 12163 return QDF_STATUS_SUCCESS; 12164 12165 fail1: 12166 dp_pdev_srng_deinit(pdev); 12167 return QDF_STATUS_E_NOMEM; 12168 } 12169 12170 /** 12171 * dp_pdev_srng_free() - free all pdev srng rings including monitor rings 12172 * @pdev: Datapath pdev handle 12173 * 12174 */ 12175 static void dp_pdev_srng_free(struct dp_pdev *pdev) 12176 { 12177 struct dp_soc *soc = pdev->soc; 12178 uint8_t i; 12179 12180 if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) 12181 dp_srng_free(soc, &soc->rx_refill_buf_ring[pdev->lmac_id]); 12182 12183 if (!soc->rxdma2sw_rings_not_supported) { 12184 for (i = 0; 12185 i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) { 12186 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, 12187 pdev->pdev_id); 12188 12189 dp_srng_free(soc, &soc->rxdma_err_dst_ring[lmac_id]); 12190 } 12191 } 12192 } 12193 12194 /** 12195 * dp_pdev_srng_alloc() - allocate memory for all pdev srng rings including 12196 * monitor rings 12197 * @pdev: Datapath pdev handle 12198 * 12199 * Return: QDF_STATUS_SUCCESS on success 12200 * QDF_STATUS_E_NOMEM on failure 12201 */ 12202 static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev) 12203 { 12204 struct dp_soc *soc = pdev->soc; 12205 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 12206 uint32_t ring_size; 12207 uint32_t i; 12208 12209 soc_cfg_ctx = soc->wlan_cfg_ctx; 12210 12211 ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); 12212 if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) { 12213 if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], 12214 RXDMA_BUF, ring_size, 0)) { 12215 dp_init_err("%pK: dp_srng_alloc failed rx refill ring", 12216 soc); 12217 goto fail1; 12218 } 12219 } 12220 12221 ring_size = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx); 12222 /* LMAC RxDMA to SW Rings configuration */ 12223 if (!wlan_cfg_per_pdev_lmac_ring(soc_cfg_ctx)) 12224 /* Only valid for MCL */ 12225 pdev = soc->pdev_list[0]; 12226 12227 if (!soc->rxdma2sw_rings_not_supported) { 12228 for (i = 0; 12229 i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) { 12230 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i, 12231 pdev->pdev_id); 12232 struct dp_srng *srng = 12233 &soc->rxdma_err_dst_ring[lmac_id]; 12234 12235 if (srng->base_vaddr_unaligned) 12236 continue; 12237 12238 if (dp_srng_alloc(soc, srng, RXDMA_DST, ring_size, 0)) { 12239 dp_init_err("%pK:" RNG_ERR "rxdma_err_dst_ring", 12240 soc); 12241 goto fail1; 12242 } 12243 } 12244 } 12245 12246 return QDF_STATUS_SUCCESS; 12247 fail1: 12248 dp_pdev_srng_free(pdev); 12249 return QDF_STATUS_E_NOMEM; 12250 } 12251 12252 static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, 12253 HTC_HANDLE htc_handle, 12254 qdf_device_t qdf_osdev, 12255 uint8_t pdev_id) 12256 { 12257 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; 12258 int nss_cfg; 12259 void *sojourn_buf; 12260 12261 struct dp_soc *soc = (struct dp_soc *)txrx_soc; 12262 struct dp_pdev *pdev = soc->pdev_list[pdev_id]; 12263 12264 soc_cfg_ctx = soc->wlan_cfg_ctx; 12265 pdev->soc = soc; 12266 pdev->pdev_id = pdev_id; 12267 12268 /* 12269 * Variable to prevent double pdev deinitialization during 12270 * radio detach execution .i.e. in the absence of any vdev. 12271 */ 12272 pdev->pdev_deinit = 0; 12273 12274 if (dp_wdi_event_attach(pdev)) { 12275 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 12276 "dp_wdi_evet_attach failed"); 12277 goto fail0; 12278 } 12279 12280 if (dp_pdev_srng_init(pdev)) { 12281 dp_init_err("%pK: Failed to initialize pdev srng rings", soc); 12282 goto fail1; 12283 } 12284 12285 /* Initialize descriptors in TCL Rings used by IPA */ 12286 if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) { 12287 hal_tx_init_data_ring(soc->hal_soc, 12288 soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng); 12289 dp_ipa_hal_tx_init_alt_data_ring(soc); 12290 } 12291 12292 /* 12293 * Initialize command/credit ring descriptor 12294 * Command/CREDIT ring also used for sending DATA cmds 12295 */ 12296 dp_tx_init_cmd_credit_ring(soc); 12297 12298 dp_tx_pdev_init(pdev); 12299 12300 /* 12301 * set nss pdev config based on soc config 12302 */ 12303 nss_cfg = wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx); 12304 wlan_cfg_set_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx, 12305 (nss_cfg & (1 << pdev_id))); 12306 pdev->target_pdev_id = 12307 dp_calculate_target_pdev_id_from_host_pdev_id(soc, pdev_id); 12308 12309 if (soc->preferred_hw_mode == WMI_HOST_HW_MODE_2G_PHYB && 12310 pdev->lmac_id == PHYB_2G_LMAC_ID) { 12311 pdev->target_pdev_id = PHYB_2G_TARGET_PDEV_ID; 12312 } 12313 12314 /* Reset the cpu ring map if radio is NSS offloaded */ 12315 if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) { 12316 dp_soc_reset_cpu_ring_map(soc); 12317 dp_soc_reset_intr_mask(soc); 12318 } 12319 12320 /* Reset the cpu ring map if radio is NSS offloaded */ 12321 dp_soc_reset_ipa_vlan_intr_mask(soc); 12322 12323 TAILQ_INIT(&pdev->vdev_list); 12324 qdf_spinlock_create(&pdev->vdev_list_lock); 12325 pdev->vdev_count = 0; 12326 pdev->is_lro_hash_configured = 0; 12327 12328 qdf_spinlock_create(&pdev->tx_mutex); 12329 pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MON_INVALID_LMAC_ID; 12330 pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MON_INVALID_LMAC_ID; 12331 pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MON_INVALID_LMAC_ID; 12332 12333 DP_STATS_INIT(pdev); 12334 12335 dp_local_peer_id_pool_init(pdev); 12336 12337 dp_dscp_tid_map_setup(pdev); 12338 dp_pcp_tid_map_setup(pdev); 12339 12340 /* set the reo destination during initialization */ 12341 dp_pdev_set_default_reo(pdev); 12342 12343 qdf_mem_zero(&pdev->sojourn_stats, sizeof(struct cdp_tx_sojourn_stats)); 12344 12345 pdev->sojourn_buf = qdf_nbuf_alloc(pdev->soc->osdev, 12346 sizeof(struct cdp_tx_sojourn_stats), 0, 4, 12347 TRUE); 12348 12349 if (!pdev->sojourn_buf) { 12350 dp_init_err("%pK: Failed to allocate sojourn buf", soc); 12351 goto fail2; 12352 } 12353 sojourn_buf = qdf_nbuf_data(pdev->sojourn_buf); 12354 qdf_mem_zero(sojourn_buf, sizeof(struct cdp_tx_sojourn_stats)); 12355 12356 qdf_event_create(&pdev->fw_peer_stats_event); 12357 qdf_event_create(&pdev->fw_stats_event); 12358 qdf_event_create(&pdev->fw_obss_stats_event); 12359 12360 pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); 12361 pdev->num_tx_spl_allowed = 12362 wlan_cfg_get_num_tx_spl_desc(soc->wlan_cfg_ctx); 12363 pdev->num_reg_tx_allowed = 12364 pdev->num_tx_allowed - pdev->num_tx_spl_allowed; 12365 if (dp_rxdma_ring_setup(soc, pdev)) { 12366 dp_init_err("%pK: RXDMA ring config failed", soc); 12367 goto fail3; 12368 } 12369 12370 if (dp_init_ipa_rx_refill_buf_ring(soc, pdev)) 12371 goto fail3; 12372 12373 if (dp_ipa_ring_resource_setup(soc, pdev)) 12374 goto fail4; 12375 12376 if (dp_ipa_uc_attach(soc, pdev) != QDF_STATUS_SUCCESS) { 12377 dp_init_err("%pK: dp_ipa_uc_attach failed", soc); 12378 goto fail4; 12379 } 12380 12381 if (dp_pdev_bkp_stats_attach(pdev) != QDF_STATUS_SUCCESS) { 12382 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, 12383 FL("dp_pdev_bkp_stats_attach failed")); 12384 goto fail5; 12385 } 12386 12387 if (dp_monitor_pdev_init(pdev)) { 12388 dp_init_err("%pK: dp_monitor_pdev_init failed\n", soc); 12389 goto fail6; 12390 } 12391 12392 /* initialize sw rx descriptors */ 12393 dp_rx_pdev_desc_pool_init(pdev); 12394 /* allocate buffers and replenish the RxDMA ring */ 12395 dp_rx_pdev_buffers_alloc(pdev); 12396 12397 dp_init_tso_stats(pdev); 12398 12399 pdev->rx_fast_flag = false; 12400 dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u", 12401 qdf_dma_mem_stats_read(), 12402 qdf_heap_mem_stats_read(), 12403 qdf_skb_total_mem_stats_read()); 12404 12405 return QDF_STATUS_SUCCESS; 12406 fail6: 12407 dp_pdev_bkp_stats_detach(pdev); 12408 fail5: 12409 dp_ipa_uc_detach(soc, pdev); 12410 fail4: 12411 dp_deinit_ipa_rx_refill_buf_ring(soc, pdev); 12412 fail3: 12413 dp_rxdma_ring_cleanup(soc, pdev); 12414 qdf_nbuf_free(pdev->sojourn_buf); 12415 fail2: 12416 qdf_spinlock_destroy(&pdev->tx_mutex); 12417 qdf_spinlock_destroy(&pdev->vdev_list_lock); 12418 dp_pdev_srng_deinit(pdev); 12419 fail1: 12420 dp_wdi_event_detach(pdev); 12421 fail0: 12422 return QDF_STATUS_E_FAILURE; 12423 } 12424 12425 /** 12426 * dp_pdev_init_wifi3() - Init txrx pdev 12427 * @txrx_soc: 12428 * @htc_handle: HTC handle for host-target interface 12429 * @qdf_osdev: QDF OS device 12430 * @pdev_id: pdev Id 12431 * 12432 * Return: QDF_STATUS 12433 */ 12434 static QDF_STATUS dp_pdev_init_wifi3(struct cdp_soc_t *txrx_soc, 12435 HTC_HANDLE htc_handle, 12436 qdf_device_t qdf_osdev, 12437 uint8_t pdev_id) 12438 { 12439 return dp_pdev_init(txrx_soc, htc_handle, qdf_osdev, pdev_id); 12440 } 12441 12442 #ifdef FEATURE_DIRECT_LINK 12443 struct dp_srng *dp_setup_direct_link_refill_ring(struct cdp_soc_t *soc_hdl, 12444 uint8_t pdev_id) 12445 { 12446 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 12447 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 12448 12449 if (!pdev) { 12450 dp_err("DP pdev is NULL"); 12451 return NULL; 12452 } 12453 12454 if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring4, 12455 RXDMA_BUF, DIRECT_LINK_REFILL_RING_ENTRIES, false)) { 12456 dp_err("SRNG alloc failed for rx_refill_buf_ring4"); 12457 return NULL; 12458 } 12459 12460 if (dp_srng_init(soc, &pdev->rx_refill_buf_ring4, 12461 RXDMA_BUF, DIRECT_LINK_REFILL_RING_IDX, 0)) { 12462 dp_err("SRNG init failed for rx_refill_buf_ring4"); 12463 dp_srng_free(soc, &pdev->rx_refill_buf_ring4); 12464 return NULL; 12465 } 12466 12467 if (htt_srng_setup(soc->htt_handle, pdev_id, 12468 pdev->rx_refill_buf_ring4.hal_srng, RXDMA_BUF)) { 12469 dp_srng_deinit(soc, &pdev->rx_refill_buf_ring4, RXDMA_BUF, 12470 DIRECT_LINK_REFILL_RING_IDX); 12471 dp_srng_free(soc, &pdev->rx_refill_buf_ring4); 12472 return NULL; 12473 } 12474 12475 return &pdev->rx_refill_buf_ring4; 12476 } 12477 12478 void dp_destroy_direct_link_refill_ring(struct cdp_soc_t *soc_hdl, 12479 uint8_t pdev_id) 12480 { 12481 struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); 12482 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 12483 12484 if (!pdev) { 12485 dp_err("DP pdev is NULL"); 12486 return; 12487 } 12488 12489 dp_srng_deinit(soc, &pdev->rx_refill_buf_ring4, RXDMA_BUF, 0); 12490 dp_srng_free(soc, &pdev->rx_refill_buf_ring4); 12491 } 12492 #endif 12493