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