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