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