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