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