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