1 /* 2 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-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 /** 21 * DOC: wlan_cp_stats_utils_api.c 22 * 23 * This file provide public API definitions for other accessing other UMAC 24 * components 25 */ 26 #include <cfg_ucfg_api.h> 27 #include "../../core/src/wlan_cp_stats_defs.h" 28 #include "../../core/src/wlan_cp_stats_obj_mgr_handler.h" 29 #include "../../core/src/wlan_cp_stats_comp_handler.h" 30 #include <wlan_cp_stats_utils_api.h> 31 #include <wlan_cp_stats_ucfg_api.h> 32 #include <wlan_cp_stats_chipset_stats.h> 33 34 QDF_STATUS wlan_cp_stats_init(void) 35 { 36 QDF_STATUS status = QDF_STATUS_E_FAILURE; 37 38 status = wlan_objmgr_register_psoc_create_handler 39 (WLAN_UMAC_COMP_CP_STATS, 40 wlan_cp_stats_psoc_obj_create_handler, 41 NULL); 42 if (QDF_IS_STATUS_ERROR(status)) { 43 cp_stats_err("Failed to register psoc create handler"); 44 goto wlan_cp_stats_psoc_init_fail1; 45 } 46 47 status = wlan_objmgr_register_psoc_destroy_handler 48 (WLAN_UMAC_COMP_CP_STATS, 49 wlan_cp_stats_psoc_obj_destroy_handler, 50 NULL); 51 if (QDF_IS_STATUS_ERROR(status)) { 52 cp_stats_err("Failed to register psoc destroy handler"); 53 goto wlan_cp_stats_psoc_init_fail2; 54 } 55 56 status = wlan_objmgr_register_pdev_create_handler 57 (WLAN_UMAC_COMP_CP_STATS, 58 wlan_cp_stats_pdev_obj_create_handler, 59 NULL); 60 if (QDF_IS_STATUS_ERROR(status)) { 61 cp_stats_err("Failed to register pdev create handler"); 62 goto wlan_cp_stats_pdev_init_fail1; 63 } 64 65 status = wlan_objmgr_register_pdev_destroy_handler 66 (WLAN_UMAC_COMP_CP_STATS, 67 wlan_cp_stats_pdev_obj_destroy_handler, 68 NULL); 69 if (QDF_IS_STATUS_ERROR(status)) { 70 cp_stats_err("Failed to register pdev destroy handler"); 71 goto wlan_cp_stats_pdev_init_fail2; 72 } 73 74 status = wlan_objmgr_register_vdev_create_handler 75 (WLAN_UMAC_COMP_CP_STATS, 76 wlan_cp_stats_vdev_obj_create_handler, 77 NULL); 78 if (QDF_IS_STATUS_ERROR(status)) { 79 cp_stats_err("Failed to register vdev create handler"); 80 goto wlan_cp_stats_vdev_init_fail1; 81 } 82 83 status = wlan_objmgr_register_vdev_destroy_handler 84 (WLAN_UMAC_COMP_CP_STATS, 85 wlan_cp_stats_vdev_obj_destroy_handler, 86 NULL); 87 if (QDF_IS_STATUS_ERROR(status)) { 88 cp_stats_err("Failed to register vdev destroy handler"); 89 goto wlan_cp_stats_vdev_init_fail2; 90 } 91 92 status = wlan_objmgr_register_peer_create_handler 93 (WLAN_UMAC_COMP_CP_STATS, 94 wlan_cp_stats_peer_obj_create_handler, 95 NULL); 96 if (QDF_IS_STATUS_ERROR(status)) { 97 cp_stats_err("Failed to register peer create handler"); 98 goto wlan_cp_stats_peer_init_fail1; 99 } 100 101 status = wlan_objmgr_register_peer_destroy_handler 102 (WLAN_UMAC_COMP_CP_STATS, 103 wlan_cp_stats_peer_obj_destroy_handler, 104 NULL); 105 if (QDF_IS_STATUS_ERROR(status)) { 106 cp_stats_err("Failed to register peer destroy handler"); 107 goto wlan_cp_stats_peer_init_fail2; 108 } 109 110 status = wlan_cp_stats_cstats_init(); 111 if (QDF_IS_STATUS_ERROR(status)) { 112 cp_stats_err("Failed to init chipset stats"); 113 goto wlan_cp_stats_peer_init_fail2; 114 } 115 116 return QDF_STATUS_SUCCESS; 117 118 wlan_cp_stats_peer_init_fail2: 119 wlan_objmgr_unregister_peer_create_handler 120 (WLAN_UMAC_COMP_CP_STATS, 121 wlan_cp_stats_peer_obj_create_handler, 122 NULL); 123 wlan_cp_stats_peer_init_fail1: 124 wlan_objmgr_unregister_vdev_destroy_handler 125 (WLAN_UMAC_COMP_CP_STATS, 126 wlan_cp_stats_vdev_obj_destroy_handler, 127 NULL); 128 wlan_cp_stats_vdev_init_fail2: 129 wlan_objmgr_unregister_vdev_create_handler 130 (WLAN_UMAC_COMP_CP_STATS, 131 wlan_cp_stats_vdev_obj_create_handler, 132 NULL); 133 wlan_cp_stats_vdev_init_fail1: 134 wlan_objmgr_unregister_pdev_destroy_handler 135 (WLAN_UMAC_COMP_CP_STATS, 136 wlan_cp_stats_pdev_obj_destroy_handler, 137 NULL); 138 wlan_cp_stats_pdev_init_fail2: 139 wlan_objmgr_unregister_pdev_create_handler 140 (WLAN_UMAC_COMP_CP_STATS, 141 wlan_cp_stats_pdev_obj_create_handler, 142 NULL); 143 wlan_cp_stats_pdev_init_fail1: 144 wlan_objmgr_unregister_psoc_destroy_handler 145 (WLAN_UMAC_COMP_CP_STATS, 146 wlan_cp_stats_psoc_obj_destroy_handler, 147 NULL); 148 wlan_cp_stats_psoc_init_fail2: 149 wlan_objmgr_unregister_psoc_create_handler 150 (WLAN_UMAC_COMP_CP_STATS, 151 wlan_cp_stats_psoc_obj_create_handler, 152 NULL); 153 wlan_cp_stats_psoc_init_fail1: 154 return status; 155 } 156 157 QDF_STATUS wlan_cp_stats_deinit(void) 158 { 159 QDF_STATUS status = QDF_STATUS_E_FAILURE; 160 161 wlan_cp_stats_cstats_deinit(); 162 163 status = wlan_objmgr_unregister_psoc_create_handler 164 (WLAN_UMAC_COMP_CP_STATS, 165 wlan_cp_stats_psoc_obj_create_handler, 166 NULL); 167 if (QDF_IS_STATUS_ERROR(status)) 168 cp_stats_err("Failed to unregister psoc create handler"); 169 170 status = wlan_objmgr_unregister_psoc_destroy_handler 171 (WLAN_UMAC_COMP_CP_STATS, 172 wlan_cp_stats_psoc_obj_destroy_handler, 173 NULL); 174 if (QDF_IS_STATUS_ERROR(status)) 175 cp_stats_err("Failed to unregister psoc destroy handler"); 176 177 status = wlan_objmgr_unregister_pdev_create_handler 178 (WLAN_UMAC_COMP_CP_STATS, 179 wlan_cp_stats_pdev_obj_create_handler, 180 NULL); 181 if (QDF_IS_STATUS_ERROR(status)) 182 cp_stats_err("Failed to unregister pdev create handler"); 183 184 status = wlan_objmgr_unregister_pdev_destroy_handler 185 (WLAN_UMAC_COMP_CP_STATS, 186 wlan_cp_stats_pdev_obj_destroy_handler, 187 NULL); 188 if (QDF_IS_STATUS_ERROR(status)) 189 cp_stats_err("Failed to unregister pdev destroy handler"); 190 191 status = wlan_objmgr_unregister_vdev_create_handler 192 (WLAN_UMAC_COMP_CP_STATS, 193 wlan_cp_stats_vdev_obj_create_handler, 194 NULL); 195 if (QDF_IS_STATUS_ERROR(status)) 196 cp_stats_err("Failed to unregister vdev create handler"); 197 198 status = wlan_objmgr_unregister_vdev_destroy_handler 199 (WLAN_UMAC_COMP_CP_STATS, 200 wlan_cp_stats_vdev_obj_destroy_handler, 201 NULL); 202 if (QDF_IS_STATUS_ERROR(status)) 203 cp_stats_err("Failed to unregister vdev destroy handler"); 204 205 status = wlan_objmgr_unregister_peer_create_handler 206 (WLAN_UMAC_COMP_CP_STATS, 207 wlan_cp_stats_peer_obj_create_handler, 208 NULL); 209 if (QDF_IS_STATUS_ERROR(status)) 210 cp_stats_err("Failed to unregister peer create handler"); 211 212 status = wlan_objmgr_unregister_peer_destroy_handler 213 (WLAN_UMAC_COMP_CP_STATS, 214 wlan_cp_stats_peer_obj_destroy_handler, 215 NULL); 216 if (QDF_IS_STATUS_ERROR(status)) 217 cp_stats_err("Failed to unregister peer destroy handler"); 218 219 return status; 220 } 221 222 #ifdef WLAN_CHIPSET_STATS 223 static void wlan_cp_stats_init_cfg(struct wlan_objmgr_psoc *psoc, 224 struct cp_stats_context *csc) 225 { 226 if (!psoc) { 227 cp_stats_err("psoc is NULL"); 228 return; 229 } 230 csc->host_params.chipset_stats_enable = 231 cfg_get(psoc, CHIPSET_STATS_ENABLE); 232 } 233 #else 234 static inline 235 void wlan_cp_stats_init_cfg(struct wlan_objmgr_psoc *psoc, 236 struct cp_stats_context *csc) 237 { 238 } 239 #endif 240 241 /* DA/OL specific call back initialization */ 242 QDF_STATUS wlan_cp_stats_open(struct wlan_objmgr_psoc *psoc) 243 { 244 QDF_STATUS status = QDF_STATUS_E_FAILURE; 245 struct cp_stats_context *csc; 246 247 if (!psoc) { 248 cp_stats_err("PSOC is null!"); 249 return QDF_STATUS_E_INVAL; 250 } 251 csc = 252 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 253 if (!csc) { 254 cp_stats_err("cp_stats_context is null!"); 255 return QDF_STATUS_E_FAILURE; 256 } 257 wlan_cp_stats_init_cfg(psoc, csc); 258 259 if (csc->cp_stats_open) 260 status = csc->cp_stats_open(psoc); 261 262 qdf_spinlock_create(&csc->csc_lock); 263 return status; 264 } 265 266 QDF_STATUS wlan_cp_stats_close(struct wlan_objmgr_psoc *psoc) 267 { 268 struct cp_stats_context *csc; 269 270 if (!psoc) { 271 cp_stats_err("PSOC is null!"); 272 return QDF_STATUS_E_INVAL; 273 } 274 csc = 275 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 276 if (csc && csc->cp_stats_close) { 277 csc->cp_stats_close(psoc); 278 qdf_spinlock_destroy(&csc->csc_lock); 279 } 280 281 return QDF_STATUS_SUCCESS; 282 } 283 284 /* WMI registrations stage */ 285 QDF_STATUS wlan_cp_stats_enable(struct wlan_objmgr_psoc *psoc) 286 { 287 QDF_STATUS status = QDF_STATUS_E_FAILURE; 288 struct cp_stats_context *csc; 289 290 if (!psoc) { 291 cp_stats_err("PSOC is null!"); 292 return QDF_STATUS_E_INVAL; 293 } 294 csc = 295 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 296 if (!csc) { 297 cp_stats_err("cp_stats_context is null!"); 298 return QDF_STATUS_E_FAILURE; 299 } 300 301 if (csc->cp_stats_enable) 302 status = csc->cp_stats_enable(psoc); 303 304 return status; 305 } 306 307 QDF_STATUS wlan_cp_stats_disable(struct wlan_objmgr_psoc *psoc) 308 { 309 struct cp_stats_context *csc; 310 311 if (!psoc) { 312 cp_stats_err("PSOC is null!\n"); 313 return QDF_STATUS_E_INVAL; 314 } 315 csc = 316 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 317 if (csc && csc->cp_stats_disable) 318 csc->cp_stats_disable(psoc); 319 320 return QDF_STATUS_SUCCESS; 321 } 322 323 QDF_STATUS 324 wlan_cp_stats_comp_obj_cfg(enum wlan_objmgr_obj_type obj_type, 325 enum wlan_cp_stats_cfg_state cfg_state, 326 enum wlan_umac_comp_id comp_id, 327 void *cmn_obj, void *data) 328 { 329 QDF_STATUS status = QDF_STATUS_E_FAILURE; 330 struct cp_stats_context *csc; 331 struct wlan_objmgr_psoc *psoc; 332 struct wlan_objmgr_pdev *pdev; 333 struct wlan_objmgr_vdev *vdev; 334 struct wlan_objmgr_peer *peer; 335 enum wlan_cp_stats_comp_id cp_stats_comp_id; 336 337 if (!cmn_obj) { 338 cp_stats_err("common object is null!"); 339 return QDF_STATUS_E_INVAL; 340 } 341 342 cp_stats_comp_id = wlan_cp_stats_get_comp_id(comp_id); 343 if (cp_stats_comp_id >= WLAN_CP_STATS_MAX_COMPONENTS) { 344 cp_stats_err("Invalid UMAC id provided to cp_stats"); 345 return QDF_STATUS_E_INVAL; 346 } 347 348 switch (obj_type) { 349 case WLAN_PSOC_OP: 350 psoc = (struct wlan_objmgr_psoc *)cmn_obj; 351 csc = 352 wlan_objmgr_psoc_get_comp_private_obj 353 (psoc, WLAN_UMAC_COMP_CP_STATS); 354 break; 355 case WLAN_PDEV_OP: 356 pdev = (struct wlan_objmgr_pdev *)cmn_obj; 357 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 358 break; 359 case WLAN_VDEV_OP: 360 vdev = (struct wlan_objmgr_vdev *)cmn_obj; 361 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 362 break; 363 case WLAN_PEER_OP: 364 peer = (struct wlan_objmgr_peer *)cmn_obj; 365 csc = wlan_cp_stats_ctx_get_from_peer(peer); 366 break; 367 default: 368 cp_stats_err("Invalid common object type"); 369 return QDF_STATUS_E_INVAL; 370 } 371 372 if (!csc) { 373 cp_stats_err("cp_stats_context is null!"); 374 return QDF_STATUS_E_FAILURE; 375 } 376 377 if (csc->cp_stats_comp_obj_config) 378 status = csc->cp_stats_comp_obj_config(obj_type, cfg_state, 379 cp_stats_comp_id, 380 cmn_obj, data); 381 382 return status; 383 } 384 385 void wlan_cp_stats_vdev_mcast_rx_pnerr(struct wlan_objmgr_vdev *vdev) 386 { 387 struct vdev_cp_stats *vdev_cs = wlan_cp_stats_get_vdev_stats_obj(vdev); 388 389 if (vdev_cs && vdev_cs->mcast_rx_pnerr_stats_inc) 390 vdev_cs->mcast_rx_pnerr_stats_inc(vdev, 1); 391 } 392 393 void wlan_cp_stats_peer_rx_pnerr(struct wlan_objmgr_peer *peer) 394 { 395 struct peer_cp_stats *peer_cs = wlan_cp_stats_get_peer_stats_obj(peer); 396 397 if (peer_cs && peer_cs->rx_pnerr_stats_inc) 398 peer_cs->rx_pnerr_stats_inc(peer, 1); 399 } 400 401 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED) 402 QDF_STATUS 403 tgt_cp_stats_twt_get_session_evt_handler( 404 struct wlan_objmgr_psoc *psoc, 405 struct twt_session_stats_info *twt_params) 406 { 407 return wlan_cp_stats_twt_get_session_evt_handler(psoc, twt_params); 408 } 409 #endif 410