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