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