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