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 return QDF_STATUS_SUCCESS; 111 112 wlan_cp_stats_peer_init_fail2: 113 wlan_objmgr_unregister_peer_create_handler 114 (WLAN_UMAC_COMP_CP_STATS, 115 wlan_cp_stats_peer_obj_create_handler, 116 NULL); 117 wlan_cp_stats_peer_init_fail1: 118 wlan_objmgr_unregister_vdev_destroy_handler 119 (WLAN_UMAC_COMP_CP_STATS, 120 wlan_cp_stats_vdev_obj_destroy_handler, 121 NULL); 122 wlan_cp_stats_vdev_init_fail2: 123 wlan_objmgr_unregister_vdev_create_handler 124 (WLAN_UMAC_COMP_CP_STATS, 125 wlan_cp_stats_vdev_obj_create_handler, 126 NULL); 127 wlan_cp_stats_vdev_init_fail1: 128 wlan_objmgr_unregister_pdev_destroy_handler 129 (WLAN_UMAC_COMP_CP_STATS, 130 wlan_cp_stats_pdev_obj_destroy_handler, 131 NULL); 132 wlan_cp_stats_pdev_init_fail2: 133 wlan_objmgr_unregister_pdev_create_handler 134 (WLAN_UMAC_COMP_CP_STATS, 135 wlan_cp_stats_pdev_obj_create_handler, 136 NULL); 137 wlan_cp_stats_pdev_init_fail1: 138 wlan_objmgr_unregister_psoc_destroy_handler 139 (WLAN_UMAC_COMP_CP_STATS, 140 wlan_cp_stats_psoc_obj_destroy_handler, 141 NULL); 142 wlan_cp_stats_psoc_init_fail2: 143 wlan_objmgr_unregister_psoc_create_handler 144 (WLAN_UMAC_COMP_CP_STATS, 145 wlan_cp_stats_psoc_obj_create_handler, 146 NULL); 147 wlan_cp_stats_psoc_init_fail1: 148 return status; 149 } 150 151 QDF_STATUS wlan_cp_stats_deinit(void) 152 { 153 QDF_STATUS status = QDF_STATUS_E_FAILURE; 154 155 status = wlan_objmgr_unregister_psoc_create_handler 156 (WLAN_UMAC_COMP_CP_STATS, 157 wlan_cp_stats_psoc_obj_create_handler, 158 NULL); 159 if (QDF_IS_STATUS_ERROR(status)) 160 cp_stats_err("Failed to unregister psoc create handler"); 161 162 status = wlan_objmgr_unregister_psoc_destroy_handler 163 (WLAN_UMAC_COMP_CP_STATS, 164 wlan_cp_stats_psoc_obj_destroy_handler, 165 NULL); 166 if (QDF_IS_STATUS_ERROR(status)) 167 cp_stats_err("Failed to unregister psoc destroy handler"); 168 169 status = wlan_objmgr_unregister_pdev_create_handler 170 (WLAN_UMAC_COMP_CP_STATS, 171 wlan_cp_stats_pdev_obj_create_handler, 172 NULL); 173 if (QDF_IS_STATUS_ERROR(status)) 174 cp_stats_err("Failed to unregister pdev create handler"); 175 176 status = wlan_objmgr_unregister_pdev_destroy_handler 177 (WLAN_UMAC_COMP_CP_STATS, 178 wlan_cp_stats_pdev_obj_destroy_handler, 179 NULL); 180 if (QDF_IS_STATUS_ERROR(status)) 181 cp_stats_err("Failed to unregister pdev destroy handler"); 182 183 status = wlan_objmgr_unregister_vdev_create_handler 184 (WLAN_UMAC_COMP_CP_STATS, 185 wlan_cp_stats_vdev_obj_create_handler, 186 NULL); 187 if (QDF_IS_STATUS_ERROR(status)) 188 cp_stats_err("Failed to unregister vdev create handler"); 189 190 status = wlan_objmgr_unregister_vdev_destroy_handler 191 (WLAN_UMAC_COMP_CP_STATS, 192 wlan_cp_stats_vdev_obj_destroy_handler, 193 NULL); 194 if (QDF_IS_STATUS_ERROR(status)) 195 cp_stats_err("Failed to unregister vdev destroy handler"); 196 197 status = wlan_objmgr_unregister_peer_create_handler 198 (WLAN_UMAC_COMP_CP_STATS, 199 wlan_cp_stats_peer_obj_create_handler, 200 NULL); 201 if (QDF_IS_STATUS_ERROR(status)) 202 cp_stats_err("Failed to unregister peer create handler"); 203 204 status = wlan_objmgr_unregister_peer_destroy_handler 205 (WLAN_UMAC_COMP_CP_STATS, 206 wlan_cp_stats_peer_obj_destroy_handler, 207 NULL); 208 if (QDF_IS_STATUS_ERROR(status)) 209 cp_stats_err("Failed to unregister peer destroy handler"); 210 211 return status; 212 } 213 214 /* DA/OL specific call back initialization */ 215 QDF_STATUS wlan_cp_stats_open(struct wlan_objmgr_psoc *psoc) 216 { 217 QDF_STATUS status = QDF_STATUS_E_FAILURE; 218 struct cp_stats_context *csc; 219 220 if (!psoc) { 221 cp_stats_err("PSOC is null!"); 222 return QDF_STATUS_E_INVAL; 223 } 224 csc = 225 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 226 if (!csc) { 227 cp_stats_err("cp_stats_context is null!"); 228 return QDF_STATUS_E_FAILURE; 229 } 230 231 if (csc->cp_stats_open) 232 status = csc->cp_stats_open(psoc); 233 234 qdf_spinlock_create(&csc->csc_lock); 235 return status; 236 } 237 238 QDF_STATUS wlan_cp_stats_close(struct wlan_objmgr_psoc *psoc) 239 { 240 struct cp_stats_context *csc; 241 242 if (!psoc) { 243 cp_stats_err("PSOC is null!"); 244 return QDF_STATUS_E_INVAL; 245 } 246 csc = 247 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 248 if (csc && csc->cp_stats_close) { 249 csc->cp_stats_close(psoc); 250 qdf_spinlock_destroy(&csc->csc_lock); 251 } 252 253 return QDF_STATUS_SUCCESS; 254 } 255 256 /* WMI registrations stage */ 257 QDF_STATUS wlan_cp_stats_enable(struct wlan_objmgr_psoc *psoc) 258 { 259 QDF_STATUS status = QDF_STATUS_E_FAILURE; 260 struct cp_stats_context *csc; 261 262 if (!psoc) { 263 cp_stats_err("PSOC is null!"); 264 return QDF_STATUS_E_INVAL; 265 } 266 csc = 267 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 268 if (!csc) { 269 cp_stats_err("cp_stats_context is null!"); 270 return QDF_STATUS_E_FAILURE; 271 } 272 273 if (csc->cp_stats_enable) 274 status = csc->cp_stats_enable(psoc); 275 276 return status; 277 } 278 279 QDF_STATUS wlan_cp_stats_disable(struct wlan_objmgr_psoc *psoc) 280 { 281 struct cp_stats_context *csc; 282 283 if (!psoc) { 284 cp_stats_err("PSOC is null!\n"); 285 return QDF_STATUS_E_INVAL; 286 } 287 csc = 288 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS); 289 if (csc && csc->cp_stats_disable) 290 csc->cp_stats_disable(psoc); 291 292 return QDF_STATUS_SUCCESS; 293 } 294 295 QDF_STATUS 296 wlan_cp_stats_comp_obj_cfg(enum wlan_objmgr_obj_type obj_type, 297 enum wlan_cp_stats_cfg_state cfg_state, 298 enum wlan_umac_comp_id comp_id, 299 void *cmn_obj, void *data) 300 { 301 QDF_STATUS status = QDF_STATUS_E_FAILURE; 302 struct cp_stats_context *csc; 303 struct wlan_objmgr_psoc *psoc; 304 struct wlan_objmgr_pdev *pdev; 305 struct wlan_objmgr_vdev *vdev; 306 struct wlan_objmgr_peer *peer; 307 enum wlan_cp_stats_comp_id cp_stats_comp_id; 308 309 if (!cmn_obj) { 310 cp_stats_err("common object is null!"); 311 return QDF_STATUS_E_INVAL; 312 } 313 314 cp_stats_comp_id = wlan_cp_stats_get_comp_id(comp_id); 315 if (cp_stats_comp_id >= WLAN_CP_STATS_MAX_COMPONENTS) { 316 cp_stats_err("Invalid UMAC id provided to cp_stats"); 317 return QDF_STATUS_E_INVAL; 318 } 319 320 switch (obj_type) { 321 case WLAN_PSOC_OP: 322 psoc = (struct wlan_objmgr_psoc *)cmn_obj; 323 csc = 324 wlan_objmgr_psoc_get_comp_private_obj 325 (psoc, WLAN_UMAC_COMP_CP_STATS); 326 break; 327 case WLAN_PDEV_OP: 328 pdev = (struct wlan_objmgr_pdev *)cmn_obj; 329 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 330 break; 331 case WLAN_VDEV_OP: 332 vdev = (struct wlan_objmgr_vdev *)cmn_obj; 333 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 334 break; 335 case WLAN_PEER_OP: 336 peer = (struct wlan_objmgr_peer *)cmn_obj; 337 csc = wlan_cp_stats_ctx_get_from_peer(peer); 338 break; 339 default: 340 cp_stats_err("Invalid common object type"); 341 return QDF_STATUS_E_INVAL; 342 } 343 344 if (!csc) { 345 cp_stats_err("cp_stats_context is null!"); 346 return QDF_STATUS_E_FAILURE; 347 } 348 349 if (csc->cp_stats_comp_obj_config) 350 status = csc->cp_stats_comp_obj_config(obj_type, cfg_state, 351 cp_stats_comp_id, 352 cmn_obj, data); 353 354 return status; 355 } 356 357 void wlan_cp_stats_vdev_mcast_rx_pnerr(struct wlan_objmgr_vdev *vdev) 358 { 359 struct vdev_cp_stats *vdev_cs = wlan_cp_stats_get_vdev_stats_obj(vdev); 360 361 if (vdev_cs && vdev_cs->mcast_rx_pnerr_stats_inc) 362 vdev_cs->mcast_rx_pnerr_stats_inc(vdev, 1); 363 } 364 365 void wlan_cp_stats_peer_rx_pnerr(struct wlan_objmgr_peer *peer) 366 { 367 struct peer_cp_stats *peer_cs = wlan_cp_stats_get_peer_stats_obj(peer); 368 369 if (peer_cs && peer_cs->rx_pnerr_stats_inc) 370 peer_cs->rx_pnerr_stats_inc(peer, 1); 371 } 372 373 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED) 374 QDF_STATUS 375 tgt_cp_stats_twt_get_session_evt_handler( 376 struct wlan_objmgr_psoc *psoc, 377 struct twt_session_stats_info *twt_params) 378 { 379 return wlan_cp_stats_twt_get_session_evt_handler(psoc, twt_params); 380 } 381 #endif 382