1 /* 2 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: target_if_ext_twt_evt.c 19 * This file contains twt component's target related function definitions 20 */ 21 #include <qdf_util.h> 22 #include <wlan_twt_public_structs.h> 23 #include <wlan_lmac_if_def.h> 24 #include <target_if.h> 25 #include <target_if_ext_twt.h> 26 #include <wlan_twt_api.h> 27 #include "twt/core/src/wlan_twt_main.h" 28 29 static int target_if_twt_setup_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)30 target_if_twt_setup_complete_event_handler(ol_scn_t scn, uint8_t *event, 31 uint32_t len) 32 { 33 QDF_STATUS qdf_status; 34 struct wmi_unified *wmi_handle; 35 struct wlan_objmgr_psoc *psoc; 36 struct twt_add_dialog_complete_event *data; 37 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 38 39 TARGET_IF_ENTER(); 40 41 psoc = target_if_get_psoc_from_scn_hdl(scn); 42 if (!psoc) { 43 target_if_err("psoc is null"); 44 return -EINVAL; 45 } 46 47 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 48 if (!wmi_handle) { 49 target_if_err("wmi_handle is null"); 50 return -EINVAL; 51 } 52 53 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 54 if (!twt_rx_ops || !twt_rx_ops->twt_setup_comp_cb) { 55 target_if_err("No valid twt setup complete rx ops"); 56 return -EINVAL; 57 } 58 59 data = qdf_mem_malloc(sizeof(*data)); 60 if (!data) 61 return -ENOMEM; 62 63 qdf_status = wmi_extract_twt_add_dialog_comp_event(wmi_handle, 64 event, &data->params); 65 if (QDF_IS_STATUS_ERROR(qdf_status)) { 66 target_if_err("extract twt add dialog event failed (status=%d)", 67 qdf_status); 68 goto done; 69 } 70 71 if (data->params.num_additional_twt_params) { 72 qdf_status = wmi_extract_twt_add_dialog_comp_additional_params( 73 wmi_handle, event, len, 0, 74 &data->additional_params); 75 if (QDF_IS_STATUS_ERROR(qdf_status)) 76 goto done; 77 } 78 79 qdf_status = twt_rx_ops->twt_setup_comp_cb(psoc, data); 80 81 done: 82 qdf_mem_free(data); 83 84 return qdf_status_to_os_return(qdf_status); 85 } 86 87 static int target_if_twt_teardown_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)88 target_if_twt_teardown_complete_event_handler(ol_scn_t scn, uint8_t *event, 89 uint32_t len) 90 { 91 QDF_STATUS qdf_status; 92 struct wmi_unified *wmi_handle; 93 struct wlan_objmgr_psoc *psoc; 94 struct twt_del_dialog_complete_event_param *data; 95 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 96 97 TARGET_IF_ENTER(); 98 99 psoc = target_if_get_psoc_from_scn_hdl(scn); 100 if (!psoc) { 101 target_if_err("psoc is null"); 102 return -EINVAL; 103 } 104 105 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 106 if (!wmi_handle) { 107 target_if_err("wmi_handle is null"); 108 return -EINVAL; 109 } 110 111 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 112 if (!twt_rx_ops || !twt_rx_ops->twt_teardown_comp_cb) { 113 target_if_err("No valid twt teardown complete rx ops"); 114 return -EINVAL; 115 } 116 117 data = qdf_mem_malloc(sizeof(*data)); 118 if (!data) 119 return -ENOMEM; 120 121 qdf_status = wmi_extract_twt_del_dialog_comp_event(wmi_handle, 122 event, data); 123 if (QDF_IS_STATUS_ERROR(qdf_status)) { 124 target_if_err("extract twt del dialog event failed (status=%d)", 125 qdf_status); 126 goto done; 127 } 128 129 qdf_status = twt_rx_ops->twt_teardown_comp_cb(psoc, data); 130 131 done: 132 qdf_mem_free(data); 133 134 return qdf_status_to_os_return(qdf_status); 135 136 } 137 138 /** 139 * target_if_twt_pause_complete_event_handler - TWT pause complete handler 140 * @scn: scn 141 * @event: buffer with event 142 * @len: buffer length 143 * 144 * Return: 0 on success, negative value on failure 145 */ 146 static int target_if_twt_pause_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)147 target_if_twt_pause_complete_event_handler(ol_scn_t scn, uint8_t *event, 148 uint32_t len) 149 { 150 QDF_STATUS qdf_status; 151 struct wmi_unified *wmi_handle; 152 struct wlan_objmgr_psoc *psoc; 153 struct twt_pause_dialog_complete_event_param *param; 154 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 155 156 TARGET_IF_ENTER(); 157 158 psoc = target_if_get_psoc_from_scn_hdl(scn); 159 if (!psoc) { 160 target_if_err("psoc is null"); 161 return -EINVAL; 162 } 163 164 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 165 if (!wmi_handle) { 166 target_if_err("wmi_handle is null"); 167 return -EINVAL; 168 } 169 170 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 171 if (!twt_rx_ops || !twt_rx_ops->twt_pause_comp_cb) { 172 target_if_err("No valid twt pause complete rx ops"); 173 return -EINVAL; 174 } 175 176 param = qdf_mem_malloc(sizeof(*param)); 177 if (!param) 178 return -ENOMEM; 179 180 qdf_status = wmi_extract_twt_pause_dialog_comp_event(wmi_handle, 181 event, param); 182 if (QDF_IS_STATUS_ERROR(qdf_status)) { 183 target_if_err("extract twt pause dialog event failed (status=%d)", 184 qdf_status); 185 goto done; 186 } 187 188 qdf_status = twt_rx_ops->twt_pause_comp_cb(psoc, param); 189 190 done: 191 qdf_mem_free(param); 192 193 return qdf_status_to_os_return(qdf_status); 194 } 195 196 /** 197 * target_if_twt_resume_complete_event_handler - TWT resume complete evt handler 198 * @scn: scn 199 * @event: buffer with event 200 * @len: buffer length 201 * 202 * Return: 0 on success, negative value on failure 203 */ 204 static int target_if_twt_resume_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)205 target_if_twt_resume_complete_event_handler(ol_scn_t scn, uint8_t *event, 206 uint32_t len) 207 { 208 QDF_STATUS qdf_status; 209 struct wmi_unified *wmi_handle; 210 struct wlan_objmgr_psoc *psoc; 211 struct twt_resume_dialog_complete_event_param *param; 212 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 213 214 TARGET_IF_ENTER(); 215 216 psoc = target_if_get_psoc_from_scn_hdl(scn); 217 if (!psoc) { 218 target_if_err("psoc is null"); 219 return -EINVAL; 220 } 221 222 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 223 if (!wmi_handle) { 224 target_if_err("wmi_handle is null"); 225 return -EINVAL; 226 } 227 228 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 229 if (!twt_rx_ops || !twt_rx_ops->twt_resume_comp_cb) { 230 target_if_err("No valid twt resume complete rx ops"); 231 return -EINVAL; 232 } 233 234 param = qdf_mem_malloc(sizeof(*param)); 235 if (!param) 236 return -ENOMEM; 237 238 qdf_status = wmi_extract_twt_resume_dialog_comp_event(wmi_handle, 239 event, param); 240 if (QDF_IS_STATUS_ERROR(qdf_status)) { 241 target_if_err("extract twt resume event failed (status=%d)", 242 qdf_status); 243 goto done; 244 } 245 246 qdf_status = twt_rx_ops->twt_resume_comp_cb(psoc, param); 247 248 done: 249 qdf_mem_free(param); 250 251 return qdf_status_to_os_return(qdf_status); 252 } 253 254 /** 255 * target_if_twt_nudge_complete_event_handler - TWT nudge complete evt handler 256 * @scn: scn 257 * @event: buffer with event 258 * @len: buffer length 259 * 260 * Return: 0 on success, negative value on failure 261 */ 262 static int target_if_twt_nudge_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)263 target_if_twt_nudge_complete_event_handler(ol_scn_t scn, uint8_t *event, 264 uint32_t len) 265 { 266 QDF_STATUS qdf_status; 267 struct wmi_unified *wmi_handle; 268 struct wlan_objmgr_psoc *psoc; 269 struct twt_nudge_dialog_complete_event_param *param; 270 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 271 272 TARGET_IF_ENTER(); 273 274 psoc = target_if_get_psoc_from_scn_hdl(scn); 275 if (!psoc) { 276 target_if_err("psoc is null"); 277 return -EINVAL; 278 } 279 280 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 281 if (!wmi_handle) { 282 target_if_err("wmi_handle is null"); 283 return -EINVAL; 284 } 285 286 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 287 if (!twt_rx_ops || !twt_rx_ops->twt_nudge_comp_cb) { 288 target_if_err("No valid twt nudge complete rx ops"); 289 return -EINVAL; 290 } 291 292 param = qdf_mem_malloc(sizeof(*param)); 293 if (!param) 294 return -ENOMEM; 295 296 qdf_status = wmi_extract_twt_nudge_dialog_comp_event(wmi_handle, 297 event, param); 298 if (QDF_IS_STATUS_ERROR(qdf_status)) { 299 target_if_err("extract twt nudge event failed (status=%d)", 300 qdf_status); 301 goto done; 302 } 303 304 qdf_status = twt_rx_ops->twt_nudge_comp_cb(psoc, param); 305 306 done: 307 qdf_mem_free(param); 308 309 return qdf_status_to_os_return(qdf_status); 310 } 311 312 static int target_if_twt_notify_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)313 target_if_twt_notify_event_handler(ol_scn_t scn, uint8_t *event, 314 uint32_t len) 315 { 316 QDF_STATUS qdf_status; 317 struct wmi_unified *wmi_handle; 318 struct wlan_objmgr_psoc *psoc; 319 struct twt_notify_event_param *data; 320 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 321 322 TARGET_IF_ENTER(); 323 324 psoc = target_if_get_psoc_from_scn_hdl(scn); 325 if (!psoc) { 326 target_if_err("psoc is null"); 327 return -EINVAL; 328 } 329 330 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 331 if (!wmi_handle) { 332 target_if_err("wmi_handle is null"); 333 return -EINVAL; 334 } 335 336 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 337 if (!twt_rx_ops || !twt_rx_ops->twt_notify_comp_cb) { 338 target_if_err("No valid twt notify rx ops"); 339 return -EINVAL; 340 } 341 342 data = qdf_mem_malloc(sizeof(*data)); 343 if (!data) 344 return -ENOMEM; 345 346 qdf_status = wmi_extract_twt_notify_event(wmi_handle, event, data); 347 if (QDF_IS_STATUS_ERROR(qdf_status)) { 348 target_if_err("extract twt notify event failed (status=%d)", 349 qdf_status); 350 goto done; 351 } 352 353 qdf_status = twt_rx_ops->twt_notify_comp_cb(psoc, data); 354 355 done: 356 qdf_mem_free(data); 357 358 return qdf_status_to_os_return(qdf_status); 359 } 360 361 static int target_if_twt_ack_complete_event_handler(ol_scn_t scn,uint8_t * event,uint32_t len)362 target_if_twt_ack_complete_event_handler(ol_scn_t scn, uint8_t *event, 363 uint32_t len) 364 { 365 QDF_STATUS qdf_status; 366 struct wmi_unified *wmi_handle; 367 struct wlan_objmgr_psoc *psoc; 368 struct twt_ack_complete_event_param *data; 369 struct wlan_lmac_if_twt_rx_ops *twt_rx_ops; 370 371 TARGET_IF_ENTER(); 372 373 psoc = target_if_get_psoc_from_scn_hdl(scn); 374 if (!psoc) { 375 target_if_err("psoc is null"); 376 return -EINVAL; 377 } 378 379 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 380 if (!wmi_handle) { 381 target_if_err("wmi_handle is null"); 382 return -EINVAL; 383 } 384 385 twt_rx_ops = wlan_twt_get_rx_ops(psoc); 386 if (!twt_rx_ops || !twt_rx_ops->twt_ack_comp_cb) { 387 target_if_err("No valid twt ack rx ops"); 388 return -EINVAL; 389 } 390 391 data = qdf_mem_malloc(sizeof(*data)); 392 if (!data) 393 return -ENOMEM; 394 395 qdf_status = wmi_extract_twt_ack_comp_event(wmi_handle, event, data); 396 if (QDF_IS_STATUS_ERROR(qdf_status)) { 397 target_if_err("extract twt ack event failed (status=%d)", 398 qdf_status); 399 goto done; 400 } 401 402 qdf_status = twt_rx_ops->twt_ack_comp_cb(psoc, data); 403 404 done: 405 qdf_mem_free(data); 406 407 return qdf_status_to_os_return(qdf_status); 408 } 409 410 QDF_STATUS target_if_twt_register_ext_events(struct wlan_objmgr_psoc * psoc)411 target_if_twt_register_ext_events(struct wlan_objmgr_psoc *psoc) 412 { 413 QDF_STATUS status; 414 struct wmi_unified *wmi_handle; 415 416 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 417 if (!wmi_handle) { 418 target_if_err("wmi_handle is null!"); 419 return QDF_STATUS_E_INVAL; 420 } 421 422 status = wmi_unified_register_event_handler 423 (wmi_handle, 424 wmi_twt_add_dialog_complete_event_id, 425 target_if_twt_setup_complete_event_handler, 426 WMI_RX_WORK_CTX); 427 if (QDF_IS_STATUS_ERROR(status)) { 428 target_if_err("Failed to register twt add dialog event cb"); 429 return status; 430 } 431 432 status = wmi_unified_register_event_handler 433 (wmi_handle, 434 wmi_twt_del_dialog_complete_event_id, 435 target_if_twt_teardown_complete_event_handler, 436 WMI_RX_WORK_CTX); 437 if (QDF_IS_STATUS_ERROR(status)) { 438 target_if_err("Failed to register twt del dialog event cb"); 439 return status; 440 } 441 442 status = wmi_unified_register_event_handler 443 (wmi_handle, 444 wmi_twt_pause_dialog_complete_event_id, 445 target_if_twt_pause_complete_event_handler, 446 WMI_RX_WORK_CTX); 447 if (QDF_IS_STATUS_ERROR(status)) { 448 target_if_err("Failed to register twt pause dialog event cb"); 449 return status; 450 } 451 452 status = wmi_unified_register_event_handler 453 (wmi_handle, 454 wmi_twt_resume_dialog_complete_event_id, 455 target_if_twt_resume_complete_event_handler, 456 WMI_RX_WORK_CTX); 457 if (QDF_IS_STATUS_ERROR(status)) { 458 target_if_err("Failed to register twt resume dialog event cb"); 459 return status; 460 } 461 462 status = wmi_unified_register_event_handler 463 (wmi_handle, 464 wmi_twt_nudge_dialog_complete_event_id, 465 target_if_twt_nudge_complete_event_handler, 466 WMI_RX_WORK_CTX); 467 if (QDF_IS_STATUS_ERROR(status)) { 468 target_if_err("Failed to register twt nudge dialog event cb"); 469 return status; 470 } 471 472 status = wmi_unified_register_event_handler 473 (wmi_handle, 474 wmi_twt_notify_event_id, 475 target_if_twt_notify_event_handler, 476 WMI_RX_WORK_CTX); 477 if (QDF_IS_STATUS_ERROR(status)) { 478 target_if_err("Failed to register twt notify event cb"); 479 return status; 480 } 481 482 status = wmi_unified_register_event_handler 483 (wmi_handle, 484 wmi_twt_ack_complete_event_id, 485 target_if_twt_ack_complete_event_handler, 486 WMI_RX_WORK_CTX); 487 if (QDF_IS_STATUS_ERROR(status)) { 488 target_if_err("Failed to register twt ack event cb"); 489 return status; 490 } 491 492 return status; 493 } 494 495 QDF_STATUS target_if_twt_deregister_ext_events(struct wlan_objmgr_psoc * psoc)496 target_if_twt_deregister_ext_events(struct wlan_objmgr_psoc *psoc) 497 { 498 QDF_STATUS status; 499 struct wmi_unified *wmi_handle; 500 501 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 502 if (!wmi_handle) { 503 target_if_err("wmi_handle is null"); 504 return QDF_STATUS_E_NULL_VALUE; 505 } 506 507 status = wmi_unified_unregister_event_handler(wmi_handle, 508 wmi_twt_add_dialog_complete_event_id); 509 if (QDF_IS_STATUS_ERROR(status)) { 510 target_if_err("Failed to deregister twt add dialog event cb"); 511 return status; 512 } 513 514 status = wmi_unified_unregister_event_handler(wmi_handle, 515 wmi_twt_del_dialog_complete_event_id); 516 if (QDF_IS_STATUS_ERROR(status)) { 517 target_if_err("Failed to deregister twt del dialog event cb"); 518 return status; 519 } 520 521 status = wmi_unified_unregister_event_handler(wmi_handle, 522 wmi_twt_pause_dialog_complete_event_id); 523 if (QDF_IS_STATUS_ERROR(status)) { 524 target_if_err("Failed to deregister twt pause dialog event cb"); 525 return status; 526 } 527 528 status = wmi_unified_unregister_event_handler(wmi_handle, 529 wmi_twt_resume_dialog_complete_event_id); 530 if (QDF_IS_STATUS_ERROR(status)) { 531 target_if_err("Failed to deregister twt resume dialog event"); 532 return status; 533 } 534 535 status = wmi_unified_unregister_event_handler(wmi_handle, 536 wmi_twt_nudge_dialog_complete_event_id); 537 if (QDF_IS_STATUS_ERROR(status)) { 538 target_if_err("Failed to deregister twt nudge dialog event cb"); 539 return status; 540 } 541 542 status = wmi_unified_unregister_event_handler(wmi_handle, 543 wmi_twt_notify_event_id); 544 if (QDF_IS_STATUS_ERROR(status)) { 545 target_if_err("Failed to deregister twt notify event cb"); 546 return status; 547 } 548 549 status = wmi_unified_unregister_event_handler(wmi_handle, 550 wmi_twt_ack_complete_event_id); 551 if (QDF_IS_STATUS_ERROR(status)) { 552 target_if_err("Failed to deregister twt ack complete event cb"); 553 return status; 554 } 555 556 return status; 557 } 558 559