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