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