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