1 /* 2 * Copyright (c) 2018 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_defs.h" 31 #include <wlan_cp_stats_ucfg_api.h> 32 #include "wlan_cp_stats_utils_api.h" 33 34 QDF_STATUS 35 wlan_cp_stats_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg) 36 { 37 WLAN_DEV_TYPE dev_type; 38 struct cp_stats_context *csc = NULL; 39 struct psoc_cp_stats *psoc_cs = NULL; 40 QDF_STATUS status = QDF_STATUS_E_FAILURE; 41 42 if (!psoc) { 43 cp_stats_err("PSOC is NULL"); 44 status = QDF_STATUS_E_INVAL; 45 goto wlan_cp_stats_psoc_obj_create_handler_return; 46 } 47 48 csc = qdf_mem_malloc(sizeof(*csc)); 49 if (!csc) { 50 cp_stats_err("Failed to allocate cp_stats_context object"); 51 status = QDF_STATUS_E_NOMEM; 52 goto wlan_cp_stats_psoc_obj_create_handler_return; 53 } 54 55 csc->psoc_obj = psoc; 56 dev_type = wlan_objmgr_psoc_get_dev_type(csc->psoc_obj); 57 if (dev_type == WLAN_DEV_INVALID) { 58 cp_stats_err("Failed to init cp stats ctx, bad device type"); 59 status = QDF_STATUS_E_INVAL; 60 goto wlan_cp_stats_psoc_obj_create_handler_return; 61 } else if (WLAN_DEV_DA == dev_type) { 62 csc->cp_stats_ctx_init = wlan_cp_stats_ctx_init_da; 63 csc->cp_stats_ctx_deinit = wlan_cp_stats_ctx_deinit_da; 64 } else if (WLAN_DEV_OL == dev_type) { 65 csc->cp_stats_ctx_init = wlan_cp_stats_ctx_init_ol; 66 csc->cp_stats_ctx_deinit = wlan_cp_stats_ctx_deinit_ol; 67 } 68 69 if (QDF_STATUS_SUCCESS != csc->cp_stats_ctx_init(csc)) { 70 cp_stats_err("Failed to init global ctx call back handlers"); 71 goto wlan_cp_stats_psoc_obj_create_handler_return; 72 } 73 74 psoc_cs = qdf_mem_malloc(sizeof(*psoc_cs)); 75 if (!psoc_cs) { 76 cp_stats_err("Failed to allocate psoc_cp_stats object"); 77 status = QDF_STATUS_E_NOMEM; 78 goto wlan_cp_stats_psoc_obj_create_handler_return; 79 } 80 81 psoc_cs->psoc_obj = psoc; 82 csc->psoc_cs = psoc_cs; 83 if (csc->cp_stats_psoc_obj_init) { 84 if (QDF_STATUS_SUCCESS != 85 csc->cp_stats_psoc_obj_init(psoc_cs)) { 86 cp_stats_err("Failed to initialize psoc handlers"); 87 goto wlan_cp_stats_psoc_obj_create_handler_return; 88 } 89 } 90 91 status = wlan_objmgr_psoc_component_obj_attach(psoc, 92 WLAN_UMAC_COMP_CP_STATS, 93 csc, 94 QDF_STATUS_SUCCESS); 95 96 wlan_cp_stats_psoc_obj_create_handler_return: 97 if (QDF_IS_STATUS_ERROR(status)) { 98 if (csc) { 99 if (csc->cp_stats_psoc_obj_deinit) 100 csc->cp_stats_psoc_obj_deinit(psoc_cs); 101 102 if (csc->psoc_cs) { 103 qdf_mem_free(csc->psoc_cs); 104 csc->psoc_cs = NULL; 105 } 106 107 if (csc->cp_stats_ctx_deinit) 108 csc->cp_stats_ctx_deinit(csc); 109 110 qdf_mem_free(csc); 111 csc = NULL; 112 } 113 return status; 114 } 115 116 cp_stats_debug("cp stats context attach at psoc"); 117 return status; 118 } 119 120 QDF_STATUS 121 wlan_cp_stats_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg) 122 { 123 struct cp_stats_context *csc; 124 125 if (!psoc) { 126 cp_stats_err("PSOC is NULL"); 127 return QDF_STATUS_E_NOMEM; 128 } 129 csc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 130 WLAN_UMAC_COMP_CP_STATS); 131 if (!csc) { 132 cp_stats_err("cp_stats context is NULL!"); 133 return QDF_STATUS_E_INVAL; 134 } 135 136 wlan_objmgr_psoc_component_obj_detach(psoc, 137 WLAN_UMAC_COMP_CP_STATS, csc); 138 if (csc->cp_stats_psoc_obj_deinit) 139 csc->cp_stats_psoc_obj_deinit(csc->psoc_cs); 140 qdf_mem_free(csc->psoc_cs); 141 if (csc->cp_stats_ctx_deinit) 142 csc->cp_stats_ctx_deinit(csc); 143 qdf_mem_free(csc); 144 145 cp_stats_debug("cp stats context dettached at psoc"); 146 return QDF_STATUS_SUCCESS; 147 } 148 149 QDF_STATUS 150 wlan_cp_stats_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg) 151 { 152 struct cp_stats_context *csc = NULL; 153 struct pdev_cp_stats *pdev_cs = NULL; 154 QDF_STATUS status = QDF_STATUS_E_FAILURE; 155 156 if (!pdev) { 157 cp_stats_err("PDEV is NULL"); 158 status = QDF_STATUS_E_INVAL; 159 goto wlan_cp_stats_pdev_obj_create_handler_return; 160 } 161 162 pdev_cs = qdf_mem_malloc(sizeof(*pdev_cs)); 163 if (!pdev_cs) { 164 cp_stats_err("Failed to allocate pdev_cp_stats object"); 165 status = QDF_STATUS_E_NOMEM; 166 goto wlan_cp_stats_pdev_obj_create_handler_return; 167 } 168 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 169 if (!csc) { 170 cp_stats_err("cp_stats context is NULL!"); 171 status = QDF_STATUS_E_INVAL; 172 goto wlan_cp_stats_pdev_obj_create_handler_return; 173 } 174 pdev_cs->pdev_obj = pdev; 175 if (csc->cp_stats_pdev_obj_init) { 176 if (QDF_STATUS_SUCCESS != 177 csc->cp_stats_pdev_obj_init(pdev_cs)) { 178 cp_stats_err("Failed to initialize pdev handlers"); 179 goto wlan_cp_stats_pdev_obj_create_handler_return; 180 } 181 } 182 183 status = wlan_objmgr_pdev_component_obj_attach(pdev, 184 WLAN_UMAC_COMP_CP_STATS, 185 pdev_cs, 186 QDF_STATUS_SUCCESS); 187 188 cp_stats_debug("pdev cp stats object attached"); 189 wlan_cp_stats_pdev_obj_create_handler_return: 190 if (QDF_IS_STATUS_ERROR(status)) { 191 if (csc) { 192 if (csc->cp_stats_pdev_obj_deinit) 193 csc->cp_stats_pdev_obj_deinit(pdev_cs); 194 } 195 196 if (pdev_cs) 197 qdf_mem_free(pdev_cs); 198 } 199 200 return status; 201 } 202 203 QDF_STATUS 204 wlan_cp_stats_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg) 205 { 206 struct pdev_cp_stats *pdev_cs; 207 struct cp_stats_context *csc; 208 209 if (!pdev) { 210 cp_stats_err("pdev is NULL"); 211 return QDF_STATUS_E_INVAL; 212 } 213 214 pdev_cs = wlan_objmgr_pdev_get_comp_private_obj(pdev, 215 WLAN_UMAC_COMP_CP_STATS); 216 if (!pdev_cs) { 217 cp_stats_err("pdev is NULL"); 218 return QDF_STATUS_E_INVAL; 219 } 220 csc = wlan_cp_stats_ctx_get_from_pdev(pdev); 221 if (!csc) { 222 cp_stats_err("cp_stats context is NULL!"); 223 return QDF_STATUS_E_INVAL; 224 } 225 226 if (csc->cp_stats_pdev_obj_deinit) 227 csc->cp_stats_pdev_obj_deinit(pdev_cs); 228 229 wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CP_STATS, 230 pdev_cs); 231 232 qdf_mem_free(pdev_cs); 233 cp_stats_debug("pdev cp stats object dettached"); 234 return QDF_STATUS_SUCCESS; 235 } 236 237 QDF_STATUS 238 wlan_cp_stats_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg) 239 { 240 struct cp_stats_context *csc = NULL; 241 struct vdev_cp_stats *vdev_cs = NULL; 242 QDF_STATUS status = QDF_STATUS_E_FAILURE; 243 244 if (!vdev) { 245 cp_stats_err("vdev is NULL"); 246 status = QDF_STATUS_E_INVAL; 247 goto wlan_cp_stats_vdev_obj_create_handler_return; 248 } 249 250 vdev_cs = qdf_mem_malloc(sizeof(*vdev_cs)); 251 if (!vdev_cs) { 252 cp_stats_err("Failed to allocate vdev_cp_stats object"); 253 status = QDF_STATUS_E_NOMEM; 254 goto wlan_cp_stats_vdev_obj_create_handler_return; 255 } 256 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 257 if (!csc) { 258 cp_stats_err("cp_stats context is NULL!"); 259 status = QDF_STATUS_E_INVAL; 260 goto wlan_cp_stats_vdev_obj_create_handler_return; 261 } 262 vdev_cs->vdev_obj = vdev; 263 if (csc->cp_stats_vdev_obj_init) { 264 if (QDF_STATUS_SUCCESS != 265 csc->cp_stats_vdev_obj_init(vdev_cs)) { 266 cp_stats_err("Failed to initialize vdev handlers"); 267 goto wlan_cp_stats_vdev_obj_create_handler_return; 268 } 269 } 270 271 status = wlan_objmgr_vdev_component_obj_attach(vdev, 272 WLAN_UMAC_COMP_CP_STATS, 273 vdev_cs, 274 QDF_STATUS_SUCCESS); 275 276 wlan_cp_stats_vdev_obj_create_handler_return: 277 if (QDF_IS_STATUS_ERROR(status)) { 278 if (csc) { 279 if (csc->cp_stats_vdev_obj_deinit) 280 csc->cp_stats_vdev_obj_deinit(vdev_cs); 281 } 282 283 if (vdev_cs) 284 qdf_mem_free(vdev_cs); 285 } 286 287 cp_stats_debug("vdev cp stats object attach"); 288 return status; 289 } 290 291 QDF_STATUS 292 wlan_cp_stats_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg) 293 { 294 struct vdev_cp_stats *vdev_cs; 295 struct cp_stats_context *csc; 296 297 if (!vdev) { 298 cp_stats_err("vdev is NULL"); 299 return QDF_STATUS_E_INVAL; 300 } 301 302 vdev_cs = wlan_objmgr_vdev_get_comp_private_obj(vdev, 303 WLAN_UMAC_COMP_CP_STATS); 304 if (!vdev_cs) { 305 cp_stats_err("vdev is NULL"); 306 return QDF_STATUS_E_INVAL; 307 } 308 csc = wlan_cp_stats_ctx_get_from_vdev(vdev); 309 if (!csc) { 310 cp_stats_err("cp_stats context is NULL!"); 311 return QDF_STATUS_E_INVAL; 312 } 313 314 if (csc->cp_stats_vdev_obj_deinit) 315 csc->cp_stats_vdev_obj_deinit(vdev_cs); 316 317 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_CP_STATS, 318 vdev_cs); 319 320 qdf_mem_free(vdev_cs); 321 cp_stats_debug("vdev cp stats object dettach"); 322 return QDF_STATUS_SUCCESS; 323 } 324 325 QDF_STATUS 326 wlan_cp_stats_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg) 327 { 328 struct cp_stats_context *csc = NULL; 329 struct peer_cp_stats *peer_cs = NULL; 330 QDF_STATUS status = QDF_STATUS_E_FAILURE; 331 332 if (!peer) { 333 cp_stats_err("peer is NULL"); 334 status = QDF_STATUS_E_INVAL; 335 goto wlan_cp_stats_peer_obj_create_handler_return; 336 } 337 338 peer_cs = qdf_mem_malloc(sizeof(*peer_cs)); 339 if (!peer_cs) { 340 cp_stats_err("Failed to allocate peer_cp_stats object"); 341 status = QDF_STATUS_E_NOMEM; 342 goto wlan_cp_stats_peer_obj_create_handler_return; 343 } 344 csc = wlan_cp_stats_ctx_get_from_peer(peer); 345 if (!csc) { 346 cp_stats_err("cp_stats context is NULL!"); 347 status = QDF_STATUS_E_INVAL; 348 goto wlan_cp_stats_peer_obj_create_handler_return; 349 } 350 peer_cs->peer_obj = peer; 351 if (csc->cp_stats_peer_obj_init) { 352 if (QDF_STATUS_SUCCESS != 353 csc->cp_stats_peer_obj_init(peer_cs)) { 354 cp_stats_err("Failed to initialize peer handlers"); 355 goto wlan_cp_stats_peer_obj_create_handler_return; 356 } 357 } 358 359 status = wlan_objmgr_peer_component_obj_attach(peer, 360 WLAN_UMAC_COMP_CP_STATS, 361 peer_cs, 362 QDF_STATUS_SUCCESS); 363 364 wlan_cp_stats_peer_obj_create_handler_return: 365 if (QDF_IS_STATUS_ERROR(status)) { 366 if (csc) { 367 if (csc->cp_stats_peer_obj_deinit) 368 csc->cp_stats_peer_obj_deinit(peer_cs); 369 } 370 371 if (peer_cs) 372 qdf_mem_free(peer_cs); 373 } 374 375 cp_stats_debug("peer cp stats object attach"); 376 return status; 377 } 378 379 QDF_STATUS 380 wlan_cp_stats_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg) 381 { 382 struct peer_cp_stats *peer_cs; 383 struct cp_stats_context *csc; 384 385 if (!peer) { 386 cp_stats_err("peer is NULL"); 387 return QDF_STATUS_E_INVAL; 388 } 389 390 peer_cs = wlan_objmgr_peer_get_comp_private_obj(peer, 391 WLAN_UMAC_COMP_CP_STATS); 392 if (!peer_cs) { 393 cp_stats_err("peer is NULL"); 394 return QDF_STATUS_E_INVAL; 395 } 396 csc = wlan_cp_stats_ctx_get_from_peer(peer); 397 if (!csc) { 398 cp_stats_err("cp_stats context is NULL!"); 399 return QDF_STATUS_E_INVAL; 400 } 401 402 if (csc->cp_stats_peer_obj_deinit) 403 csc->cp_stats_peer_obj_deinit(peer_cs); 404 405 wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CP_STATS, 406 peer_cs); 407 408 qdf_mem_free(peer_cs); 409 cp_stats_debug("peer cp stats object dettached"); 410 return QDF_STATUS_SUCCESS; 411 } 412