1 /* 2 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * Doc: wlan_cp_stats_om_handler.c 21 * 22 * This file provide definitions to APIs invoked on receiving common object 23 * repective create/destroy event notifications, which further 24 * (de)allocate cp specific objects and (de)attach to specific 25 * common object 26 */ 27 #include "wlan_cp_stats_obj_mgr_handler.h" 28 #include "wlan_cp_stats_defs.h" 29 #include "wlan_cp_stats_ol_api.h" 30 #include <wlan_cp_stats_ucfg_api.h> 31 #include "wlan_cp_stats_utils_api.h" 32 33 QDF_STATUS 34 wlan_cp_stats_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg) 35 { 36 WLAN_DEV_TYPE dev_type; 37 struct cp_stats_context *csc = NULL; 38 struct psoc_cp_stats *psoc_cs = NULL; 39 QDF_STATUS status = QDF_STATUS_E_FAILURE; 40 41 if (!psoc) { 42 cp_stats_err("PSOC is NULL"); 43 status = QDF_STATUS_E_INVAL; 44 goto wlan_cp_stats_psoc_obj_create_handler_return; 45 } 46 47 csc = qdf_mem_malloc(sizeof(*csc)); 48 if (!csc) { 49 status = QDF_STATUS_E_NOMEM; 50 goto wlan_cp_stats_psoc_obj_create_handler_return; 51 } 52 53 csc->psoc_obj = psoc; 54 dev_type = wlan_objmgr_psoc_get_dev_type(csc->psoc_obj); 55 if (dev_type == WLAN_DEV_INVALID) { 56 cp_stats_err("Failed to init cp stats ctx, bad device type"); 57 status = QDF_STATUS_E_INVAL; 58 goto wlan_cp_stats_psoc_obj_create_handler_return; 59 } else if (WLAN_DEV_OL == dev_type) { 60 csc->cp_stats_ctx_init = wlan_cp_stats_ctx_init_ol; 61 csc->cp_stats_ctx_deinit = wlan_cp_stats_ctx_deinit_ol; 62 } 63 64 if (QDF_STATUS_SUCCESS != csc->cp_stats_ctx_init(csc)) { 65 cp_stats_err("Failed to init global ctx call back handlers"); 66 goto wlan_cp_stats_psoc_obj_create_handler_return; 67 } 68 69 psoc_cs = qdf_mem_malloc(sizeof(*psoc_cs)); 70 if (!psoc_cs) { 71 status = QDF_STATUS_E_NOMEM; 72 goto wlan_cp_stats_psoc_obj_create_handler_return; 73 } 74 75 psoc_cs->psoc_obj = psoc; 76 csc->psoc_cs = psoc_cs; 77 if (csc->cp_stats_psoc_obj_init) { 78 if (QDF_STATUS_SUCCESS != 79 csc->cp_stats_psoc_obj_init(psoc_cs)) { 80 cp_stats_err("Failed to initialize psoc handlers"); 81 goto wlan_cp_stats_psoc_obj_create_handler_return; 82 } 83 } 84 85 status = wlan_objmgr_psoc_component_obj_attach(psoc, 86 WLAN_UMAC_COMP_CP_STATS, 87 csc, 88 QDF_STATUS_SUCCESS); 89 90 wlan_cp_stats_psoc_obj_create_handler_return: 91 if (QDF_IS_STATUS_ERROR(status)) { 92 if (csc) { 93 if (csc->cp_stats_psoc_obj_deinit && psoc_cs) 94 csc->cp_stats_psoc_obj_deinit(psoc_cs); 95 96 if (csc->psoc_cs) { 97 qdf_mem_free(csc->psoc_cs); 98 csc->psoc_cs = NULL; 99 } 100 101 if (csc->cp_stats_ctx_deinit) 102 csc->cp_stats_ctx_deinit(csc); 103 104 qdf_mem_free(csc); 105 csc = NULL; 106 } 107 return status; 108 } 109 110 cp_stats_debug("cp stats context attach at psoc"); 111 return status; 112 } 113 114 QDF_STATUS 115 wlan_cp_stats_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg) 116 { 117 struct cp_stats_context *csc; 118 119 if (!psoc) { 120 cp_stats_err("PSOC is NULL"); 121 return QDF_STATUS_E_NOMEM; 122 } 123 csc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 124 WLAN_UMAC_COMP_CP_STATS); 125 if (!csc) { 126 cp_stats_err("cp_stats context is NULL!"); 127 return QDF_STATUS_E_INVAL; 128 } 129 130 wlan_objmgr_psoc_component_obj_detach(psoc, 131 WLAN_UMAC_COMP_CP_STATS, csc); 132 if (csc->cp_stats_psoc_obj_deinit) 133 csc->cp_stats_psoc_obj_deinit(csc->psoc_cs); 134 qdf_mem_free(csc->psoc_cs); 135 if (csc->cp_stats_ctx_deinit) 136 csc->cp_stats_ctx_deinit(csc); 137 qdf_mem_free(csc); 138 139 cp_stats_debug("cp stats context dettached at psoc"); 140 return QDF_STATUS_SUCCESS; 141 } 142 143 QDF_STATUS 144 wlan_cp_stats_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg) 145 { 146 struct cp_stats_context *csc = NULL; 147 struct pdev_cp_stats *pdev_cs = NULL; 148 QDF_STATUS status = QDF_STATUS_E_FAILURE; 149 150 if (!pdev) { 151 cp_stats_err("PDEV is NULL"); 152 status = QDF_STATUS_E_INVAL; 153 goto wlan_cp_stats_pdev_obj_create_handler_return; 154 } 155 156 pdev_cs = qdf_mem_malloc(sizeof(*pdev_cs)); 157 if (!pdev_cs) { 158 status = QDF_STATUS_E_NOMEM; 159 goto wlan_cp_stats_pdev_obj_create_handler_return; 160 } 161 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 162 if (!csc) { 163 cp_stats_err("cp_stats context is NULL!"); 164 status = QDF_STATUS_E_INVAL; 165 goto wlan_cp_stats_pdev_obj_create_handler_return; 166 } 167 pdev_cs->pdev_obj = pdev; 168 if (csc->cp_stats_pdev_obj_init) { 169 if (QDF_STATUS_SUCCESS != 170 csc->cp_stats_pdev_obj_init(pdev_cs)) { 171 cp_stats_err("Failed to initialize pdev handlers"); 172 goto wlan_cp_stats_pdev_obj_create_handler_return; 173 } 174 } 175 176 status = wlan_objmgr_pdev_component_obj_attach(pdev, 177 WLAN_UMAC_COMP_CP_STATS, 178 pdev_cs, 179 QDF_STATUS_SUCCESS); 180 181 cp_stats_debug("pdev cp stats object attached"); 182 wlan_cp_stats_pdev_obj_create_handler_return: 183 if (QDF_IS_STATUS_ERROR(status)) { 184 if (csc) { 185 if (csc->cp_stats_pdev_obj_deinit) 186 csc->cp_stats_pdev_obj_deinit(pdev_cs); 187 } 188 189 if (pdev_cs) 190 qdf_mem_free(pdev_cs); 191 } 192 193 return status; 194 } 195 196 QDF_STATUS 197 wlan_cp_stats_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg) 198 { 199 struct pdev_cp_stats *pdev_cs; 200 struct cp_stats_context *csc; 201 202 if (!pdev) { 203 cp_stats_err("pdev is NULL"); 204 return QDF_STATUS_E_INVAL; 205 } 206 207 pdev_cs = wlan_objmgr_pdev_get_comp_private_obj(pdev, 208 WLAN_UMAC_COMP_CP_STATS); 209 if (!pdev_cs) { 210 cp_stats_err("pdev is NULL"); 211 return QDF_STATUS_E_INVAL; 212 } 213 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 214 if (!csc) { 215 cp_stats_err("cp_stats context is NULL!"); 216 return QDF_STATUS_E_INVAL; 217 } 218 219 if (csc->cp_stats_pdev_obj_deinit) 220 csc->cp_stats_pdev_obj_deinit(pdev_cs); 221 222 wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CP_STATS, 223 pdev_cs); 224 225 qdf_mem_free(pdev_cs); 226 cp_stats_debug("pdev cp stats object dettached"); 227 return QDF_STATUS_SUCCESS; 228 } 229 230 QDF_STATUS 231 wlan_cp_stats_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg) 232 { 233 struct cp_stats_context *csc = NULL; 234 struct vdev_cp_stats *vdev_cs = NULL; 235 QDF_STATUS status = QDF_STATUS_E_FAILURE; 236 237 if (!vdev) { 238 cp_stats_err("vdev is NULL"); 239 status = QDF_STATUS_E_INVAL; 240 goto wlan_cp_stats_vdev_obj_create_handler_return; 241 } 242 243 vdev_cs = qdf_mem_malloc(sizeof(*vdev_cs)); 244 if (!vdev_cs) { 245 status = QDF_STATUS_E_NOMEM; 246 goto wlan_cp_stats_vdev_obj_create_handler_return; 247 } 248 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 249 if (!csc) { 250 cp_stats_err("cp_stats context is NULL!"); 251 status = QDF_STATUS_E_INVAL; 252 goto wlan_cp_stats_vdev_obj_create_handler_return; 253 } 254 vdev_cs->vdev_obj = vdev; 255 if (csc->cp_stats_vdev_obj_init) { 256 if (QDF_STATUS_SUCCESS != 257 csc->cp_stats_vdev_obj_init(vdev_cs)) { 258 cp_stats_err("Failed to initialize vdev handlers"); 259 goto wlan_cp_stats_vdev_obj_create_handler_return; 260 } 261 } 262 263 status = wlan_objmgr_vdev_component_obj_attach(vdev, 264 WLAN_UMAC_COMP_CP_STATS, 265 vdev_cs, 266 QDF_STATUS_SUCCESS); 267 268 wlan_cp_stats_vdev_obj_create_handler_return: 269 if (QDF_IS_STATUS_ERROR(status)) { 270 if (csc) { 271 if (csc->cp_stats_vdev_obj_deinit) 272 csc->cp_stats_vdev_obj_deinit(vdev_cs); 273 } 274 275 if (vdev_cs) 276 qdf_mem_free(vdev_cs); 277 } 278 279 cp_stats_debug("vdev cp stats object attach"); 280 return status; 281 } 282 283 QDF_STATUS 284 wlan_cp_stats_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg) 285 { 286 struct vdev_cp_stats *vdev_cs; 287 struct cp_stats_context *csc; 288 289 if (!vdev) { 290 cp_stats_err("vdev is NULL"); 291 return QDF_STATUS_E_INVAL; 292 } 293 294 vdev_cs = wlan_objmgr_vdev_get_comp_private_obj(vdev, 295 WLAN_UMAC_COMP_CP_STATS); 296 if (!vdev_cs) { 297 cp_stats_err("vdev is NULL"); 298 return QDF_STATUS_E_INVAL; 299 } 300 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 301 if (!csc) { 302 cp_stats_err("cp_stats context is NULL!"); 303 return QDF_STATUS_E_INVAL; 304 } 305 306 if (csc->cp_stats_vdev_obj_deinit) 307 csc->cp_stats_vdev_obj_deinit(vdev_cs); 308 309 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_CP_STATS, 310 vdev_cs); 311 312 qdf_mem_free(vdev_cs); 313 cp_stats_debug("vdev cp stats object dettach"); 314 return QDF_STATUS_SUCCESS; 315 } 316 317 QDF_STATUS 318 wlan_cp_stats_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg) 319 { 320 struct cp_stats_context *csc = NULL; 321 struct peer_cp_stats *peer_cs = NULL; 322 QDF_STATUS status = QDF_STATUS_E_FAILURE; 323 324 if (!peer) { 325 cp_stats_err("peer is NULL"); 326 status = QDF_STATUS_E_INVAL; 327 goto wlan_cp_stats_peer_obj_create_handler_return; 328 } 329 330 peer_cs = qdf_mem_malloc(sizeof(*peer_cs)); 331 if (!peer_cs) { 332 status = QDF_STATUS_E_NOMEM; 333 goto wlan_cp_stats_peer_obj_create_handler_return; 334 } 335 csc = wlan_cp_stats_ctx_get_from_peer(peer); 336 if (!csc) { 337 cp_stats_err("cp_stats context is NULL!"); 338 status = QDF_STATUS_E_INVAL; 339 goto wlan_cp_stats_peer_obj_create_handler_return; 340 } 341 peer_cs->peer_obj = peer; 342 if (csc->cp_stats_peer_obj_init) { 343 if (QDF_STATUS_SUCCESS != 344 csc->cp_stats_peer_obj_init(peer_cs)) { 345 cp_stats_err("Failed to initialize peer handlers"); 346 goto wlan_cp_stats_peer_obj_create_handler_return; 347 } 348 } 349 350 status = wlan_objmgr_peer_component_obj_attach(peer, 351 WLAN_UMAC_COMP_CP_STATS, 352 peer_cs, 353 QDF_STATUS_SUCCESS); 354 355 wlan_cp_stats_peer_obj_create_handler_return: 356 if (QDF_IS_STATUS_ERROR(status)) { 357 if (csc) { 358 if (csc->cp_stats_peer_obj_deinit) 359 csc->cp_stats_peer_obj_deinit(peer_cs); 360 } 361 362 if (peer_cs) 363 qdf_mem_free(peer_cs); 364 } 365 366 cp_stats_debug("peer cp stats object attach"); 367 return status; 368 } 369 370 QDF_STATUS 371 wlan_cp_stats_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg) 372 { 373 struct peer_cp_stats *peer_cs; 374 struct cp_stats_context *csc; 375 376 if (!peer) { 377 cp_stats_err("peer is NULL"); 378 return QDF_STATUS_E_INVAL; 379 } 380 381 peer_cs = wlan_objmgr_peer_get_comp_private_obj(peer, 382 WLAN_UMAC_COMP_CP_STATS); 383 if (!peer_cs) { 384 cp_stats_err("peer is NULL"); 385 return QDF_STATUS_E_INVAL; 386 } 387 csc = wlan_cp_stats_ctx_get_from_peer(peer); 388 if (!csc) { 389 cp_stats_err("cp_stats context is NULL!"); 390 return QDF_STATUS_E_INVAL; 391 } 392 393 if (csc->cp_stats_peer_obj_deinit) 394 csc->cp_stats_peer_obj_deinit(peer_cs); 395 396 wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CP_STATS, 397 peer_cs); 398 399 qdf_mem_free(peer_cs); 400 cp_stats_debug("peer cp stats object dettached"); 401 return QDF_STATUS_SUCCESS; 402 } 403